Make unsubscribe work with notifications for replies
This commit is contained in:
parent
f6f61c547a
commit
0063fd6e88
@ -81,14 +81,14 @@ class Comments:
|
||||
' mode=1',
|
||||
'WHERE id=? AND mode=2'], (id, ))
|
||||
|
||||
def unsubscribe(self, id):
|
||||
def unsubscribe(self, email, id):
|
||||
"""
|
||||
Turn off email notifications for replies to this comment.
|
||||
"""
|
||||
self.db.execute([
|
||||
'UPDATE comments SET',
|
||||
' notification=0',
|
||||
'WHERE id=?'], (id, ))
|
||||
'WHERE email=? AND (id=? OR parent=?);'], (email, id, id))
|
||||
|
||||
def update(self, id, data):
|
||||
"""
|
||||
|
@ -14,6 +14,11 @@ from email.utils import formatdate
|
||||
from email.header import Header
|
||||
from email.mime.text import MIMEText
|
||||
|
||||
try:
|
||||
from urllib.parse import quote
|
||||
except ImportError:
|
||||
from urllib import quote
|
||||
|
||||
import logging
|
||||
logger = logging.getLogger("isso")
|
||||
|
||||
@ -99,7 +104,7 @@ class SMTP(object):
|
||||
def __iter__(self):
|
||||
yield "comments.new:after-save", self.notify
|
||||
|
||||
def format(self, thread, comment, comment_parent, admin=False):
|
||||
def format(self, thread, comment, parent_comment, recipient=None, admin=False):
|
||||
|
||||
rv = io.StringIO()
|
||||
|
||||
@ -133,10 +138,10 @@ class SMTP(object):
|
||||
rv.write("Activate comment: %s\n" % (uri + "/activate/" + key))
|
||||
|
||||
else:
|
||||
uri = self.general_host + "/id/%i" % comment_parent["id"]
|
||||
key = self.isso.sign(('unsubscribe', comment_parent["id"]))
|
||||
uri = self.general_host + "/id/%i" % parent_comment["id"]
|
||||
key = self.isso.sign(('unsubscribe', recipient))
|
||||
|
||||
rv.write("Unsubscribe from this conversation: %s\n" % (uri + "/unsubscribe/" + key))
|
||||
rv.write("Unsubscribe from this conversation: %s\n" % (uri + "/unsubscribe/" + quote(recipient) + "/" + key))
|
||||
|
||||
rv.seek(0)
|
||||
return rv.read()
|
||||
@ -152,10 +157,10 @@ class SMTP(object):
|
||||
email = comment_to_notify["email"]
|
||||
if "email" in comment_to_notify and comment_to_notify["notification"] and email not in notified \
|
||||
and comment_to_notify["id"] != comment["id"] and email != comment["email"]:
|
||||
body = self.format(thread, comment, comment_to_notify, admin=False)
|
||||
body = self.format(thread, comment, parent_comment, email, admin=False)
|
||||
subject = "Re: New comment posted on %s" % thread["title"]
|
||||
self.sendmail(subject, body, thread, comment, to=email)
|
||||
notified += email
|
||||
notified.append(email)
|
||||
|
||||
body = self.format(thread, comment, None, admin=True)
|
||||
self.sendmail(thread["title"], body, thread, comment)
|
||||
|
@ -32,6 +32,10 @@ try:
|
||||
from urlparse import urlparse
|
||||
except ImportError:
|
||||
from urllib.parse import urlparse
|
||||
try:
|
||||
from urllib import unquote
|
||||
except ImportError:
|
||||
from urllib.parse import unquote
|
||||
try:
|
||||
from StringIO import StringIO
|
||||
except ImportError:
|
||||
@ -107,7 +111,7 @@ class API(object):
|
||||
('view', ('GET', '/id/<int:id>')),
|
||||
('edit', ('PUT', '/id/<int:id>')),
|
||||
('delete', ('DELETE', '/id/<int:id>')),
|
||||
('unsubscribe', ('GET', '/id/<int:id>/unsubscribe/<string:key>')),
|
||||
('unsubscribe', ('GET', '/id/<int:id>/unsubscribe/<string:email>/<string:key>')),
|
||||
('moderate', ('GET', '/id/<int:id>/<any(edit,activate,delete):action>/<string:key>')),
|
||||
('moderate', ('POST', '/id/<int:id>/<any(edit,activate,delete):action>/<string:key>')),
|
||||
('like', ('POST', '/id/<int:id>/like')),
|
||||
@ -494,18 +498,20 @@ class API(object):
|
||||
return resp
|
||||
|
||||
"""
|
||||
@api {get} /id/:id/key unsubscribe
|
||||
@api {get} /id/:id/:email/key unsubscribe
|
||||
@apiGroup Comment
|
||||
@apiDescription
|
||||
Opt out from getting any further email notifications about replies to a particular comment. In order to use this endpoint, the requestor needs a `key` that is usually obtained from an email sent out by isso.
|
||||
|
||||
@apiParam {number} id
|
||||
The id of the comment to unsubscribe from replies to.
|
||||
@apiParam {string} email
|
||||
The email address of the subscriber.
|
||||
@apiParam {string} key
|
||||
The key to authenticate the subscriber.
|
||||
|
||||
@apiExample {curl} Unsubscribe from replies to comment with id 13:
|
||||
curl -X GET 'https://comments.example.com/id/13/unsubscribe/TODO-COMPUTE-HASH'
|
||||
@apiExample {curl} Unsubscribe Alice from replies to comment with id 13:
|
||||
curl -X GET 'https://comments.example.com/id/13/unsubscribe/alice@example.com/TODO-COMPUTE-HASH'
|
||||
|
||||
@apiSuccessExample {html} Using GET:
|
||||
<!DOCTYPE html>
|
||||
@ -523,13 +529,15 @@ class API(object):
|
||||
Yo
|
||||
"""
|
||||
|
||||
def unsubscribe(self, environ, request, id, key):
|
||||
def unsubscribe(self, environ, request, id, email, key):
|
||||
email = unquote(email)
|
||||
|
||||
try:
|
||||
rv = self.isso.unsign(key, max_age=2**32)
|
||||
except (BadSignature, SignatureExpired):
|
||||
raise Forbidden
|
||||
|
||||
if rv[0] != 'unsubscribe' or rv[1] != id:
|
||||
if rv[0] != 'unsubscribe' or rv[1] != email:
|
||||
raise Forbidden
|
||||
|
||||
item = self.comments.get(id)
|
||||
@ -538,7 +546,7 @@ class API(object):
|
||||
raise NotFound
|
||||
|
||||
with self.isso.lock:
|
||||
self.comments.unsubscribe(id)
|
||||
self.comments.unsubscribe(email, id)
|
||||
|
||||
modal = (
|
||||
"<!DOCTYPE html>"
|
||||
|
Loading…
Reference in New Issue
Block a user