web/views/idownloadable.py
changeset 0 b97547f5f1fa
child 237 3df2e0ae2eba
equal deleted inserted replaced
-1:000000000000 0:b97547f5f1fa
       
     1 """Specific views for entities implementing IDownloadable
       
     2 
       
     3 :organization: Logilab
       
     4 :copyright: 2001-2008 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
       
     5 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
       
     6 """
       
     7 __docformat__ = "restructuredtext en"
       
     8 
       
     9 from logilab.mtconverter import BINARY_ENCODINGS, TransformError, html_escape
       
    10 
       
    11 from cubicweb.interfaces import IDownloadable
       
    12 from cubicweb.common.mttransforms import ENGINE
       
    13 from cubicweb.common.selectors import (onelinerset_selector, score_entity_selector,
       
    14                                     interface_selector)
       
    15 from cubicweb.web.views import baseviews
       
    16 
       
    17 _ = unicode
       
    18 
       
    19 
       
    20 def download_box(w, entity):
       
    21     w(u'<div class="sideRelated">')
       
    22     w(u'<div class="sideBoxTitle downloadBoxTitle"><span>%s</span></div>' % _('download'))
       
    23     w(u'<div class="sideBox downloadBox"><div class="sideBoxBody">')
       
    24     w(u'<a href="%s"><img src="%s" alt="%s"/> %s</a>'
       
    25       % (html_escape(entity.download_url()),
       
    26          entity.req.external_resource('DOWNLOAD_ICON'),
       
    27          _('download icon'), html_escape(entity.dc_title())))
       
    28     w(u'</div>')
       
    29     w(u'</div>\n</div>\n')
       
    30 
       
    31 class DownloadView(baseviews.EntityView):
       
    32     """this view is replacing the deprecated 'download' controller and allow downloading
       
    33     of entities providing the necessary interface
       
    34     """
       
    35     id = 'download'
       
    36     __selectors__ = (onelinerset_selector, interface_selector)
       
    37     accepts_interfaces = (IDownloadable,)
       
    38 
       
    39     templatable = False
       
    40     content_type = 'application/octet-stream'
       
    41     binary = True
       
    42     add_to_breadcrumbs = False
       
    43 
       
    44     def set_request_content_type(self):
       
    45         """overriden to set the correct filetype and filename"""
       
    46         entity = self.complete_entity(0)
       
    47         encoding = entity.download_encoding()
       
    48         if encoding in BINARY_ENCODINGS:
       
    49             contenttype = 'application/%s' % encoding
       
    50             encoding = None
       
    51         else:
       
    52             contenttype = entity.download_content_type()
       
    53         self.req.set_content_type(contenttype or self.content_type,
       
    54                                   filename=entity.download_file_name(),
       
    55                                   encoding=encoding)
       
    56 
       
    57     def call(self):
       
    58         self.w(self.complete_entity(0).download_data())
       
    59 
       
    60 
       
    61 class DownloadLinkView(baseviews.EntityView):
       
    62     """view displaying a link to download the file"""
       
    63     id = 'downloadlink'
       
    64     title = None # should not be listed in possible views
       
    65     __selectors__ = (interface_selector,)
       
    66 
       
    67     accepts_interfaces = (IDownloadable,)
       
    68     
       
    69     def cell_call(self, row, col, title=None, **kwargs):
       
    70         entity = self.entity(row, col)
       
    71         url = html_escape(entity.download_url())
       
    72         self.w(u'<a href="%s">%s</a>' % (url, html_escape(title or entity.dc_title())))
       
    73 
       
    74 
       
    75                                                                                 
       
    76 class IDownloadablePrimaryView(baseviews.PrimaryView):
       
    77     __selectors__ = (interface_selector,)
       
    78     #skip_attrs = ('eid', 'data',) # XXX
       
    79     accepts_interfaces = (IDownloadable,)
       
    80 
       
    81     def render_entity_title(self, entity):
       
    82         self.w(u'<h1>%s %s</h1>'
       
    83                % (entity.dc_type().capitalize(),
       
    84                   html_escape(entity.dc_title())))
       
    85     
       
    86     def render_entity_attributes(self, entity, siderelations):
       
    87         super(IDownloadablePrimaryView, self).render_entity_attributes(entity, siderelations)
       
    88         self.wview('downloadlink', entity.rset, title=self.req._('download'), row=entity.row)
       
    89         self.w(u'<div class="content">')
       
    90         contenttype = entity.download_content_type()
       
    91         if contenttype.startswith('image/'):
       
    92             self.wview('image', entity.rset, row=entity.row)
       
    93         else:
       
    94             try:
       
    95                 if ENGINE.has_input(contenttype):
       
    96                     self.w(entity.printable_value('data'))
       
    97             except TransformError:
       
    98                 pass
       
    99             except Exception, ex:
       
   100                 msg = self.req._("can't display data, unexpected error: %s") % ex
       
   101                 self.w('<div class="error">%s</div>' % msg)
       
   102         self.w(u'</div>')
       
   103             
       
   104     def is_side_related(self, rschema, eschema):
       
   105         """display all relations as side related"""
       
   106         return True
       
   107 
       
   108 
       
   109     def render_side_related(self, entity, siderelations):
       
   110         download_box(self.w, entity)
       
   111         super(IDownloadablePrimaryView, self).render_side_related(entity, siderelations)
       
   112 
       
   113 class IDownloadableLineView(baseviews.OneLineView):
       
   114     __selectors__ = (interface_selector,)
       
   115     # don't kick default oneline view
       
   116     accepts_interfaces = (IDownloadable,)
       
   117     
       
   118 
       
   119     def cell_call(self, row, col, title=None, **kwargs):
       
   120         """the secondary view is a link to download the file"""
       
   121         entity = self.entity(row, col)
       
   122         url = html_escape(entity.absolute_url())
       
   123         name = html_escape(entity.download_file_name())
       
   124         durl = html_escape(entity.download_url())
       
   125         self.w(u'<a href="%s">%s</a> [<a href="%s">%s</a>]' %
       
   126                (url, name, durl, self.req._('download')))
       
   127 
       
   128 
       
   129 class ImageView(baseviews.EntityView):
       
   130     __selectors__ = (interface_selector, score_entity_selector)
       
   131     id = 'image'
       
   132     title = _('image')
       
   133     accepts_interfaces = (IDownloadable,)
       
   134     
       
   135     def call(self):
       
   136         rset = self.rset
       
   137         for i in xrange(len(rset)):
       
   138             self.w(u'<div class="efile">')
       
   139             self.wview(self.id, rset, row=i, col=0)
       
   140             self.w(u'</div>')
       
   141 
       
   142     @classmethod
       
   143     def score_entity(cls, entity):
       
   144         mt = entity.download_content_type()
       
   145         if not (mt and mt.startswith('image/')):
       
   146             return 0
       
   147         return 1
       
   148     
       
   149     def cell_call(self, row, col):
       
   150         entity = self.entity(row, col)
       
   151         #if entity.data_format.startswith('image/'):
       
   152         self.w(u'<img src="%s" alt="%s"/>' % (html_escape(entity.download_url()),
       
   153                                               html_escape(entity.download_file_name())))
       
   154