pelican_comment_system.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  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. from __future__ import unicode_literals
  9. import logging
  10. import os
  11. import copy
  12. logger = logging.getLogger(__name__)
  13. from itertools import chain
  14. from pelican import signals
  15. from pelican.readers import MarkdownReader
  16. from pelican.writers import Writer
  17. from . comment import Comment
  18. from . import avatars
  19. def pelican_initialized(pelican):
  20. from pelican.settings import DEFAULT_CONFIG
  21. DEFAULT_CONFIG.setdefault('PELICAN_COMMENT_SYSTEM', False)
  22. DEFAULT_CONFIG.setdefault('PELICAN_COMMENT_SYSTEM_DIR' 'comments')
  23. DEFAULT_CONFIG.setdefault('PELICAN_COMMENT_SYSTEM_IDENTICON_OUTPUT_PATH' 'images/identicon')
  24. DEFAULT_CONFIG.setdefault('PELICAN_COMMENT_SYSTEM_IDENTICON_DATA', ())
  25. DEFAULT_CONFIG.setdefault('PELICAN_COMMENT_SYSTEM_IDENTICON_SIZE', 72)
  26. DEFAULT_CONFIG.setdefault('PELICAN_COMMENT_SYSTEM_AUTHORS', {})
  27. DEFAULT_CONFIG.setdefault('PELICAN_COMMENT_SYSTEM_FEED', os.path.join('feeds', 'comment.%s.atom.xml'))
  28. DEFAULT_CONFIG.setdefault('COMMENT_URL', '#comment-{path}')
  29. if pelican:
  30. pelican.settings.setdefault('PELICAN_COMMENT_SYSTEM', False)
  31. pelican.settings.setdefault('PELICAN_COMMENT_SYSTEM_DIR', 'comments')
  32. pelican.settings.setdefault('PELICAN_COMMENT_SYSTEM_IDENTICON_OUTPUT_PATH', 'images/identicon')
  33. pelican.settings.setdefault('PELICAN_COMMENT_SYSTEM_IDENTICON_DATA', ())
  34. pelican.settings.setdefault('PELICAN_COMMENT_SYSTEM_IDENTICON_SIZE', 72)
  35. pelican.settings.setdefault('PELICAN_COMMENT_SYSTEM_AUTHORS', {})
  36. pelican.settings.setdefault('PELICAN_COMMENT_SYSTEM_FEED', os.path.join('feeds', 'comment.%s.atom.xml'))
  37. pelican.settings.setdefault('COMMENT_URL', '#comment-{path}')
  38. def initialize(article_generator):
  39. avatars.init(
  40. article_generator.settings['OUTPUT_PATH'],
  41. article_generator.settings['PELICAN_COMMENT_SYSTEM_IDENTICON_OUTPUT_PATH'],
  42. article_generator.settings['PELICAN_COMMENT_SYSTEM_IDENTICON_DATA'],
  43. article_generator.settings['PELICAN_COMMENT_SYSTEM_IDENTICON_SIZE']/3,
  44. article_generator.settings['PELICAN_COMMENT_SYSTEM_AUTHORS'],
  45. )
  46. def add_static_comments(gen, content):
  47. if gen.settings['PELICAN_COMMENT_SYSTEM'] != True:
  48. return
  49. content.comments_count = 0
  50. content.comments = []
  51. #Modify the local context, so we get proper values for the feed
  52. context = copy.copy(gen.context)
  53. context['SITEURL'] += "/" + content.url
  54. context['SITENAME'] = "Comments for: " + content.title
  55. context['SITESUBTITLE'] = ""
  56. path = gen.settings['PELICAN_COMMENT_SYSTEM_FEED'] % content.slug
  57. writer = Writer(gen.output_path, settings=gen.settings)
  58. folder = os.path.join(gen.settings['PELICAN_COMMENT_SYSTEM_DIR'], content.slug)
  59. if not os.path.isdir(folder):
  60. logger.debug("No comments found for: " + content.slug)
  61. writer.write_feed( [], context, path)
  62. return
  63. reader = MarkdownReader(gen.settings)
  64. comments = []
  65. replies = []
  66. for file in os.listdir(folder):
  67. name, extension = os.path.splitext(file)
  68. if extension[1:].lower() in reader.file_extensions:
  69. com_content, meta = reader.read(os.path.join(folder, file))
  70. avatar_path = avatars.getAvatarPath(name, meta)
  71. com = Comment(file, avatar_path, com_content, meta, gen.settings, file, context)
  72. if 'replyto' in meta:
  73. replies.append( com )
  74. else:
  75. comments.append( com )
  76. writer.write_feed( comments + replies, context, path)
  77. #TODO: Fix this O(n²) loop
  78. for reply in replies:
  79. for comment in chain(comments, replies):
  80. if comment.id == reply.metadata['replyto']:
  81. comment.addReply(reply)
  82. count = 0
  83. for comment in comments:
  84. comment.sortReplies()
  85. count += comment.countReplies()
  86. comments = sorted(comments)
  87. content.comments_count = len(comments) + count
  88. content.comments = comments
  89. def writeIdenticonsToDisk(gen, writer):
  90. avatars.generateAndSaveMissingAvatars()
  91. def register():
  92. signals.initialized.connect(pelican_initialized)
  93. signals.article_generator_init.connect(initialize)
  94. signals.article_generator_write_article.connect(add_static_comments)
  95. signals.article_writer_finalized.connect(writeIdenticonsToDisk)