Skip to content

Instantly share code, notes, and snippets.

@maethu
Created July 2, 2019 16:11
Show Gist options
  • Save maethu/4a63e80eb3783d54de8a650dfcedb55c to your computer and use it in GitHub Desktop.
Save maethu/4a63e80eb3783d54de8a650dfcedb55c to your computer and use it in GitHub Desktop.
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