Example #1
0
    def prepareRenderContext(self, ctx):
        ctx.pagination_source = self.inner_source

        route_params = ctx.page.source_metadata['route_params']
        year = route_params.get('year')
        if year is None:
            raise Exception(
                "Can't find the archive year in the route metadata")
        if type(year) is not int:
            raise Exception(
                "The route for generator '%s' should specify an integer "
                "parameter for 'year'." % self.name)

        flt = PaginationFilter()
        flt.addClause(IsFromYearFilterClause(year))
        ctx.pagination_filter = flt

        ctx.custom_data['year'] = year

        flt2 = PaginationFilter()
        flt2.addClause(IsFromYearFilterClause(year))
        it = PageIterator(self.inner_source)
        it._simpleNonSortedWrap(HardCodedFilterIterator, flt2)
        it._wrapAsSort(DateSortIterator, reverse=False)
        ctx.custom_data['archives'] = it

        ctx.custom_data['monthly_archives'] = _MonthlyArchiveData(
            self.inner_source, year)
Example #2
0
    def _load(self):
        if self._months is not None:
            return

        month_index = {}
        for page in self._inner_source.getAllPages():
            if page.datetime.year != self._year:
                continue

            month = page.datetime.month

            posts_this_month = month_index.get(month)
            if posts_this_month is None:
                posts_this_month = []
                month_index[month] = posts_this_month
            posts_this_month.append(page.content_item)

        self._months = []
        for m in sorted(month_index.keys()):
            timestamp = time.mktime((self._year, m, 1, 0, 0, 0, 0, 0, -1))

            ptm = month_index[m]
            it = PageIterator(ListSource(self._inner_source, ptm))
            it._wrapAsSort(DateSortIterator, reverse=False)

            self._months.append({'timestamp': timestamp, 'posts': it})
Example #3
0
    def _load(self):
        if self._months is not None:
            return

        month_index = {}
        for page in self._inner_source.getAllPages():
            if page.datetime.year != self._year:
                continue

            month = page.datetime.month

            posts_this_month = month_index.get(month)
            if posts_this_month is None:
                posts_this_month = []
                month_index[month] = posts_this_month
            posts_this_month.append(page.content_item)

        self._months = []
        for m in sorted(month_index.keys()):
            timestamp = time.mktime((self._year, m, 1, 0, 0, 0, 0, 0, -1))

            ptm = month_index[m]
            it = PageIterator(ListSource(self._inner_source, ptm))
            it._wrapAsSort(DateSortIterator, reverse=False)

            self._months.append({
                'timestamp': timestamp,
                'posts': it
            })
def test_filter():
    page = mock.MagicMock(spec=Page)
    page.config = PageConfiguration()
    page.config.set('threes', {'is_foo': 3})
    it = PageIterator([_TestItem(v) for v in [3, 2, 3, 1, 4, 3]],
                      current_page=page)
    it.filter('threes')
    assert it.total_count == 3
    assert len(it) == 3
    assert list(it) == [_TestItem(3), _TestItem(3), _TestItem(3)]
Example #5
0
    def _load(self):
        if self._iterator is not None:
            return

        from piecrust.data.filters import PaginationFilter
        from piecrust.dataproviders.pageiterator import (
            PageIterator, HardCodedFilterIterator)

        self._iterator = PageIterator(
            self._source,
            current_page=self._page)

        if self._pgn_filter is not None:
            pag_fil = PaginationFilter()
            pag_fil.addClause(self._pgn_filter.root_clause)
            self._iterator._simpleNonSortedWrap(
                HardCodedFilterIterator, pag_fil)

        offset = (self._sub_num - 1) * self.items_per_page
        limit = self.items_per_page
        self._iterator.slice(offset, limit)

        if self._is_content_source:
            self._iterator._iter_event += self._onIteration

        self._iterator._lockIterator()
Example #6
0
    def prepareRenderContext(self, ctx):
        ctx.pagination_source = self.inner_source

        route_params = ctx.page.source_metadata['route_params']
        year = route_params.get('year')
        if year is None:
            raise Exception(
                "Can't find the archive year in the route metadata")
        if type(year) is not int:
            raise Exception(
                "The route for generator '%s' should specify an integer "
                "parameter for 'year'." % self.name)

        flt = PaginationFilter()
        flt.addClause(IsFromYearFilterClause(year))
        ctx.pagination_filter = flt

        ctx.custom_data['year'] = year

        flt2 = PaginationFilter()
        flt2.addClause(IsFromYearFilterClause(year))
        it = PageIterator(self.inner_source)
        it._simpleNonSortedWrap(HardCodedFilterIterator, flt2)
        it._wrapAsSort(DateSortIterator, reverse=False)
        ctx.custom_data['archives'] = it

        ctx.custom_data['monthly_archives'] = _MonthlyArchiveData(
            self.inner_source, year)
Example #7
0
    def _load(self):
        if self._iterator is not None:
            return

        from piecrust.data.filters import PaginationFilter
        from piecrust.dataproviders.pageiterator import (
            PageIterator, HardCodedFilterIterator)

        self._iterator = PageIterator(self._source, current_page=self._page)

        if self._pgn_filter is not None:
            pag_fil = PaginationFilter()
            pag_fil.addClause(self._pgn_filter.root_clause)
            self._iterator._simpleNonSortedWrap(HardCodedFilterIterator,
                                                pag_fil)

        offset = (self._sub_num - 1) * self.items_per_page
        limit = self.items_per_page
        self._iterator.slice(offset, limit)

        if self._is_content_source:
            self._iterator._iter_event += self._onIteration

        self._iterator._lockIterator()
Example #8
0
    def _writeAutoLocs(self, sitemap, fp):
        source_names = sitemap.setdefault('autogen', None)
        if not source_names:
            return

        cur_time = strftime_iso8601(time.time())
        for name in source_names:
            logger.debug("Generating automatic sitemap entries for '%s'." %
                         name)
            source = self.app.getSource(name)
            if source is None:
                raise Exception("No such source: %s" % name)

            it = PageIterator(source)
            for page in it:
                uri = page['url']
                sm_cfg = page.get('sitemap')

                args = {'url': uri, 'lastmod': cur_time}
                if sm_cfg:
                    args.update(sm_cfg)

                self._writeEntry(args, fp)
def test_skip():
    it = PageIterator(range(12))
    it.skip(5)
    assert it.total_count == 12
    assert len(it) == 7
    assert list(it) == list(range(5, 12))
Example #10
0
    def _load(self):
        if self._iterator is not None:
            return

        src = ListSource(self._source, self._items)
        self._iterator = PageIterator(src, current_page=self._page)
Example #11
0
class Paginator(object):
    debug_render = [
        'has_more', 'items', 'has_items', 'items_per_page', 'items_this_page',
        'prev_page_number', 'this_page_number', 'next_page_number',
        'prev_page', 'next_page', 'total_item_count', 'total_page_count',
        'next_item', 'prev_item'
    ]
    debug_render_invoke = [
        'has_more', 'items', 'has_items', 'items_per_page', 'items_this_page',
        'prev_page_number', 'this_page_number', 'next_page_number',
        'prev_page', 'next_page', 'total_item_count', 'total_page_count',
        'next_item', 'prev_item'
    ]

    def __init__(self,
                 source,
                 current_page,
                 sub_num,
                 *,
                 pgn_filter=None,
                 items_per_page=-1):
        self._source = source
        self._page = current_page
        self._sub_num = sub_num
        self._iterator = None
        self._pgn_filter = pgn_filter
        self._items_per_page = items_per_page
        self._pgn_set_on_ctx = False
        self._is_content_source = isinstance(source, ContentSource)

    @property
    def is_loaded(self):
        return self._iterator is not None

    @property
    def has_more(self):
        return self.next_page_number is not None

    @property
    def unload(self):
        self._iterator = None

    # Backward compatibility with PieCrust 1.0 {{{
    @property
    def posts(self):
        return self.items

    @property
    def has_posts(self):
        return self.has_items

    @property
    def posts_per_page(self):
        return self.items_per_page

    @property
    def posts_this_page(self):
        return self.items_this_page

    @property
    def total_post_count(self):
        return self.total_item_count

    @property
    def next_post(self):
        return self.next_item

    @property
    def prev_post(self):
        return self.prev_item

    # }}}

    @property
    def items(self):
        self._load()
        return self._iterator

    @property
    def has_items(self):
        return self.items_this_page > 0

    @cached_property
    def items_per_page(self):
        if self._items_per_page > 0:
            return self._items_per_page

        if self._page is not None:
            ipp = self._page.config.get('items_per_page')
            if ipp is not None:
                return ipp

        if self._is_content_source:
            ipp = self._source.config.get('items_per_page')
            if ipp is not None:
                return ipp

        raise Exception("No way to figure out how many items to display "
                        "per page.")

    @property
    def items_this_page(self):
        self._load()
        return len(self._iterator)

    @property
    def prev_page_number(self):
        if self._sub_num > 1:
            return self._sub_num - 1
        return None

    @property
    def this_page_number(self):
        return self._sub_num

    @property
    def next_page_number(self):
        self._load()
        if self._iterator._has_more:
            return self._sub_num + 1
        return None

    @property
    def prev_page(self):
        num = self.prev_page_number
        if num is not None:
            return self._getPageUri(num)
        return None

    @property
    def this_page(self):
        return self._getPageUri(self._sub_num)

    @property
    def next_page(self):
        num = self.next_page_number
        if num is not None:
            return self._getPageUri(num)
        return None

    @property
    def total_item_count(self):
        self._load()
        return self._iterator.total_count

    @property
    def total_page_count(self):
        total_count = self.total_item_count
        per_page = self.items_per_page
        return int(math.ceil(total_count / per_page))

    @property
    def next_item(self):
        self._load()
        return self._iterator.prev_page

    @property
    def prev_item(self):
        self._load()
        return self._iterator.next_page

    def all_page_numbers(self, radius=-1):
        total_page_count = self.total_page_count
        if total_page_count == 0:
            return []

        if radius <= 0 or total_page_count < (2 * radius + 1):
            return list(range(1, total_page_count + 1))

        first_num = self._sub_num - radius
        last_num = self._sub_num + radius
        if first_num <= 0:
            last_num += 1 - first_num
            first_num = 1
        elif last_num > total_page_count:
            first_num -= (last_num - total_page_count)
            last_num = total_page_count
        first_num = max(1, first_num)
        last_num = min(total_page_count, last_num)
        return list(range(first_num, last_num + 1))

    def page(self, index):
        return self._getPageUri(index)

    def _load(self):
        if self._iterator is not None:
            return

        from piecrust.data.filters import PaginationFilter
        from piecrust.dataproviders.pageiterator import (
            PageIterator, HardCodedFilterIterator)

        self._iterator = PageIterator(self._source, current_page=self._page)

        if self._pgn_filter is not None:
            pag_fil = PaginationFilter()
            pag_fil.addClause(self._pgn_filter.root_clause)
            self._iterator._simpleNonSortedWrap(HardCodedFilterIterator,
                                                pag_fil)

        offset = (self._sub_num - 1) * self.items_per_page
        limit = self.items_per_page
        self._iterator.slice(offset, limit)

        if self._is_content_source:
            self._iterator._iter_event += self._onIteration

        self._iterator._lockIterator()

    def _getPageUri(self, index):
        return self._page.getUri(index)

    def _onIteration(self, it):
        if not self._pgn_set_on_ctx:
            rcs = self._source.app.env.render_ctx_stack
            if rcs.current_ctx is not None:
                rcs.current_ctx.setPagination(self)
                self._pgn_set_on_ctx = True
def test_magic_filter():
    it = PageIterator([_TestItem(v) for v in [3, 2, 3, 1, 4, 3]])
    it.is_foo(3)
    assert it.total_count == 3
    assert len(it) == 3
    assert list(it) == [_TestItem(3), _TestItem(3), _TestItem(3)]
def test_setting_sort_reversed():
    it = PageIterator([_TestItem(v) for v in [4, 3, 1, 2, 0]])
    it.sort('foo', reverse=True)
    assert it.total_count == 5
    assert len(it) == 5
    assert list(it) == [_TestItem(v) for v in reversed(range(5))]
Example #14
0
 def _buildPosts(self):
     if self._posts is None:
         it = PageIterator(self._sources[0], current_page=self._page)
         self._onIteration()
         self._posts = it
def test_setting_sort():
    it = PageIterator([_TestItem(v) for v in [4, 3, 1, 2, 0]])
    it.sort('foo')
    assert it.total_count == 5
    assert len(it) == 5
    assert list(it) == [_TestItem(v) for v in range(5)]
Example #16
0
class Paginator(object):
    debug_render = [
        'has_more', 'items', 'has_items', 'items_per_page',
        'items_this_page', 'prev_page_number', 'this_page_number',
        'next_page_number', 'prev_page', 'next_page',
        'total_item_count', 'total_page_count',
        'next_item', 'prev_item']
    debug_render_invoke = [
        'has_more', 'items', 'has_items', 'items_per_page',
        'items_this_page', 'prev_page_number', 'this_page_number',
        'next_page_number', 'prev_page', 'next_page',
        'total_item_count', 'total_page_count',
        'next_item', 'prev_item']

    def __init__(self, source, current_page, sub_num, *,
                 pgn_filter=None, items_per_page=-1):
        self._source = source
        self._page = current_page
        self._sub_num = sub_num
        self._iterator = None
        self._pgn_filter = pgn_filter
        self._items_per_page = items_per_page
        self._pgn_set_on_ctx = False
        self._is_content_source = isinstance(source, ContentSource)

    @property
    def is_loaded(self):
        return self._iterator is not None

    @property
    def has_more(self):
        return self.next_page_number is not None

    @property
    def unload(self):
        self._iterator = None

    # Backward compatibility with PieCrust 1.0 {{{
    @property
    def posts(self):
        return self.items

    @property
    def has_posts(self):
        return self.has_items

    @property
    def posts_per_page(self):
        return self.items_per_page

    @property
    def posts_this_page(self):
        return self.items_this_page

    @property
    def total_post_count(self):
        return self.total_item_count

    @property
    def next_post(self):
        return self.next_item

    @property
    def prev_post(self):
        return self.prev_item
    # }}}

    @property
    def items(self):
        self._load()
        return self._iterator

    @property
    def has_items(self):
        return self.items_this_page > 0

    @cached_property
    def items_per_page(self):
        if self._items_per_page > 0:
            return self._items_per_page

        if self._page is not None:
            ipp = self._page.config.get('items_per_page')
            if ipp is not None:
                return ipp

        if self._is_content_source:
            ipp = self._source.config.get('items_per_page')
            if ipp is not None:
                return ipp

        raise Exception("No way to figure out how many items to display "
                        "per page.")

    @property
    def items_this_page(self):
        self._load()
        return len(self._iterator)

    @property
    def prev_page_number(self):
        if self._sub_num > 1:
            return self._sub_num - 1
        return None

    @property
    def this_page_number(self):
        return self._sub_num

    @property
    def next_page_number(self):
        self._load()
        if self._iterator._has_more:
            return self._sub_num + 1
        return None

    @property
    def prev_page(self):
        num = self.prev_page_number
        if num is not None:
            return self._getPageUri(num)
        return None

    @property
    def this_page(self):
        return self._getPageUri(self._sub_num)

    @property
    def next_page(self):
        num = self.next_page_number
        if num is not None:
            return self._getPageUri(num)
        return None

    @property
    def total_item_count(self):
        self._load()
        return self._iterator.total_count

    @property
    def total_page_count(self):
        total_count = self.total_item_count
        per_page = self.items_per_page
        return int(math.ceil(total_count / per_page))

    @property
    def next_item(self):
        self._load()
        return self._iterator.prev_page

    @property
    def prev_item(self):
        self._load()
        return self._iterator.next_page

    def all_page_numbers(self, radius=-1):
        total_page_count = self.total_page_count
        if total_page_count == 0:
            return []

        if radius <= 0 or total_page_count < (2 * radius + 1):
            return list(range(1, total_page_count + 1))

        first_num = self._sub_num - radius
        last_num = self._sub_num + radius
        if first_num <= 0:
            last_num += 1 - first_num
            first_num = 1
        elif last_num > total_page_count:
            first_num -= (last_num - total_page_count)
            last_num = total_page_count
        first_num = max(1, first_num)
        last_num = min(total_page_count, last_num)
        return list(range(first_num, last_num + 1))

    def page(self, index):
        return self._getPageUri(index)

    def _load(self):
        if self._iterator is not None:
            return

        from piecrust.data.filters import PaginationFilter
        from piecrust.dataproviders.pageiterator import (
            PageIterator, HardCodedFilterIterator)

        self._iterator = PageIterator(
            self._source,
            current_page=self._page)

        if self._pgn_filter is not None:
            pag_fil = PaginationFilter()
            pag_fil.addClause(self._pgn_filter.root_clause)
            self._iterator._simpleNonSortedWrap(
                HardCodedFilterIterator, pag_fil)

        offset = (self._sub_num - 1) * self.items_per_page
        limit = self.items_per_page
        self._iterator.slice(offset, limit)

        if self._is_content_source:
            self._iterator._iter_event += self._onIteration

        self._iterator._lockIterator()

    def _getPageUri(self, index):
        return self._page.getUri(index)

    def _onIteration(self, it):
        if not self._pgn_set_on_ctx:
            rcs = self._source.app.env.render_ctx_stack
            if rcs.current_ctx is not None:
                rcs.current_ctx.setPagination(self)
                self._pgn_set_on_ctx = True
def test_natural_sort_reversed():
    it = PageIterator([4, 3, 1, 2, 0])
    it.sort(reverse=True)
    assert it.total_count == 5
    assert len(it) == 5
    assert list(it) == list(reversed(range(5)))
def test_slice():
    it = PageIterator(range(12))
    it.slice(3, 4)
    assert it.total_count == 12
    assert len(it) == 4
    assert list(it) == list(range(3, 7))
def test_limit():
    it = PageIterator(range(12))
    it.limit(4)
    assert it.total_count == 12
    assert len(it) == 4
    assert list(it) == list(range(4))