130 lines
No EOL
3.7 KiB
Python
130 lines
No EOL
3.7 KiB
Python
#!/usr/bin/env python
|
|
# -*- coding: utf-8 -*-
|
|
|
|
import logging
|
|
from datetime import datetime
|
|
import time
|
|
import re
|
|
from core import mailer
|
|
from core.templater import get_template
|
|
from core import rss
|
|
from model.comment import Comment
|
|
from model.comment import Site
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def cron(func):
|
|
def wrapper():
|
|
logger.debug("execute CRON " + func.__name__)
|
|
func()
|
|
|
|
return wrapper
|
|
|
|
|
|
@cron
|
|
def fetch_mail_answers():
|
|
|
|
for msg in mailer.fetch():
|
|
if re.search(r".*STACOSYS.*\[(\d+)\:(\w+)\]", msg["subject"], re.DOTALL):
|
|
full_msg = mailer.get(msg["id"])
|
|
if full_msg and reply_comment_email(full_msg['email']):
|
|
mailer.delete(msg["id"])
|
|
|
|
@cron
|
|
def submit_new_comment():
|
|
|
|
for comment in Comment.select().where(Comment.notified.is_null()):
|
|
|
|
comment_list = (
|
|
"author: %s" % comment.author_name,
|
|
"site: %s" % comment.author_site,
|
|
"date: %s" % comment.created,
|
|
"url: %s" % comment.url,
|
|
"",
|
|
"%s" % comment.content,
|
|
"",
|
|
)
|
|
comment_text = "\n".join(comment_list)
|
|
email_body = get_template("new_comment").render(
|
|
url=comment.url, comment=comment_text
|
|
)
|
|
|
|
# send email
|
|
site = Site.get(Site.id == comment.site)
|
|
subject = "STACOSYS %s: [%d:%s]" % (site.name, comment.id, site.token)
|
|
mailer.send(site.admin_email, subject, email_body)
|
|
logger.debug("new comment processed ")
|
|
|
|
# update comment
|
|
comment.notified = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
comment.save()
|
|
|
|
|
|
def reply_comment_email(data):
|
|
|
|
from_email = data["from"]
|
|
subject = data["subject"]
|
|
message = ""
|
|
for part in data["parts"]:
|
|
if part["content-type"] == "text/plain":
|
|
message = part["content"]
|
|
break
|
|
|
|
m = re.search(r"\[(\d+)\:(\w+)\]", subject)
|
|
if not m:
|
|
logger.warn("ignore corrupted email. No token %s" % subject)
|
|
return
|
|
comment_id = int(m.group(1))
|
|
token = m.group(2)
|
|
|
|
# retrieve site and comment rows
|
|
try:
|
|
comment = Comment.select().where(Comment.id == comment_id).get()
|
|
except:
|
|
logger.warn("unknown comment %d" % comment_id)
|
|
return True
|
|
|
|
if comment.published:
|
|
logger.warn("ignore already published email. token %d" % comment_id)
|
|
return
|
|
|
|
if comment.site.token != token:
|
|
logger.warn("ignore corrupted email. Unknown token %d" % comment_id)
|
|
return
|
|
|
|
if not message:
|
|
logger.warn("ignore empty email")
|
|
return
|
|
|
|
# safe logic: no answer or unknown answer is a go for publishing
|
|
if message[:2].upper() in ("NO", "SP"):
|
|
|
|
# put a log to help fail2ban
|
|
if message[:2].upper() == "SP": # SPAM
|
|
if comment.ip:
|
|
logger.info(
|
|
"SPAM comment from %s: %d" % (comment.ip, comment_id)
|
|
)
|
|
else:
|
|
logger.info("cannot identify SPAM source: %d" % comment_id)
|
|
|
|
logger.info("discard comment: %d" % comment_id)
|
|
comment.delete_instance()
|
|
email_body = get_template("drop_comment").render(original=message)
|
|
mailer.send(from_email, "Re: " + subject, email_body)
|
|
else:
|
|
# update Comment row
|
|
comment.published = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
comment.ip = None
|
|
comment.save()
|
|
logger.info("commit comment: %d" % comment_id)
|
|
|
|
# rebuild RSS
|
|
rss.generate_site(token)
|
|
|
|
# send approval confirmation email to admin
|
|
email_body = get_template("approve_comment").render(original=message)
|
|
mailer.send(from_email, "Re: " + subject, email_body)
|
|
|
|
return True |