Beispiel #1
0
    def exportModule(self, parent, module):
        """:returns: An XML node with the details of an
        :obj:`euphorie.content.module`."""
        node = etree.SubElement(
            parent, "module", optional="true" if module.optional else "false")
        if getattr(module, "external_id", None):
            node.attrib["external-id"] = module.external_id
        etree.SubElement(node, "title").text = module.title
        if self.include_module_description_texts and HasText(
                module.description):
            node = self._add_string_or_html(node, module.description,
                                            "description")
        if module.optional:
            etree.SubElement(node, "question").text = module.question
        if self.include_module_solution_texts and StripMarkup(
                module.solution_direction):
            etree.SubElement(node, "solution-direction").text = StripUnwanted(
                module.solution_direction)
        if module.image is not None:
            self.exportImage(node, module.image, module.caption)

        for child in module.values():
            if IModule.providedBy(child):
                self.exportModule(node, child)
            elif IRisk.providedBy(child):
                self.exportRisk(node, child)
        return node
Beispiel #2
0
 def walk(node):
     for idx, sub_node in node.ZopeFind(node, search_sub=0):
         if IRisk.providedBy(sub_node):
             yield sub_node
         if IDexterityContainer.providedBy(sub_node):
             for sub_sub_node in walk(sub_node):
                 yield sub_sub_node
Beispiel #3
0
    def exportProfileQuestion(self, parent, profile):
        """:returns: An XML node with the details of an
        :obj:`euphorie.content.profilequestion`.
        """
        node = etree.SubElement(parent, "profile-question")
        if getattr(profile, "external_id", None):
            node.attrib["external-id"] = profile.external_id
        etree.SubElement(node, "title").text = profile.title
        # Use title if question is not available (Euphorie < 2.0rc2 data)
        if HasText(profile.question):
            node = self._add_string_or_html(node, profile.question, "question")
        else:
            etree.SubElement(node, "question").text = profile.title
        if HasText(profile.description):
            node = self._add_string_or_html(node, profile.description,
                                            "description")
        for fname in ProfileQuestionLocationFields:
            value = getattr(profile, fname, None)
            if value:
                etree.SubElement(node, fname.replace("_", "-")).text = value

        etree.SubElement(
            node, "use-location-question").text = ("true" if getattr(
                profile, "use_location_question", True) else "false")

        for child in profile.values():
            if IModule.providedBy(child):
                self.exportModule(node, child)
            elif IRisk.providedBy(child):
                self.exportRisk(node, child)
        return node
Beispiel #4
0
    def exportModule(self, parent, module):
        """ :returns: An XML node with the details of an :obj:`euphorie.content.module`.
        """
        node = etree.SubElement(parent, "module",
                optional="true" if module.optional else "false")
        if getattr(module, "external_id", None):
            node.attrib["external-id"] = module.external_id
        etree.SubElement(node, "title").text = module.title
        if HasText(module.description):
            etree.SubElement(node, "description").text = StripUnwanted(
                module.description)
        if module.optional:
            etree.SubElement(node, "question").text = module.question
        if StripMarkup(module.solution_direction):
            etree.SubElement(node, "solution-direction").text = StripUnwanted(
                module.solution_direction)
        if module.image is not None:
            self.exportImage(node, module.image, module.caption)

        for child in module.values():
            if IModule.providedBy(child):
                self.exportModule(node, child)
            elif IRisk.providedBy(child):
                self.exportRisk(node, child)
        return node
Beispiel #5
0
def build_survey_tree(context, root):
    """Build a simple datastructure describing (part of) a survey.

    This implementation does a walk over the content itself. It is possible
    to also do this based on a catalog query, but since we use light-weight
    content items this should be simpler and removes the need to turn a
    catalog result back into a tree.

    :rtype: dict
    """
    normalize = getUtility(IIDNormalizer).normalize
    tree = {'title': root.title,
            'path': '/'.join(root.getPhysicalPath()),
            'portal_type': normalize(root.portal_type),
            'children': [],
            'url': root.absolute_url(),
            }
    todo = collections.deque([(root, [], tree['children'])])
    while todo:
        (node, index, child_list) = todo.popleft()
        for (ix, child) in enumerate(node.values(), 1):
            if not (IQuestionContainer.providedBy(child) or IRisk.providedBy(child)):
                continue
            child_index = index + [str(ix)]
            info = {'title': child.title,
                    'children': [],
                    'number': '.'.join(child_index),
                    'path': '/'.join(child.getPhysicalPath()),
                    'url': child.absolute_url(),
                    'disabled': not is_allowed(context, child),
                    'portal_type': normalize(child.portal_type),
                    }
            child_list.append(info)
            todo.append((child, child_index, info['children']))
    return tree
Beispiel #6
0
    def exportProfileQuestion(self, parent, profile):
        node = etree.SubElement(parent, "profile-question")
        if getattr(profile, "external_id", None):
            node.attrib["external-id"] = profile.external_id
        etree.SubElement(node, "title").text = profile.title
        # Use title if question is not available (Euphorie < 2.0rc2 data)
        etree.SubElement(node, "question").text = \
                profile.question or profile.title
        if HasText(profile.description):
            etree.SubElement(node, "description").text = profile.description

        for child in profile.values():
            if IModule.providedBy(child):
                self.exportModule(node, child)
            elif IRisk.providedBy(child):
                self.exportRisk(node, child)
        return node
Beispiel #7
0
    def copyTemplate(self, source, target):
        target = self.context[target.id]  # Acquisition-wrap
        try:
            source._notifyOfCopyTo(target, op=0)
        except ConflictError:
            raise

        copy = source._getCopy(target)

        today = datetime.date.today()
        title = self.request.locale.dates.getFormatter("date", length="long").format(
            datetime.date.today()
        )
        copy.id = today.isoformat()
        copy.title = title
        source_algorithm = aq_parent(source).evaluation_algorithm
        target_algorithm = self.request.form.get(
            "form.widgets.evaluation_algorithm", [source_algorithm]
        ).pop()
        target.evaluation_algorithm = target_algorithm
        target._setObject(copy.id, copy)
        if source_algorithm != target_algorithm:
            from euphorie.content.risk import EnsureInterface
            from euphorie.content.risk import IRisk

            risks = [
                item
                for (id, item) in target.ZopeFind(target, search_sub=1)
                if IRisk.providedBy(item)
            ]
            for risk in risks:
                EnsureInterface(risk)

        if hasattr(copy, "published"):
            delattr(copy, "published")
        copy = target[copy.id]  # Acquisition-wrap
        copy.wl_clearLocks()
        copy._postCopy(target, op=0)

        wt = api.portal.get_tool("portal_workflow")
        if wt.getInfoFor(copy, "review_state") == "published":
            wt.doActionFor(copy, "retract")

        notify(ObjectClonedEvent(target[copy.id]))
        return copy
Beispiel #8
0
def AddToTree(root, node, zodb_path=[], title=None, profile_index=0, skip_children=False):
    """Add a new node to the session tree.

    :param root: parent node of the new child
    :type root: py:class:`euphorie.client.model.SurveySession` or
          :py:class:`euphorie.client.model.SurveyTreeItem`
    :param node: ZODB object to add to the node.
    :type node: one of the :py:mod:`euphorie.content` content types
    :param zodb_path: list of ids of all parents of the root in the session
           tree
    :param title: title for the generated node. Defaults to the title of the
           ZODB object
    :type title: unicode or None
    :param int profile_index: profile answer index number.
    """
    title = title or node.title

    if title:
        title = title[:500]

    if IQuestionContainer.providedBy(node):
        child = model.Module(title=title, module_id=node.id)
        child.has_description = HasText(node.description)
        if IModule.providedBy(node):
            child.solution_direction = HasText(node.solution_direction)
            if node.optional:
                child.skip_children = False
                child.has_description = True
            else:
                child.postponed = False
    elif IRisk.providedBy(node):
        priority = getattr(node, "default_priority", None)
        if priority == "none":
            priority = None

        if IFrenchRisk.providedBy(node):
            effect = node.default_severity
        else:
            effect = node.default_effect

        child = model.Risk(title=title,
                         risk_id=node.id,
                         risk_type=node.type,
                         skip_evaluation=(node.evaluation_method == 'fixed'),
                         probability=node.default_probability,
                         frequency=node.default_frequency,
                         effect=effect,
                         priority=priority)
        child.skip_children = False
        child.postponed = False
        child.has_description = HasText(node.description)
        if node.type in ['top5', 'policy']:
            child.priority = 'high'
        if node.risk_always_present:
            child.identification = u"no"
    else:
        return None  # Should never happen

    zodb_path = zodb_path + [node.id]
    child.zodb_path = "/".join(zodb_path)
    child.profile_index = profile_index
    root.addChild(child)

    if IQuestionContainer.providedBy(node) and not skip_children:
        for grandchild in node.values():
            AddToTree(child, grandchild, zodb_path, None, profile_index)
    return child
Beispiel #9
0
def AddToTree(root,
              node,
              zodb_path=[],
              title=None,
              profile_index=0,
              skip_children=False):
    """Add a new node to the session tree.

    :param root: parent node of the new child
    :type root: py:class:`euphorie.client.model.SurveySession` or
          :py:class:`euphorie.client.model.SurveyTreeItem`
    :param node: ZODB object to add to the node.
    :type node: one of the :py:mod:`euphorie.content` content types
    :param zodb_path: list of ids of all parents of the root in the session
           tree
    :param title: title for the generated node. Defaults to the title of the
           ZODB object
    :type title: unicode or None
    :param int profile_index: profile answer index number.
    """
    title = title or node.title

    if title:
        title = title[:500]

    if IQuestionContainer.providedBy(node):
        child = model.Module(title=title, module_id=node.id)
        child.has_description = HasText(node.description)
        if IModule.providedBy(node):
            child.solution_direction = HasText(node.solution_direction)
            if node.optional:
                child.skip_children = False
                child.has_description = True
            else:
                child.postponed = False
    elif IRisk.providedBy(node):
        priority = getattr(node, "default_priority", None)
        if priority == "none":
            priority = None

        if IFrenchRisk.providedBy(node):
            effect = node.default_severity
        else:
            effect = node.default_effect

        child = model.Risk(title=title,
                           risk_id=node.id,
                           risk_type=node.type,
                           skip_evaluation=(node.evaluation_method == 'fixed'),
                           probability=node.default_probability,
                           frequency=node.default_frequency,
                           effect=effect,
                           priority=priority)
        child.skip_children = False
        child.postponed = False
        child.has_description = HasText(node.description)
        if node.type in ['top5', 'policy']:
            child.priority = 'high'
        if node.risk_always_present:
            child.identification = u"no"
    else:
        return None  # Should never happen

    zodb_path = zodb_path + [node.id]
    child.zodb_path = "/".join(zodb_path)
    child.profile_index = profile_index
    root.addChild(child)

    if IQuestionContainer.providedBy(node) and not skip_children:
        for grandchild in node.values():
            AddToTree(child, grandchild, zodb_path, None, profile_index)
    return child
Beispiel #10
0
def migrate_actgion_plans(context):
    # Work in chunks of 25
    max_tools = 25
    site = api.portal.get()
    client = getattr(site, "client")
    today = date.today()
    request = context.REQUEST.clone()
    alsoProvides(request, IClientSkinLayer)
    # path = "eu/maritime-transport/maritime-transport-1"
    tool_paths = Session.query(model.SurveySession.zodb_path).distinct()
    # .filter(model.SurveySession.zodb_path==path).distinct()
    tool_count = 0
    skip_count = 0
    for result in tool_paths:
        tool_path = str(result[0])
        try:
            tool = client.restrictedTraverse(tool_path)
        except KeyError:
            log.warning("No tool in client found for {}".format(tool_path))
            continue
        country = tool_path.split("/")[0]
        sessions = (
            Session.query(model.SurveySession).filter(
                and_(
                    model.Account.id == model.SurveySession.account_id,
                    model.Account.account_type != "guest",
                    model.SurveySession.zodb_path == tool_path,
                    model.SurveySession.migrated == None,  # noqa: E711
                )).order_by(model.SurveySession.zodb_path))
        if not sessions.count():
            skip_count += 1
            if skip_count % 5 == 0:
                log.info("Skipped the first %d, already handled" % skip_count)
            continue
        log.info("\n\nHandle tool {}".format(tool_path))
        risks_by_path = {}
        solutions_by_path = {}
        measures_by_path = {}
        for session in sessions:
            log.info("Session {}".format(session.id))
            risks = (Session.query(model.Risk).filter(
                model.Risk.session_id == session.id).order_by(model.Risk.path))
            for risk in risks:
                risk_path = str(risk.zodb_path)
                is_custom = "custom" in risk_path
                if is_custom:
                    zodb_risk = None
                elif risk_path not in risks_by_path:
                    try:
                        zodb_risk = tool.restrictedTraverse(risk_path)
                    except Exception:
                        log.warning("Risk {} not found in tool {}".format(
                            risk_path, tool_path))
                        continue
                    else:
                        if not IRisk.providedBy(zodb_risk):
                            zodb_risk = None
                            solutions_by_path[risk_path] = []
                            measures_by_path[risk_path] = []
                        else:
                            solutions = zodb_risk._solutions
                            solutions_by_path[risk_path] = solutions
                            measures_by_path[
                                risk_path] = get_pre_defined_measures(
                                    solutions, country)
                        risks_by_path[risk_path] = zodb_risk

                else:
                    zodb_risk = risks_by_path[risk_path]

                # convert ActionPlan items that are clearly based on solutions
                # to "standard" type
                if not is_custom:
                    for ap in risk.custom_measures:
                        for solution in solutions_by_path[risk_path]:
                            if solution.action_plan == (ap.action_plan
                                                        or "").strip():
                                if (getattr(solution, "prevention_plan", "")
                                        or "").strip() == (
                                            ap.prevention_plan
                                            or "") and (getattr(
                                                solution, "requirements",
                                                "") or "").strip() == (
                                                    ap.requirements or ""):
                                    ap.plan_type = "measure_standard"
                                    ap.solution_id = solution.id
                # Convert the measures-in-place to their respective ActionPlan items
                try:
                    saved_existing_measures = (risk.existing_measures and
                                               loads(risk.existing_measures)
                                               or [])
                except ValueError:
                    saved_existing_measures = []
                # Backwards compat. We used to save dicts before we
                # switched to list of tuples.
                if isinstance(saved_existing_measures, dict):
                    saved_existing_measures = [
                        (k, v) for (k, v) in saved_existing_measures.items()
                    ]
                new_action_plans = []
                already_converted_measure_ids = [
                    x.solution_id for x in risk.in_place_standard_measures
                ]
                already_converted_custom_texts = [
                    x.action for x in risk.in_place_custom_measures
                ]
                if saved_existing_measures:
                    custom = []
                    while saved_existing_measures:
                        text, active = saved_existing_measures.pop()
                        if not active:
                            continue
                        if not is_custom and text in measures_by_path[
                                risk_path]:
                            solution_id = measures_by_path[risk_path][text]
                            if solution_id not in already_converted_measure_ids:
                                new_action_plans.append(
                                    model.ActionPlan(
                                        action=text,
                                        plan_type="in_place_standard",
                                        solution_id=solution_id,
                                    ))
                        else:
                            if text not in already_converted_custom_texts:
                                custom.append(text)
                    for text in custom:
                        new_action_plans.append(
                            model.ActionPlan(action=text,
                                             plan_type="in_place_custom"))
                if new_action_plans:
                    risk.action_plans.extend(new_action_plans)
            session.migrated = today
        tool_count += 1
        if max_tools > 0 and tool_count >= max_tools:
            log.info("Broke off after %d tools" % tool_count)
            return