nicer mainvars/expression handling when initializing rql constraints
"""basic support for SIMILE's timline widgetscf. http://code.google.com/p/simile-widgets/:organization: Logilab:copyright: 2008-2009 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses"""__docformat__="restructuredtext en"importsimplejsonfromlogilab.mtconverterimportxml_escapefromcubicweb.interfacesimportICalendarablefromcubicweb.selectorsimportimplementsfromcubicweb.viewimportEntityView,StartupView_=unicodeclassTimelineJsonView(EntityView):"""generates a json file to feed Timeline.loadJSON() NOTE: work in progress (image_url, bubbleUrl and so on should be properties of entity classes or subviews) """id='timeline-json'binary=Truetemplatable=Falsecontent_type='application/json'__select__=implements(ICalendarable)date_fmt='%Y/%m/%d'defcall(self):events=[]forentityinself.rset.entities():event=self.build_event(entity)ifeventisnotNone:events.append(event)timeline_data={'dateTimeFormat':self.date_fmt,'events':events}self.w(simplejson.dumps(timeline_data))# FIXME: those properties should be defined by the entity classdefonclick_url(self,entity):returnentity.absolute_url()defonclick(self,entity):url=self.onclick_url(entity)ifurl:returnu"javascript: document.location.href='%s'"%urlreturnNonedefbuild_event(self,entity):"""converts `entity` into a JSON object {'start': '1891', 'end': '1915', 'title': 'Portrait of Horace Brodsky', 'description': 'by Henri Gaudier-Brzeska, French Sculptor, 1891-1915', 'image': 'http://imagecache2.allposters.com/images/BRGPOD/102770_b.jpg', 'link': 'http://www.allposters.com/-sp/Portrait-of-Horace-Brodsky-Posters_i1584413_.htm' } """start=entity.startstop=entity.stopstart=startorstopifstartisNoneandstopisNone:returnNoneevent_data={'start':start.strftime(self.date_fmt),'title':xml_escape(entity.dc_title()),'description':entity.dc_description(format='text/html'),'link':entity.absolute_url(),}onclick=self.onclick(entity)ifonclick:event_data['onclick']=onclickifstop:event_data['end']=stop.strftime(self.date_fmt)returnevent_dataclassTimelineViewMixIn(object):widget_class='TimelineWidget'jsfiles=('cubicweb.timeline-bundle.js','cubicweb.widgets.js','cubicweb.timeline-ext.js','cubicweb.ajax.js')defrender_url(self,loadurl,tlunit=None):tlunit=tlunitorself.req.form.get('tlunit')self.req.add_js(self.jsfiles)self.req.add_css('timeline-bundle.css')iftlunit:additional=u' cubicweb:tlunit="%s"'%tlunitelse:additional=u''self.w(u'<div class="widget" cubicweb:wdgtype="%s" 'u'cubicweb:loadtype="auto" cubicweb:loadurl="%s" %s >'%(self.widget_class,xml_escape(loadurl),additional))self.w(u'</div>')classTimelineView(TimelineViewMixIn,EntityView):"""builds a cubicweb timeline widget node"""id='timeline'title=_('timeline')__select__=implements(ICalendarable)need_navigation=Falsedefcall(self,tlunit=None):self.req.html_headers.define_var('Timeline_urlPrefix',self.req.datadir_url)rql=self.rset.printable_rql()loadurl=self.build_url(rql=rql,vid='timeline-json')self.render_url(loadurl,tlunit)classStaticTimelineView(TimelineViewMixIn,StartupView):"""similar to `TimelineView` but loads data from a static JSON file instead of one after a RQL query. """id='static-timeline'defcall(self,loadurl,tlunit=None,wdgclass=None):self.widget_class=wdgclassorself.widget_classself.render_url(loadurl,tlunit)