rophako/rophako/model/comment.py

249 rivejä
6.6 KiB
Python
Raaka Normaali näkymä Historia

2014-04-06 22:45:43 +00:00
# -*- coding: utf-8 -*-
2015-07-10 07:27:13 +00:00
from __future__ import unicode_literals, absolute_import
2014-04-06 22:45:43 +00:00
"""Commenting models."""
2014-12-04 23:06:44 +00:00
from flask import url_for
2014-04-06 22:45:43 +00:00
import time
import hashlib
import urllib
import random
import re
2014-06-02 21:04:44 +00:00
import sys
2014-04-06 22:45:43 +00:00
2014-12-04 23:06:44 +00:00
from rophako.settings import Config
2014-04-06 22:45:43 +00:00
import rophako.jsondb as JsonDB
import rophako.model.user as User
import rophako.model.emoticons as Emoticons
from rophako.utils import send_email, render_markdown
2014-04-06 22:45:43 +00:00
from rophako.log import logger
def add_comment(thread, uid, name, subject, message, url, time, ip, image=None):
"""Add a comment to a comment thread.
* uid is 0 if it's a guest post, otherwise the UID of the user.
* name is the commenter's name (if a guest)
* subject is for the e-mails that are sent out
* message is self explanatory.
* url is the URL where the comment can be read.
* time, epoch time of comment.
* ip is the IP address of the commenter.
* image is a Gravatar image URL etc.
"""
# Get the comments for this thread.
comments = get_comments(thread)
# Make up a unique ID for the comment.
cid = random_hash()
while cid in comments:
cid = random_hash()
# Add the comment.
comments[cid] = dict(
uid=uid,
name=name or "Anonymous",
image=image or "",
message=message,
time=time or int(time.time()),
ip=ip,
)
write_comments(thread, comments)
# Get info about the commenter.
if uid > 0:
user = User.get_user(uid=uid)
if user:
name = user["name"]
# Send the e-mail to the site admins.
send_email(
2014-12-04 23:06:44 +00:00
to=Config.site.notify_address,
2014-04-06 22:45:43 +00:00
subject="New comment: {}".format(subject),
message="""{name} has left a comment on: {subject}
{message}
To view this comment, please go to {url}
=====================
This e-mail was automatically generated. Do not reply to it.""".format(
name=name,
subject=subject,
message=message,
url=url,
),
)
# Notify any subscribers.
subs = get_subscribers(thread)
for sub in subs.keys():
# Make the unsubscribe link.
unsub = url_for("comment.unsubscribe", thread=thread, who=sub, _external=True)
send_email(
to=sub,
subject="New Comment: {}".format(subject),
message="""Hello,
You are currently subscribed to the comment thread '{thread}', and somebody has
just added a new comment!
{name} has left a comment on: {subject}
{message}
To view this comment, please go to {url}
=====================
This e-mail was automatically generated. Do not reply to it.
If you wish to unsubscribe from this comment thread, please visit the following
URL: {unsub}""".format(
thread=thread,
name=name,
subject=subject,
message=message,
url=url,
unsub=unsub,
)
)
def get_comment(thread, cid):
"""Look up a specific comment."""
comments = get_comments(thread)
return comments.get(cid, None)
def update_comment(thread, cid, data):
"""Update the data for a comment."""
comments = get_comments(thread)
if cid in comments:
comments[cid].update(data)
write_comments(thread, comments)
2014-04-06 22:45:43 +00:00
def delete_comment(thread, cid):
"""Delete a comment from a thread."""
comments = get_comments(thread)
del comments[cid]
write_comments(thread, comments)
def count_comments(thread):
"""Count the comments on a thread."""
comments = get_comments(thread)
return len(comments.keys())
def add_subscriber(thread, email):
"""Add a subscriber to a thread."""
if not "@" in email:
return
# Sanity check: only subscribe to threads that exist.
if not JsonDB.exists("comments/threads/{}".format(thread)):
return
logger.info("Subscribe e-mail {} to thread {}".format(email, thread))
subs = get_subscribers(thread)
subs[email] = int(time.time())
write_subscribers(thread, subs)
def unsubscribe(thread, email):
"""Unsubscribe an e-mail address from a thread.
If `thread` is `*`, the e-mail is unsubscribed from all threads."""
# Which threads to unsubscribe from?
threads = []
if thread == "*":
threads = JsonDB.list_docs("comments/subscribers")
else:
threads = [thread]
# Remove them as a subscriber.
for thread in threads:
if JsonDB.exists("comments/subscribers/{}".format(thread)):
logger.info("Unsubscribe e-mail address {} from comment thread {}".format(email, thread))
db = get_subscribers(thread)
del db[email]
write_subscribers(thread, db)
def format_message(message):
"""HTML sanitize the message and format it for display."""
# Comments use Markdown formatting, and HTML tags are escaped by default.
message = render_markdown(message)
2014-04-06 22:45:43 +00:00
# Process emoticons.
message = Emoticons.render(message)
return message
def get_comments(thread):
"""Get the comment thread."""
doc = "comments/threads/{}".format(thread)
if JsonDB.exists(doc):
return JsonDB.get(doc)
return {}
def write_comments(thread, comments):
"""Save the comments DB."""
if len(comments.keys()) == 0:
return JsonDB.delete("comments/threads/{}".format(thread))
return JsonDB.commit("comments/threads/{}".format(thread), comments)
def get_subscribers(thread):
"""Get the subscribers to a comment thread."""
doc = "comments/subscribers/{}".format(thread)
if JsonDB.exists(doc):
return JsonDB.get(doc)
return {}
def write_subscribers(thread, subs):
"""Save the subscribers to the DB."""
if len(subs.keys()) == 0:
return JsonDB.delete("comments/subscribers/{}".format(thread))
return JsonDB.commit("comments/subscribers/{}".format(thread), subs)
def random_hash():
"""Get a short random hash to use as the ID for a comment."""
md5 = hashlib.md5()
2014-06-02 21:04:44 +00:00
md5.update(str(random.randint(0, 1000000)).encode("utf-8"))
2014-04-06 22:45:43 +00:00
return md5.hexdigest()
def gravatar(email):
"""Generate a Gravatar link for an email address."""
if "@" in email:
# Default avatar?
2014-12-04 23:06:44 +00:00
default = Config.comment.default_avatar
2014-04-06 22:45:43 +00:00
# Construct the URL.
params = {
"s": "96", # size
}
if default:
params["d"] = default
2014-06-02 21:04:44 +00:00
url = "//www.gravatar.com/avatar/" + hashlib.md5(email.lower().encode("utf-8")).hexdigest() + "?"
# URL encode the params, the Python 2 & Python 3 way.
if sys.version_info[0] < 3:
url += urllib.urlencode(params)
else:
url += urllib.parse.urlencode(params)
2014-04-06 22:45:43 +00:00
return url
2014-04-18 23:00:13 +00:00
return ""