76 lines
2.5 KiB
Python
76 lines
2.5 KiB
Python
|
# -*- coding: utf-8 -*-
|
||
|
"""
|
||
|
This plugin extends the original series plugin
|
||
|
by FELD Boris <lothiraldan@gmail.com>
|
||
|
|
||
|
Copyright (c) Leonardo Giordani <giordani.leonardo@gmail.com>
|
||
|
|
||
|
Joins articles in a series and provides variables to
|
||
|
manage the series in the template.
|
||
|
"""
|
||
|
|
||
|
from collections import defaultdict
|
||
|
|
||
|
from pelican import signals
|
||
|
|
||
|
from logging import warning
|
||
|
|
||
|
from operator import itemgetter
|
||
|
|
||
|
|
||
|
def aggregate_series(generator):
|
||
|
series = defaultdict(list)
|
||
|
|
||
|
# This cycles through all articles in the given generator
|
||
|
# and collects the 'series' metadata, if present.
|
||
|
# The 'series_index' metadata is also stored, if specified
|
||
|
for article in generator.articles:
|
||
|
if 'series' in article.metadata:
|
||
|
article_entry = (
|
||
|
article.metadata.get('series_index', None),
|
||
|
article.metadata['date'],
|
||
|
article
|
||
|
)
|
||
|
|
||
|
series[article.metadata['series']].append(article_entry)
|
||
|
|
||
|
# This uses items() which on Python2 is not a generator
|
||
|
# but we are dealing with a small amount of data so
|
||
|
# there shouldn't be performance issues =)
|
||
|
for series_name, series_articles in series.items():
|
||
|
# This is not DRY but very simple to understand
|
||
|
forced_order_articles = [
|
||
|
art_tup for art_tup in series_articles if art_tup[0] is not None]
|
||
|
|
||
|
date_order_articles = [
|
||
|
art_tup for art_tup in series_articles if art_tup[0] is None]
|
||
|
|
||
|
forced_order_articles.sort(key=itemgetter(0))
|
||
|
date_order_articles.sort(key=itemgetter(1))
|
||
|
|
||
|
all_articles = forced_order_articles + date_order_articles
|
||
|
ordered_articles = [art_tup[2] for art_tup in all_articles]
|
||
|
enumerated_articles = enumerate(ordered_articles)
|
||
|
|
||
|
for index, article in enumerated_articles:
|
||
|
article.series = dict()
|
||
|
article.series['name'] = series_name
|
||
|
article.series['index'] = index + 1
|
||
|
article.series['all'] = ordered_articles
|
||
|
article.series['all_previous'] = ordered_articles[0: index]
|
||
|
article.series['all_next'] = ordered_articles[index + 1:]
|
||
|
|
||
|
if index > 0:
|
||
|
article.series['previous'] = ordered_articles[index - 1]
|
||
|
else:
|
||
|
article.series['previous'] = None
|
||
|
|
||
|
try:
|
||
|
article.series['next'] = ordered_articles[index + 1]
|
||
|
except IndexError:
|
||
|
article.series['next'] = None
|
||
|
|
||
|
|
||
|
def register():
|
||
|
signals.article_generator_finalized.connect(aggregate_series)
|