Example #1
0
    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
Example #2
0
    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)
Example #3
0
    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()
Example #5
0
    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
Example #6
0
    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
Example #7
0
    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
Example #8
0
    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)
Example #9
0
 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
         })
Example #10
0
    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
Example #11
0
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)
Example #12
0
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)
Example #16
0
    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 [], [], {}
Example #17
0
    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)
Example #19
0
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)
Example #20
0
    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)
Example #22
0
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()
Example #24
0
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)
Example #25
0
 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))
Example #26
0
 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', '')
Example #27
0
 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
Example #28
0
 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"
Example #29
0
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
Example #30
0
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
Example #31
0
 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']
Example #35
0
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
Example #36
0
 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)
Example #37
0
 def __init__(self, *args, **kwargs):
     super(InstallerView, self).__init__(*args, **kwargs)
     self.ps = getToolByName(self.context, 'portal_setup')
     self.errors = {}
Example #38
0
    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
Example #39
0
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()
Example #40
0
    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
Example #42
0
    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)
Example #43
0
    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)
Example #44
0
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()
Example #45
0
    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)
Example #46
0
    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()
Example #47
0
 def get_indicator_codes(self):
     """get indicator codes"""
     atvm = getToolByName(self, ATVOCABULARYTOOL)
     vocab = getattr(atvm, 'indicator_codes')
     return vocab.getDisplayList(self)
Example #48
0
    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')
Example #49
0
 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')
Example #50
0
    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
        }
Example #51
0
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
Example #52
0
    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())
Example #53
0
 def author(self):
     membership = getToolByName(self.context, 'portal_membership')
     return membership.getMemberInfo(self.creator())
Example #54
0
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())
Example #55
0
 def contentsMethod(self, contentFilter):
     pc = getToolByName(self.context, 'portal_catalog')
     if 'SamplingRoundUID' not in contentFilter.keys():
         contentFilter['SamplingRoundUID'] = self.context.UID()
     return pc(contentFilter)
Example #56
0
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)
Example #57
0
def registerTransform(self, out, name, module):
    transforms = getToolByName(self, 'portal_transforms')
    transforms.manage_addTransform(name, module)
    print >> out, "Registered transform", name
Example #58
0
    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
Example #59
0
    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)
Example #60
0
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