def post_install(portal_setup): """Runs after the last import step of the *default* profile This handler is registered as a *post_handler* in the generic setup profile :param portal_setup: SetupTool """ logger.info("{} install handler [BEGIN]".format(PRODUCT_NAME.upper())) context = portal_setup._getImportContext(PROFILE_ID) portal = context.getSite() # noqa # Allow SampleImport type in Client client_fti = portal.portal_types.getTypeInfo("Client") allowed_types = list(client_fti.allowed_content_types) allowed_types.append('SampleImport') client_fti.allowed_content_types = allowed_types # Setup catalogs # setup_catalogs(portal) # Reindex new content types reindex_new_content_types(portal) # Setup ID Formatting for SampleImporter content types setup_id_formatting(portal) # Hide actions hide_actions(portal) # hide_navbar_items(portal) # Injects "store" and "recover" transitions into senaite's workflow setup_workflows(portal) logger.info("{} install handler [DONE]".format(PRODUCT_NAME.upper()))
def hide_action(folder, action_id): logger.info("Hiding {} from {} ...".format(action_id, folder.id)) if action_id not in folder: logger.info("{} not found in {} [SKIP]".format(action_id, folder.id)) return item = folder[action_id] logger.info("Hide {} ({}) from nav bar".format(action_id, item.Title())) item.setExcludeFromNav(True) def get_action_index(action_id): for n, action in enumerate(cp.listActions()): if action.getId() == action_id: return n return -1 logger.info("Hide {} from control_panel".format(action_id, item.Title())) cp = api.get_tool("portal_controlpanel") action_index = get_action_index(action_id) if (action_index == -1): logger.info("{} not found in control_panel [SKIP]".format(cp.id)) return actions = cp._cloneActions() del actions[action_index] cp._actions = tuple(actions) cp._p_changed = 1
def hide_actions(portal): """Excludes actions from both navigation portlet and from control_panel """ logger.info("Hiding actions ...") for action_id, folder_id in ACTIONS_TO_HIDE: if folder_id and folder_id not in portal: logger.info("{} not found in portal [SKIP]".format(folder_id)) continue folder = folder_id and portal[folder_id] or portal hide_action(folder, action_id)
def reindex_new_content_types(portal): """Setup new content types""" logger.info("*** Reindex new content types ***") # Index objects - Importing through GenericSetup doesn't for obj_id, folder_id in NEW_CONTENT_TYPES: folder = folder_id and portal[folder_id] or portal logger.info("Reindexing {}".format(obj_id)) obj = folder[obj_id] obj.unmarkCreationFlag() obj.reindexObject()
def hide_navbar_items(portal): """Hide root items in navigation """ logger.info("*** Hide Navigation Items ***") # Get the list of object ids for portal object_ids = portal.objectIds() object_ids = filter(lambda id: id in object_ids, NAV_BAR_ITEMS_TO_HIDE) for object_id in object_ids: item = portal[object_id] item.setExcludeFromNav(True) item.reindexObject()
def setup_id_formatting(portal, format=None): """Setup default ID Formatting for sampleimporter content types """ if not format: logger.info("Setting up ID formatting ...") for formatting in ID_FORMATTING: setup_id_formatting(portal, format=formatting) return bs = portal.bika_setup p_type = format.get("portal_type", None) if not p_type: return id_map = bs.getIDFormatting() id_format = filter(lambda id: id.get("portal_type", "") == p_type, id_map) if id_format: logger.info("ID Format for {} already set: '{}' [SKIP]".format( p_type, id_format[0]["form"])) return form = format.get("form", "") if not form: logger.info("Param 'form' for portal type {} not set [SKIP") return logger.info("Applying format '{}' for {}".format(form, p_type)) ids = list() for record in id_map: if record.get('portal_type', '') == p_type: continue ids.append(record) ids.append(format) bs.setIDFormatting(ids)
def update_workflow(portal, workflow_id, settings): """Injects 'store' and 'recover' transitions into workflow """ logger.info("Updating workflow '{}' ...".format(workflow_id)) wf_tool = api.get_tool("portal_workflow") workflow = wf_tool.getWorkflowById(workflow_id) if not workflow: logger.warn("Workflow '{}' not found [SKIP]".format(workflow_id)) states = settings.get("states", {}) for state_id, values in states.items(): update_workflow_state(workflow, state_id, values) transitions = settings.get("transitions", {}) for transition_id, values in transitions.items(): update_workflow_transition(workflow, transition_id, values)
def pre_install(portal_setup): """Runs before the first import step of the *default* profile This handler is registered as a *pre_handler* in the generic setup profile :param portal_setup: SetupTool """ logger.info("{} pre-install handler [BEGIN]".format(PRODUCT_NAME.upper())) context = portal_setup._getImportContext(PROFILE_ID) portal = context.getSite() # noqa # Only install senaite.lims once! qi = portal.portal_quickinstaller if not qi.isProductInstalled("senaite.lims"): portal_setup.runAllImportStepsFromProfile( "profile-senaite.lims:default") logger.info("{} pre-install handler [DONE]".format(PRODUCT_NAME.upper()))
def update_workflow_transition(workflow, transition_id, settings): logger.info("Updating workflow '{}', transition: '{}'".format( workflow.id, transition_id)) if transition_id not in workflow.transitions: workflow.transitions.addTransition(transition_id) transition = workflow.transitions.get(transition_id) transition.setProperties(title=settings.get("title"), new_state_id=settings.get("new_state"), after_script_name=settings.get( "after_script", ""), actbox_name=settings.get("action", settings.get("title"))) guard = transition.guard or Guard() guard_props = { "guard_permissions": "", "guard_roles": "", "guard_expr": "" } guard_props = settings.get("guard", guard_props) guard.changeFromProperties(guard_props) transition.guard = guard
def update_workflow_state(workflow, status_id, settings): logger.info("Updating workflow '{}', status: '{}' ...".format( workflow.id, status_id)) # Create the status (if does not exist yet) new_status = workflow.states.get(status_id) if not new_status: workflow.states.addState(status_id) new_status = workflow.states.get(status_id) # Set basic info (title, description, etc.) new_status.title = settings.get("title", new_status.title) new_status.description = settings.get("description", new_status.description) # Set transitions trans = settings.get("transitions", ()) if settings.get("preserve_transitions", False): trans = tuple(set(new_status.transitions + trans)) new_status.transitions = trans # Set permissions update_workflow_state_permissions(workflow, new_status, settings)
def get_ar_schema(self): """Return the AR schema """ logger.info("*** GET AR SCHEMA ***") ar = self.get_ar() return ar.Schema()
def get_ar(self): """Create a temporary AR to fetch the fields from """ logger.info("*** CREATING TEMPORARY AR ***") return self.restrictedTraverse( "portal_factory/AnalysisRequest/Request new analyses")
def update_workflow_state_permissions(workflow, status, settings): # Copy permissions from another state? permissions_copy_from = settings.get("permissions_copy_from", None) if permissions_copy_from: logger.info("Copying permissions from '{}' to '{}' ...".format( permissions_copy_from, status.id)) copy_from_state = workflow.states.get(permissions_copy_from) if not copy_from_state: logger.info("State '{}' not found [SKIP]".format(copy_from_state)) else: for perm_id in copy_from_state.permissions: perm_info = copy_from_state.getPermissionInfo(perm_id) acquired = perm_info.get("acquired", 1) roles = perm_info.get("roles", acquired and [] or ()) logger.info( "Setting permission '{}' (acquired={}): '{}'".format( perm_id, repr(acquired), ', '.join(roles))) status.setPermission(perm_id, acquired, roles) # Override permissions logger.info("Overriding permissions for '{}' ...".format(status.id)) state_permissions = settings.get('permissions', {}) if not state_permissions: logger.info("No permissions set for '{}' [SKIP]".format(status.id)) return for permission_id, roles in state_permissions.items(): state_roles = roles and roles or () if isinstance(state_roles, tuple): acq = 0 else: acq = 1 logger.info("Setting permission '{}' (acquired={}): '{}'".format( permission_id, repr(acq), ', '.join(state_roles))) status.setPermission(permission_id, acq, state_roles)
def setup_workflows(portal): """Injects 'store' and 'recover' transitions into workflow """ logger.info("Setup sampleimporter workflow ...") for wf_id, settings in WORKFLOWS_TO_UPDATE.items(): update_workflow(portal, wf_id, settings)