Example #1
0
def tree_info(items, features=None):
    """
    Given a list of tree items, produces doubles of a tree item and a
    ``dict`` containing information about the tree structure around the
    item, with the following contents:

       new_level
          ``True`` if the current item is the start of a new level in
          the tree, ``False`` otherwise.

       closed_levels
          A list of levels which end after the current item. This will
          be an empty list if the next item is at the same level as the
          current item.

    Using this filter with unpacking in a ``{% for %}`` tag, you should
    have enough information about the tree structure to create a
    hierarchical representation of the tree.

    Example::

       {% for genre,structure in genres|tree_info %}
       {% if tree.new_level %}<ul><li>{% else %}</li><li>{% endif %}
       {{ genre.name }}
       {% for level in tree.closed_levels %}</li></ul>{% endfor %}
       {% endfor %}

    """
    kwargs = {}
    if features:
        feature_names = features.split(',')
        if 'ancestors' in feature_names:
            kwargs['ancestors'] = True
    return tree_item_iterator(items, **kwargs)
Example #2
0
 def get_context_data(self, **kwargs):
     context = super().get_context_data(**kwargs)
     context['child_users_iter'] = None
     if self.request.user.has_perm('users.can_crud_all_child'):
         context['child_users_iter'] = tree_item_iterator(
             self.object.get_descendants())
     return context
Example #3
0
    def menu_by_sub_tree(node, order_field, html):
        print 'menu_by_sub_tree->{0}'.format(node.name)
        if not node.is_leaf_node():
            if not node.is_root_node():
                html += ('<li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">{0}<b class="caret"></b></a><ul class="dropdown-menu">'.format(node.name))
            else:
                # root node
                html += '<ul class="nav nav-pills pull-right">'
                
            for i,s in tree_item_iterator(node.get_children().order_by(order_field)):
                html = MenuManager.menu_by_sub_tree(i, order_field, html)
            
            if not node.is_root_node():
                html += '</ul>'
            else:
                html += '</ul></li>'
        else:
            # leaf node print <li></li>
            html += ('<li><a href="{0}">{1}</a></li>'.format(node.url, node.name))
        
        return html
            
# class NodeManager():
#     
#     @staticmethod
#     def getNodes():
#         print 'calling getNodes()...'
#         nodes = Node.objects.all()
#         return nodes
Example #4
0
    def __get_table_content(self):
        # Get presets tree in tree order
        presets_tree = OrderedDict()
        for preset_job, tree_info in tree_item_iterator(PresetJob.objects.all()):
            presets_tree[preset_job.id] = {'instance': preset_job, 'jobs': OrderedDict()}

        for job in self._jobs_qs:
            presets_tree[job.preset_id]['jobs'][job.id] = {
                'instance': job, 'decisions': [], 'values': self.__get_job_values_row(job)
            }

        # Cut preset jobs branches without jobs on leaves
        if self.view.user.role == USER_ROLES[0][0]:
            presets_to_preserve = set()
            for preset_id in reversed(list(presets_tree)):
                parent_id = presets_tree[preset_id]['instance'].parent_id
                if presets_tree[preset_id]['jobs'] or preset_id in presets_to_preserve:
                    presets_to_preserve.add(parent_id)
                else:
                    del presets_tree[preset_id]

        # Initialize values dictionary
        for decision in self._decisions_qs:
            if decision.job.preset_id not in presets_tree or \
                    decision.job_id not in presets_tree[decision.job.preset_id]['jobs']:
                continue
            values_row = self._values_collector.get_decision_values_row(decision)
            presets_tree[decision.job.preset_id]['jobs'][decision.job_id]['decisions'].append([decision, values_row])
        return presets_tree
Example #5
0
def microsite(request, microsite):

    microsite = get_object_or_404(Microsite, slug=microsite)

    page_title = u"%s Home" % microsite.name
    breadcrumbs = [{"url": reverse("materials:microsite", kwargs=dict(microsite=microsite.slug)), "title": page_title}]

    query = SearchQuerySet().narrow("is_displayed:true")
    query = query.narrow("microsites:%i" % microsite.id)
    query = query.order_by("-rating")
    query = query.facet("indexed_topics").facet("keywords").facet("grade_levels").facet("course_material_types")

    items = []
    results = query[0:8]
    for result in results:
        items.append(populate_item_from_search_result(result))

    facets = query.facet_counts()["fields"]

    topics = []
    topic_counts = dict(facets["indexed_topics"])
    for topic, tree_info in tree_item_iterator(microsite.topics.all()):
        topic.count = topic_counts.get(str(topic.id), 0)
        topics.append((topic, tree_info))

    grade_levels = []
    grade_level_counts = dict(facets["grade_levels"])
    for level in GradeLevel.objects.all():
        level.count = grade_level_counts.get(str(level.id), 0)
        grade_levels.append(level)

    course_material_types = []
    course_material_type_counts = dict(facets["course_material_types"])
    for material_type in CourseMaterialType.objects.all():
        material_type.count = course_material_type_counts.get(str(material_type.id), 0)
        course_material_types.append(material_type)

    keywords = query.count() and facets.get("keywords", []) or []
    if len(keywords) > MAX_TOP_KEYWORDS:
        keywords = keywords[:MAX_TOP_KEYWORDS]
    keywords = get_tag_cloud(dict(keywords), 3, 0, 0)
    for keyword in keywords:
        name = get_name_from_slug(Keyword, keyword["slug"]) or \
               get_name_from_slug(Tag, keyword["slug"]) or \
               keyword["slug"]
        keyword["name"] = name

    featured_k12 = SearchQuerySet().filter(workflow_state=PUBLISHED_STATE, featured=True, grade_levels__in=(1, 2), microsites=microsite.id).order_by("-featured_on").load_all()[:3]
    featured_k12 = [r.object for r in featured_k12 if r]

    featured_highered = SearchQuerySet().filter(workflow_state=PUBLISHED_STATE, featured=True, grade_levels=3, microsites=microsite.id).order_by("-featured_on").load_all()[:3]
    featured_highered = [r.object for r in featured_highered if r]

    slides = Slide.objects.filter(microsite=microsite)

    resource_number = SearchQuerySet().filter(workflow_state=PUBLISHED_STATE, microsites=microsite.id).count()

    return direct_to_template(request, "materials/microsites/%s.html" % microsite.slug, locals())
Example #6
0
 def print_sub_tree(self, node, field_name):
     
     mark = self.get_mark()
     if not node.is_leaf_node():
         self.level.append('+')
         if not node.is_root_node():
             print '{0}{1}'.format(mark,node)
             
         for i,s in tree_item_iterator(node.get_children().order_by(field_name)):
             self.print_sub_tree(i, field_name)
         self.level.pop()
     else:
         print '{0}{1}'.format(mark,node)
Example #7
0
def navigation(request):
    """Get all pages with one query, then aranges in a tree."""
    
    pages = Page.objects.active().filter(in_navigation=True)
    if not request.user.is_authenticated():
        pages = pages.filter(require_login=False)
    else:
        allpages = pages.filter(only_public=False)
        pages = list(allpages.filter(require_permission=False))
        pages += list(get_objects_for_user(request.user, "page.can_view", 
                     allpages.filter(require_permission=True)))
        pages.sort(key=lambda p: (p.tree_id, p.lft))
        
    return tree_item_iterator(pages)
Example #8
0
def navigation(request):
    """Get all pages with one query, then aranges in a tree."""

    pages = Page.objects.active().filter(in_navigation=True)
    if not request.user.is_authenticated():
        pages = pages.filter(require_login=False)
    else:
        allpages = pages.filter(only_public=False)
        pages = list(allpages.filter(require_permission=False))
        pages += list(
            get_objects_for_user(request.user, "page.can_view",
                                 allpages.filter(require_permission=True)))
        pages.sort(key=lambda p: (p.tree_id, p.lft))

    return tree_item_iterator(pages)
Example #9
0
    def __get_table_content(self):
        # Get presets tree in tree order
        presets_tree = OrderedDict()
        for preset_job, tree_info in tree_item_iterator(PresetJob.objects.all()):
            presets_tree[preset_job.id] = {'instance': preset_job, 'jobs': OrderedDict()}

        for job in self._jobs_qs:
            presets_tree[job.preset_id]['jobs'][job.id] = {
                'instance': job, 'decisions': [], 'values': self.__get_job_values_row(job)
            }

        # Initialize values dictionary
        for decision in self._decisions_qs:
            if decision.job_id not in presets_tree[decision.job.preset_id]['jobs']:
                continue
            values_row = self._values_collector.get_decision_values_row(decision)
            presets_tree[decision.job.preset_id]['jobs'][decision.job_id]['decisions'].append([decision, values_row])
        return presets_tree
Example #10
0
def green_browse(request):

    microsite = get_object_or_404(Microsite, slug="green")

    query = SearchQuerySet().narrow("is_displayed:true")
    query = query.narrow("microsites:%i" % microsite.id)
    query = query.facet("indexed_topics").facet("keywords").facet("grade_levels").facet("course_material_types")

    facets = query.facet_counts()["fields"]

    topics = []
    topic_counts = dict(facets["indexed_topics"])
    for topic, tree_info in tree_item_iterator(microsite.topics.all()):
        topic.count = topic_counts.get(str(topic.id), 0)
        topics.append((topic, tree_info))

    grade_levels = []
    grade_level_counts = dict(facets["grade_levels"])
    for level in GradeLevel.objects.all():
        level.count = grade_level_counts.get(str(level.id), 0)
        grade_levels.append(level)

    course_material_types = []
    course_material_type_counts = dict(facets["course_material_types"])
    for material_type in CourseMaterialType.objects.all():
        material_type.count = course_material_type_counts.get(str(material_type.id), 0)
        course_material_types.append(material_type)

    keywords = query.count() and facets.get("keywords", []) or []
    if len(keywords) > MAX_TOP_KEYWORDS:
        keywords = keywords[:MAX_TOP_KEYWORDS]
    keywords = get_tag_cloud(dict(keywords), 3, 0, 0)
    for keyword in keywords:
        name = get_name_from_slug(Keyword, keyword["slug"]) or \
               get_name_from_slug(Tag, keyword["slug"]) or \
               keyword["slug"]
        keyword["name"] = name

    query = SearchQuerySet().narrow("is_displayed:true")
    query = query.narrow("microsites:%i" % microsite.id)
    query = query.order_by("-published_on").load_all()
    recently_added = [r.object for r in query[:7]]

    return direct_to_template(request, "materials/microsites/green-browse.html", locals())
Example #11
0
    def as_python_tree(self):
        iterator = tree_item_iterator(self)
        first = True

        current = []
        stack = [current]
        for row, infos in iterator:
            if infos["new_level"] and not first:
                stack.append(current)
                current = current[-1][1]

            current.append([row, []])

            first = False

            for i in infos["closed_levels"]:
                if stack:
                    current = stack.pop()

        return current
Example #12
0
def get_menu_iterative(context, menu, menu_tree):
    user = context['request'].user
    children = tree_item_iterator(menu.get_descendants_by_user(user))
    if children:
        for child, options in children:
            if user.is_staff or child.is_published():
                menu_child = {}
                menu_child['name'] = child.name
                menu_child['slug'] = child.slug
                menu_child['url'] = child.get_absolute_url()
                new_level = options['new_level']
                closed_levels = options['closed_levels']
                if child.level in closed_levels:
                    len_closed_levels = len(closed_levels)
                    if child.level == 1:
                        len_closed_levels -= 1
                    menu_child['end_level'] = range(len_closed_levels)
                else:
                    menu_child['end_level'] = range(False)
                menu_child['new_level'] = new_level
                menu_tree.append(menu_child)
Example #13
0
def get_menu_iterative(context, menu, menu_tree):
    user = context['request'].user
    children = tree_item_iterator(menu.get_descendants_by_user(user))
    if children:
        for child, options in children:
            if user.is_staff or child.is_published():
                menu_child = {}
                menu_child['name'] = child.name
                menu_child['slug'] = child.slug
                menu_child['url'] = child.get_absolute_url()
                new_level = options['new_level']
                closed_levels = options['closed_levels']
                if child.level in closed_levels:
                    len_closed_levels = len(closed_levels)
                    if child.level == 1:
                        len_closed_levels -= 1
                    menu_child['end_level'] = range(len_closed_levels)
                else:
                    menu_child['end_level'] = range(False)
                menu_child['new_level'] = new_level
                menu_tree.append(menu_child)
Example #14
0
 def menu_by_sub_tree(self, node, order_field, html):
     print 'menu_by_sub_tree->{0}'.format(node.name)
     if not node.is_leaf_node():
         if not node.is_root_node():
             html += ('<li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">{0}<b class="caret"></b></a><ul class="dropdown-menu">'.format(node.name))
         else:
             # root node
             html += '<ul class="nav nav-pills pull-right">'
             
         for i,s in tree_item_iterator(node.get_children().order_by(order_field)):
             html = self.menu_by_sub_tree(i, order_field, html)
         
         if not node.is_root_node():
             html += '</ul>'
         else:
             html += '</ul></li>'
     else:
         # leaf node print <li></li>
         html += ('<li><a href="{0}">{1}</a></li>'.format(node.url, node.name))
     
     return html
Example #15
0
    def process_request(self, request):
        # When working with multiple tenants, we want to shard the cache for
        # each of them. Use of the version is a nice way to do this as it will
        # prevent collisions while making the API consistent.
        v_kw = {}
        if hasattr(request, "tenant"):
            v_kw.setdefault("version", request.tenant.schema_name)

        # TODO write a cache backend that will do this automatically, and
        #      contribute it back to django-tenant-schemas

        dehydrated = cache.get(DEHYDRATED_URLPATTERNS_KEY, [], **v_kw)

        if not dehydrated:
            logging.getLogger("newrelic.cache").debug("RECALCULATE URLCONF")

            # We need a secret set of account urls so we can bounce the user
            # here if the page is protected. As we haven't yet embedded our
            # url conf (we're in the middle of building it!) this will need
            # to be found using a reverse_lazy below.
            try:
                root = SitemapNode._tree_manager.root_nodes().first()
            except ObjectDoesNotExist:
                root = None
            dehydrated.append({
                "route": "p/",
                "site": protect,
                "kwargs": {
                    "node": root
                }
            })

            enabled_nodes = SitemapNode._tree_manager.all()
            related_nodes = enabled_nodes.select_related("content_type")

            def has_disabled_ancestors(st):
                for ancestor in st["ancestors"]:
                    if not ancestor.enabled:
                        return True
                return False

            def get_absolute_url(n, st):
                assert not n.is_root_node()
                offset = 1 if st["ancestors"][0].slug == SITEMAP_ROOT else 0
                paths = [
                    ancestor.slug for ancestor in st["ancestors"][offset:]
                ]
                if paths:
                    return os.path.join(os.path.join(*paths), n.slug)
                return n.slug

            for node, struct in tree_item_iterator(related_nodes, True,
                                                   lambda x: x):
                # Skip over nodes that they themselves or have disabled ancestors.
                if not node.enabled:
                    logger.debug("%r is disabled, omit from urlconf", node)
                    continue
                if has_disabled_ancestors(struct):
                    logger.debug("%r has disabled ancestor, omit from urlconf",
                                 node)
                    continue

                if node.is_root_node() and node.slug == SITEMAP_ROOT:
                    part = ""
                elif node.is_root_node():
                    part = node.slug
                else:
                    part = get_absolute_url(node, struct)

                if part and settings.APPEND_SLASH:
                    part += "/"

                if (node.content_type is not None
                        and node.content_type.model == "placeholder"):
                    try:
                        app = node.object.site(node)
                    except (AttributeError, ImportError, ValueError):
                        logger.exception(
                            "Application is unavailable, disabling this node.")
                        node.disable()
                    else:
                        pattern = {
                            "route": part,
                            "site": app,
                            "kwargs": dict(node=node, **node.kwargs),
                            "name": app.name,
                        }
                        # When nesting applications we need to ensure that any
                        # root url is not clobbered by the patterns of the
                        # parent application. In these cases, force them to the
                        # top of the map.
                        if (node.parent and node.parent.content_type
                                and node.parent.content_type.model
                                == "placeholder"):
                            dehydrated.insert(0, pattern)
                        else:
                            dehydrated.append(pattern)

                elif node.object_id is None:
                    dehydrated.append({
                        "route": part,
                        "view": dispatch,
                        "kwargs": dict(node=node, url=part),
                        "name": f"folder_{node.pk}",
                    })

                else:
                    dehydrated.append({
                        "route":
                        part,
                        "view":
                        dispatch,
                        "kwargs":
                        dict(page_id=node.object_id, node=node, url=part),
                        "name":
                        f"page_{node.object_id if node.object_id else None}",
                    })

            cache.set(
                DEHYDRATED_URLPATTERNS_KEY,
                dehydrated,
                timeout=DEHYDRATED_URLPATTERNS_TIMEOUT,
                **v_kw,
            )

        # Always start with the project wide ROOT_URLCONF and add our sitemap.xml view
        urlpatterns = [
            path(
                "sitemap.xml",
                sitemap,
                {"sitemaps": {
                    "nodes": NodeSitemap
                }},
                name="sitemap",
            ),
            path("", include(settings.ROOT_URLCONF)),
        ]

        # Construct the cache of url pattern definitions. We are not keeping
        # the actual patterns, because pickling is problematic for the .url
        # instancemethod - instead we keep the skeleton and build it on the
        # fly from cache... rehydrating it ;)
        for node in dehydrated:
            try:
                pattern = path(
                    node["route"],
                    node["view"],
                    node["kwargs"],
                    name=node.get("name"),
                )
            except KeyError:
                pattern = path(
                    node["route"],
                    node["site"].urls,
                    node["kwargs"],
                    name=node["site"].name,
                )
            urlpatterns.append(pattern)

        # Create a new module on the fly and attach the rehydrated urlpatterns
        dynamic_urls = module_from_spec(ModuleSpec("dynamic_urls", None))
        dynamic_urls.urlpatterns = urlpatterns

        # Attach the module to the request
        request.urlconf = dynamic_urls