Passed
Pull Request — 2.x (#1755)
by Jordi
04:16
created

senaite.core.setuphandlers.post_install()   A

Complexity

Conditions 1

Size

Total Lines 18
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 7
dl 0
loc 18
rs 10
c 0
b 0
f 0
cc 1
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-2021 by it's authors.
19
# Some rights reserved, see README and LICENSE.
20
21
from bika.lims.setuphandlers import add_dexterity_portal_items
22
from bika.lims.setuphandlers import add_dexterity_setup_items
23
from bika.lims.setuphandlers import reindex_content_structure
24
from bika.lims.setuphandlers import setup_auditlog_catalog
25
from bika.lims.setuphandlers import setup_catalog_mappings
26
from bika.lims.setuphandlers import setup_core_catalogs
27
from bika.lims.setuphandlers import setup_form_controller_actions
28
from bika.lims.setuphandlers import setup_groups
29
from plone.registry.interfaces import IRegistry
30
from Products.CMFPlone.utils import get_installer
31
from senaite.core import logger
32
from senaite.core.config import PROFILE_ID
33
from zope.component import getUtility
34
from zope.interface import implementer
35
36
try:
37
    from Products.CMFPlone.interfaces import IMarkupSchema
38
    from Products.CMFPlone.interfaces import INonInstallable
39
except ImportError:
40
    from zope.interface import Interface
41
    IMarkupSchema = None
42
43
    class INonInstallable(Interface):
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable Interface does not seem to be defined.
Loading history...
44
        pass
45
46
47
@implementer(INonInstallable)
48
class HiddenProfiles(object):
49
    def getNonInstallableProfiles(self):
50
        """Hide all profiles from site-creation and quickinstaller (not ZMI)"""
51
        return [
52
            # Leave visible to allow upgrade via the Plone Add-on controlpanel
53
            # "bika.lims:default",
54
55
            # hide install profiles that come with Plone
56
            "Products.CMFPlacefulWorkflow:CMFPlacefulWorkflow",
57
            "Products.CMFPlacefulWorkflow:base",
58
            "Products.CMFPlacefulWorkflow:uninstall",
59
            "Products.DataGridField:default",
60
            "Products.DataGridField:example",
61
            "Products.TextIndexNG3:default",
62
            "archetypes.multilingual:default",
63
            "archetypes.referencebrowserwidget:default",
64
            "collective.js.jqueryui:default"
65
            "plone.app.iterate:default",
66
            "plone.app.iterate:plone.app.iterate",
67
            "plone.app.iterate:test",
68
            "plone.app.iterate:uninstall",
69
            "plone.app.jquery:default",
70
            "plonetheme.barceloneta:default",
71
        ]
72
73
74
CONTENTS_TO_DELETE = (
75
    # List of items to delete
76
    "Members",
77
    "news",
78
    "events",
79
)
80
81
82
def install(context):
83
    """Install handler
84
    """
85
    if context.readDataFile("senaite.core.txt") is None:
86
        return
87
88
    logger.info("SENAITE CORE install handler [BEGIN]")
89
    portal = context.getSite()
90
91
    # Run required import steps
92
    _run_import_step(portal, "skins")
93
    _run_import_step(portal, "browserlayer")
94
    _run_import_step(portal, "rolemap")
95
    _run_import_step(portal, "typeinfo")
96
    _run_import_step(portal, "factorytool")
97
    _run_import_step(portal, "workflow", "profile-senaite.core:default")
98
    _run_import_step(portal, "toolset", "profile-senaite.core:default")
99
    _run_import_step(portal, "typeinfo", "profile-senaite.core:default")
100
101
    # skip installers if already installed
102
    qi = get_installer(portal)
103
    profiles = ["bika.lims", "senaite.core"]
104
    if any(map(lambda p: qi.is_product_installed(p), profiles)):
0 ignored issues
show
introduced by
The variable qi does not seem to be defined for all execution paths.
Loading history...
105
        logger.info("SENAITE CORE already installed [SKIP]")
106
        return
107
108
    # Run Installers
109
    setup_groups(portal)
110
    remove_default_content(portal)
111
    setup_core_catalogs(portal)
112
    setup_content_structure(portal)
113
    add_dexterity_portal_items(portal)
114
    add_dexterity_setup_items(portal)
115
    setup_catalog_mappings(portal)
116
117
    # Run after all catalogs have been setup
118
    setup_auditlog_catalog(portal)
119
120
    # Set CMF Form actions
121
    setup_form_controller_actions(portal)
122
    setup_form_controller_more_action(portal)
123
124
    # Setup markup default and allowed schemas
125
    setup_markup_schema(portal)
126
127
    logger.info("SENAITE CORE install handler [DONE]")
128
129
130
def remove_default_content(portal):
131
    """Remove default Plone contents
132
    """
133
    logger.info("*** Remove Default Content ***")
134
135
    # Get the list of object ids for portal
136
    object_ids = portal.objectIds()
137
    delete_ids = filter(lambda id: id in object_ids, CONTENTS_TO_DELETE)
138
    if delete_ids:
139
        portal.manage_delObjects(ids=list(delete_ids))
140
141
142
def setup_content_structure(portal):
143
    """Install the base content structure
144
    """
145
    logger.info("*** Install SENAITE Content Types ***")
146
    _run_import_step(portal, "content")
147
    reindex_content_structure(portal)
148
149
150
def setup_form_controller_more_action(portal):
151
    """Install form controller actions for ported record widgets
152
153
    Code taken from Products.ATExtensions
154
    """
155
    logger.info("*** Install SENAITE Form Controller Actions ***")
156
    pfc = portal.portal_form_controller
157
    pfc.addFormValidators(
158
        "base_edit", "", "more", "")
159
    pfc.addFormAction(
160
        "base_edit", "success", "", "more", "traverse_to", "string:more_edit")
161
    pfc.addFormValidators(
162
        "atct_edit", "", "more", "",)
163
    pfc.addFormAction(
164
        "atct_edit", "success", "", "more", "traverse_to", "string:more_edit")
165
166
167
def _run_import_step(portal, name, profile="profile-bika.lims:default"):
168
    """Helper to install a GS import step from the given profile
169
    """
170
    logger.info("*** Running import step '{}' from profile '{}' ***"
171
                .format(name, profile))
172
    setup = portal.portal_setup
173
    setup.runImportStepFromProfile(profile, name)
174
175
176
def pre_install(portal_setup):
177
    """Runs berfore the first import step of the *default* profile
178
179
    This handler is registered as a *pre_handler* in the generic setup profile
180
181
    :param portal_setup: SetupTool
182
    """
183
    logger.info("SENAITE CORE pre-install handler [BEGIN]")
184
185
    # https://docs.plone.org/develop/addons/components/genericsetup.html#custom-installer-code-setuphandlers-py
186
    profile_id = PROFILE_ID
187
    context = portal_setup._getImportContext(profile_id)
188
    portal = context.getSite()  # noqa
189
190
    logger.info("SENAITE CORE pre-install handler [DONE]")
191
192
193
def post_install(portal_setup):
194
    """Runs after the last import step of the *default* profile
195
196
    This handler is registered as a *post_handler* in the generic setup profile
197
198
    :param portal_setup: SetupTool
199
    """
200
    logger.info("SENAITE CORE post install handler [BEGIN]")
201
202
    # https://docs.plone.org/develop/addons/components/genericsetup.html#custom-installer-code-setuphandlers-py
203
    profile_id = PROFILE_ID
204
    context = portal_setup._getImportContext(profile_id)
205
    portal = context.getSite()  # noqa
206
207
    # always apply the skins profile last to ensure our layers are first
208
    _run_import_step(portal, "skins", profile=profile_id)
209
210
    logger.info("SENAITE CORE post install handler [DONE]")
211
212
213
def setup_markup_schema(portal):
214
    """Sets the default and allowed markup schemas for RichText widgets
215
    """
216
    if not IMarkupSchema:
217
        return
218
219
    registry = getUtility(IRegistry, context=portal)
220
    settings = registry.forInterface(IMarkupSchema, prefix='plone')
221
    settings.default_type = u"text/html"
222
    settings.allowed_types = ("text/html", )
223