Example #1
0
    def get_items(self):
        tree = self.get_tree()
        tree, prev_item, next_item = self._apply_pagination(tree)

        message_ids = []
        for parent_id, child_ids in tree:
            message_ids.append(parent_id)
            message_ids.extend(child_ids)

        if prev_item:
            message_ids.append(prev_item)

        messages = Message._byID(message_ids, data=True, return_dict=False)
        wrapped = {m._id: m for m in self.wrap_items(messages)}

        if prev_item:
            prev_item = wrapped[prev_item]
        if next_item:
            next_item = wrapped[next_item]

        final = []
        for parent_id, child_ids in tree:
            if parent_id not in wrapped:
                continue

            parent = wrapped[parent_id]

            if not self._viewable_message(parent):
                continue

            children = [wrapped[child_id] for child_id in child_ids if child_id in wrapped]

            depth = {parent_id: 0}
            substitute_parents = {}

            if (
                children
                and self.skip
                and not self.threaded
                and not self.parent
                and not parent.new
                and parent.is_collapsed
            ):
                for i, child in enumerate(children):
                    if child.new or not child.is_collapsed:
                        break
                else:
                    i = -1
                # in flat view replace collapsed chain with MoreMessages
                add_child_listing(parent)
                parent = Wrapped(MoreMessages(parent, parent.child))
                children = children[i:]

            for child in sorted(children, key=lambda child: child._id):
                # iterate from the root outwards so we can check the depth
                if self.threaded:
                    try:
                        child_parent = wrapped[child.parent_id]
                    except KeyError:
                        # the stored comment tree was missing this message's
                        # parent, treat it as a top level reply
                        child_parent = parent
                else:
                    # for flat view all messages are decendants of the
                    # parent message
                    child_parent = parent
                parent_depth = depth[child_parent._id]
                child_depth = parent_depth + 1
                depth[child._id] = child_depth

                if child_depth == MAX_RECURSION:
                    # current message is at maximum depth level, all its
                    # children will be displayed as children of its parent
                    substitute_parents[child._id] = child_parent._id

                if child_depth > MAX_RECURSION:
                    child_parent_id = substitute_parents[child.parent_id]
                    substitute_parents[child._id] = child_parent_id
                    child_parent = wrapped[child_parent_id]

                if not hasattr(child_parent, "child"):
                    add_child_listing(child_parent)
                child.is_child = True
                child_parent.child.things.append(child)

            for child in children:
                # look over the children again to decide whether they can be
                # collapsed
                child.threaded = self.threaded
                child.collapsed = self.should_collapse(child)

            if self.threaded and children:
                most_recent_child_id = max(child._id for child in children)
                most_recent_child = wrapped[most_recent_child_id]
                most_recent_child.most_recent = True

            parent.is_parent = True
            parent.threaded = self.threaded
            parent.collapsed = self.should_collapse(parent)
            final.append(parent)

        return (final, prev_item, next_item, len(final), len(final))