Passed
Push — master ( 804f45...1fa2c0 )
by Jordi
04:08
created

AuditLogView.__init__()   B

Complexity

Conditions 1

Size

Total Lines 67
Code Lines 56

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 56
dl 0
loc 67
rs 8.44
c 0
b 0
f 0
cc 1
nop 3

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
# -*- coding: utf-8 -*-
2
#
3
# This file is part of SENAITE.CORE.
4
#
5
# SENAITE.CORE is free software: you can redistribute it and/or modify it under
6
# the terms of the GNU General Public License as published by the Free Software
7
# Foundation, version 2.
8
#
9
# This program is distributed in the hope that it will be useful, but WITHOUT
10
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12
# details.
13
#
14
# You should have received a copy of the GNU General Public License along with
15
# this program; if not, write to the Free Software Foundation, Inc., 51
16
# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17
#
18
# Copyright 2018-2019 by it's authors.
19
# Some rights reserved, see README and LICENSE.
20
21
import collections
22
23
from bika.lims import api
24
from bika.lims import bikaMessageFactory as _
25
from bika.lims.api.snapshot import compare_snapshots
26
from bika.lims.api.snapshot import get_last_snapshot
27
from bika.lims.api.snapshot import get_snapshot_by_version
28
from bika.lims.api.snapshot import get_snapshot_metadata
29
from bika.lims.api.snapshot import get_snapshot_version
30
from bika.lims.browser.bika_listing import BikaListingView
31
from bika.lims.config import PROJECTNAME
32
from bika.lims.interfaces import IAuditLog
33
from bika.lims.utils import get_link
34
from plone.app.folder.folder import ATFolder
35
from plone.app.folder.folder import ATFolderSchema
36
from Products.Archetypes import atapi
37
from Products.ATContentTypes.content import schemata
38
from zope.interface.declarations import implements
39
40
41
class AuditLogView(BikaListingView):
42
43
    def __init__(self, context, request):
44
        super(AuditLogView, self).__init__(context, request)
45
46
        self.catalog = "auditlog_catalog"
47
48
        self.contentFilter = {
49
            "sort_on": "snapshot_created",
50
            "sort_order": "desscending",
51
        }
52
53
        self.context_actions = {}
54
55
        self.title = self.context.translate(_("Audit Log"))
56
        self.icon = "{}/{}".format(
57
            self.portal_url,
58
            "/++resource++bika.lims.images/auditlog_big.png"
59
        )
60
61
        self.show_select_column = False
62
        self.pagesize = 25
63
64
        self.columns = collections.OrderedDict((
65
            ("title", {
66
                "title": _("Title"),
67
                "index": "title"}),
68
            ("version", {
69
                "title": _("Version"),
70
                "index": "snapshot_version",
71
                "sortable": True}),
72
            ("modified", {
73
                "title": _("Date Modified"),
74
                "index": "modified",
75
                "sortable": True}),
76
            ("actor", {
77
                "title": _("Actor"),
78
                "index": "actor",
79
                "sortable": True}),
80
            ("fullname", {
81
                "title": _("Fullname"),
82
                "index": "fullname",
83
                "sortable": True}),
84
            ("roles", {
85
                "title": _("Roles"),
86
                "sortable": False,
87
                "toggle": False}),
88
            ("remote_address", {
89
                "title": _("Remote IP"),
90
                "sortable": True}),
91
            ("action", {
92
                "title": _("Action"),
93
                "index": "action",
94
                "sortable": True}),
95
            ("review_state", {
96
                "title": _("Workflow State"),
97
                "index": "review_state",
98
                "sortable": True}),
99
            ("diff", {
100
                "title": _("Changes"),
101
                "sortable": False}),
102
        ))
103
104
        self.review_states = [
105
            {
106
                "id": "default",
107
                "title": _("Active"),
108
                "contentFilter": {},
109
                "columns": self.columns.keys(),
110
            }
111
        ]
112
113
    def before_render(self):
114
        """Before template render hook
115
        """
116
        # Don't allow any context actions
117
        self.request.set("disable_border", 1)
118
119
    def folderitem(self, obj, item, index):
120
        """Service triggered each time an item is iterated in folderitems.
121
        The use of this service prevents the extra-loops in child objects.
122
        :obj: the instance of the class to be foldered
123
        :item: dict containing the properties of the object to be used by
124
            the template
125
        :index: current index of the item
126
        """
127
128
        # We are using the existing logic from the auditview
129
        logview = api.get_view("auditlog", context=obj, request=self.request)
130
131
        # get the last snapshot
132
        snapshot = get_last_snapshot(obj)
133
        # get the metadata of the last snapshot
134
        metadata = get_snapshot_metadata(snapshot)
135
136
        title = obj.Title()
137
        url = obj.absolute_url()
138
        auditlog_url = "{}/@@auditlog".format(url)
139
140
        # Title
141
        item["title"] = title
142
        # Link the title to the auditlog of the object
143
        item["replace"]["title"] = get_link(auditlog_url, value=title)
144
145
        # Version
146
        version = get_snapshot_version(obj, snapshot)
147
        item["version"] = version
148
149
        # Modification Date
150
        m_date = metadata.get("modified")
151
        item["modified"] = logview.to_localized_time(m_date)
152
153
        # Actor
154
        actor = metadata.get("actor")
155
        item["actor"] = actor
156
157
        # Fullname
158
        properties = api.get_user_properties(actor)
159
        item["fullname"] = properties.get("fullname", actor)
160
161
        # Roles
162
        roles = metadata.get("roles", [])
163
        item["roles"] = ", ".join(roles)
164
165
        # Remote Address
166
        remote_address = metadata.get("remote_address")
167
        item["remote_address"] = remote_address
168
169
        # Action
170
        action = metadata.get("action")
171
        item["action"] = logview.translate_state(action)
172
173
        # Review State
174
        review_state = metadata.get("review_state")
175
        item["review_state"] = logview.translate_state(review_state)
176
177
        # get the previous snapshot
178
        prev_snapshot = get_snapshot_by_version(obj, version-1)
179 View Code Duplication
        if prev_snapshot:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
180
            prev_metadata = get_snapshot_metadata(prev_snapshot)
181
            prev_review_state = prev_metadata.get("review_state")
182
            if prev_review_state != review_state:
183
                item["replace"]["review_state"] = "{} → {}".format(
184
                    logview.translate_state(prev_review_state),
185
                    logview.translate_state(review_state))
186
187
            # Rendered Diff
188
            diff = compare_snapshots(snapshot, prev_snapshot)
189
            item["diff"] = logview.render_diff(diff)
190
191
        return item
192
193
194
schema = ATFolderSchema.copy()
195
196
197
class AuditLog(ATFolder):
198
    implements(IAuditLog)
199
    displayContentsTab = False
200
    schema = schema
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable schema does not seem to be defined.
Loading history...
201
202
203
schemata.finalizeATCTSchema(schema, folderish=True, moveDiscussion=False)
204
atapi.registerType(AuditLog, PROJECTNAME)
205