def clubs(self, start=0, size=11): """Get all clubs related to a person. """ mship = getToolByName(self.context, 'portal_membership') home = mship.getHomeFolder() catalog = getToolByName(self.context, 'portal_catalog') portal_workflow = getToolByName(self.context, "portal_workflow") clubs = [dict(clubobj=uuidToObject(relation.getObject().foreign_id), relation=relation, portal_type=relation.getObject().aq_inner.aq_parent.portal_type, parentobj=relation.getObject().aq_inner.aq_parent, status=portal_workflow.getStatusOf("hejasverige_relation_workflow", relation.getObject())['review_state']) for relation in catalog({'object_provides': IRelation.__identifier__, 'review_state': ('pending', 'approved'), 'path': dict(query='/'.join(home.getPhysicalPath()),), 'sort_on': 'sortable_title'})] clubs = [x for x in clubs if x['clubobj']] # for j in [i for i in dir(clubs[0].get('relation').getObject().aq_inner.aq_parent) if i.startswith('p')]: print j # clubs[0].get('relation').getObject().aq_inner.aq_parent.portal_type = 'hejasverige.person' return clubs
def update(self): self.registry = getUtility(IRegistry) self.settings = Settings(self.context) self.global_settings = self.registry.forInterface(IStreamingSettings) self.site = getPortal(self.context) self.portal_url = getMultiAdapter((self.context, self.request), name="plone_portal_state").portal_url() utils = getToolByName(self.context, 'plone_utils') msg = None if self.settings.converting is not None and \ self.settings.converting: msg = "O arquivo está sendo convertido." self.enabled = False elif self.settings.successfully_converted is not None and \ not self.settings.successfully_converted: msg = "Ocorreu um erro ao converter o arquivo. " +\ "Talvez o arquivo esteja corrombido ou é mal formatado." +\ "Cheque o log para ter mais detalhes." self.enabled = False elif self.settings.successfully_converted is None: # must have just switched to this view msg = "This document is not yet converted to document Este documento ainda não foi convertido. Por favor clique na aba `Conversor Multimídia` " +\ "para fazer a conversão." self.enabled = False mtool = getToolByName(self.context, 'portal_membership') self.can_modify = mtool.checkPermission('cmf.ModifyPortalContent', self.context) if msg and self.can_modify: utils.addPortalMessage(msg)
def applyProperties(self, userid, data): portal = getToolByName(self.context, 'portal_url').getPortalObject() mt = getToolByName(self.context, 'portal_membership') member = mt.getMemberById(userid) # cache adapters adapters = {} # Set any fields that are simply properties for the new user, rather # than fields to help create the new user register_fields = getFieldNames(IRegisterSchema) + \ getFieldNames(IAddUserSchema) for k, value in data.items(): # skip fields not available in the schema if k in ['login_name', 'user_id']: continue # skip fields that are handled exclusively on user registration and # are not part of personal information form if k in register_fields: continue # get schema adapter schema = self.fields[k].field.interface if schema in adapters: adapter = adapters[schema] else: adapters[schema] = adapter = getAdapter(portal, schema) adapter.context = member adapter.schema = schema # finally set value setattr(adapter, k, value)
def install(self, reinstall=False): """Install a set of products (which themselves may either use Install.py or GenericSetup extension profiles for their configuration) and then install a set of extension profiles. One of the extension profiles we install is that of this product. This works because an Install.py installation script (such as this one) takes precedence over extension profiles for the same product in portal_quickinstaller. We do this because it is not possible to install other products during the execution of an extension profile (i.e. we cannot do this during the importVarious step for this profile). """ portal_quickinstaller = getToolByName(self, 'portal_quickinstaller') portal_setup = getToolByName(self, 'portal_setup') for product in PRODUCT_DEPENDENCIES: if reinstall and portal_quickinstaller.isProductInstalled(product): portal_quickinstaller.reinstallProducts([product]) transaction.savepoint() elif not portal_quickinstaller.isProductInstalled(product): portal_quickinstaller.installProduct(product) transaction.savepoint() for extension_id in EXTENSION_PROFILES: portal_setup.runAllImportStepsFromProfile('profile-%s' % extension_id, purge_old=False) product_name = extension_id.split(':')[0] portal_quickinstaller.notifyInstalled(product_name) transaction.savepoint()
def sendEmail(self, addresses, subject, text): """ Send an e-mail message to the specified list of addresses. """ if not addresses: return portal_url = getToolByName(self, 'portal_url') #plone_utils = getToolByName(self, 'plone_utils') portal = portal_url.getPortalObject() fromAddress = portal.getProperty('email_from_address', None) #mailHost = plone_utils.getMailHost() #charset = plone_utils.getSiteEncoding() mailHost = getToolByName(portal, 'MailHost') #self.MailHost charset = portal.getProperty('email_charset', 'UTF-8') if fromAddress is None: LOG.error('Cannot send email: address or name is %s' % fromAddress) return try: if (type(text) == unicode): msg = MIMEText(text.encode(charset), 'plain', charset) else: msg = MIMEText(text, 'plain', charset) except Exception, e: LOG.error('Cannot send notification email: %s' % e) return
def get_actions(self, category=''): """Returns the available and visible types actions in the given category """ context = self.context types_tool = getToolByName(context, 'portal_types') ai_tool = getToolByName(context, 'portal_actionicons') actions = types_tool.listActions(object=context) plone_state = queryMultiAdapter((self.context, self.request), name='plone_portal_state') member = plone_state.member() for action in actions: wrong_permission = False for permission in action.permissions: if not member.has_permission(permission, self.context): wrong_permission = True continue if wrong_permission: continue if action.category == category: icon = ai_tool.queryActionIcon(action_id=action.id, category=category, context=context) econtext = getExprContext(context, context) action = action.getAction(ec=econtext) if action['available'] and action['visible']: yield action, icon
def handle_join_success(self, data): # portal should be acquisition wrapped, this is needed for the schema # adapter below portal = getToolByName(self.context, 'portal_url').getPortalObject() registration = getToolByName(self.context, 'portal_registration') portal_props = getToolByName(self.context, 'portal_properties') mt = getToolByName(self.context, 'portal_membership') props = portal_props.site_properties use_email_as_login = props.getProperty('use_email_as_login') if use_email_as_login: # The username field is not shown as the email is going to # be the username, but the field *is* needed further down # the line. data['username'] = data['email'] # Set username in the form; at least needed for logging in # immediately when password reset is bypassed. self.request.form['form.username'] = data['email'] user_id = data['username'] password = data.get('password') or registration.generatePassword() if isinstance(password, unicode): password = password.encode('utf8') try: registration.addMember(user_id, password, REQUEST=self.request) except (AttributeError, ValueError), err: logging.exception(err) IStatusMessage(self.request).addStatusMessage(err, type="error") return
def __call__(self): self.protect() self.errors = [] site = getSite() context = aq_inner(self.context) selection = self.get_selection() self.dest = site.restrictedTraverse( str(self.request.form['folder'].lstrip('/'))) self.catalog = getToolByName(context, 'portal_catalog') self.mtool = getToolByName(self.context, 'portal_membership') for brain in self.catalog(UID=selection): selection.remove(brain.UID) # remove everyone so we know if we # missed any obj = brain.getObject() if self.required_obj_permission: if not self.mtool.checkPermission(self.required_obj_permission, obj): self.errors.append(_('Permission denied for "${title}"', mapping={ 'title': self.objectTitle(obj) })) self.action(obj) return self.message(selection)
def __call__(self): self.pworkflow = getToolByName(self.context, 'portal_workflow') self.putils = getToolByName(self.context, 'plone_utils') self.transition_id = self.request.form.get('transition', None) self.comments = self.request.form.get('comments', '') self.recurse = self.request.form.get('recurse', 'no') == 'yes' if self.request.REQUEST_METHOD == 'POST': return super(WorkflowAction, self).__call__() else: # for GET, we return available transitions selection = self.get_selection() catalog = getToolByName(self.context, 'portal_catalog') brains = catalog(UID=selection) transitions = [] for brain in brains: obj = brain.getObject() for transition in self.pworkflow.getTransitionsFor(obj): tdata = { 'id': transition['id'], 'title': transition['name'] } if tdata not in transitions: transitions.append(tdata) return self.json({ 'transitions': transitions })
def invokeFactory(self, repo_clone, source, selector=None): """See IReferenceFactories """ # Just assuming ObjectManager behaviour for now portal_hidhandler = getToolByName(self, 'portal_historyidhandler') portal_archivist = getToolByName(self, 'portal_archivist') try: portal_type = repo_clone.getPortalTypeName() except AttributeError: # We attach the clone directly if the object has no portal type, # perhaps we should clone it. return repo_clone id = repo_clone.getId() if id in source.objectIds(): id = generateId(source, prefix=id) # XXX: This makes a lot of changes outside the object scope we :( id = source.invokeFactory(portal_type, id) obj = getattr(source, id) try: history_id = portal_hidhandler.getUid(repo_clone) portal_hidhandler.setUid(obj, history_id) except portal_hidhandler.UniqueIdError: portal_hidhandler.register(obj) return obj
def install_workflow(context, logger): setup = getToolByName(context, 'portal_setup') wtool = getToolByName(context, 'portal_workflow') catalog = getToolByName(context, 'portal_catalog') wtool.manage_delObjects([ 'esd-question-review-workflow', ]) setup.runImportStepFromProfile(PROFILE_ID, 'workflow') logger.info('Reinstalled Workflows.') brains = catalog(portal_type='Question', review_state=STATES) brains_len = len(brains) for idx, brain in enumerate(brains, start=1): content = brain.getObject() current_roles = [ r['name'] for r in content.rolesOfPermission(PERMISSION) if r['selected'] ] new_roles = list(set(current_roles + ['MSAuthority'])) content.manage_permission(PERMISSION, roles=new_roles, acquire=0) content.reindexObjectSecurity() logger.info('Updated %s %s/%s.', brain.getURL(), idx, brains_len)
def install_catalog(context, logger): setup = getToolByName(context, 'portal_setup') setup.runImportStepFromProfile(PROFILE_ID, 'catalog') logger.info('Catalog updated. Reindexing.') catalog = getToolByName(context, 'portal_catalog') catalog.clearFindAndRebuild() logger.info('Reindexed')
def __init__(self, context, selectable_filter, navigation_tree_query=None, default=None, defaultFactory=None): self.context = context nav_root = getNavigationRootObject(context, None) query_builder = getMultiAdapter((nav_root, self), INavigationQueryBuilder) query = query_builder() if navigation_tree_query is None: navigation_tree_query = {} # Copy path from selectable_filter into the navigation_tree_query # normally it does not make sense to show elements that wouldn't be # selectable anyway and are unneeded to navigate to selectable items if ('path' not in navigation_tree_query and 'path' in selectable_filter.criteria): navigation_tree_query['path'] = selectable_filter.criteria['path'] query.update(navigation_tree_query) self.navigation_tree_query = query self.selectable_filter = selectable_filter self.catalog = getToolByName(context, "portal_catalog") portal_tool = getToolByName(context, "portal_url") self.portal_path = portal_tool.getPortalPath() self._default_terms = [] if default is not None: term = self.getTerm(default) self._default_terms = [term] elif defaultFactory is not None: term = self.getTerm(defaultFactory(context)) self._default_terms = [term]
def approve(self, key): if key not in self._data.keys(): raise KeyError(key) portal = getSite() registration = getToolByName(self, 'portal_registration') portal_props = getToolByName(self, 'portal_properties') mt = getToolByName(self, 'portal_membership') props = portal_props.site_properties use_email_as_login = props.getProperty('use_email_as_login') data = self._data[key] if use_email_as_login: data['username'] = data['email'] user_id = data['username'] password = registration.generatePassword() request = getRequest() try: registration.addMember(user_id, password, REQUEST=request) except (AttributeError, ValueError), err: logging.exception(err) IStatusMessage(request).addStatusMessage(err, type="error") return
def __call__(self, context): try: catalog = getToolByName(context, "portal_catalog") except AttributeError: catalog = getToolByName(getSite(), "portal_catalog") brains = catalog.searchResults(**self.query) return BrainsVocabulary.fromBrains(brains, context)
def afterRetrieveModifier(self, obj, repo_clone, preserve=()): # check if the modifier is called with a valid working copy if obj is None: return [], [], {} #Preserve CMFUid uid_tool = getToolByName(obj, 'portal_historyidhandler', None) if uid_tool is not None: working_uid = uid_tool.queryUid(obj) copy_uid = uid_tool.queryUid(repo_clone) anno_tool = getToolByName(obj, 'portal_uidannotation') annotation = anno_tool(repo_clone, uid_tool.UID_ATTRIBUTE_NAME) annotation.setUid(working_uid) #Preserve ATUID uid = getattr(aq_base(obj), 'UID', None) if UUID_ATTR is not None and uid is not None and callable(obj.UID): working_atuid = obj.UID() repo_uid = repo_clone.UID() setattr(repo_clone, UUID_ATTR, working_atuid) if working_atuid != repo_uid: # XXX: We need to do something with forward references annotations = repo_clone._getReferenceAnnotations() for ref in annotations.objectValues(): ref.sourceUID = working_atuid return [], [], {}
def toFieldValue(self, value): """Converts from widget value to field. :param value: List of UID's separated by separator defined :type value: string :returns: List of content objects :rtype: list | tuple | set """ if not value: return self.field.missing_value collectionType = self.field._type if isinstance(collectionType, tuple): collectionType = collectionType[-1] separator = getattr(self.widget, 'separator', ';') value = value.split(separator) if IRelationList.providedBy(self.field): try: catalog = getToolByName(self.widget.context, 'portal_catalog') except AttributeError: catalog = getToolByName(getSite(), 'portal_catalog') objects = {item.UID: item.getObject() for item in catalog(UID=value) if item} return collectionType(objects[uid] for uid in value if uid in objects.keys()) else: return collectionType(v for v in value)
def modifiedDexterity(obj, event): """ a dexterity based object was modified """ pu = getToolByName(obj, 'portal_url', None) if pu is None: # `getObjectFromLinks` is not possible without access # to `portal_url` return rc = getToolByName(obj, 'reference_catalog', None) if rc is None: # `updateReferences` is not possible without access # to `reference_catalog` return fti = getUtility(IDexterityFTI, name=obj.portal_type) fields = [] schema = fti.lookupSchema() additional_schema = getAdditionalSchemata(context=obj, portal_type=obj.portal_type) schemas = [i for i in additional_schema] + [schema] refs = set() for schema in schemas: for name,field in getFieldsInOrder(schema): if isinstance(field, RichText): # Only check for "RichText" ? value = getattr(schema(obj), name) if not value: continue links = extractLinks(value.raw) refs |= getObjectsFromLinks(obj, links) updateReferences(IReferenceable(obj), referencedRelationship, refs)
def restoreSquidTool(portal, out): # get rid of the url expression in portal_squid squid_tool = getToolByName(portal, 'portal_squid', None) if squid_tool: squid_tool.setUrlExpression('') qi = getToolByName(portal, 'portal_quickinstaller', None) qi.notifyInstalled('CMFSquidTool', locked=False)
def get_related_languages(self): results = [] for relation in self.context.language_references: subsite = relation.to_object lang_code = subsite.force_language if not lang_code: continue results.append({ 'url': subsite.absolute_url(), 'title': translate_language(self.context, lang_code), 'code': lang_code}) if self.context.link_site_in_languagechooser: portal_url = getToolByName(self.context, 'portal_url') ltool = getToolByName(self.context, 'portal_languages') lang_code = ltool.getDefaultLanguage() results.append({ 'url': portal_url(), 'title': translate_language(self.context, lang_code), 'code': lang_code}) results.sort(key=lambda item: item.get('title')) return results
def modifiedArchetype(obj, event): """ an archetype based object was modified """ pu = getToolByName(obj, 'portal_url', None) if pu is None: # `getObjectFromLinks` is not possible without access # to `portal_url` return rc = getToolByName(obj, 'reference_catalog', None) if rc is None: # `updateReferences` is not possible without access # to `reference_catalog` return refs = set() for field in obj.Schema().fields(): if isinstance(field, TextField): accessor = field.getAccessor(obj) encoding = field.getRaw(obj, raw=1).original_encoding if accessor is not None: value = accessor() else: # Fields that have been added via schema extension do # not have an accessor method. value = field.get(obj) links = extractLinks(value, encoding) refs |= getObjectsFromLinks(obj, links) updateReferences(obj, referencedRelationship, refs)
def upgrade(context): catalog = getToolByName(context, 'portal_catalog') wft = getToolByName(context, 'portal_workflow') type_mapping = upw.get_workflow_type_mapping(wft) queries = [ dict( portal_type='Observation', review_state=['phase2-pending', 'phase1-pending'], reindex_self_only=True, ), # Reindex old content from 57->58->59 steps. # Needed because of fixed bug in upw which # didn't reindex the correct objects. dict( portal_type='Comment', review_state='initial', reindex_self_only=True, ), dict( portal_type='Question', reindex_self_only=True, ), dict( portal_type='Conclusion', review_state='draft', reindex_self_only=True, ), ] upw.upgrade(wft, catalog, type_mapping, queries)
def testOnItemCreation(self): """Test notification on item creation.""" portal = self.portal ntool = getToolByName(portal, NTOOL_ID) changeProperty = lambda key, value: \ ntool.manage_changeProperties(**{key: value}) wtool = getToolByName(portal, 'portal_workflow') mh = portal.MailHost self.login('manager') ## Set correct rules so that 3 mails should be sent. changeProperty('item_creation_notification_enabled', True) changeProperty('on_item_creation_users', ['* :: *']) changeProperty('on_item_creation_mail_template', ['* :: string:creation_mail_notification']) portal.invokeFactory('Document', 'document') ## See 'events/events.txt' for futher details about this ## manually fired event. event.notify(ObjectInitializedEvent(portal['document'])) self.failUnlessSent(1) portal.manage_delObjects(['document']) mh.clearSentList() ## Set workflow initial state to 'publish', thus showing the ## new item to every users. wtool.simple_publication_workflow.initial_state = 'published' portal.invokeFactory('Document', 'document') event.notify(ObjectInitializedEvent(portal['document'])) self.failUnlessSent(3) portal.manage_delObjects(['document']) mh.clearSentList() ## Disable notification changeProperty('item_creation_notification_enabled', False) portal.invokeFactory('Document', 'document') event.notify(ObjectInitializedEvent(portal['document'])) self.failUnlessSent(0) portal.manage_delObjects(['document']) mh.clearSentList() ## Enable notification but set the notified users list to [] changeProperty('item_creation_notification_enabled', True) ntool.manage_changeProperties(on_item_creation_users='* :: python: []') portal.invokeFactory('Document', 'document') event.notify(ObjectInitializedEvent(portal['document'])) self.failUnlessSent(0) portal.manage_delObjects(['document']) mh.clearSentList() ## Set the notified users list to "everybody" but ask for a ## missing mail template changeProperty('on_item_creation_users', ['* :: *']) changeProperty('on_item_creation_mail_template', ['* :: string:does_not_exist']) portal.invokeFactory('Document', 'document') event.notify(ObjectInitializedEvent(portal['document'])) self.failUnlessSent(0) portal.manage_delObjects(['document']) mh.clearSentList()
def handle_file_creation(object, event): qi = getToolByName(object, 'portal_quickinstaller') if not qi.isProductInstalled('wc.pageturner'): return if object.getContentType() not in ('application/pdf', 'application/x-pdf', 'image/pdf'): return ptool = getToolByName(object, 'portal_properties') site_props = getattr(ptool, 'site_properties', None) auto_layout = site_props.getProperty('page_turner_auto_select_layout', False) if auto_layout and object.getLayout() != 'page-turner': object.setLayout('page-turner') # for circular depend try: from wildcard.pdfpal.ocr import copyPdfMetadata new_pdfpal_installed = True except: new_pdfpal_installed = False if not new_pdfpal_installed or not \ qi.isProductInstalled('wildcard.pdfpal'): # if the new version of wildcard.pdfpal is installed, allow it to queue # this job up after it creates the searchable pdf. # otherwise, just queue it up here. queue_job(object)
def remove(self): mtool = getToolByName(self.context, 'portal_membership') user = mtool.getAuthenticatedMember() portal = getToolByName(self.context, 'portal_url').getPortalObject() site = getNavigationRootObject(self.context, portal) IFavoriteStorage(site).remove_favorite(user.getId(), IUUID(self.context))
def getCustomScript( self ): context = self.context.aq_inner portal_props = getToolByName(context, 'portal_properties') seo_props = getToolByName(portal_props, 'seo_properties', None) if seo_props is None: return '' return seo_props.getProperty('custom_script', '')
def _sampler_data(self, sample=None): data = {} if not sample or not sample.getSampler(): return data sampler = sample.getSampler() mtool = getToolByName(self, 'portal_membership') member = mtool.getMemberById(sampler) if member: mfullname = member.getProperty('fullname') memail = member.getProperty('email') mhomepage = member.getProperty('home_page') pc = getToolByName(self, 'portal_catalog') c = pc(portal_type='Contact', getUsername=member.id) c = c[0].getObject() if c else None cfullname = c.getFullname() if c else None cemail = c.getEmailAddress() if c else None data = {'id': member.id, 'fullname': to_utf8(cfullname) if cfullname else to_utf8(mfullname), 'email': cemail if cemail else memail, 'business_phone': c.getBusinessPhone() if c else '', 'business_fax': c.getBusinessFax() if c else '', 'home_phone': c.getHomePhone() if c else '', 'mobile_phone': c.getMobilePhone() if c else '', 'job_title': to_utf8(c.getJobTitle()) if c else '', 'department': to_utf8(c.getDepartment()) if c else '', 'physical_address': to_utf8(c.getPhysicalAddress()) if c else '', 'postal_address': to_utf8(c.getPostalAddress()) if c else '', 'home_page': to_utf8(mhomepage)} return data
def importMembers(self, portal): print "\n= Importing Members ==========================================" pm = portal.portal_membership pg = portal.portal_groups mdc = getToolByName(portal, 'portal_memberdata') fac = getToolByName(portal, 'portal_factory') for elem in self.root: if type(elem) == ElementTree._Comment: pass elif elem.tag == 'member': id = elem.get('id') pwd = elem.get('password') roles = self._getMemberRoles(elem) md = self._getMemberData(elem) print "%s %s %s" %(id, md, roles) if self.with_membrane: mem = mdc.restrictedTraverse('portal_factory/%s/%s' % (self.default_member_type, id)) user = fac.doCreate(mem, id) md['roles'] = roles md['password'] = pwd md['confirm_password'] = pwd user.processForm(values=md) else: pm.addMember(id, pwd, [], [], md) user = pm.getMemberById(id) user.setSecurityProfile(password=pwd, roles=roles) for group in self._getMemberGroups(elem): pg.getGroupById(group).addMember(id) print "==============================================================\n"
def patched_getPersonalPortrait(self, id=None, verifyPermission=0): """Return a members personal portait. Modified from CMFPlone version to URL-quote the member id. """ # XXX eeek, id is built-in, dont use as identifier userid = id if not userid: userid = self.getAuthenticatedMember().getId() portrait = getPortraitFromSheet(self, userid) if portrait: return portrait # fallback to memberdata safe_id = self._getSafeMemberId(userid) membertool = getToolByName(self, 'portal_memberdata') portrait = membertool._getPortrait(safe_id) if isinstance(portrait, str): portrait = None if portrait is not None: if verifyPermission and not _checkPermission('View', portrait): # Don't return the portrait if the user can't get to it portrait = None if portrait is None: portal = getToolByName(self, 'portal_url').getPortalObject() portrait = getattr(portal, default_portrait, None) return portrait
def getAllowedContentTypes(): """Get a set of allowed MIME types according to the portal_properties tool """ site = getSite() if site is None: return None portal_transforms = getToolByName(site, 'portal_transforms', None) if portal_transforms is None: return None portal_properties = getToolByName(site, 'portal_properties', None) if portal_properties is None: return None site_properties = portal_properties.get('site_properties', None) if site_properties is None: return None allowed = set(portal_transforms.listAvailableTextInputs()) forbidden = set(site_properties.getProperty('forbidden_contenttypes', [])) return allowed - forbidden
def _encode(self, txt): if isinstance(txt, six.text_type): plone_utils = getToolByName(self.context, "plone_utils") encoding = plone_utils.getSiteEncoding() txt = txt.encode(encoding) return txt
def setupRotaItemWorkflow(self, workflow): """Define the RotaItemWorkflow workflow. """ # Add additional roles to portal portal = getToolByName(self, 'portal_url').getPortalObject() data = list(portal.__ac_roles__) for role in ['ChiefEditor']: if not role in data: data.append(role) # add to portal_role_manager # first try to fetch it. if its not there, we probaly have no PAS # or another way to deal with roles was configured. try: prm = portal.acl_users.get('portal_role_manager', None) if prm is not None: try: prm.addRole( role, role, "Added by product 'Bungeni'/workflow 'RotaItemWorkflow'" ) except KeyError: # role already exists pass except AttributeError: pass portal.__ac_roles__ = tuple(data) workflow.setProperties(title='RotaItemWorkflow') ##code-section create-workflow-setup-method-header #fill in your manual code here ##/code-section create-workflow-setup-method-header for s in ['new', 'final']: workflow.states.addState(s) for t in ['retract', 'finalize']: workflow.transitions.addTransition(t) for v in ['review_history', 'comments', 'time', 'actor', 'action']: workflow.variables.addVariable(v) workflow.addManagedPermission('Modify portal content') for l in []: if not l in workflow.worklists.objectValues(): workflow.worklists.addWorklist(l) ## Initial State workflow.states.setInitialState('new') ## States initialization stateDef = workflow.states['new'] stateDef.setProperties(title="""new""", description="""""", transitions=['finalize']) stateDef.setPermission('Modify portal content', 0, ['ChiefEditor']) stateDef = workflow.states['final'] stateDef.setProperties(title="""final""", description="""""", transitions=['retract']) stateDef.setPermission('Modify portal content', 0, ['Manager']) ## Transitions initialization transitionDef = workflow.transitions['retract'] transitionDef.setProperties( title="""retract""", new_state_id="""new""", trigger_type=1, script_name="""""", after_script_name="""""", actbox_name="""retract""", actbox_url="""""", actbox_category="""workflow""", props={}, ) transitionDef = workflow.transitions['finalize'] transitionDef.setProperties( title="""finalize""", new_state_id="""final""", trigger_type=1, script_name="""""", after_script_name="""""", actbox_name="""finalize""", actbox_url="""""", actbox_category="""workflow""", props={}, ) ## State Variable workflow.variables.setStateVar('review_state') ## Variables initialization variableDef = workflow.variables['review_history'] variableDef.setProperties( description="""Provides access to workflow history""", default_value="""""", default_expr="""state_change/getHistory""", for_catalog=0, for_status=0, update_always=0, props={'guard_permissions': 'Request review; Review portal content'}) variableDef = workflow.variables['comments'] variableDef.setProperties( description="""Comments about the last transition""", default_value="""""", default_expr="""python:state_change.kwargs.get('comment', '')""", for_catalog=0, for_status=1, update_always=1, props=None) variableDef = workflow.variables['time'] variableDef.setProperties(description="""Time of the last transition""", default_value="""""", default_expr="""state_change/getDateTime""", for_catalog=0, for_status=1, update_always=1, props=None) variableDef = workflow.variables['actor'] variableDef.setProperties( description="""The ID of the user who performed the last transition""", default_value="""""", default_expr="""user/getId""", for_catalog=0, for_status=1, update_always=1, props=None) variableDef = workflow.variables['action'] variableDef.setProperties(description="""The last transition""", default_value="""""", default_expr="""transition/getId|nothing""", for_catalog=0, for_status=1, update_always=1, props=None)
def many_groups(self): pprop = getToolByName(aq_inner(self.context), 'portal_properties') return pprop.site_properties.many_groups
def portal_roles(self): pmemb = getToolByName(aq_inner(self.context), 'portal_membership') return [r for r in pmemb.getPortalRoles() if r != 'Owner']
def upgrade(tool): """ issue #623, #583, ... """ # Hack prevent out-of-date upgrading # Related: PR #1484 # https://github.com/bikalabs/Bika-LIMS/pull/1484 from bika.lims.upgrade import skip_pre315 if skip_pre315(aq_parent(aq_inner(tool))): return True portal = aq_parent(aq_inner(tool)) setup = portal.portal_setup typestool = getToolByName(portal, 'portal_types') # update affected tools setup.runImportStepFromProfile('profile-bika.lims:default', 'typeinfo') setup.runImportStepFromProfile('profile-bika.lims:default', 'workflow') setup.runImportStepFromProfile('profile-bika.lims:default', 'factorytool') setup.runImportStepFromProfile('profile-bika.lims:default', 'jsregistry') setup.runImportStepFromProfile('profile-bika.lims:default', 'propertiestool') setup.runImportStepFromProfile('profile-bika.lims:default', 'plone.app.registry') # Changes to the catalogs # create lexicon wordSplitter = Empty() wordSplitter.group = 'Word Splitter' wordSplitter.name = 'Unicode Whitespace splitter' caseNormalizer = Empty() caseNormalizer.group = 'Case Normalizer' caseNormalizer.name = 'Unicode Case Normalizer' stopWords = Empty() stopWords.group = 'Stop Words' stopWords.name = 'Remove listed and single char words' zc_extras = Empty() zc_extras.index_type = 'Okapi BM25 Rank' zc_extras.lexicon_id = 'Lexicon' # then add indexes bc = getToolByName(portal, 'bika_catalog') bc.addIndex('getContactTitle', 'FieldIndex', zc_extras) bc.addIndex('getClientTitle', 'FieldIndex', zc_extras) bc.addIndex('getProfileTitle', 'FieldIndex', zc_extras) bc.addIndex('getAnalysisCategory', 'KeywordIndex') bc.addIndex('getAnalysisService', 'KeywordIndex') bc.addIndex('getAnalysts', 'KeywordIndex') bc.clearFindAndRebuild() # add new types not to list in nav # AnalysisRequestQuery and QueryFolder (listed in portal_tabs already) portal_properties = getToolByName(portal, 'portal_properties') ntp = getattr(portal_properties, 'navtree_properties') types = list(ntp.getProperty('metaTypesNotToList')) types.append("AnalysisRequestQuery") types.append("QueryFolder") ntp.manage_changeProperties(MetaTypesNotToQuery=types) # Add /queries folder typestool.constructContent(type_name="QueryFolder", container=portal, id='queries', title='Queries') obj = portal['queries'] obj.unmarkCreationFlag() obj.reindexObject() # /queries folder permissions mp = portal.queries.manage_permission mp(permissions.ListFolderContents, ['Manager', 'LabManager', 'LabClerk', 'Analyst'], 0) mp(permissions.AddPortalContent, ['Manager', 'LabManager', 'LabClerk', 'Analyst'], 0) mp(permissions.View, ['Manager', 'LabManager', 'LabClerk', 'Analyst'], 0) mp('Access contents information', ['Manager', 'LabManager', 'LabClerk', 'Analyst'], 0) mp(permissions.DeleteObjects, ['Manager'], 0) portal.queries.reindexObject() # idserver prefix for AnalysisRequestQuery prefixes = portal.bika_setup.getPrefixes() if [x for x in prefixes if x['portal_type'] == 'AnalysisRequestQuery']: prefixes.append({ 'portal_type': 'AnalysisRequestQuery', 'prefix': 'query-', 'padding': '4' }) portal.bika_setup.setPrefixes(prefixes) return True
def __init__(self, context, request): super(PubSubItem, self).__init__(context, request) self.mt = getToolByName(self.context, 'portal_membership') self.host = urlparse(getToolByName(self.context, 'portal_url')()).netloc self.storage = getUtility(IPubSubStorage)
def __init__(self, *args, **kwargs): super(InstallerView, self).__init__(*args, **kwargs) self.ps = getToolByName(self.context, 'portal_setup') self.errors = {}
def retractInvalidAnalyses(self): """ Retract the analyses with validation pending status for which the instrument used failed a QC Test. """ toretract = {} instruments = {} refs = [] rc = getToolByName(self.context, REFERENCE_CATALOG) selected = WorkflowAction._get_selected_items(self) for uid in selected.iterkeys(): # We need to do this instead of using the dict values # directly because all these analyses have been saved before # and don't know if they already had an instrument assigned an = rc.lookupObject(uid) if an.portal_type == 'ReferenceAnalysis': refs.append(an) instrument = an.getInstrument() if instrument and instrument.UID() not in instruments: instruments[instrument.UID()] = instrument for instr in instruments.itervalues(): analyses = instr.getAnalysesToRetract() for a in analyses: if a.UID() not in toretract: toretract[a.UID] = a retracted = [] for analysis in toretract.itervalues(): try: # add a remark to this analysis failedtxt = ulocalized_time(DateTime(), long_format=0) failedtxt = '%s: %s' % (failedtxt, _("Instrument failed reference test")) analysis.setRemarks(failedtxt) # retract the analysis doActionFor(analysis, 'retract') retracted.append(analysis) except: # Already retracted as a dependant from a previous one? pass if len(retracted) > 0: # Create the Retracted Analyses List rep = AnalysesRetractedListReport(self.context, self.request, self.portal_url, 'Retracted analyses', retracted) # Attach the pdf to the ReferenceAnalysis (accessible # from Instrument's Internal Calibration Tests list pdf = rep.toPdf() for ref in refs: ref.setRetractedAnalysesPdfReport(pdf) # Send the email try: rep.sendEmail() except: pass # TODO: mostra una finestra amb els resultats publicats d'AS # que han utilitzat l'instrument des de la seva última # calibració vàlida, amb els emails, telèfons dels # contactes associats per a una intervenció manual pass
def install(self, reinstall=False): """ External Method to install Marginalia """ out = StringIO() print >> out, "Installation log of %s:" % PROJECTNAME # If the config contains a list of dependencies, try to install # them. Add a list called DEPENDENCIES to your custom # AppConfig.py (imported by config.py) to use it. try: from Products.Marginalia.config import DEPENDENCIES except: DEPENDENCIES = [] portal = getToolByName(self, 'portal_url').getPortalObject() quickinstaller = portal.portal_quickinstaller for dependency in DEPENDENCIES: print >> out, "Installing dependency %s:" % dependency quickinstaller.installProduct(dependency) import transaction transaction.savepoint(optimistic=True) classes = listTypes(PROJECTNAME) installTypes(self, out, classes, PROJECTNAME) install_subskin(self, out, GLOBALS) # autoinstall tools portal = getToolByName(self, 'portal_url').getPortalObject() for t in ['Annotations']: try: portal.manage_addProduct[PROJECTNAME].manage_addTool(t) except BadRequest: # if an instance with the same name already exists this error will # be swallowed. Zope raises in an unelegant manner a 'Bad Request' error pass except: e = sys.exc_info() if e[0] != 'Bad Request': raise # Adding a new catalog index catalog = getToolByName(portal, "portal_catalog") if 'getAccess' not in catalog.indexes(): catalog.addIndex('getAccess', 'FieldIndex') catalog.addIndex('getEditType', 'FieldIndex') # hide tools in the search form portalProperties = getToolByName(self, 'portal_properties', None) if portalProperties is not None: siteProperties = getattr(portalProperties, 'site_properties', None) if siteProperties is not None and siteProperties.hasProperty( 'types_not_searched'): for tool in ['Annotations']: current = list( siteProperties.getProperty('types_not_searched')) if tool not in current: current.append(tool) siteProperties.manage_changeProperties( **{'types_not_searched': current}) # remove workflow for tools portal_workflow = getToolByName(self, 'portal_workflow') portal_workflow.setChainForPortalTypes(['Annotations'], '') portal_workflow.setChainForPortalTypes(['Annotation'], 'annotation_workflow') # uncatalog tools for toolname in ['portal_annotations']: try: portal[toolname].unindexObject() except: pass # hide tools in the navigation portalProperties = getToolByName(self, 'portal_properties', None) if portalProperties is not None: navtreeProperties = getattr(portalProperties, 'navtree_properties', None) if navtreeProperties is not None and navtreeProperties.hasProperty( 'idsNotToList'): for toolname in ['portal_annotations']: current = list(navtreeProperties.getProperty('idsNotToList')) if toolname not in current: current.append(toolname) navtreeProperties.manage_changeProperties( **{'idsNotToList': current}) # try to call a workflow install method # in 'InstallWorkflows.py' method 'installWorkflows' try: installWorkflows = ExternalMethod('temp', 'temp', PROJECTNAME + '.InstallWorkflows', 'installWorkflows').__of__(self) except NotFound: installWorkflows = None if installWorkflows: print >> out, 'Workflow Install:' res = installWorkflows(self, out) print >> out, res or 'no output' else: print >> out, 'no workflow install' # enable portal_factory for given types factory_tool = getToolByName(self, 'portal_factory') factory_types = [ "Annotation", "AnnotatableDocument", "Annotations", ] + factory_tool.getFactoryTypes().keys() factory_tool.manage_setPortalFactoryTypes(listOfTypeIds=factory_types) portal.portal_annotations.manage_permission("Add portal content", ["Member", "Anonymous"], 1) from Products.Marginalia.config import STYLESHEETS try: portal_css = getToolByName(portal, 'portal_css') for stylesheet in STYLESHEETS: try: portal_css.unregisterResource(stylesheet['id']) except: pass defaults = {'id': '', 'media': 'all', 'enabled': True} defaults.update(stylesheet) portal_css.registerStylesheet(**defaults) except: # No portal_css registry pass from Products.Marginalia.config import JAVASCRIPTS try: portal_javascripts = getToolByName(portal, 'portal_javascripts') for javascript in JAVASCRIPTS: try: portal_javascripts.unregisterResource(javascript['id']) except: pass defaults = {'id': ''} defaults.update(javascript) portal_javascripts.registerScript(**defaults) except: # No portal_javascripts registry pass # try to call a custom install method # in 'AppInstall.py' method 'install' try: install = ExternalMethod('temp', 'temp', PROJECTNAME + '.AppInstall', 'install') except NotFound: install = None if install: print >> out, 'Custom Install:' try: res = install(self, reinstall) except TypeError: res = install(self) if res: print >> out, res else: print >> out, 'no output' else: print >> out, 'no custom install' return out.getvalue()
def __call__(self): form = self.request.form CheckAuthenticator(form) workflow = getToolByName(self.context, 'portal_workflow') rc = getToolByName(self.context, REFERENCE_CATALOG) bsc = getToolByName(self.context, 'bika_setup_catalog') bac = getToolByName(self.context, 'bika_analysis_catalog') action, came_from = WorkflowAction._get_form_workflow_action(self) if action == 'submit': # Submit the form. Saves the results, methods, etc. self.submit() ## assign elif action == 'assign': if not self.context.checkUserManage(): self.request.response.redirect(self.context.absolute_url()) return analysis_uids = form.get("uids", []) if analysis_uids: # We retrieve the analyses from the database sorted by AR ID # ascending, so the positions of the ARs inside the WS are # consistent with the order of the ARs catalog = get_tool(CATALOG_ANALYSIS_LISTING) brains = catalog({ 'UID': analysis_uids, 'sort_on': 'getRequestID' }) # Now, we need the analyses within a request ID to be sorted by # sortkey (sortable_title index), so it will appear in the same # order as they appear in Analyses list from AR view curr_arid = None curr_brains = [] sorted_brains = [] for brain in brains: arid = brain.getRequestID if curr_arid != arid: # Sort the brains we've collected until now, that belong to # the same Analysis Request curr_brains.sort(key=attrgetter('getPrioritySortkey')) sorted_brains.extend(curr_brains) curr_arid = arid curr_brains = [] # Now we are inside the same AR curr_brains.append(brain) continue # Sort the last set of brains we've collected curr_brains.sort(key=attrgetter('getPrioritySortkey')) sorted_brains.extend(curr_brains) # Add analyses in the worksheet for brain in sorted_brains: analysis = brain.getObject() self.context.addAnalysis(analysis) self.destination_url = self.context.absolute_url() self.request.response.redirect(self.destination_url) ## unassign elif action == 'unassign': if not self.context.checkUserManage(): self.request.response.redirect(self.context.absolute_url()) return selected_analyses = WorkflowAction._get_selected_items(self) selected_analysis_uids = selected_analyses.keys() for analysis_uid in selected_analysis_uids: try: analysis = bac(UID=analysis_uid)[0].getObject() except IndexError: # Duplicate analyses are removed when their analyses # get removed, so indexerror is expected. continue if skip(analysis, action, peek=True): continue self.context.removeAnalysis(analysis) message = PMF("Changes saved.") self.context.plone_utils.addPortalMessage(message, 'info') self.destination_url = self.context.absolute_url() self.request.response.redirect(self.destination_url) ## verify elif action == 'verify': # default bika_listing.py/WorkflowAction, but then go to view screen. self.destination_url = self.context.absolute_url() return self.workflow_action_default(action='verify', came_from=came_from) else: # default bika_listing.py/WorkflowAction for other transitions WorkflowAction.__call__(self)
def doSearch(self, searchString): """ Search for a group by id or title""" acl = getToolByName(self, 'acl_users') rolemakers = acl.plugins.listPlugins(IRolesPlugin) searchView = getMultiAdapter((aq_inner(self.context), self.request), name='pas_search') # First, search for inherited roles assigned to each group. # We push this in the request so that IRoles plugins are told provide # the roles inherited from the groups to which the principal belongs. self.request.set('__ignore_group_roles__', False) self.request.set('__ignore_direct_roles__', True) inheritance_enabled_groups = searchView.merge( chain(*[ searchView.searchGroups(**{field: searchString}) for field in ['id', 'title'] ]), 'id') allInheritedRoles = {} for group_info in inheritance_enabled_groups: groupId = group_info['id'] group = acl.getGroupById(groupId) group_info['title'] = group.getProperty('title', group_info['title']) allAssignedRoles = [] for rolemaker_id, rolemaker in rolemakers: # getRolesForPrincipal can return None roles = rolemaker.getRolesForPrincipal(group) or () allAssignedRoles.extend(roles) allInheritedRoles[groupId] = allAssignedRoles # Now, search for all roles explicitly assigned to each group. # We push this in the request so that IRoles plugins don't provide # the roles inherited from the groups to which the principal belongs. self.request.set('__ignore_group_roles__', True) self.request.set('__ignore_direct_roles__', False) explicit_groups = searchView.merge( chain(*[ searchView.searchGroups(**{field: searchString}) for field in ['id', 'title'] ]), 'id') # Tack on some extra data, including whether each role is explicitly # assigned ('explicit'), inherited ('inherited'), or not assigned at # all (None). results = [] for group_info in explicit_groups: groupId = group_info['id'] group = acl.getGroupById(groupId) group_info['title'] = group.getProperty('title', group_info['title']) explicitlyAssignedRoles = [] for rolemaker_id, rolemaker in rolemakers: # getRolesForPrincipal can return None roles = rolemaker.getRolesForPrincipal(group) or () explicitlyAssignedRoles.extend(roles) roleList = {} for role in self.portal_roles: canAssign = group.canAssignRole(role) if role == 'Manager' and not self.is_zope_manager: canAssign = False roleList[role] = { 'canAssign': canAssign, 'explicit': role in explicitlyAssignedRoles, 'inherited': role in allInheritedRoles.get(groupId, []) } canDelete = group.canDelete() if ('Manager' in explicitlyAssignedRoles or 'Manager' in allInheritedRoles.get(groupId, [])): if not self.is_zope_manager: canDelete = False group_info['roles'] = roleList group_info['can_delete'] = canDelete results.append(group_info) # Sort the groups by title sortedResults = searchView.sort(results, 'title') # Reset the request variable, just in case. self.request.set('__ignore_group_roles__', False) return sortedResults
def submit(self): """ Saves the form """ form = self.request.form remarks = form.get('Remarks', [{}])[0] results = form.get('Result', [{}])[0] retested = form.get('retested', {}) methods = form.get('Method', [{}])[0] instruments = form.get('Instrument', [{}])[0] analysts = self.request.form.get('Analyst', [{}])[0] uncertainties = self.request.form.get('Uncertainty', [{}])[0] dlimits = self.request.form.get('DetectionLimit', [{}])[0] selected = WorkflowAction._get_selected_items(self) workflow = getToolByName(self.context, 'portal_workflow') rc = getToolByName(self.context, REFERENCE_CATALOG) sm = getSecurityManager() hasInterims = {} # XXX combine data from multiple bika listing tables. item_data = {} if 'item_data' in form: if type(form['item_data']) == list: for i_d in form['item_data']: for i, d in json.loads(i_d).items(): item_data[i] = d else: item_data = json.loads(form['item_data']) # Iterate for each selected analysis and save its data as needed for uid, analysis in selected.items(): allow_edit = sm.checkPermission(EditResults, analysis) analysis_active = isActive(analysis) # Need to save remarks? if uid in remarks and allow_edit and analysis_active: analysis.setRemarks(remarks[uid]) # Retested? if uid in retested and allow_edit and analysis_active: analysis.setRetested(retested[uid]) # Need to save the instrument? if uid in instruments and analysis_active: # TODO: Add SetAnalysisInstrument permission # allow_setinstrument = sm.checkPermission(SetAnalysisInstrument) allow_setinstrument = True # ---8<----- if allow_setinstrument == True: # The current analysis allows the instrument regards # to its analysis service and method? if (instruments[uid] == ''): previnstr = analysis.getInstrument() if previnstr: previnstr.removeAnalysis(analysis) analysis.setInstrument(None) elif analysis.isInstrumentAllowed(instruments[uid]): previnstr = analysis.getInstrument() if previnstr: previnstr.removeAnalysis(analysis) analysis.setInstrument(instruments[uid]) instrument = analysis.getInstrument() instrument.addAnalysis(analysis) if analysis.meta_type == 'ReferenceAnalysis': instrument.setDisposeUntilNextCalibrationTest( False) # Need to save the method? if uid in methods and analysis_active: # TODO: Add SetAnalysisMethod permission # allow_setmethod = sm.checkPermission(SetAnalysisMethod) allow_setmethod = True # ---8<----- if allow_setmethod == True and analysis.isMethodAllowed( methods[uid]): analysis.setMethod(methods[uid]) # Need to save the analyst? if uid in analysts and analysis_active: analysis.setAnalyst(analysts[uid]) # Need to save the uncertainty? if uid in uncertainties and analysis_active: analysis.setUncertainty(uncertainties[uid]) # Need to save the detection limit? if analysis_active and uid in dlimits and dlimits[uid]: analysis.setDetectionLimitOperand(dlimits[uid]) # Need to save results? if uid in results and results[uid] and allow_edit \ and analysis_active: interims = item_data.get(uid, []) analysis.setInterimFields(interims) analysis.setResult(results[uid]) analysis.reindexObject() can_submit = True deps = analysis.getDependencies() \ if hasattr(analysis, 'getDependencies') else [] for dependency in deps: if workflow.getInfoFor(dependency, 'review_state') in \ ('to_be_sampled', 'to_be_preserved', 'sample_due', 'sample_received'): can_submit = False break if can_submit: # doActionFor transitions the analysis to verif pending, # so must only be done when results are submitted. doActionFor(analysis, 'submit') # Maybe some analyses need to be retracted due to a QC failure # Done here because don't know if the last selected analysis is # a valid QC for the instrument used in previous analyses. # If we add this logic in subscribers.analyses, there's the # possibility to retract analyses before the QC being reached. self.retractInvalidAnalyses() message = PMF("Changes saved.") self.context.plone_utils.addPortalMessage(message, 'info') self.destination_url = self.request.get_header( "referer", self.context.absolute_url()) self.request.response.redirect(self.destination_url)
def applyWorksheetTemplate(self, wst, client_title=None): """ Add analyses to worksheet according to wst's layout. Will not overwrite slots which are filled already. If the selected template has an instrument assigned, it will only be applied to those analyses for which the instrument is allowed """ rc = getToolByName(self, REFERENCE_CATALOG) bac = getToolByName(self, "bika_analysis_catalog") bc = getToolByName(self, 'bika_catalog') layout = self.getLayout() wstlayout = wst.getLayout() services = wst.getService() wst_service_uids = [s.UID() for s in services] wst_slots = [row['pos'] for row in wstlayout if row['type'] == 'a'] ws_slots = [row['position'] for row in layout if row['type'] == 'a'] nr_slots = len(wst_slots) - len(ws_slots) positions = [pos for pos in wst_slots if pos not in ws_slots] contentFilter = { 'portal_type': 'Analysis', 'getServiceUID': wst_service_uids, 'review_state': 'sample_received', 'worksheetanalysis_review_state': 'unassigned', 'cancellation_state': 'active', 'sort_on': 'getDueDate' } if client_title and client_title != 'any': contentFilter['getClientTitle'] = client_title analyses = bac(contentFilter) # ar_analyses is used to group analyses by AR. ar_analyses = {} instr = self.getInstrument() if self.getInstrument( ) else wst.getInstrument() for brain in analyses: analysis = brain.getObject() if instr and brain.getObject().isInstrumentAllowed(instr) is False: # Exclude those analyses for which the ws selected # instrument is not allowed continue ar_id = brain.getRequestID if ar_id in ar_analyses: ar_analyses[ar_id].append(analysis) else: if len(ar_analyses.keys()) < nr_slots: ar_analyses[ar_id] = [ analysis, ] # Add analyses, sorted by AR ID ars = sorted(ar_analyses.keys()) for ar in ars: for analysis in ar_analyses[ar]: self.addAnalysis(analysis, position=positions[ars.index(ar)]) # find best maching reference samples for Blanks and Controls for t in ('b', 'c'): form_key = t == 'b' and 'blank_ref' or 'control_ref' ws_slots = [row['position'] for row in layout if row['type'] == t] for row in [ r for r in wstlayout if r['type'] == t and r['pos'] not in ws_slots ]: reference_definition_uid = row.get(form_key, None) if (not reference_definition_uid): continue samples = bc( portal_type='ReferenceSample', review_state='current', inactive_state='active', getReferenceDefinitionUID=reference_definition_uid) if not samples: break samples = [s.getObject() for s in samples] if t == 'b': samples = [s for s in samples if s.getBlank()] else: samples = [s for s in samples if not s.getBlank()] complete_reference_found = False references = {} for reference in samples: reference_uid = reference.UID() references[reference_uid] = {} references[reference_uid]['services'] = [] references[reference_uid]['count'] = 0 specs = reference.getResultsRangeDict() for service_uid in wst_service_uids: if service_uid in specs: references[reference_uid]['services'].append( service_uid) references[reference_uid]['count'] += 1 if references[reference_uid]['count'] == len( wst_service_uids): complete_reference_found = True break if complete_reference_found: supported_uids = wst_service_uids self.addReferences(int(row['pos']), reference, supported_uids) else: # find the most complete reference sample instead reference_keys = references.keys() no_of_services = 0 reference = None for key in reference_keys: if references[key]['count'] > no_of_services: no_of_services = references[key]['count'] reference = key if reference: reference = rc.lookupObject(reference) supported_uids = [ s.UID() for s in reference.getServices() if s.UID() in wst_service_uids ] self.addReferences(int(row['pos']), reference, supported_uids) # fill duplicate positions layout = self.getLayout() ws_slots = [row['position'] for row in layout if row['type'] == 'd'] for row in [ r for r in wstlayout if r['type'] == 'd' and r['pos'] not in ws_slots ]: dest_pos = int(row['pos']) src_pos = int(row['dup']) if src_pos in [int(slot['position']) for slot in layout]: self.addDuplicateAnalyses(src_pos, dest_pos) # Apply the wst instrument to all analyses and ws if instr: self.setInstrument(instr, True)
def uninstall(self, reinstall=False): out = StringIO() # Adding a new catalog index catalog = getToolByName(self, "portal_catalog") if 'getAccess' in catalog.indexes(): catalog.manage_delIndex([ 'getAccess', ]) # unhide tools in the search form portalProperties = getToolByName(self, 'portal_properties', None) if portalProperties is not None: siteProperties = getattr(portalProperties, 'site_properties', None) if siteProperties is not None and siteProperties.hasProperty( 'types_not_searched'): for tool in ['Annotations']: current = list( siteProperties.getProperty('types_not_searched')) if tool in current: current.remove(tool) siteProperties.manage_changeProperties( **{'types_not_searched': current}) # unhide tools portalProperties = getToolByName(self, 'portal_properties', None) if portalProperties is not None: navtreeProperties = getattr(portalProperties, 'navtree_properties', None) if navtreeProperties is not None and navtreeProperties.hasProperty( 'idsNotToList'): for toolname in ['portal_annotations']: current = list(navtreeProperties.getProperty('idsNotToList')) if toolname in current: current.remove(toolname) navtreeProperties.manage_changeProperties( **{'idsNotToList': current}) # try to call a workflow uninstall method # in 'InstallWorkflows.py' method 'uninstallWorkflows' try: uninstallWorkflows = ExternalMethod('temp', 'temp', PROJECTNAME + '.InstallWorkflows', 'uninstallWorkflows').__of__(self) except NotFound: uninstallWorkflows = None if uninstallWorkflows: print >> out, 'Workflow Uninstall:' res = uninstallWorkflows(self, out) print >> out, res or 'no output' else: print >> out, 'no workflow uninstall' # try to call a custom uninstall method # in 'AppInstall.py' method 'uninstall' try: uninstall = ExternalMethod('temp', 'temp', PROJECTNAME + '.AppInstall', 'uninstall') except: uninstall = None if uninstall: print >> out, 'Custom Uninstall:' try: res = uninstall(self, reinstall) except TypeError: res = uninstall(self) if res: print >> out, res else: print >> out, 'no output' else: print >> out, 'no custom uninstall' return out.getvalue()
def addAnalysis(self, analysis, position=None): """- add the analysis to self.Analyses(). - position is overruled if a slot for this analysis' parent exists - if position is None, next available pos is used. """ workflow = getToolByName(self, 'portal_workflow') analysis_uid = analysis.UID() parent_uid = analysis.aq_parent.UID() analyses = self.getAnalyses() layout = self.getLayout() # check if this analysis is already in the layout if analysis_uid in [l['analysis_uid'] for l in layout]: return # If the ws has an instrument assigned for which the analysis # is allowed, set it instr = self.getInstrument() if instr and analysis.isInstrumentAllowed(instr): # Set the method assigned to the selected instrument analysis.setMethod(instr.getMethod()) analysis.setInstrument(instr) self.setAnalyses(analyses + [ analysis, ]) # if our parent has a position, use that one. if analysis.aq_parent.UID() in [ slot['container_uid'] for slot in layout ]: position = [ int(slot['position']) for slot in layout if slot['container_uid'] == analysis.aq_parent.UID() ][0] else: # prefer supplied position parameter if not position: used_positions = [ 0, ] + [int(slot['position']) for slot in layout] position = [ pos for pos in range(1, max(used_positions) + 2) if pos not in used_positions ][0] self.setLayout(layout + [ { 'position': position, 'type': 'a', 'container_uid': parent_uid, 'analysis_uid': analysis.UID() }, ]) allowed_transitions = [ t['id'] for t in workflow.getTransitionsFor(analysis) ] if 'assign' in allowed_transitions: workflow.doActionFor(analysis, 'assign') # If a dependency of DryMatter service is added here, we need to # make sure that the dry matter analysis itself is also # present. Otherwise WS calculations refer to the DB version # of the DM analysis, which is out of sync with the form. dms = self.bika_setup.getDryMatterService() if dms: dmk = dms.getKeyword() deps = analysis.getDependents() # if dry matter service in my dependents: if dmk in [a.getService().getKeyword() for a in deps]: # get dry matter analysis from AR dma = analysis.aq_parent.getAnalyses(getKeyword=dmk, full_objects=True)[0] # add it. if dma not in self.getAnalyses(): self.addAnalysis(dma)
def workflow_script_reject(self): """Copy real analyses to RejectAnalysis, with link to real create a new worksheet, with the original analyses, and new duplicates and references to match the rejected worksheet. """ if skip(self, "reject"): return utils = getToolByName(self, 'plone_utils') workflow = self.portal_workflow def copy_src_fields_to_dst(src, dst): # These will be ignored when copying field values between analyses ignore_fields = [ 'UID', 'id', 'title', 'allowDiscussion', 'subject', 'description', 'location', 'contributors', 'creators', 'effectiveDate', 'expirationDate', 'language', 'rights', 'creation_date', 'modification_date', 'Layout', # ws 'Analyses', # ws ] fields = src.Schema().fields() for field in fields: fieldname = field.getName() if fieldname in ignore_fields: continue getter = getattr( src, 'get' + fieldname, src.Schema().getField(fieldname).getAccessor(src)) setter = getattr( dst, 'set' + fieldname, dst.Schema().getField(fieldname).getMutator(dst)) if getter is None or setter is None: # ComputedField continue setter(getter()) analysis_positions = {} for item in self.getLayout(): analysis_positions[item['analysis_uid']] = item['position'] old_layout = [] new_layout = [] # New worksheet worksheets = self.aq_parent new_ws = _createObjectByType('Worksheet', worksheets, tmpID()) new_ws.unmarkCreationFlag() new_ws_id = renameAfterCreation(new_ws) copy_src_fields_to_dst(self, new_ws) new_ws.edit(Number=new_ws_id, Remarks=self.getRemarks()) # Objects are being created inside other contexts, but we want their # workflow handlers to be aware of which worksheet this is occurring in. # We save the worksheet in request['context_uid']. # We reset it again below.... be very sure that this is set to the # UID of the containing worksheet before invoking any transitions on # analyses. self.REQUEST['context_uid'] = new_ws.UID() # loop all analyses analyses = self.getAnalyses() new_ws_analyses = [] old_ws_analyses = [] for analysis in analyses: # Skip published or verified analyses review_state = workflow.getInfoFor(analysis, 'review_state', '') if review_state in ['published', 'verified', 'retracted']: old_ws_analyses.append(analysis.UID()) old_layout.append({ 'position': position, 'type': 'a', 'analysis_uid': analysis.UID(), 'container_uid': analysis.aq_parent.UID() }) continue # Normal analyses: # - Create matching RejectAnalysis inside old WS # - Link analysis to new WS in same position # - Copy all field values # - Clear analysis result, and set Retested flag if analysis.portal_type == 'Analysis': reject = _createObjectByType('RejectAnalysis', self, tmpID()) reject.unmarkCreationFlag() reject_id = renameAfterCreation(reject) copy_src_fields_to_dst(analysis, reject) reject.setAnalysis(analysis) reject.reindexObject() analysis.edit( Result=None, Retested=True, ) analysis.reindexObject() position = analysis_positions[analysis.UID()] old_ws_analyses.append(reject.UID()) old_layout.append({ 'position': position, 'type': 'r', 'analysis_uid': reject.UID(), 'container_uid': self.UID() }) new_ws_analyses.append(analysis.UID()) new_layout.append({ 'position': position, 'type': 'a', 'analysis_uid': analysis.UID(), 'container_uid': analysis.aq_parent.UID() }) # Reference analyses # - Create a new reference analysis in the new worksheet # - Transition the original analysis to 'rejected' state if analysis.portal_type == 'ReferenceAnalysis': service_uid = analysis.getService().UID() reference = analysis.aq_parent reference_type = analysis.getReferenceType() new_analysis_uid = reference.addReferenceAnalysis( service_uid, reference_type) position = analysis_positions[analysis.UID()] old_ws_analyses.append(analysis.UID()) old_layout.append({ 'position': position, 'type': reference_type, 'analysis_uid': analysis.UID(), 'container_uid': reference.UID() }) new_ws_analyses.append(new_analysis_uid) new_layout.append({ 'position': position, 'type': reference_type, 'analysis_uid': new_analysis_uid, 'container_uid': reference.UID() }) workflow.doActionFor(analysis, 'reject') new_reference = reference.uid_catalog( UID=new_analysis_uid)[0].getObject() workflow.doActionFor(new_reference, 'assign') analysis.reindexObject() # Duplicate analyses # - Create a new duplicate inside the new worksheet # - Transition the original analysis to 'rejected' state if analysis.portal_type == 'DuplicateAnalysis': src_analysis = analysis.getAnalysis() ar = src_analysis.aq_parent service = src_analysis.getService() duplicate_id = new_ws.generateUniqueId('DuplicateAnalysis') new_duplicate = _createObjectByType('DuplicateAnalysis', new_ws, duplicate_id) new_duplicate.unmarkCreationFlag() copy_src_fields_to_dst(analysis, new_duplicate) workflow.doActionFor(new_duplicate, 'assign') new_duplicate.reindexObject() position = analysis_positions[analysis.UID()] old_ws_analyses.append(analysis.UID()) old_layout.append({ 'position': position, 'type': 'd', 'analysis_uid': analysis.UID(), 'container_uid': self.UID() }) new_ws_analyses.append(new_duplicate.UID()) new_layout.append({ 'position': position, 'type': 'd', 'analysis_uid': new_duplicate.UID(), 'container_uid': new_ws.UID() }) workflow.doActionFor(analysis, 'reject') analysis.reindexObject() new_ws.setAnalyses(new_ws_analyses) new_ws.setLayout(new_layout) new_ws.replaces_rejected_worksheet = self.UID() for analysis in new_ws.getAnalyses(): review_state = workflow.getInfoFor(analysis, 'review_state', '') if review_state == 'to_be_verified': changeWorkflowState(analysis, "bika_analysis_workflow", "sample_received") self.REQUEST['context_uid'] = self.UID() self.setLayout(old_layout) self.setAnalyses(old_ws_analyses) self.replaced_by = new_ws.UID()
def get_indicator_codes(self): """get indicator codes""" atvm = getToolByName(self, ATVOCABULARYTOOL) vocab = getattr(atvm, 'indicator_codes') return vocab.getDisplayList(self)
def addDuplicateAnalyses(self, src_slot, dest_slot): """ add duplicate analyses to worksheet """ rc = getToolByName(self, REFERENCE_CATALOG) workflow = getToolByName(self, 'portal_workflow') layout = self.getLayout() wst = self.getWorksheetTemplate() wstlayout = wst and wst.getLayout() or [] src_ar = [ slot['container_uid'] for slot in layout if slot['position'] == src_slot ] if src_ar: src_ar = src_ar[0] if not dest_slot or dest_slot == 'new': highest_existing_position = len(wstlayout) for pos in [int(slot['position']) for slot in layout]: if pos > highest_existing_position: highest_existing_position = pos dest_slot = highest_existing_position + 1 src_analyses = [ rc.lookupObject(slot['analysis_uid']) for slot in layout if int(slot['position']) == int(src_slot) ] dest_analyses = [ rc.lookupObject(slot['analysis_uid']).getAnalysis().UID() for slot in layout if int(slot['position']) == int(dest_slot) ] refgid = None processed = [] for analysis in src_analyses: if analysis.UID() in dest_analyses: continue if analysis.portal_type == 'ReferenceAnalysis': logger.warning('Cannot create duplicate analysis from ' 'ReferenceAnalysis at {}'.format(analysis)) continue # If retracted analyses, for some reason, the getLayout() returns # two times the regular analysis generated automatically after a # a retraction. if analysis.UID() in processed: continue # Omit retracted analyses # https://jira.bikalabs.com/browse/LIMS-1745 # https://jira.bikalabs.com/browse/LIMS-2001 if workflow.getInfoFor(analysis, "review_state") == 'retracted': continue processed.append(analysis.UID()) # services with dependents don't belong in duplicates service = analysis.getService() calc = service.getCalculation() if calc and calc.getDependentServices(): continue service = analysis.getService() _id = self._findUniqueId(service.getKeyword()) duplicate = _createObjectByType("DuplicateAnalysis", self, _id) duplicate.setAnalysis(analysis) # Set the required number of verifications reqvers = analysis.getNumberOfRequiredVerifications() duplicate.setNumberOfRequiredVerifications(reqvers) # Set ReferenceAnalysesGroupID (same id for the analyses from # the same Reference Sample and same Worksheet) if not refgid: prefix = analysis.aq_parent.getSample().id dups = [] for an in self.getAnalyses(): if an.portal_type == 'DuplicateAnalysis' \ and hasattr(an.aq_parent, 'getSample') \ and an.aq_parent.getSample().id == prefix: dups.append(an.getReferenceAnalysesGroupID()) dups = list(set(dups)) postfix = dups and len(dups) + 1 or 1 postfix = str(postfix).zfill(int(2)) refgid = '%s-D%s' % (prefix, postfix) duplicate.setReferenceAnalysesGroupID(refgid) duplicate.reindexObject(idxs=["getReferenceAnalysesGroupID"]) duplicate.processForm() if calc: duplicate.setInterimFields(calc.getInterimFields()) self.setLayout(self.getLayout() + [ { 'position': dest_slot, 'type': 'd', 'container_uid': analysis.aq_parent.UID(), 'analysis_uid': duplicate.UID() }, ]) self.setAnalyses(self.getAnalyses() + [ duplicate, ]) workflow.doActionFor(duplicate, 'assign')
def test_installed(self): portal_setup = getToolByName(self.portal, 'portal_setup') version = portal_setup.getLastVersionForProfile('ipa_demo.web:default') self.assertNotEqual(version, None) self.assertNotEqual(version, 'unknown')
def factory_Assessment(self): """factory""" type_name = 'Assessment' create = self.REQUEST.form.get('create_in_latest_spec') if create == 'true': latest = IGetVersions(self).latest_version() if latest.UID() != self.UID(): return latest.factory_Assessment() #drop with error if no PolicyQuestions are created if not self.objectValues('PolicyQuestion'): raise ValueError("You need to create first a Policy Question") #create a version if we already have an Assessment assessments = self.objectValues(type_name) if assessments: #NOTE: we assume the latest object is the last one original = assessments[-1] ast = createVersion(original) return { 'obj': ast, 'subview': '@@edit_aggregated', 'direct_edit': True } #we want to make this assessment a version of a previous assessment #if this Specification is already versioned, so we try get a versionId version_id = None spec_versions = IGetVersions(self).versions() for spec in spec_versions: asts = spec.objectValues("Assessment") if asts: original = asts[0] version_id = IVersionControl(original).versionId break #if there are no other assessments in this version set we look for #other IndicatorFactSheet objects with same indicator code to #get the versionId if not version_id: brains = [] codes = self.get_codes() cat = getToolByName(self, 'portal_catalog') for code in codes[1::2]: brains = cat.searchResults({ 'portal_type': 'IndicatorFactSheet', 'get_codes': code }) if brains: break if brains: version_id = IVersionControl(brains[0].getObject()).versionId #create a new Assessment from scratch #id = self.generateUniqueId(type_name) aid = make_id('assessment', self.objectIds()) new_id = self.invokeFactory(type_name=type_name, id=aid, base_impl=True, title=self.translate( msgid='label-newly-created-type', domain='indicators', default="Newly created ${type_name}", mapping={'type_name': type_name}, )) ast = self[new_id] if version_id: IVersionControl(ast).setVersionId(version_id) #create assessment parts for each policy question for pq in self.objectValues("PolicyQuestion"): aid = ast.invokeFactory( type_name="AssessmentPart", id=ast.generateUniqueId("AssessmentPart"), ) ap = ast[aid] ap.setRelatedItems(pq) try: ap.reindexObject() except AttributeError: log("#ZZZ: this happens when executed from test") ast.reindexObject() notify(ObjectInitializedEvent(ast)) return { 'obj': ast, 'subview': '@@edit_aggregated', 'direct_edit': True }
def install_indexes(self, out, types): portal_catalog = catalog = getToolByName(self, 'portal_catalog') for cls in types: if 'indexes' not in cls.installMode: continue for field in cls.schema.fields(): if not field.index: continue if isinstance(field.index, basestring): index = (field.index, ) elif isinstance(field.index, (tuple, list)): index = field.index else: raise SyntaxError("Invalid Index Specification %r" % field.index) for alternative in index: installed = None index_spec = alternative.split(':', 1) use_column = 0 if len(index_spec) == 2 and index_spec[1] in ('schema', 'brains'): use_column = 1 index_spec = index_spec[0] accessor = field.getIndexAccessorName() parts = index_spec.split('|') # we want to be able to specify which catalog we want to use # for each index. syntax is # index=('member_catalog/:schema',) # portal catalog is used by default if not specified if parts[0].find('/') > 0: str_idx = parts[0].find('/') catalog_name = parts[0][:str_idx] parts[0] = parts[0][str_idx + 1:] catalog = getToolByName(self, catalog_name) else: catalog = portal_catalog ##################### # add metadata column # lets see if the catalog is itself an Archetype: isArchetype = IBaseObject.providedBy(catalog) # archetypes based zcatalogs need to provide a different method # to list its schema-columns to not conflict with archetypes # schema hasNewWayMethod = hasattr(catalog, 'zcschema') hasOldWayMethod = not isArchetype and hasattr( catalog, 'schema') notInNewWayResults = hasNewWayMethod and accessor not in catalog.zcschema( ) notInOldWayResults = hasOldWayMethod and accessor not in catalog.schema( ) if use_column and (notInNewWayResults or notInOldWayResults): try: catalog.addColumn(accessor) except: import traceback traceback.print_exc(file=out) ########### # add index # if you want to add a schema field without an index # if not parts[0]: # continue for itype in parts: extras = itype.split(',') if len(extras) > 1: itype = extras[0] props = Extra() for extra in extras[1:]: name, value = extra.split('=') setattr(props, name.strip(), value.strip()) else: props = None try: # Check for the index and add it if missing catalog.addIndex(accessor, itype, extra=props) catalog.manage_reindexIndex(ids=(accessor, )) except: # FIXME: should only catch "Index Exists" # damned string exception ! pass else: installed = 1 break if installed: break
def archive(self, action): """Try to archive this dossier. For that to happen, first all subdossiers need to have filing_no and end_date set, and then be resolved. If resolving any of the subdossier fails, we'll throw and error and return. """ data, errors = self.extractData() # Abort if there were errors if len(errors) > 0: return self.ptool = getToolByName(self.context, 'plone_utils') self.wft = self.context.portal_workflow action = data.get('filing_action') filing_year = data.get('filing_year') filing_no = None filing_prefix = data.get('filing_prefix') end_date = data.get('dossier_enddate') if action == METHOD_FILING: # allready resolved only give a filing number IDossierArchiver(self.context).archive(filing_prefix, filing_year) self.ptool.addPortalMessage(_("The filing number has been given."), type="info") return self.request.RESPONSE.redirect(self.context.absolute_url()) # Validate resolving preconditions resolver = get_resolver(self.context) try: resolver.raise_on_failed_preconditions() except PreconditionsViolated as exc: return self.show_errors(exc.errors) except InvalidDates as exc: return self.show_invalid_end_dates( titles=exc.invalid_dossier_titles) if action == METHOD_RESOLVING_AND_FILING: IDossierArchiver(self.context).archive(filing_prefix, filing_year) if action == METHOD_RESOLVING_EXISTING_FILING: # archive all with the existing filing number filing_no = IFilingNumber(self.context).filing_no filing_prefix = IDossier(self.context).filing_prefix IDossierArchiver(self.context).archive(filing_prefix, filing_year, number=filing_no) if action == METHOD_RESOLVING: # only update the prefixes if filing_prefix: IDossierArchiver(self.context).update_prefix(filing_prefix) # If everything went well, resolve the main dossier resolver.resolve(end_date=end_date) self.ptool.addPortalMessage(_("The Dossier has been resolved"), type="info") return self.request.RESPONSE.redirect(self.context.absolute_url())
def author(self): membership = getToolByName(self.context, 'portal_membership') return membership.getMemberInfo(self.creator())
class RegisterForm(form.EditForm): ''' Implementation of the registration form ''' fields = field.Fields(IRegisterFormSchema) id = 'RegisterForm' label = _(u'heading_register_form', default=u'Sign up') description = _(u'description_register_form', default=u'Join the club.') ignoreContext = True prefix = '' def updateWidgets(self): super(RegisterForm, self).updateWidgets(prefix='') portal_props = getToolByName(self.context, 'portal_properties') props = portal_props.site_properties use_email_as_login = props.getProperty('use_email_as_login') self.widgets['email'].tabindex = 1 self.widgets['email'].autocapitalize = 'off' self.widgets['email'].placeholder = _(u'placeholder_email', default=u'Email address') append_klasses(self.widgets['email'], 'stretch') if not use_email_as_login: self.widgets['email'].tabindex += 1 self.widgets['username'].tabindex = 1 self.widgets['username'].autocapitalize = _(u'off') self.widgets['username'].placeholder = _(u'placeholder_username', default=u'Username') append_klasses(self.widgets['username'], 'stretch') self.widgets['password'].tabindex = 3 self.widgets['password'].placeholder = _( u'placeholder_password', default=u'Super secure password') append_klasses(self.widgets['password'], 'stretch') self.widgets['password_confirm'].tabindex = 4 self.widgets['password_confirm'].placeholder = _( u'placeholder_password_confirm', default=u'Confirm password') append_klasses(self.widgets['password_confirm'], 'stretch') def updateFields(self): super(RegisterForm, self).updateFields() fields = field.Fields(IRegisterForm) portal_props = getToolByName(self.context, 'portal_properties') props = portal_props.site_properties use_email_as_login = props.getProperty('use_email_as_login') if use_email_as_login: fields.remove('username') @button.buttonAndHandler(_(u'button_register', default=u'Register'), name='register') def handleRegister(self, action): authenticator = getMultiAdapter((self.context, self.request), name=u'authenticator') if not authenticator.verify(): raise Unauthorized data, errors = self.extractData() if errors: self.status = self.formErrorsMessage return password = str(data.get('password')) username = str(data.get('username')) email = data.get('email') portal_props = getToolByName(self.context, 'portal_properties') props = portal_props.site_properties use_email_as_login = props.getProperty('use_email_as_login') if use_email_as_login: username = email = str(data.get('email')) registration = getToolByName(self.context, 'portal_registration') try: registration.addMember(username, password) except (AttributeError, ValueError), err: IStatusMessage(self.request).addStatusMessage(err, type='error') return authenticated = self.context.acl_users.authenticate( username, password, self.request) if authenticated: self.context.acl_users.updateCredentials(self.request, self.request.response, username, password) membership_tool = getToolByName(self.context, 'portal_membership') member = membership_tool.getMemberById(username) # XXX: Improve this for further fields member.setMemberProperties({'email': email}) login_time = member.getProperty('login_time', '2000/01/01') if not isinstance(login_time, DateTime): login_time = DateTime(login_time) initial_login = login_time == DateTime('2000/01/01') if initial_login: # TODO: Redirect if this is initial login pass IStatusMessage(self.request).addStatusMessage( _(u'statusmessage_your_now_logged_in', default=u'You are now ' u'logged in.'), 'info') # TODO: Add way to configure the redirect self.request.response.redirect(self.context.absolute_url())
def contentsMethod(self, contentFilter): pc = getToolByName(self.context, 'portal_catalog') if 'SamplingRoundUID' not in contentFilter.keys(): contentFilter['SamplingRoundUID'] = self.context.UID() return pc(contentFilter)
def install_actions(self, out, types): typesTool = getToolByName(self, 'portal_types') for portal_type in types: # rr: XXX TODO somehow the following doesn't do anymore what # it used to do :-( fixActionsForType(portal_type, typesTool)
def registerTransform(self, out, name, module): transforms = getToolByName(self, 'portal_transforms') transforms.manage_addTransform(name, module) print >> out, "Registered transform", name
def revisionHistory(self): context = aq_inner(self.context) if not _checkPermission(AccessPreviousVersions, context): return [] rt = getToolByName(context, "portal_repository", None) if rt is None or not rt.isVersionable(context): return [] context_url = context.absolute_url() history = rt.getHistoryMetadata(context) portal_diff = getToolByName(context, "portal_diff", None) can_diff = portal_diff is not None \ and len(portal_diff.getDiffForPortalType(context.portal_type)) > 0 can_revert = _checkPermission( 'CMFEditions: Revert to previous versions', context) def morphVersionDataToHistoryFormat(vdata, version_id): meta = vdata["metadata"]["sys_metadata"] userid = meta["principal"] token = createToken() preview_url = \ "%s/versions_history_form?version_id=%s&_authenticator=%s#version_preview" % ( # noqa context_url, version_id, token ) info = dict( type='versioning', action=_(u"Edited"), transition_title=_(u"Edited"), actorid=userid, time=meta["timestamp"], comments=meta['comment'], version_id=version_id, preview_url=preview_url, ) if can_diff: if version_id > 0: info["diff_previous_url"] = ( "%s/@@history?one=%s&two=%s&_authenticator=%s" % (context_url, version_id, version_id - 1, token)) if not rt.isUpToDate(context, version_id): info["diff_current_url"] = ( "%s/@@history?one=current&two=%s&_authenticator=%s" % (context_url, version_id, token)) if can_revert: info["revert_url"] = "%s/revertversion" % context_url else: info["revert_url"] = None info.update(self.getUserInfo(userid)) return info # History may be an empty list if not history: return history version_history = [] retrieve = history.retrieve getId = history.getVersionId # Count backwards from most recent to least recent for i in xrange(history.getLength(countPurged=False) - 1, -1, -1): version_history.append( morphVersionDataToHistoryFormat(retrieve(i, countPurged=False), getId(i, countPurged=False))) return version_history
def mailPassword(self, login, REQUEST, immediate=False): """ Wrapper around mailPassword """ membership = getToolByName(self, 'portal_membership') if not membership.checkPermission('Mail forgotten password', self): raise Unauthorized( _(u"Mailing forgotten passwords has been disabled.")) utils = getToolByName(self, 'plone_utils') member = get_member_by_login_name(self, login, raise_exceptions=False) if member is None: raise ValueError( _(u'The username you entered could not be found.')) # assert that we can actually get an email address, otherwise # the template will be made with a blank To:, this is bad email = member.getProperty('email') if not email: raise ValueError(_(u'That user does not have an email address.')) else: # add the single email address if not utils.validateSingleEmailAddress(email): raise ValueError(_(u'The email address did not validate.')) check, msg = _checkEmail(email) if not check: raise ValueError(msg) # Rather than have the template try to use the mailhost, we will # render the message ourselves and send it from here (where we # don't need to worry about 'UseMailHost' permissions). reset_tool = getToolByName(self, 'portal_password_reset') reset = reset_tool.requestReset(member.getId()) encoding = getUtility(ISiteRoot).getProperty('email_charset', 'utf-8') mail_text = self.mail_password_template(self, REQUEST, member=member, reset=reset, password=member.getPassword(), charset=encoding) # The mail headers are not properly encoded we need to extract # them and let MailHost manage the encoding. if isinstance(mail_text, unicode): mail_text = mail_text.encode(encoding) message_obj = message_from_string(mail_text.strip()) subject = message_obj['Subject'] m_to = message_obj['To'] m_from = message_obj['From'] host = getToolByName(self, 'MailHost') try: host.send(mail_text, m_to, m_from, subject=subject, charset=encoding, immediate=immediate) except SMTPRecipientsRefused: # Don't disclose email address on failure raise SMTPRecipientsRefused( _(u'Recipient address rejected by server.')) except SMTPException as e: raise (e) # return the rendered template "mail_password_response.pt" # (in Products.PasswordResetTool) return self.mail_password_response(self, REQUEST)
def unregisterMimeType(self, out, mimetype): if type(mimetype) != InstanceType: mimetype = mimetype() mimetypes_registry = getToolByName(self, 'mimetypes_registry') mimetypes_registry.unregister(mimetype) print >> out, "Unregistered mimetype", mimetype