[treeview] uuid is not available in the stdlib before python 2.5
"""Some utilities for CubicWeb server/clients.:organization: Logilab:copyright: 2001-2008 LOGILAB S.A. (Paris, FRANCE), all rights reserved.:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr"""__docformat__="restructuredtext en"frommd5importmd5fromtimeimporttimefromrandomimportrandint,seed# initialize random seed from current timeseed()defmake_uid(key):"""forge a unique identifier"""msg=str(key)+"%.10f"%time()+str(randint(0,1000000))returnmd5(msg).hexdigest()defworking_hours(mxdate):""" Predicate returning True is the date's hour is in working hours (8h->20h) """ifmxdate.hour>7andmxdate.hour<21:returnTruereturnFalsedefdate_range(begin,end,incr=1,include=None):"""yields each date between begin and end :param begin: the start date :param end: the end date :param incr: the step to use to iterate over dates. Default is one day. :param include: None (means no exclusion) or a function taking a date as parameter, and returning True if the date should be included. """date=beginwhiledate<=end:ifincludeisNoneorinclude(date):yielddatedate+=incrdefdump_class(cls,clsname):"""create copy of a class by creating an empty class inheriting from the given cls. Those class will be used as place holder for attribute and relation description """# type doesn't accept unicode name# return type.__new__(type, str(clsname), (cls,), {})# __autogenerated__ attribute is just a markerreturntype(str(clsname),(cls,),{'__autogenerated__':True})defmerge_dicts(dict1,dict2):"""update a copy of `dict1` with `dict2`"""dict1=dict(dict1)dict1.update(dict2)returndict1classSizeConstrainedList(list):"""simple list that makes sure the list does not get bigger than a given size. when the list is full and a new element is added, the first element of the list is removed before appending the new one >>> l = SizeConstrainedList(2) >>> l.append(1) >>> l.append(2) >>> l [1, 2] >>> l.append(3) [2, 3] """def__init__(self,maxsize):self.maxsize=maxsizedefappend(self,element):iflen(self)==self.maxsize:delself[0]super(SizeConstrainedList,self).append(element)defextend(self,sequence):super(SizeConstrainedList,self).extend(sequence)keepafter=len(self)-self.maxsizeifkeepafter>0:delself[:keepafter]__iadd__=extendclassUStringIO(list):"""a file wrapper which automatically encode unicode string to an encoding specifed in the constructor """def__nonzero__(self):returnTruedefwrite(self,value):assertisinstance(value,unicode),u"unicode required not %s : %s"\%(type(value).__name__,repr(value))self.append(value)defgetvalue(self):returnu''.join(self)def__repr__(self):return'<%s at %#x>'%(self.__class__.__name__,id(self))classHTMLHead(UStringIO):"""wraps HTML header's stream Request objects use a HTMLHead instance to ease adding of javascripts and stylesheets """js_unload_code=u'jQuery(window).unload(unloadPageData);'def__init__(self):super(HTMLHead,self).__init__()self.jsvars=[]self.jsfiles=[]self.cssfiles=[]self.ie_cssfiles=[]self.post_inlined_scripts=[]self.pagedata_unload=Falsedefadd_raw(self,rawheader):self.write(rawheader)defdefine_var(self,var,value):self.jsvars.append((var,value))defadd_post_inline_script(self,content):self.post_inlined_scripts.append(content)defadd_onload(self,jscode):self.add_post_inline_script(u"""jQuery(document).ready(function () {%s });"""%jscode)defadd_js(self,jsfile):"""adds `jsfile` to the list of javascripts used in the webpage This function checks if the file has already been added :param jsfile: the script's URL """ifjsfilenotinself.jsfiles:self.jsfiles.append(jsfile)defadd_css(self,cssfile,media):"""adds `cssfile` to the list of javascripts used in the webpage This function checks if the file has already been added :param cssfile: the stylesheet's URL """if(cssfile,media)notinself.cssfiles:self.cssfiles.append((cssfile,media))defadd_ie_css(self,cssfile,media='all'):"""registers some IE specific CSS"""if(cssfile,media)notinself.ie_cssfiles:self.ie_cssfiles.append((cssfile,media))defadd_unload_pagedata(self):"""registers onunload callback to clean page data on server"""ifnotself.pagedata_unload:self.post_inlined_scripts.append(self.js_unload_code)self.pagedata_unload=Truedefgetvalue(self):"""reimplement getvalue to provide a consistent (and somewhat browser optimzed cf. http://stevesouders.com/cuzillion) order in external resources declaration """w=self.write# 1/ variable declaration if anyifself.jsvars:fromsimplejsonimportdumpsw(u'<script type="text/javascript">\n')forvar,valueinself.jsvars:w(u'%s = %s;\n'%(var,dumps(value)))w(u'</script>\n')# 2/ css filesforcssfile,mediainself.cssfiles:w(u'<link rel="stylesheet" type="text/css" media="%s" href="%s"/>\n'%(media,cssfile))# 3/ ie css if necessaryifself.ie_cssfiles:w(u'<!--[if lt IE 8]>\n')forcssfile,mediainself.ie_cssfiles:w(u'<link rel="stylesheet" type="text/css" media="%s" href="%s"/>\n'%(media,cssfile))w(u'<![endif]--> \n')# 4/ js filesforjsfileinself.jsfiles:w(u'<script type="text/javascript" src="%s"></script>\n'%jsfile)# 5/ post inlined scripts (i.e. scripts depending on other JS files)ifself.post_inlined_scripts:w(u'<script type="text/javascript">\n')w(u'\n\n'.join(self.post_inlined_scripts))w(u'\n</script>\n')returnu'<head>\n%s</head>\n'%super(HTMLHead,self).getvalue()classHTMLStream(object):"""represents a HTML page. This is used my main templates so that HTML headers can be added at any time during the page generation. HTMLStream uses the (U)StringIO interface to be compliant with existing code. """def__init__(self,req):# stream for <head>self.head=req.html_headers# main streamself.body=UStringIO()self.doctype=u''# xmldecl and html opening tagself.xmldecl=u'<?xml version="1.0" encoding="%s"?>\n'%req.encodingself.htmltag=u'<html xmlns="http://www.w3.org/1999/xhtml" ' \'xmlns:cubicweb="http://www.logilab.org/2008/cubicweb" ' \'xml:lang="%s" lang="%s">'%(req.lang,req.lang)defwrite(self,data):"""StringIO interface: this method will be assigned to self.w """self.body.write(data)defgetvalue(self):"""writes HTML headers, closes </head> tag and writes HTML body"""returnu'%s\n%s\n%s\n%s\n%s\n</html>'%(self.xmldecl,self.doctype,self.htmltag,self.head.getvalue(),self.body.getvalue())classAcceptMixIn(object):"""Mixin class for vobjects defining the 'accepts' attribute describing a set of supported entity type (Any by default). """# XXX deprecated, no more necessaryfromlogilab.common.deprecationimportmoved,class_movedrql_for_eid=moved('cubicweb.common.uilib','rql_for_eid')ajax_replace_url=moved('cubicweb.common.uilib','ajax_replace_url')importcubicwebBinary=class_moved(cubicweb.Binary)