# ------------------------------------------------------------------------
# coding=utf-8
# ------------------------------------------------------------------------

from django.db.models import Max
from django.contrib.sitemaps import Sitemap

from feincms.module.page.models import Page

# ------------------------------------------------------------------------
class PageSitemap(Sitemap):
    """
    The PageSitemap can be used to automatically generate sitemap.xml files
    for submission to index engines. See http://www.sitemaps.org/ for details.
    """
    def __init__(self, navigation_only=False, max_depth=0, changefreq=None, queryset=None, filter=None, extended_navigation=False, *args, **kwargs):
        """
        The PageSitemap accepts the following parameters for customisation
        of the resulting sitemap.xml output:

        * navigation_only -- if set to True, only pages that are in_navigation
        will appear in the site map.
        * max_depth -- if set to a non-negative integer, will limit the sitemap
        generated to this page hierarchy depth.
        * changefreq -- should be a string or callable specifiying the page
        update frequency, according to the sitemap protocol.
        * queryset -- pass in a query set to restrict the Pages to include
        in the site map.
        * filter -- pass in a callable that transforms a queryset to filter
        out the pages you want to include in the site map.
        * extended_navigation -- if set to True, adds pages from any navigation
        extensions. If using PagePretender, make sure to include title, url,
        level, in_navigation and optionally modification_date.
        """
        super(PageSitemap, self).__init__(*args, **kwargs)
        self.depth_cutoff        = max_depth
        self.navigation_only     = navigation_only
        self.changefreq          = changefreq
        self.filter              = filter
        self.extended_navigation = extended_navigation
        if queryset is not None:
            self.queryset        = queryset
        else:
            self.queryset        = Page.objects.active()

    def items(self):
        """
        Consider all pages that are active and that are not a redirect
        """

        base_qs = self.queryset
        if callable(base_qs):
            base_qs = base_qs()

        self.max_depth = base_qs.aggregate(Max('level'))['level__max']
        if self.depth_cutoff > 0:
            self.max_depth = min(self.depth_cutoff, self.max_depth)

        self.per_level = 1.0 / (self.max_depth + 1.0)

        qs = base_qs.filter(redirect_to="")
        if self.filter:
            qs = self.filter(qs)
        if self.navigation_only:
            qs = qs.filter(in_navigation=True)
        if self.depth_cutoff > 0:
            qs = qs.filter(level__lte=self.max_depth-1)

        pages = [ p for p in qs if p.is_active() ]

        if self.extended_navigation:
            for idx, page in enumerate(pages):
                if getattr(page, 'navigation_extension', None):
                    pages[idx + 1:idx + 1] = page.extended_navigation()

        return pages

    def lastmod(self, obj):
        return getattr(obj, 'modification_date', None)

    # the priority is computed of the depth in the tree of a page
    # may we should make an extension to give control to the user for priority
    def priority(self, obj):
        """
        The priority is staggered according to the depth of the page in
        the site. Top level get highest priority, then each level is decreased
        by per_level.
        """
        prio = 1.0 - (obj.level + 1) * self.per_level

        # If the page is in_navigation, then it's more important, so boost
        # its importance
        if obj.in_navigation:
            prio += 1.2 * self.per_level

        return "%0.2g" % min(1.0, prio)

    # After a call to the sitemap, be sure to erase the cached _paginator
    # attribute, so next time we'll re-fetch the items list instead of using
    # a stale list.
    # This has been fixed in Django r17468
    def get_urls(self, *args, **kwargs):
        urls = super(PageSitemap, self).get_urls(*args, **kwargs)
        if hasattr(self, '_paginator'):
            del(self._paginator)
        return urls

# ------------------------------------------------------------------------
