aboutsummaryrefslogtreecommitdiffstats
path: root/plugins/pelican_comments/pelican_comments.py
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/pelican_comments/pelican_comments.py')
-rw-r--r--plugins/pelican_comments/pelican_comments.py112
1 files changed, 112 insertions, 0 deletions
diff --git a/plugins/pelican_comments/pelican_comments.py b/plugins/pelican_comments/pelican_comments.py
new file mode 100644
index 0000000..3a75ba2
--- /dev/null
+++ b/plugins/pelican_comments/pelican_comments.py
@@ -0,0 +1,112 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2012, Brian St. Pierre
+# Copyright (c) 2019, Jesús E.
+
+import sys
+
+import collections
+import hashlib # libravatar
+
+import pelican.signals as signals
+import pelican.generators as generators
+import pelican.readers as readers
+
+from pelican.contents import Content
+
+
+# Python 3 __cmp__ compatibility mixin from https://stackoverflow.com/a/39166382/807307
+PY3 = sys.version_info[0] >= 3
+if PY3:
+ def cmp(a, b):
+ return (a > b) - (a < b)
+ # mixin class for Python3 supporting __cmp__
+ class PY3__cmp__:
+ def __eq__(self, other):
+ return self.__cmp__(other) == 0
+ def __ne__(self, other):
+ return self.__cmp__(other) != 0
+ def __gt__(self, other):
+ return self.__cmp__(other) > 0
+ def __lt__(self, other):
+ return self.__cmp__(other) < 0
+ def __ge__(self, other):
+ return self.__cmp__(other) >= 0
+ def __le__(self, other):
+ return self.__cmp__(other) <= 0
+else:
+ class PY3__cmp__:
+ pass
+
+
+class Comment(Content, PY3__cmp__):
+ mandatory_properties = ('post_id', 'author')
+ default_template = 'comment' # this is required, but not used
+ default_status = 'published'
+
+ def __cmp__(self, other):
+ """
+ Comment comparison is by date. This is so that a comment list
+ can easily be sorted by date. The date attribute will be
+ automatically set from metadata by Content base class
+ """
+ if self.date == other.date:
+ return 0
+ elif self.date < other.date:
+ return -1
+ else:
+ return 1
+
+ def __hash__(self):
+ return hash((self.post_id, self.author, self.date, self._content))
+
+
+class CommentReader(object):
+ def __init__(self, generator):
+ self._comments = collections.defaultdict(list)
+ reader = readers.Readers(settings=generator.settings)
+
+ comments_dir = generator.settings.get('COMMENTS_DIR', 'comments')
+ comment_filenames = generator.get_files(comments_dir)
+
+ for comment_filename in comment_filenames:
+ comment = reader.read_file(
+ base_path=generator.settings['PATH'],
+ path=comment_filename,
+ content_class=Comment,
+ context=generator.context)
+
+ if 'post_id' not in comment.metadata:
+ raise Exception("comment %s does not have a post_id" % (
+ comment_filename, ))
+ self._comments[comment.metadata['post_id']].append(comment)
+
+ """
+ libravatar
+ """
+ email = comment.metadata['email'].encode('utf-8')
+ ahash = hashlib.md5(email.strip().lower()).hexdigest()
+ comment.avatar = "https://cdn.libravatar.org/avatar/%s" % (ahash)
+
+ for slug, comments in self._comments.items():
+ comments.sort()
+ for n, comment in enumerate(comments):
+ comment.cid = n
+
+ def get_comments(self, slug):
+ return self._comments[slug]
+
+def comment_initialization(generator):
+ """
+ Set up the comment plugin.
+ """
+ generator.plugin_instance = CommentReader(generator)
+
+
+def add_comments(generator, metadata):
+ metadata["comments"] = generator.plugin_instance.get_comments(
+ metadata['slug'])
+
+
+def register():
+ signals.article_generator_init.connect(comment_initialization)
+ signals.article_generator_context.connect(add_comments)