Ejemplo n.º 1
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
Ejemplo n.º 2
0
 def buildExternalIdMap(self, root, zodb_path=[], mapping=None):
     if mapping is None:
         mapping = {}
     for child in root.values():
         external_id = getattr(aq_base(child), "external_id", None)
         newpath = zodb_path + [child.id]
         if external_id is not None:
             mapping[external_id] = "/".join(newpath)
         if IQuestionContainer.providedBy(child):
             self.buildExternalIdMap(child, newpath, mapping)
     return mapping
Ejemplo n.º 3
0
 def update(self):
     actions = getFactoriesInContext(self.context)
     if IModule.providedBy(self.context):
         for (i, action) in enumerate(actions):
             # To be able to determine what button label to display, we
             # explicitly set the action.id to the fake "euphorie.submodule"
             if action.id == "euphorie.module":
                 actions[i] = FactoryInfo("euphorie.submodule",
                         _(u"Submodule"), *action[2:])
                 break
     self.actions = sorted(actions, key=lambda x: x.title)
     self.can_edit = checkPermission(self.context, "Modify portal content")
     self.library_available = IQuestionContainer.providedBy(self.context)
Ejemplo n.º 4
0
 def update(self):
     actions = getFactoriesInContext(self.context)
     if IModule.providedBy(self.context):
         for (i, action) in enumerate(actions):
             # To be able to determine what button label to display, we
             # explicitly set the action.id to the fake "euphorie.submodule"
             if action.id == "euphorie.module":
                 actions[i] = FactoryInfo("euphorie.submodule",
                                          _("Submodule"), *action[2:])
                 break
     self.actions = sorted(actions, key=lambda x: x.title)
     self.can_edit = checkPermission(self.context, "Modify portal content")
     self.library_available = IQuestionContainer.providedBy(self.context)
Ejemplo n.º 5
0
def getSurveyTree(survey, profile=None):
    """Return a list of all modules, profile questions and risks in
    a survey. Each entry is represented by a dict with a `zodb_path`
    and `type` key.
    """
    # XXX Can this be cached on the survey instance?
    nodes = []
    base_length = len(survey.getPhysicalPath())
    queue = collections.deque(survey.values())
    while queue:
        node = queue.popleft()
        if node.portal_type not in [
                "euphorie.profilequestion",
                "euphorie.module",
                "euphorie.risk",
        ]:
            continue
        # Note that in profile.AddToTree, we pretend that an optional module
        # always has a description. This logic needs to be replicated here.
        if node.portal_type == "euphorie.module":
            has_description = HasText(node.description) or node.optional
        else:
            has_description = HasText(node.description)
        if profile and node.portal_type == "euphorie.profilequestion":
            if not profile.get(node.id):
                continue
        nodes.append({
            "zodb_path":
            "/".join(node.getPhysicalPath()[base_length:]),
            "type":
            node.portal_type[9:],
            "has_description":
            has_description,
            "always_present":
            (node.portal_type[9:] == "risk" and node.risk_always_present
             or False),
            "risk_type": (node.portal_type[9:] == "risk" and node.type
                          or None),
            "optional":
            node.optional,
        })
        if IQuestionContainer.providedBy(node):
            queue.extend(node.values())
    return nodes
Ejemplo n.º 6
0
def getSurveyTree(survey):
    """Return a list of all modules, profile questions and risks in
    a survey. Each entry is represented by a dict with a `zodb_path`
    and `type` key.
    """
    # XXX Can this be cached on the survey instance?
    nodes = []
    base_length = len(survey.getPhysicalPath())
    queue = collections.deque(survey.values())
    while queue:
        node = queue.popleft()
        if node.portal_type not in \
                ['euphorie.profilequestion', 'euphorie.module',
                 'euphorie.risk']:
            continue
        nodes.append({
            'zodb_path': '/'.join(node.getPhysicalPath()[base_length:]),
            'type': node.portal_type[9:],
            'has_description': HasText(node.description),
            'optional': node.optional, })
        if IQuestionContainer.providedBy(node):
            queue.extend(node.values())
    return nodes
Ejemplo n.º 7
0
def getSurveyTree(survey):
    """Return a list of all modules, profile questions and risks in
    a survey. Each entry is represented by a dict with a `zodb_path`
    and `type` key.
    """
    # XXX Can this be cached on the survey instance?
    nodes = []
    base_length = len(survey.getPhysicalPath())
    queue = collections.deque(survey.values())
    while queue:
        node = queue.popleft()
        if node.portal_type not in \
                ['euphorie.profilequestion', 'euphorie.module',
                 'euphorie.risk']:
            continue
        nodes.append({
            'zodb_path': '/'.join(node.getPhysicalPath()[base_length:]),
            'type': node.portal_type[9:],
            'has_description': HasText(node.description),
            'always_present': node.portal_type[9:] == "risk" and node.risk_always_present or False,
            'optional': node.optional, })
        if IQuestionContainer.providedBy(node):
            queue.extend(node.values())
    return nodes
Ejemplo n.º 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
Ejemplo n.º 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
Ejemplo n.º 10
0
 def update(self):
     super(OshaAddBarTile, self).update()
     self.library_available = IQuestionContainer.providedBy(self.context)