Passed
Push — 2.x ( a7f0a0...02ca02 )
by Jordi
07:10
created

reindex_content_structure()   B

Complexity

Conditions 6

Size

Total Lines 20
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 13
dl 0
loc 20
rs 8.6666
c 0
b 0
f 0
cc 6
nop 1
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-2025 by it's authors.
19
# Some rights reserved, see README and LICENSE.
20
21
import itertools
22
23
from Acquisition import aq_base
24
from bika.lims import api
25
from bika.lims import logger
26
from plone import api as ploneapi
27
28
PROFILE_ID = "profile-bika.lims:default"
29
30
GROUPS = [
31
    {
32
        "id": "Analysts",
33
        "title": "Analysts",
34
        "roles": ["Analyst"],
35
    }, {
36
        "id": "Clients",
37
        "title": "Clients",
38
        "roles": ["Client"],
39
    }, {
40
        "id": "LabClerks",
41
        "title": "Lab Clerks",
42
        "roles": ["LabClerk"],
43
    }, {
44
        "id": "LabManagers",
45
        "title": "Lab Managers",
46
        "roles": ["LabManager"],
47
    }, {
48
        "id": "Preservers",
49
        "title": "Preservers",
50
        "roles": ["Preserver"],
51
    }, {
52
        "id": "Publishers",
53
        "title": "Publishers",
54
        "roles": ["Publisher"],
55
    }, {
56
        "id": "Verifiers",
57
        "title": "Verifiers",
58
        "roles": ["Verifier"],
59
    }, {
60
        "id": "Samplers",
61
        "title": "Samplers",
62
        "roles": ["Sampler"],
63
    }, {
64
        "id": "RegulatoryInspectors",
65
        "title": "Regulatory Inspectors",
66
        "roles": ["RegulatoryInspector"],
67
    }, {
68
        "id": "SamplingCoordinators",
69
        "title": "Sampling Coordinator",
70
        "roles": ["SamplingCoordinator"],
71
    }
72
]
73
74
NAV_BAR_ITEMS_TO_HIDE = (
75
    # List of items to hide from navigation bar
76
    "pricelists",
77
)
78
79
80
CONTENTS_TO_DELETE = (
81
    # List of items to delete
82
    "Members",
83
    "news",
84
    "events",
85
)
86
87
ALLOWED_STYLES = [
88
    "color",
89
    "background-color"
90
]
91
92
93
def setup_handler(context):
94
    """SENAITE setup handler
95
    """
96
97
    if context.readDataFile("bika.lims_various.txt") is None:
98
        return
99
100
    logger.info("SENAITE setup handler [BEGIN]")
101
102
    portal = context.getSite()
103
104
    # Run Installers
105
    hide_navbar_items(portal)
106
    reindex_content_structure(portal)
107
    setup_groups(portal)
108
    # XXX P5: Fix HTML filtering
109
    # setup_html_filter(portal)
110
111
    logger.info("SENAITE setup handler [DONE]")
112
113
114
def hide_navbar_items(portal):
115
    """Hide root items in navigation
116
    """
117
    logger.info("*** Hide Navigation Items ***")
118
119
    # Get the list of object ids for portal
120
    object_ids = portal.objectIds()
121
    object_ids = filter(lambda id: id in object_ids, NAV_BAR_ITEMS_TO_HIDE)
122
    for object_id in object_ids:
123
        item = portal[object_id]
124
        item.setExcludeFromNav(True)
125
        item.reindexObject()
126
127
128
def reindex_content_structure(portal):
129
    """Reindex contents generated by Generic Setup
130
    """
131
    logger.info("*** Reindex content structure ***")
132
133
    def reindex(obj, recurse=False):
134
        # skip catalog tools etc.
135
        if api.is_object(obj):
136
            obj.reindexObject()
137
        if recurse and hasattr(aq_base(obj), "objectValues"):
138
            map(reindex, obj.objectValues())
139
140
    # Get bika_setup for subfolder reindexing (analysisservices, etc.)
141
    bika_setup = portal.get("bika_setup")
142
    setupitems = bika_setup.objectValues() if bika_setup else []
143
    rootitems = portal.objectValues()
144
145
    for obj in itertools.chain(setupitems, rootitems):
146
        logger.info("Reindexing {}".format(repr(obj)))
147
        reindex(obj)
148
149
150
def setup_groups(portal):
151
    """Setup roles and groups
152
    """
153
    logger.info("*** Setup Roles and Groups ***")
154
155
    portal_groups = api.get_tool("portal_groups")
156
157
    for gdata in GROUPS:
158
        group_id = gdata["id"]
159
        # create the group and grant the roles
160
        if group_id not in portal_groups.listGroupIds():
161
            logger.info("+++ Adding group {title} ({id})".format(**gdata))
162
            portal_groups.addGroup(group_id,
163
                                   title=gdata["title"],
164
                                   roles=gdata["roles"])
165
        # grant the roles to the existing group
166
        else:
167
            ploneapi.group.grant_roles(
168
                groupname=gdata["id"],
169
                roles=gdata["roles"],)
170
            logger.info("+++ Granted group {title} ({id}) the roles {roles}"
171
                        .format(**gdata))
172
173
174
def setup_html_filter(portal):
175
    """Setup HTML filtering for resultsinterpretations
176
    """
177
    logger.info("*** Setup HTML Filter ***")
178
    # XXX P5: Fix ImportError: No module named controlpanel.filter
179
    from plone.app.controlpanel.filter import IFilterSchema
180
    # bypass the broken API from portal_transforms
181
    adapter = IFilterSchema(portal)
182
    style_whitelist = adapter.style_whitelist
183
    for style in ALLOWED_STYLES:
184
        logger.info("Allow style '{}'".format(style))
185
        if style not in style_whitelist:
186
            style_whitelist.append(style)
187
    adapter.style_whitelist = style_whitelist
188