Source code for cubicweb.web.views.idownloadable

# copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
#
# CubicWeb is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 2.1 of the License, or (at your option)
# any later version.
#
# CubicWeb is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
# details.
#
# You should have received a copy of the GNU Lesser General Public License along
# with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
"""
Specific views for entities adapting to IDownloadable
=====================================================
"""
__docformat__ = "restructuredtext en"
from cubicweb import _

from six.moves import range

from logilab.mtconverter import BINARY_ENCODINGS, TransformError, xml_escape
from logilab.common.deprecation import class_renamed, deprecated

from cubicweb import tags
from cubicweb.view import EntityView
from cubicweb.predicates import (one_line_rset, is_instance, match_context_prop,
                                 adaptable, has_mimetype)
from cubicweb.mttransforms import ENGINE
from cubicweb.web import component, httpcache
from cubicweb.web.views import primary, baseviews


[docs]class DownloadBox(component.EntityCtxComponent): """add download box""" __regid__ = 'download_box' # no download box for images __select__ = (component.EntityCtxComponent.__select__ & adaptable('IDownloadable') & ~has_mimetype('image/')) order = 10 title = _('download') def init_rendering(self): self.items = [self.entity] def render_body(self, w): for item in self.items: idownloadable = item.cw_adapt_to('IDownloadable') w(u'<a href="%s"><img src="%s" alt="%s"/> %s</a>' % (xml_escape(idownloadable.download_url()), self._cw.uiprops['DOWNLOAD_ICON'], self._cw._('download icon'), xml_escape(idownloadable.download_file_name())))
[docs]class DownloadView(EntityView): """download view this view is replacing the deprecated 'download' controller and allow downloading of entities providing the necessary interface """ __regid__ = 'download' __select__ = one_line_rset() & adaptable('IDownloadable') templatable = False content_type = 'application/octet-stream' binary = True http_cache_manager = httpcache.EntityHTTPCacheManager add_to_breadcrumbs = False def set_request_content_type(self): """overriden to set the correct filetype and filename""" entity = self.cw_rset.complete_entity(self.cw_row or 0, self.cw_col or 0) adapter = entity.cw_adapt_to('IDownloadable') encoding = adapter.download_encoding() if encoding in BINARY_ENCODINGS: contenttype = 'application/%s' % encoding encoding = None else: contenttype = adapter.download_content_type() self._cw.set_content_type(contenttype or self.content_type, filename=adapter.download_file_name(), encoding=encoding, disposition='attachment') def call(self): entity = self.cw_rset.complete_entity(self.cw_row or 0, self.cw_col or 0) adapter = entity.cw_adapt_to('IDownloadable') self.w(adapter.download_data()) def last_modified(self): return self.cw_rset.get_entity(self.cw_row or 0, self.cw_col or 0).modification_date
[docs]class DownloadLinkView(EntityView): """view displaying a link to download the file""" __regid__ = 'downloadlink' __select__ = adaptable('IDownloadable') title = None # should not be listed in possible views def cell_call(self, row, col, title=None, **kwargs): entity = self.cw_rset.get_entity(row, col) url = xml_escape(entity.cw_adapt_to('IDownloadable').download_url()) self.w(u'<a href="%s">%s</a>' % (url, xml_escape(title or entity.dc_title())))
[docs]class IDownloadablePrimaryView(primary.PrimaryView): __select__ = adaptable('IDownloadable') def render_entity_attributes(self, entity): self.w(u'<div class="content">') adapter = entity.cw_adapt_to('IDownloadable') contenttype = adapter.download_content_type() if contenttype.startswith('image/'): self._cw.add_js('cubicweb.image.js') self.wview('image', entity.cw_rset, row=entity.cw_row, col=entity.cw_col, link=True, klass='contentimage') super(IDownloadablePrimaryView, self).render_entity_attributes(entity) elif contenttype.endswith('html'): self.wview('downloadlink', entity.cw_rset, title=self._cw._('download'), row=entity.cw_row) self.wview('ehtml', entity.cw_rset, row=entity.cw_row, col=entity.cw_col, height='600px', width='100%') else: super(IDownloadablePrimaryView, self).render_entity_attributes(entity) self.wview('downloadlink', entity.cw_rset, title=self._cw._('download'), row=entity.cw_row) self.render_data(entity, contenttype, 'text/html') self.w(u'</div>') def render_data(self, entity, sourcemt, targetmt): adapter = entity.cw_adapt_to('IDownloadable') if ENGINE.find_path(sourcemt, targetmt): try: self.w(entity._cw_mtc_transform(adapter.download_data(), sourcemt, targetmt, adapter.download_encoding())) except Exception as ex: self.exception('while rendering data for %s', entity) msg = self._cw._("can't display data, unexpected error: %s") \ % xml_escape(unicode(ex)) self.w('<div class="error">%s</div>' % msg) return True return False
[docs]class IDownloadableOneLineView(baseviews.OneLineView): __select__ = adaptable('IDownloadable') def cell_call(self, row, col, title=None, **kwargs): """the oneline view is a link to download the file""" entity = self.cw_rset.get_entity(row, col) url = xml_escape(entity.absolute_url()) adapter = entity.cw_adapt_to('IDownloadable') name = xml_escape(title or entity.dc_title()) durl = xml_escape(adapter.download_url()) self.w(u'<a href="%s">%s</a> [<a href="%s">%s</a>]' % (url, name, durl, self._cw._('download')))
class AbstractEmbeddedView(EntityView): __abstract__ = True _embedding_tag = None def call(self, **kwargs): rset = self.cw_rset for i in range(len(rset)): self.w(u'<div class="efile">') self.wview(self.__regid__, rset, row=i, col=0, **kwargs) self.w(u'</div>') def cell_call(self, row, col, link=False, **kwargs): entity = self.cw_rset.get_entity(row, col) adapter = entity.cw_adapt_to('IDownloadable') tag = self._embedding_tag(src=adapter.download_url(), # pylint: disable=E1102 alt=(self._cw._('download %s') % adapter.download_file_name()), **kwargs) if link: self.w(u'<a href="%s">%s</a>' % (adapter.download_url(), tag)) else: self.w(tag)
[docs]class ImageView(AbstractEmbeddedView): """image embedded view""" __regid__ = 'image' __select__ = has_mimetype('image/') title = _('image') _embedding_tag = tags.img
[docs]class EHTMLView(AbstractEmbeddedView): """html embedded view""" __regid__ = 'ehtml' __select__ = has_mimetype('text/html') title = _('embedded html') _embedding_tag = tags.iframe