views/primary.py
author Nicolas Chauvat <nicolas.chauvat@logilab.fr>
Tue, 31 Aug 2010 14:51:59 +0200
changeset 227 3f6c3b5c133f
parent 226 411f1f56c998
child 239 607876043cd6
permissions -rw-r--r--
improve feed parsing and display of microblogs

"""Primary views for blogs

:organization: Logilab
:copyright: 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
"""
__docformat__ = "restructuredtext en"

from logilab.mtconverter import xml_escape

from cubicweb.utils import UStringIO
from cubicweb.selectors import is_instance
from cubicweb.web import uicfg, component
from cubicweb.web.views import primary, workflow, baseviews

_pvs = uicfg.primaryview_section
_pvs.tag_attribute(('Blog', 'title'), 'hidden')
_pvs.tag_attribute(('Blog', 'rss_url'), 'hidden')
_pvs.tag_attribute(('BlogEntry', 'title'), 'hidden')
_pvs.tag_object_of(('*', 'entry_of', 'Blog'), 'hidden')
_pvs.tag_subject_of(('BlogEntry', 'entry_of', '*'), 'relations')
_pvs.tag_object_of(('*', 'has_creator', 'UserAccount'), 'relations')
_pvs.tag_attribute(('UserAccount', 'name'), 'hidden')

_pvdc = uicfg.primaryview_display_ctrl
_pvdc.tag_attribute(('Blog', 'description'), {'showlabel': False})

_abaa = uicfg.actionbox_appearsin_addmenu
_abaa.tag_object_of(('*', 'entry_of', 'Blog'), True)

_afs = uicfg.autoform_section
_afs.tag_subject_of(('BlogEntry', 'entry_of', 'Blog'), 'main', 'attributes')


class BlogPrimaryView(primary.PrimaryView):
    __select__ = is_instance('Blog')

    def render_entity_relations(self, entity):
        super(BlogPrimaryView, self).render_entity_relations(entity)
        rset = entity.related('entry_of', 'object')
        if rset:
            strio = UStringIO()
            self.paginate(self._cw, w=strio.write, page_size=10, rset=rset)
            self.w(strio.getvalue())
            self.wview('sameetypelist', rset, showtitle=False)
            self.w(strio.getvalue())

class SubscribeToBlogComponent(component.EntityVComponent):
    __regid__ = 'blogsubscribe'
    __select__ = component.EntityVComponent.__select__ & is_instance('Blog')
    context = 'ctxtoolbar'

    def cell_call(self, row, col, view):
        entity = self.cw_rset.get_entity(row, col)
        self.w('<a href="%s"><img src="%s" alt="%s"/></a>' % (
            xml_escape(entity.cw_adapt_to('IFeed').rss_feed_url()),
            self._cw.uiprops['RSS_LOGO_16'],
            self._cw._(u'subscribe to this blog')))

def render_blogentry_title(req, w, entity):
    w(u'<h1>%s</h1>' % entity.view('incontext'))
    w(u'<div class="author_date"><div>%s' %
      req.format_date(entity.creation_date))
    rql = None
    if entity.has_creator:
        creator = entity.has_creator[0]
        name = creator.name
        rql = 'Any X ORDERBY D DESC WHERE X is BlogEntry, X has_creator Y, '\
              'Y eid %s, X creation_date D' % creator.eid
    elif entity.creator:
        creator = entity.creator
        name = creator.name()
        rql = 'Any X ORDERBY D DESC WHERE X is BlogEntry, X created_by Y, '\
              'Y eid %s, X creation_date D' % creator.eid
    if rql:
        vtitle = _('blog entries created by %s') % name
        url = req.build_url('view', rql=rql, vtitle=vtitle, page_size=10)
        w(u' %s <a title="%s" href="%s">%s</a>' % (
            _('by'), xml_escape(vtitle), xml_escape(url), xml_escape(name)))
    w(u'</div></div>')

class BlogEntryPrimaryView(primary.PrimaryView):
    __select__ = is_instance('BlogEntry')
    show_attr_label = False

    def render_entity_toolbox(self, entity):
        # copy from PrimaryView
        context = 'ctxtoolbar'
        self.w(u'<div class="%s">' % context)
        for comp in self._cw.vreg['contentnavigation'].poss_visible_objects(
            self._cw, rset=self.cw_rset, row=self.cw_row, view=self, context=context):
            comp.render(w=self.w, row=self.cw_row, view=self)
        self.w(u'</div>')

    def render_entity_relations(self, entity):
        rset = entity.related('entry_of', 'subject')
        if rset:
            self.w(self._cw._('blogged in '))
            self.wview('csv', rset, 'null')

    def render_entity_title(self, entity):
        self._cw.add_css('cubes.blog.css')
        w = self.w
        w(u'<div class="blogentry_title">')
        render_blogentry_title(self._cw, w, entity)
        w(u'</div>')
        w(u'<br class="clear"/>')

# don't show workflow history for blog entry
class BlogEntryWFHistoryVComponent(workflow.WFHistoryVComponent):
    __select__ = workflow.WFHistoryVComponent.__select__ & is_instance('BlogEntry')

    def cell_call(self, row, col, view=None):
        pass

def format_microblog(entity):
    author = entity.has_creator[0]
    if author.has_avatar:
        imgurl = author.has_avatar[0].uri
        ablock = u'<a href="%s"><img src="%s" /></a>' % (author.absolute_url(),
                                                         xml_escape(imgurl))
    else:
        ablock = entity.has_creator[0].view('outofcontext')
    if entity.content_format == 'text/html':
        content = entity.content
    else:
        words = []
        for word in entity.content.split():
            if word.startswith('http://'):
                word = u'<a href="%s">%s</a>' % (word, word)
            else:
                word = xml_escape(word)
            words.append(word)
        content = u' '.join(words)
    return (u'<div class="microblog">'
            u'<span class="author">%s</span>'
            u'<span class="msgtxt">%s</span>'
            u'<span class="meta"><a href="%s">%s</a></span>'
            u'</div>' % (ablock, content, entity.absolute_url(), entity.creation_date))

class MicroBlogEntryPrimaryView(primary.PrimaryView):
    __select__ = primary.PrimaryView.__select__ & is_instance('MicroBlogEntry')

    def cell_call(self, row, col):
        self._cw.add_css('cubes.blog.css')
        entity = self.cw_rset.get_entity(row, col)
        self.w(format_microblog(entity))

class MicroBlogEntrySameETypeListView(baseviews.SameETypeListView):
    __select__ = baseviews.SameETypeListView.__select__ & is_instance('MicroBlogEntry')

    def cell_call(self, row, col):
        self._cw.add_css('cubes.blog.css')
        entity = self.cw_rset.get_entity(row, col)
        self.w(format_microblog(entity))