Manage reader subscription

pull/6/head
Yax 10 years ago
parent e156ed6db7
commit 9e1bf963c8

@ -14,7 +14,7 @@ def new_mail():
try: try:
data = request.get_json() data = request.get_json()
logger.info(data) logger.debug(data)
processor.enqueue({'request': 'new_mail', 'data': data}) processor.enqueue({'request': 'new_mail', 'data': data})

@ -0,0 +1,29 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import logging
from flask import request, abort
from app import app
from app.services import processor
logger = logging.getLogger(__name__)
@app.route("/unsubscribe", methods=['GET'])
def unsubscribe():
try:
data = {
'token': request.args.get('token', ''),
'url': request.args.get('url', ''),
'email': request.args.get('email', '')
}
logger.debug(data)
processor.enqueue({'request': 'unsubscribe', 'data': data})
except:
logger.exception("unsubscribe failure")
abort(400)
return "OK"

@ -0,0 +1,17 @@
#!/usr/bin/python
# -*- coding: UTF-8 -*-
from peewee import Model
from peewee import CharField
from peewee import ForeignKeyField
from app.services.database import get_db
from app.models.site import Site
class Reader(Model):
url = CharField()
email = CharField(default='')
site = ForeignKeyField(Site, related_name='reader_site')
class Meta:
database = get_db()

@ -21,6 +21,7 @@ from app.services import database
from app.services import processor from app.services import processor
from app.controllers import api from app.controllers import api
from app.controllers import mail from app.controllers import mail
from app.controllers import reader
from app import app from app import app
@ -49,6 +50,7 @@ database.setup()
# routes # routes
logger.debug('imported: %s ' % api.__name__) logger.debug('imported: %s ' % api.__name__)
logger.debug('imported: %s ' % mail.__name__) logger.debug('imported: %s ' % mail.__name__)
logger.debug('imported: %s ' % reader.__name__)
# start processor # start processor
template_path = os.path.abspath(os.path.join(current_path, 'templates')) template_path = os.path.abspath(os.path.join(current_path, 'templates'))

@ -23,5 +23,6 @@ def provide_db(func):
def setup(db): def setup(db):
from app.models.site import Site from app.models.site import Site
from app.models.comment import Comment from app.models.comment import Comment
from app.models.reader import Reader
db.create_tables([Site, Comment], safe=True) db.create_tables([Site, Comment, Reader], safe=True)

@ -9,6 +9,7 @@ from queue import Queue
from jinja2 import Environment, FileSystemLoader from jinja2 import Environment, FileSystemLoader
from app.models.site import Site from app.models.site import Site
from app.models.comment import Comment from app.models.comment import Comment
from app.models.reader import Reader
import requests import requests
import json import json
import config import config
@ -36,8 +37,8 @@ class Processor(Thread):
new_comment(msg['data']) new_comment(msg['data'])
elif msg['request'] == 'new_mail': elif msg['request'] == 'new_mail':
reply_comment_email(msg['data']) reply_comment_email(msg['data'])
# elif req['type'] == 'unsubscribe': elif msg['request'] == 'unsubscribe':
# unsubscribe_reader(req['email'], req['article']) unsubscribe_reader(msg['data'])
else: else:
logger.info("throw unknown request " + str(msg)) logger.info("throw unknown request " + str(msg))
except: except:
@ -91,16 +92,14 @@ def new_comment(data):
# Reader subscribes to further comments # Reader subscribes to further comments
if subscribe and author_email: if subscribe and author_email:
# TODO support subscription subscribe_reader(author_email, token, url)
# subscribe_reader(email, article, url)
pass
logger.debug("new comment processed ") logger.debug("new comment processed ")
def reply_comment_email(data): def reply_comment_email(data):
email_address = data['from'] from_email = data['from']
subject = data['subject'] subject = data['subject']
message = '' message = ''
for part in data['parts']: for part in data['parts']:
@ -127,7 +126,7 @@ def reply_comment_email(data):
logger.info('discard comment: %d' % comment_id) logger.info('discard comment: %d' % comment_id)
comment.delete_instance() comment.delete_instance()
email_body = get_template('drop_comment').render(original=message) email_body = get_template('drop_comment').render(original=message)
mail(email_address, 'Re: ' + subject, email_body) mail(from_email, 'Re: ' + subject, email_body)
else: else:
# update Comment row # update Comment row
comment.published = datetime.now().strftime("%Y-%m-%d %H:%M:%S") comment.published = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
@ -137,63 +136,71 @@ def reply_comment_email(data):
# send approval confirmation email to admin # send approval confirmation email to admin
email_body = get_template('approve_comment').render(original=message) email_body = get_template('approve_comment').render(original=message)
mail(email_address, 'Re: ' + subject, email_body) mail(from_email, 'Re: ' + subject, email_body)
# TODO manage subscriptions
# notify reader once comment is published # notify reader once comment is published
# reader_email, article_url = get_email_metadata(message) reader_email = get_email_metadata(message)
# if reader_email: if reader_email:
# notify_reader(reader_email, article_url) notify_reader(from_email, reader_email, comment.site.token,
comment.url)
# notify subscribers every time a new comment is published # notify subscribers every time a new comment is published
# notify_subscribers(article) notify_subscribed_readers(comment.site.token, comment.url)
def get_email_metadata(message): def get_email_metadata(message):
# retrieve metadata reader email and URL from email body sent by admin # retrieve metadata reader email from email body sent by admin
email = "" email = ""
url = ""
m = re.search('email:\s(.+@.+\..+)', message) m = re.search('email:\s(.+@.+\..+)', message)
if m: if m:
email = m.group(1) email = m.group(1)
return email
m = re.search('url:\s(.+)', message)
if m:
url = m.group(1)
return (email, url)
def subscribe_reader(email, article, url):
logger.info("subscribe reader %s to %s (%s)" % (email, article, url))
db = TinyDB(pecosys.get_config('global', 'cwd') + '/db.json')
db.insert({'email': email, 'article': article, 'url': url})
def unsubscribe_reader(email, article): def subscribe_reader(email, token, url):
logger.info("unsubscribe reader %s from %s" % (email, article)) logger.info('subscribe reader %s to %s [%s]' % (email, url, token))
db = TinyDB(pecosys.get_config('global', 'cwd') + '/db.json') recorded = Reader.select().join(Site).where(Site.token == token,
db.remove((where('email') == email) & (where('article') == article)) Reader.email == email,
Reader.url == url).count()
if recorded:
logger.debug('reader %s is already recorded' % email)
else:
site = Site.select().where(Site.token == token).get()
reader = Reader(site=site, email=email, url=url)
reader.save()
def notify_subscribers(article): def unsubscribe_reader(data):
logger.info('notify subscribers for article %s' % article) token = data.get('token', '')
db = TinyDB(pecosys.get_config('global', 'cwd') + '/db.json') url = data.get('url', '')
for item in db.search(where('article') == article): email = data.get('email', '')
logger.info(item) logger.info('unsubscribe reader %s from %s (%s)' % (email, url, token))
to_email = item['email'] for reader in Reader.select().join(Site).where(Site.token == token,
logger.info("notify reader %s for article %s" % (to_email, article)) Reader.email == email,
unsubscribe_url = pecosys.get_config('subscription', 'url') + '?email=' + to_email + '&article=' + article Reader.url == url):
email_body = get_template('notify_subscriber').render(article_url=item['url'], reader.delete_instance()
unsubscribe_url=unsubscribe_url)
def notify_subscribed_readers(token, url):
logger.info('notify subscribers for %s (%s)' % (url, token))
for reader in Reader.select().join(Site).where(Site.token == token,
Reader.url == url):
to_email = reader.email
logger.info('notify reader %s' % to_email)
unsubscribe_url = '%s?email=%s&token=%s&url=%s' % (
config.UNSUBSCRIBE_URL, to_email, token, reader.url)
email_body = get_template(
'notify_subscriber').render(article_url=reader.url,
unsubscribe_url=unsubscribe_url)
subject = get_template('notify_message').render() subject = get_template('notify_message').render()
mail(pecosys.get_config('subscription', 'from_email'), to_email, subject, email_body) mail(to_email, subject, email_body)
def notify_reader(email, url): def notify_reader(from_email, to_email, token, url):
logger.info('notify reader: email %s about URL %s' % (email, url)) logger.info('notify reader: email %s about URL %s' % (to_email, url))
email_body = get_template('notify_reader').render(article_url=url) email_body = get_template('notify_reader').render(article_url=url)
subject = get_template('notify_message').render() subject = get_template('notify_message').render()
mail(pecosys.get_config('subscription', 'from_email'), email, subject, email_body) mail(to_email, subject, email_body)
def mail(to_email, subject, message): def mail(to_email, subject, message):

@ -13,3 +13,5 @@ HTTP_ADDRESS = "0.0.0.0"
HTTP_PORT = 8000 HTTP_PORT = 8000
SALT = "BRRJRqXgGpXWrgTidBPcixIThHpDuKc0" SALT = "BRRJRqXgGpXWrgTidBPcixIThHpDuKc0"
UNSUBSCRIBE_URL = 'http://localhost:8000/unsubscribe'

Loading…
Cancel
Save