_regenerate_context_helpers.py 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. import math
  2. import random
  3. from collections import defaultdict
  4. from operator import attrgetter, itemgetter
  5. def regenerate_context_articles(generator):
  6. """Helper to regenerate context after modifying articles draft state
  7. essentially just a copy from pelican.generators.ArticlesGenerator.generate_context
  8. after process_translations up to signal sending
  9. This has to be kept in sync untill a better solution is found
  10. This is for Pelican version 3.3.0
  11. """
  12. # Simulate __init__ for fields that need it
  13. generator.dates = {}
  14. generator.tags = defaultdict(list)
  15. generator.categories = defaultdict(list)
  16. generator.authors = defaultdict(list)
  17. # Simulate ArticlesGenerator.generate_context
  18. for article in generator.articles:
  19. # only main articles are listed in categories and tags
  20. # not translations
  21. generator.categories[article.category].append(article)
  22. if hasattr(article, 'tags'):
  23. for tag in article.tags:
  24. generator.tags[tag].append(article)
  25. # ignore blank authors as well as undefined
  26. if hasattr(article, 'author') and article.author.name != '':
  27. generator.authors[article.author].append(article)
  28. # sort the articles by date
  29. generator.articles.sort(key=attrgetter('date'), reverse=True)
  30. generator.dates = list(generator.articles)
  31. generator.dates.sort(key=attrgetter('date'),
  32. reverse=generator.context['NEWEST_FIRST_ARCHIVES'])
  33. # create tag cloud
  34. tag_cloud = defaultdict(int)
  35. for article in generator.articles:
  36. for tag in getattr(article, 'tags', []):
  37. tag_cloud[tag] += 1
  38. tag_cloud = sorted(tag_cloud.items(), key=itemgetter(1), reverse=True)
  39. tag_cloud = tag_cloud[:generator.settings.get('TAG_CLOUD_MAX_ITEMS')]
  40. tags = list(map(itemgetter(1), tag_cloud))
  41. if tags:
  42. max_count = max(tags)
  43. steps = generator.settings.get('TAG_CLOUD_STEPS')
  44. # calculate word sizes
  45. generator.tag_cloud = [
  46. (
  47. tag,
  48. int(math.floor(steps - (steps - 1) * math.log(count)
  49. / (math.log(max_count)or 1)))
  50. )
  51. for tag, count in tag_cloud
  52. ]
  53. # put words in chaos
  54. random.shuffle(generator.tag_cloud)
  55. # and generate the output :)
  56. # order the categories per name
  57. generator.categories = list(generator.categories.items())
  58. generator.categories.sort(
  59. reverse=generator.settings['REVERSE_CATEGORY_ORDER'])
  60. generator.authors = list(generator.authors.items())
  61. generator.authors.sort()
  62. generator._update_context(('articles', 'dates', 'tags', 'categories',
  63. 'tag_cloud', 'authors', 'related_posts'))