• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

IMIO / imio.history / 9516193436

14 Jun 2024 12:34PM UTC coverage: 95.873%. Remained the same
9516193436

push

github

gbastien
Added `utils.get_all_history_attr` to `safe_utils`.

302 of 315 relevant lines covered (95.87%)

0.96 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.41
/src/imio/history/browser/views.py
1
# -*- coding: utf-8 -*-
2

3
from imio.history.config import HISTORY_REVISION_NOT_VIEWABLE
1✔
4
from imio.history.interfaces import IImioHistory
1✔
5
from imio.prettylink.interfaces import IPrettyLink
1✔
6
from plone import api
1✔
7
from plone.app.layout.viewlets.content import ContentHistoryView
1✔
8
from plone.app.layout.viewlets.content import DocumentBylineViewlet
1✔
9
from plone.memoize.view import memoize
1✔
10
from Products.CMFCore.utils import getToolByName
1✔
11
from Products.CMFPlone.utils import safe_unicode
1✔
12
from Products.Five.browser import BrowserView
1✔
13
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
1✔
14
from zope.component import getAdapter
1✔
15
from zope.component import getAdapters
1✔
16
from zope.component import getMultiAdapter
1✔
17
from zope.i18n import translate
1✔
18

19

20
def should_highlight_history_link(context, contenthistory):
1✔
21
    """ """
22
    adapter = getAdapter(context, IImioHistory, 'workflow')
1✔
23
    history_adapters = getAdapters((context,), IImioHistory)
1✔
24
    highlight = False
1✔
25
    for adapter_name, adapter in history_adapters:
1✔
26
        if adapter.highlight_last_comment and \
1✔
27
           adapter_name in contenthistory.histories_to_handle:
28
            if adapter.historyLastEventHasComments():
1✔
29
                highlight = True
1✔
30
                break
1✔
31
    if highlight:
1✔
32
        return True
1✔
33

34

35
class IHDocumentBylineViewlet(DocumentBylineViewlet):
1✔
36
    """Overrides the DocumentBylineViewlet."""
37

38
    index = ViewPageTemplateFile("templates/document_byline.pt")
1✔
39

40
    def render(self):
1✔
41
        self.contenthistory = getMultiAdapter(
1✔
42
            (self.context, self.request), name='contenthistory')
43
        return super(IHDocumentBylineViewlet, self).render()
1✔
44

45
    def show_history(self):
1✔
46
        """Rely on contenthistory.show_history."""
47
        if super(IHDocumentBylineViewlet, self).show_history():
1✔
48
            return self.contenthistory.show_history()
1✔
49

50
    def highlight_history_link(self):
1✔
51
        """
52
          If a comment was added to last event of the object history,
53
          we highlight the link (set a css class on it) so user eye is drawn to it.
54
        """
55
        return should_highlight_history_link(self.context, self.contenthistory)
1✔
56

57

58
class IHContentHistoryView(ContentHistoryView):
1✔
59
    '''
60
      Overrides the ContentHistoryView template to use our own.
61
      We want to display the content_history as a table.
62
    '''
63
    histories_to_handle = (u'revision', u'workflow')
1✔
64
    index = ViewPageTemplateFile("templates/content_history.pt")
1✔
65

66
    def getHistory(self, checkMayViewEvent=True, checkMayViewComment=True):
1✔
67
        """Get the history for current object.
68
           Merge workflow history with content history and sort by time."""
69
        history = []
1✔
70
        history_adapters = getAdapters((self.context,), IImioHistory)
1✔
71
        for adapter_name, adapter in history_adapters:
1✔
72
            # for now, specifically limit display to u'revision' and u'workflow'
73
            if adapter_name in self.histories_to_handle:
1✔
74
                history.extend(adapter.getHistory(
1✔
75
                    checkMayViewEvent=checkMayViewEvent,
76
                    checkMayViewComment=checkMayViewComment))
77

78
        if not history:
1✔
79
            return []
1✔
80

81
        history.sort(key=lambda x: x["time"], reverse=True)
1✔
82
        return history
1✔
83

84
    def getTransitionTitle(self, transitionName):
1✔
85
        """
86
          Given a p_transitionName, return the defined title in portal_workflow
87
          as it is what is really displayed in the template.
88
        """
89
        currentWF = self._getCurrentContextWorkflow()
1✔
90
        if currentWF and transitionName in currentWF.transitions and \
1✔
91
           currentWF.transitions[transitionName].title:
92
            return currentWF.transitions[transitionName].title
1✔
93
        else:
94
            return transitionName
1✔
95

96
    def _extra_render_comments_mapping(self, event):
1✔
97
        """ """
98
        return {}
1✔
99

100
    def _translate_comments(self, event):
1✔
101
        """ """
102
        # prepare some data passed to translate as mappings
103
        mapping = event.copy()
1✔
104
        mapping['event_time'] = float(event['time'])
1✔
105
        mapping['url'] = self.context.absolute_url()
1✔
106
        mapping.update(self._extra_render_comments_mapping(event))
1✔
107
        # try to translate comments before it is turned into text/html
108
        return translate(
1✔
109
            safe_unicode(event['comments']),
110
            mapping=mapping,
111
            domain='imio.history',
112
            context=self.request)
113

114
    def renderComments(self, event, mimetype='text/plain'):
1✔
115
        """
116
          Render comments correctly as it is 'plain/text' and we want 'text/html'.
117
        """
118
        translated = self._translate_comments(event)
1✔
119
        # bypass transform when comments not viewable as we have HTML
120
        if event['comments_viewable'] is False:
1✔
121
            return translated
1✔
122
        transformsTool = api.portal.get_tool('portal_transforms')
1✔
123
        data = transformsTool.convertTo(
1✔
124
            'text/x-html-safe', translated, mimetype=mimetype)
125
        return data.getData()
1✔
126

127
    @memoize
1✔
128
    def _getCurrentContextWorkflow(self):
×
129
        """
130
          Return currently used workflow.
131
        """
132
        wfTool = getToolByName(self.context, 'portal_workflow')
1✔
133
        workflows = wfTool.getWorkflowsFor(self.context)
1✔
134
        return workflows and workflows[0] or None
1✔
135

136
    def showColors(self):
1✔
137
        """
138
          Colorize transition name?
139
        """
140
        return True
1✔
141

142
    def show_history(self):
1✔
143
        """
144
          Show the history?  This is a common method used by :
145
          - the view (@@historyview);
146
          - the viewlet (imio.history.documentbyline);
147
          - imio.actionspanel history action icon.
148
          Originally, the history is shown to people having the
149
          'CMFEditions: Access previous versions' permission, here
150
          we want everybody than can acces the object to see the history...
151
        """
152
        return True
1✔
153

154
    def show_preview(self, event):
1✔
155
        """When True, a @@history-event-preview view is displayed under the comment."""
156
        return False
×
157

158
    def showRevisionInfos(self):
1✔
159
        """Return True if the type of the context is versioned. """
160
        pr = getToolByName(self.context, 'portal_repository')
1✔
161
        if self.context.portal_type in pr.getVersionableContentTypes():
1✔
162
            return True
1✔
163
        else:
164
            return False
1✔
165

166
    def versionIsViewable(self, event):
1✔
167
        """
168
          Check if version we want to show is viewable.
169
        """
170
        return not bool(event['comments'] == HISTORY_REVISION_NOT_VIEWABLE)
1✔
171

172
    def renderCustomJS(self):
1✔
173
        """ """
174
        return '<script></script>'
1✔
175

176
    @property
1✔
177
    def member(self):
×
178
        """ """
179
        member = getattr(self, "_member", api.user.get_current())
1✔
180
        setattr(self, "_member", member)
1✔
181
        return member
1✔
182

183

184
class VersionPreviewView(BrowserView):
1✔
185
    """Makes it possible to display a preview of a given version."""
186

187
    def __init__(self, context, request):
1✔
188
        """ """
189
        super(VersionPreviewView, self).__init__(context, request)
1✔
190
        self.portal = getToolByName(self.context, 'portal_url').getPortalObject()
1✔
191
        self.portal_url = self.portal.absolute_url()
1✔
192

193
    def __call__(self, version_id):
1✔
194
        pr = getToolByName(self.context, 'portal_repository')
1✔
195
        self.versioned_object = pr.retrieve(self.context, version_id).object
1✔
196
        return super(VersionPreviewView, self).__call__()
1✔
197

198

199
class EventPreviewView(BrowserView):
1✔
200
    """Makes it possible to display a preview of a given event."""
201

202
    def __init__(self, context, request):
1✔
203
        """ """
204
        super(EventPreviewView, self).__init__(context, request)
1✔
205
        self.portal = getToolByName(self.context, 'portal_url').getPortalObject()
1✔
206
        self.portal_url = self.portal.absolute_url()
1✔
207

208
    def may_view_historized_data(self):
1✔
209
        """ """
210
        return True
1✔
211

212
    def __call__(self, event):
1✔
213
        self.event = event
1✔
214
        return super(EventPreviewView, self).__call__(event)
1✔
215

216

217
class HeaderView(BrowserView):
1✔
218
    """ """
219

220
    def get_title(self):
1✔
221
        """ """
222
        return IPrettyLink(self.context).getLink()
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc