Created
July 2, 2019 16:11
-
-
Save maethu/4a63e80eb3783d54de8a650dfcedb55c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from Acquisition import aq_inner | |
from Acquisition import aq_parent | |
from bumblebee.file import _ | |
from bumblebee.file.utils import format_filesize | |
from collective.prettydate.interfaces import IPrettyDate | |
from ftw.bumblebee.mimetypes import get_mimetype_image_url | |
from ftw.bumblebee.mimetypes import get_mimetype_title | |
from ftw.bumblebee.mimetypes import is_mimetype_supported | |
from ftw.bumblebee.utils import get_fallback_url | |
from ftw.bumblebee.utils import get_representation_url_by_object | |
from ftw.file.utils import FileMetadata | |
from plone.memoize import view | |
from Products.CMFCore.utils import _checkPermission | |
from Products.CMFCore.utils import getToolByName | |
from Products.CMFEditions.Permissions import AccessPreviousVersions | |
from Products.CMFPlone import PloneMessageFactory as pmf | |
from zope.component import getMultiAdapter | |
from zope.component import getUtility | |
from zope.i18n import translate | |
from zope.viewlet.interfaces import IViewlet | |
from zope.viewlet.interfaces import IViewletManager | |
class FilePreviewJournal(object): | |
"""Returns all journal items in a list | |
""" | |
def __init__(self, context, request): | |
self.context = context | |
self.request = request | |
def number_of_events(self): | |
return len(self._get_full_history()) | |
def get_journal(self, amount=5, next_event_id=0): | |
date_utility = getUtility(IPrettyDate) | |
journal_items = [] | |
for i, item in enumerate(self._get_full_history() | |
[next_event_id:next_event_id + amount]): | |
journal_items.append({ | |
'time': self.context.toLocalizedTime( | |
item['time'], long_format=True), | |
'relative_time': date_utility.date(item['time']), | |
'action': item['transition_title'], | |
'actor': self._get_user_info(item['actorid']), | |
'comment': item['comments'], | |
'downloadable_version': item['type'] == 'versioning', | |
'version_id': item.get('version_id'), | |
'version_preview_image_url': | |
self._get_version_preview_image_url( | |
item.get('version_id')), | |
'event_id': next_event_id + i}) | |
return journal_items | |
@view.memoize | |
def _get_full_history(self): | |
return self.fullHistory() or () | |
def revisionHistory(self): | |
context = aq_inner(self.context) | |
if not _checkPermission(AccessPreviousVersions, context): | |
return [] | |
rt = getToolByName(context, "portal_repository", None) | |
if rt is None or not rt.isVersionable(context): | |
return [] | |
history = rt.getHistoryMetadata(context) | |
def morphVersionDataToHistoryFormat(vdata, version_id): | |
meta = vdata['metadata']['sys_metadata'] | |
userid = meta['principal'] | |
return dict(type='versioning', | |
action=pmf(u'Edited'), | |
transition_title=pmf(u'Edited'), | |
actorid=userid, | |
time=meta['timestamp'], | |
comments=meta['comment'], | |
version_id=version_id, | |
) | |
# History may be an empty list | |
if not history: | |
return history | |
version_history = [] | |
versions = history._available | |
versions.reverse() | |
for version_id in versions: | |
vdata = history._full[version_id] | |
version_history.append( | |
morphVersionDataToHistoryFormat(vdata, version_id)) | |
return version_history | |
def fullHistory(self): | |
viewlet = self._get_content_history_viewlet() | |
history = viewlet.workflowHistory() + self.revisionHistory() | |
if len(history) == 0: | |
return None | |
history.sort(key=lambda x: x["time"], reverse=True) | |
return history | |
@view.memoize | |
def _get_content_history_viewlet(self): | |
view = getMultiAdapter( | |
(self.context, self.request), name='file_view') | |
manager = getMultiAdapter( | |
(self.context, self.request, view), | |
IViewletManager, name='plone.belowcontentbody') | |
viewlet = getMultiAdapter( | |
(self.context, self.request, view, manager), | |
IViewlet, name='plone.belowcontentbody.inlinecontenthistory') | |
viewlet.update() | |
return viewlet | |
def _get_user_info(self, userid): | |
membership_tool = getToolByName(self.context, 'portal_membership') | |
member = membership_tool.getMemberById(userid) | |
if not member: | |
return userid | |
return member.getProperty('fullname') or userid | |
def _get_version_preview_image_url(self, version_id): | |
if version_id is None: | |
return "" | |
prtool = getToolByName(self.context, 'portal_repository') | |
version_context = prtool.retrieve(self.context, version_id).object | |
representation_url = get_representation_url_by_object( | |
'thumbnail', | |
obj=version_context, | |
fallback_url=get_fallback_url()) | |
return representation_url | |
class FilePreviewCollector(object): | |
"""Returns a list with collected data. | |
Calls each function defined in collector_list | |
and adds appends the returned value to the list. | |
The prefix _data_ will be prepended to the function-names. | |
""" | |
def __init__(self, context, request): | |
self.context = context | |
self.request = request | |
self.metadata = FileMetadata(self.context) | |
self.function_prefix = '_data_' | |
def __call__(self, collector_list=[]): | |
return self.collect(collector_list) | |
def collect(self, collector_list=[]): | |
collected = [] | |
for function_name in collector_list: | |
function_ = getattr(self, "{0}{1}".format( | |
self.function_prefix, function_name), None) | |
if not function_: | |
continue | |
info_value = function_() | |
if not info_value: | |
continue | |
collected.append(info_value) | |
return collected | |
class FilePreviewFileInfoCollector(FilePreviewCollector): | |
"""Returns all collected actions infos of the context | |
""" | |
def _data_mimetype_and_filesize(self): | |
mimetype = self.context.getContentType() | |
filesize = self.context.getPrimaryField().get_size(self.context) | |
return { | |
'leftcolumn': get_mimetype_title(mimetype), | |
'rightcolumn': format_filesize(filesize), | |
} | |
def _data_filename(self): | |
return { | |
'leftcolumn': translate(_( | |
u'file_metadata_filenname_info', | |
default=u'Filename:'), | |
context=self.context.REQUEST), | |
'rightcolumn': self.context.getPrimaryField().getFilename( | |
self.context), | |
} | |
def _data_modified_date(self): | |
return { | |
'leftcolumn': translate(_( | |
u'file_metadata_dates', | |
default=u'Modified:'), | |
context=self.context.REQUEST), | |
'rightcolumn': self.metadata.modified_date, | |
} | |
def _data_document_date(self): | |
return { | |
'leftcolumn': translate(_( | |
u'file_metadata_documentdate', | |
default=u'Documentdate:'), | |
context=self.context.REQUEST), | |
'rightcolumn': self.metadata.document_date, | |
} | |
def _data_author(self): | |
if not self.metadata.show_author: | |
return None | |
author = self.metadata.author | |
authorname = author.get('name') | |
if author.get('url', None): | |
authorname = "<a href='{0}'>{1}</a>".format( | |
author.get('url'), authorname) | |
return { | |
'leftcolumn': translate(_( | |
u'file_metadata_author', | |
default=u'Author:'), | |
context=self.context.REQUEST), | |
'rightcolumn': authorname, | |
} | |
def _data_description(self): | |
description = self.context.Description() | |
if not description: | |
return None | |
return { | |
'leftcolumn': translate(_( | |
u'file_metadata_description', | |
default=u'Description:'), | |
context=self.context.REQUEST), | |
'rightcolumn': description, | |
} | |
def _data_open_containing_folder(self): | |
link = "<a href='{0}'>{1}</a>".format( | |
aq_parent(self.context).absolute_url(), | |
aq_parent(self.context).Title()) | |
return { | |
'leftcolumn': translate(_(u'file_metadata_saved_under', | |
default=u"Filed in:"), | |
context=self.context.REQUEST), | |
'rightcolumn': link, | |
} | |
class FilePreviewActionsCollector(FilePreviewCollector): | |
"""Returns all collected actions of the context | |
""" | |
def _data_open_in_overlay(self): | |
return { | |
'url': self.context.absolute_url() + '/file-preview', | |
'target': '_top', | |
'cssclass': 'openInOverlay', | |
'image': None, | |
'text': translate(_( | |
u'file_metadata_open_in_overlay', | |
default=u'Open in overlay'), | |
context=self.context.REQUEST) | |
} | |
def _data_download_original(self): | |
mimetype = self.context.getContentType() | |
return { | |
'url': self.context.absolute_url() + '/download', | |
'target': '_top', | |
'cssclass': 'original-file-link', | |
'image': {'src': get_mimetype_image_url(mimetype), | |
'title': get_mimetype_title(mimetype), | |
'alt': get_mimetype_title(mimetype), | |
'cssclass': 'mimetype_icon'}, | |
'text': translate(_( | |
u'file_metadata_download_original', | |
default=u'Download Original'), | |
context=self.context.REQUEST) | |
} | |
def _data_open_view(self): | |
return {'url': (self.context).absolute_url() + "/view", | |
'target': '_top', | |
'cssclass': 'open-view-link', | |
'image': None, | |
'text': translate(_( | |
u'file_metadata_view', | |
default=u'Open detailview'), | |
context=self.context.REQUEST) | |
} | |
def _data_send_notification(self): | |
if not self.context.restrictedTraverse('notification_form', None): | |
return None | |
return {'url': self.context.absolute_url() + '/notification_form', | |
'target': '_top', | |
'cssclass': 'send-notification-link', | |
'image': None, | |
'text': translate(_( | |
u'file_metadata_open_notification', | |
default=u'Send Notification'), | |
context=self.context.REQUEST) | |
} | |
def _data_open_pdf(self): | |
mimetype = self.context.getContentType() | |
if mimetype == 'application/pdf': | |
return None | |
if not is_mimetype_supported(mimetype): | |
return None | |
portal_url = getToolByName(self.context, 'portal_url')() | |
fallback_url = portal_url + '/preview_not_available' | |
return { | |
'url': get_representation_url_by_object( | |
'pdf', obj=self.context, fallback_url=fallback_url), | |
'target': '_top', | |
'cssclass': 'pdf-file-link', | |
'image': {'src': get_mimetype_image_url('application/pdf'), | |
'title': get_mimetype_title('application/pdf'), | |
'alt': get_mimetype_title('application/pdf'), | |
'cssclass': 'mimetype_icon'}, | |
'text': translate( | |
_(u'file_metadata_open_pdf', default=u'Open PDF'), | |
context=self.context.REQUEST) | |
} | |
def _data_delete(self): | |
if self._is_locked(): | |
return None | |
if not _checkPermission("Delete objects", self.context): | |
return None | |
return { | |
'url': "{0}/delete_confirmation".format( | |
self.context.absolute_url()), | |
'target': '_top', | |
'cssclass': 'deleteObjectLink', | |
'image': None, | |
'text': translate( | |
_(u'file_metadata_delete_file', default=u'Delete File'), | |
context=self.context.REQUEST) | |
} | |
def _data_edit(self): | |
if self._is_locked(): | |
return None | |
if not _checkPermission("Modify portal content", self.context): | |
return None | |
return { | |
'url': "{0}/edit".format( | |
self.context.absolute_url()), | |
'target': '_top', | |
'cssclass': 'editObjectLink', | |
'image': None, | |
'text': translate( | |
_(u'file_metadata_edit_file', default=u'Edit File'), | |
context=self.context.REQUEST) | |
} | |
def _data_download_this_version(self): | |
mimetype = self.context.getContentType() | |
return { | |
'url': "{0}/file_download_version?version_id={1}".format( | |
self.context.absolute_url(), self.context.version_id), | |
'target': '_top', | |
'cssclass': 'download-version-link', | |
'image': {'src': get_mimetype_image_url(mimetype), | |
'title': get_mimetype_title(mimetype), | |
'alt': get_mimetype_title(mimetype), | |
'cssclass': 'mimetype_icon'}, | |
'text': translate( | |
_(u'file_metadata_download_this_version', | |
default=u'Download this version'), | |
context=self.context.REQUEST) | |
} | |
def _data_goto_original_file(self): | |
if not _checkPermission("Modify portal content", self.context): | |
return None | |
return { | |
'url': self.context.absolute_url(), | |
'target': '_top', | |
'cssclass': 'gotoOriginalVersionLink', | |
'image': None, | |
'text': translate( | |
_(u'file_metadata_goto_original', | |
default=u'Open original document'), | |
context=self.context.REQUEST) | |
} | |
def _data_external_edit(self): | |
portal_props = getToolByName(self.context, 'portal_properties') | |
if not portal_props.site_properties.ext_editor: | |
return None | |
actions_tool = getToolByName(self.context, 'portal_actions') | |
# Do not check condition because its a bad condition | |
action = actions_tool.listActionInfos( | |
'document_actions/extedit', | |
object=self.context, | |
check_visibility=1, | |
check_permissions=1, | |
check_condition=1) | |
if not action: | |
return None | |
return { | |
'url': "{0}/external_edit".format(self.context.absolute_url()), | |
'target': '_top', | |
'cssclass': 'externalEditLink', | |
'image': None, | |
'text': translate( | |
_(u'file_metadata_external_edit', | |
default=u'Open in external editor'), | |
context=self.context.REQUEST) | |
} | |
def _is_locked(self): | |
if not hasattr(self, '_is_locked_cache'): | |
lockinfo = self.context.restrictedTraverse('@@plone_lock_info') | |
self._is_locked_cache = lockinfo.is_locked_for_current_user() | |
return self._is_locked_cache | |
class FilePreviewCollectorDefaultLists(object): | |
"""Returns the default list | |
""" | |
_list_actions_list = [ | |
'open_view', | |
'open_pdf', | |
'download_original', | |
'edit', | |
'external_edit', | |
'send_notification', | |
'delete', | |
] | |
_list_file_infos_list = [ | |
'mimetype_and_filesize', | |
'filename', | |
'modified_date', | |
'document_date', | |
'author', | |
'description', | |
'open_containing_folder'] | |
def __init__(self, context, request): | |
self.context = context | |
self.request = request | |
self.list_prefix = "_list_" | |
def __call__(self, listname): | |
collectorlist = getattr(self, "{0}{1}".format( | |
self.list_prefix, listname), None) | |
return collectorlist and collectorlist or [] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment