pelican_comment_system.py 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. # -*- coding: utf-8 -*-
  2. """
  3. Pelican Comment System
  4. ======================
  5. A Pelican plugin, which allows you to add comments to your articles.
  6. Author: Bernhard Scheirle
  7. """
  8. import logging
  9. import os
  10. logger = logging.getLogger(__name__)
  11. from itertools import chain
  12. from pelican import signals
  13. from pelican.utils import strftime
  14. from pelican.readers import MarkdownReader
  15. class Comment:
  16. def __init__(self, id, metadata, content):
  17. self.id = id
  18. self.content = content
  19. self.metadata = metadata
  20. self.replies = []
  21. def addReply(self, comment):
  22. self.replies.append(comment)
  23. def getReply(self, id):
  24. for reply in self.replies:
  25. if reply.id == id:
  26. return reply
  27. else:
  28. deepReply = reply.getReply(id)
  29. if deepReply != None:
  30. return deepReply
  31. return None
  32. def __lt__(self, other):
  33. return self.metadata['date'] < other.metadata['date']
  34. def sortReplies(self):
  35. for r in self.replies:
  36. r.sortReplies()
  37. self.replies = sorted(self.replies)
  38. def countReplies(self):
  39. amount = 0
  40. for r in self.replies:
  41. amount += r.countReplies()
  42. return amount + len(self.replies)
  43. def initialized(pelican):
  44. from pelican.settings import DEFAULT_CONFIG
  45. DEFAULT_CONFIG.setdefault('PELICAN_COMMENT_SYSTEM', False)
  46. DEFAULT_CONFIG.setdefault('PELICAN_COMMENT_SYSTEM_DIR' 'comments')
  47. if pelican:
  48. pelican.settings.setdefault('PELICAN_COMMENT_SYSTEM', False)
  49. pelican.settings.setdefault('PELICAN_COMMENT_SYSTEM_DIR', 'comments')
  50. def add_static_comments(gen, metadata):
  51. if gen.settings['PELICAN_COMMENT_SYSTEM'] != True:
  52. return
  53. metadata['comments_count'] = 0
  54. metadata['comments'] = []
  55. if not 'slug' in metadata:
  56. logger.warning("pelican_comment_system: cant't locate comments files without slug tag in the article")
  57. return
  58. reader = MarkdownReader(gen.settings)
  59. comments = []
  60. replies = []
  61. folder = os.path.join(gen.settings['PELICAN_COMMENT_SYSTEM_DIR'], metadata['slug'])
  62. if not os.path.isdir(folder):
  63. logger.debug("No comments found for: " + metadata['slug'])
  64. return
  65. for file in os.listdir(folder):
  66. name, extension = os.path.splitext(file)
  67. if extension[1:].lower() in reader.file_extensions:
  68. content, meta = reader.read(folder + "/" + file)
  69. meta['locale_date'] = strftime(meta['date'], gen.settings['DEFAULT_DATE_FORMAT'])
  70. com = Comment(name, meta, content)
  71. if 'replyto' in meta:
  72. replies.append( com )
  73. else:
  74. comments.append( com )
  75. #TODO: Fix this O(n²) loop
  76. for reply in replies:
  77. for comment in chain(comments, replies):
  78. if comment.id == reply.metadata['replyto']:
  79. comment.addReply(reply)
  80. count = 0
  81. for comment in comments:
  82. comment.sortReplies()
  83. count += comment.countReplies()
  84. comments = sorted(comments)
  85. metadata['comments_count'] = len(comments) + count
  86. metadata['comments'] = comments
  87. def register():
  88. signals.initialized.connect(initialized)
  89. signals.article_generator_context.connect(add_static_comments)