series.py 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. # -*- coding: utf-8 -*-
  2. """
  3. This plugin extends the original series plugin
  4. by FELD Boris <lothiraldan@gmail.com>
  5. Copyright (c) Leonardo Giordani <giordani.leonardo@gmail.com>
  6. Joins articles in a series and provides variables to
  7. manage the series in the template.
  8. """
  9. from collections import defaultdict
  10. from pelican import signals
  11. from logging import warning
  12. from operator import itemgetter
  13. def aggregate_series(generator):
  14. series = defaultdict(list)
  15. # This cycles through all articles in the given generator
  16. # and collects the 'series' metadata, if present.
  17. # The 'series_index' metadata is also stored, if specified
  18. for article in generator.articles:
  19. if 'series' in article.metadata:
  20. article_entry = (
  21. article.metadata.get('series_index', None),
  22. article.metadata['date'],
  23. article
  24. )
  25. series[article.metadata['series']].append(article_entry)
  26. # This uses items() which on Python2 is not a generator
  27. # but we are dealing with a small amount of data so
  28. # there shouldn't be performance issues =)
  29. for series_name, series_articles in series.items():
  30. # This is not DRY but very simple to understand
  31. forced_order_articles = [
  32. art_tup for art_tup in series_articles if art_tup[0] is not None]
  33. date_order_articles = [
  34. art_tup for art_tup in series_articles if art_tup[0] is None]
  35. forced_order_articles.sort(key=itemgetter(0))
  36. date_order_articles.sort(key=itemgetter(1))
  37. all_articles = forced_order_articles + date_order_articles
  38. ordered_articles = [art_tup[2] for art_tup in all_articles]
  39. enumerated_articles = enumerate(ordered_articles)
  40. for index, article in enumerated_articles:
  41. article.series = dict()
  42. article.series['name'] = series_name
  43. article.series['index'] = index + 1
  44. article.series['all'] = ordered_articles
  45. article.series['all_previous'] = ordered_articles[0: index]
  46. article.series['all_next'] = ordered_articles[index + 1:]
  47. if index > 0:
  48. article.series['previous'] = ordered_articles[index - 1]
  49. else:
  50. article.series['previous'] = None
  51. try:
  52. article.series['next'] = ordered_articles[index + 1]
  53. except IndexError:
  54. article.series['next'] = None
  55. def register():
  56. signals.article_generator_finalized.connect(aggregate_series)