Fix approved filtered comments not notifying.
Moves behavior in api_comment that updates stateful counters and generates notifications into a function which can also be called if a filtered comment is approved. Fixes #272. Incidentally, also fixes #278 by adding another filter to the post subscribers query during general clean-up/refactoring. Originally was going to move this function into the Comments model, since assurances about state (even with side effects) should probably be made there, but I couldn't find a sane way to untangle the imports.
This commit is contained in:
parent
0ec522d897
commit
f5f2c008ad
3 changed files with 84 additions and 58 deletions
|
@ -13,6 +13,7 @@ from files.classes import *
|
|||
from flask import *
|
||||
from files.__main__ import app, cache, limiter
|
||||
from .front import frontlist
|
||||
from files.routes.comments import comment_on_publish
|
||||
from files.helpers.discord import add_role
|
||||
from datetime import datetime
|
||||
import requests
|
||||
|
@ -426,13 +427,25 @@ def update_filter_status(v):
|
|||
return { 'result': f'Status of {new_status} is not permitted' }
|
||||
|
||||
if post_id:
|
||||
rows_updated = g.db.query(Submission).where(Submission.id == post_id).update({Submission.filter_state: new_status})
|
||||
p = g.db.query(Submission).get(post_id)
|
||||
old_status = p.filter_state
|
||||
rows_updated = g.db.query(Submission).where(Submission.id == post_id) \
|
||||
.update({Submission.filter_state: new_status})
|
||||
elif comment_id:
|
||||
rows_updated = g.db.query(Comment).where(Comment.id == comment_id).update({Comment.filter_state: new_status})
|
||||
c = g.db.query(Comment).get(comment_id)
|
||||
old_status = c.filter_state
|
||||
rows_updated = g.db.query(Comment).where(Comment.id == comment_id) \
|
||||
.update({Comment.filter_state: new_status})
|
||||
else:
|
||||
return { 'result': f'No valid item ID provided' }
|
||||
|
||||
if rows_updated == 1:
|
||||
# If comment now visible, update state to reflect publication.
|
||||
if (comment_id
|
||||
and old_status in ['filtered', 'removed']
|
||||
and new_status in ['normal', 'ignored']):
|
||||
comment_on_publish(c)
|
||||
|
||||
g.db.commit()
|
||||
return { 'result': 'Update successful' }
|
||||
else:
|
||||
|
|
|
@ -3,7 +3,6 @@ from files.helpers.alerts import *
|
|||
from files.helpers.images import *
|
||||
from files.helpers.const import *
|
||||
from files.classes import *
|
||||
from files.routes.front import comment_idlist
|
||||
from pusher_push_notifications import PushNotifications
|
||||
from flask import *
|
||||
from files.__main__ import app, limiter
|
||||
|
@ -317,38 +316,15 @@ def api_comment(v):
|
|||
if c.level == 1: c.top_comment_id = c.id
|
||||
else: c.top_comment_id = parent.top_comment_id
|
||||
|
||||
if parent_post.id not in ADMINISTRATORS:
|
||||
if not v.shadowbanned and not is_filtered:
|
||||
notify_users = NOTIFY_USERS(body, v)
|
||||
|
||||
for x in g.db.query(Subscription.user_id).filter_by(submission_id=c.parent_submission).all(): notify_users.add(x[0])
|
||||
|
||||
if parent.author.id not in (v.id, BASEDBOT_ID, AUTOJANNY_ID, SNAPPY_ID, LONGPOSTBOT_ID, ZOZBOT_ID):
|
||||
notify_users.add(parent.author.id)
|
||||
|
||||
for x in notify_users:
|
||||
n = Notification(comment_id=c.id, user_id=x)
|
||||
g.db.add(n)
|
||||
|
||||
if parent.author.id != v.id and PUSHER_ID != 'blahblahblah' and not v.shadowbanned:
|
||||
try: gevent.spawn(pusher_thread, f'{request.host}{parent.author.id}', c, c.author_name)
|
||||
except: pass
|
||||
|
||||
|
||||
if not v.shadowbanned and not is_filtered:
|
||||
comment_on_publish(c)
|
||||
|
||||
vote = CommentVote(user_id=v.id,
|
||||
comment_id=c.id,
|
||||
vote_type=1,
|
||||
)
|
||||
|
||||
g.db.add(vote)
|
||||
|
||||
|
||||
cache.delete_memoized(comment_idlist)
|
||||
|
||||
v.comment_count = g.db.query(Comment.id).filter(Comment.author_id == v.id, Comment.parent_submission != None).filter_by(is_banned=False, deleted_utc=0).count()
|
||||
g.db.add(v)
|
||||
|
||||
c.voted = 1
|
||||
|
||||
if v.id == PIZZASHILL_ID:
|
||||
|
@ -364,15 +340,68 @@ def api_comment(v):
|
|||
if v.marseyawarded and parent_post.id not in ADMINISTRATORS and marseyaward_body_regex.search(body_html):
|
||||
return {"error":"You can only type marseys!"}, 403
|
||||
|
||||
parent_post.comment_count += 1
|
||||
g.db.add(parent_post)
|
||||
|
||||
g.db.commit()
|
||||
|
||||
if request.headers.get("Authorization"): return c.json
|
||||
return {"comment": render_template("comments.html", v=v, comments=[c], ajax=True)}
|
||||
|
||||
|
||||
def comment_on_publish(comment):
|
||||
"""
|
||||
Run when comment becomes visible: immediately for non-filtered comments,
|
||||
or on approval for previously filtered comments.
|
||||
Should be used to update stateful counters, notifications, etc. that
|
||||
reflect the comments users will actually see.
|
||||
"""
|
||||
# TODO: Get this out of the routes and into a model eventually...
|
||||
|
||||
# Shadowbanned users are invisible. This may lead to inconsistencies if
|
||||
# a user comments while shadowed and is later unshadowed. (TODO?)
|
||||
if comment.author.shadowbanned:
|
||||
return
|
||||
|
||||
# Comment instances used for purposes other than actual comments (notifs,
|
||||
# DMs) shouldn't be considered published.
|
||||
if not comment.parent_submission:
|
||||
return
|
||||
|
||||
# Generate notifs for: mentions, post subscribers, parent post/comment
|
||||
to_notify = NOTIFY_USERS(comment.body, comment.author)
|
||||
|
||||
post_subscribers = g.db.query(Subscription.user_id).filter(
|
||||
Subscription.submission_id == comment.parent_submission,
|
||||
Subscription.user_id != comment.author_id,
|
||||
).all()
|
||||
to_notify.update([x[0] for x in post_subscribers])
|
||||
|
||||
parent = comment.parent
|
||||
if parent and parent.author_id != comment.author_id:
|
||||
to_notify.add(parent.author_id)
|
||||
|
||||
for uid in to_notify:
|
||||
notif = Notification(comment_id=comment.id, user_id=uid)
|
||||
g.db.add(notif)
|
||||
|
||||
# Comment counter for parent submission
|
||||
comment.post.comment_count += 1
|
||||
g.db.add(comment.post)
|
||||
|
||||
# Comment counter for author's profile
|
||||
comment.author.comment_count = g.db.query(Comment).filter(
|
||||
Comment.author_id == comment.author_id,
|
||||
Comment.parent_submission != None,
|
||||
Comment.is_banned == False,
|
||||
Comment.deleted_utc == 0,
|
||||
).count()
|
||||
g.db.add(comment.author)
|
||||
|
||||
# Generate push notifications if enabled.
|
||||
if PUSHER_ID != 'blahblahblah' and comment.author_id != parent.author_id:
|
||||
try:
|
||||
gevent.spawn(pusher_thread, f'{request.host}{parent.author.id}',
|
||||
comment, comment.author_name)
|
||||
except: pass
|
||||
|
||||
|
||||
@app.post("/edit_comment/<cid>")
|
||||
@limiter.limit("1/second;30/minute;200/hour;1000/day")
|
||||
|
@ -467,13 +496,15 @@ def edit_comment(cid, v):
|
|||
|
||||
g.db.add(c)
|
||||
|
||||
notify_users = NOTIFY_USERS(body, v)
|
||||
if c.filter_state != 'filtered':
|
||||
notify_users = NOTIFY_USERS(body, v)
|
||||
|
||||
for x in notify_users:
|
||||
notif = g.db.query(Notification).filter_by(comment_id=c.id, user_id=x).one_or_none()
|
||||
if not notif:
|
||||
n = Notification(comment_id=c.id, user_id=x)
|
||||
g.db.add(n)
|
||||
for x in notify_users:
|
||||
notif = g.db.query(Notification) \
|
||||
.filter_by(comment_id=c.id, user_id=x).one_or_none()
|
||||
if not notif:
|
||||
n = Notification(comment_id=c.id, user_id=x)
|
||||
g.db.add(n)
|
||||
|
||||
g.db.commit()
|
||||
|
||||
|
@ -494,9 +525,6 @@ def delete_comment(cid, v):
|
|||
c.deleted_utc = int(time.time())
|
||||
|
||||
g.db.add(c)
|
||||
|
||||
cache.delete_memoized(comment_idlist)
|
||||
|
||||
g.db.commit()
|
||||
|
||||
return {"message": "Comment deleted!"}
|
||||
|
@ -514,9 +542,6 @@ def undelete_comment(cid, v):
|
|||
c.deleted_utc = 0
|
||||
|
||||
g.db.add(c)
|
||||
|
||||
cache.delete_memoized(comment_idlist)
|
||||
|
||||
g.db.commit()
|
||||
|
||||
return {"message": "Comment undeleted!"}
|
||||
|
|
|
@ -490,8 +490,6 @@ def random_user(v):
|
|||
@app.get("/comments")
|
||||
@auth_required
|
||||
def all_comments(v):
|
||||
|
||||
|
||||
try: page = max(int(request.values.get("page", 1)), 1)
|
||||
except: page = 1
|
||||
|
||||
|
@ -504,15 +502,7 @@ def all_comments(v):
|
|||
try: lt=int(request.values.get("before", 0))
|
||||
except: lt=0
|
||||
|
||||
idlist = comment_idlist(v=v,
|
||||
page=page,
|
||||
sort=sort,
|
||||
t=t,
|
||||
gt=gt,
|
||||
lt=lt,
|
||||
site=SITE
|
||||
)
|
||||
|
||||
idlist = get_comments_idlist(v=v, page=page, sort=sort, t=t, gt=gt, lt=lt)
|
||||
comments = get_comments(idlist, v=v)
|
||||
|
||||
next_exists = len(idlist) > 25
|
||||
|
@ -523,9 +513,7 @@ def all_comments(v):
|
|||
return render_template("home_comments.html", v=v, sort=sort, t=t, page=page, comments=comments, standalone=True, next_exists=next_exists)
|
||||
|
||||
|
||||
|
||||
@cache.memoize(timeout=86400)
|
||||
def comment_idlist(page=1, v=None, nsfw=False, sort="new", t="all", gt=0, lt=0, site=None):
|
||||
def get_comments_idlist(page=1, v=None, sort="new", t="all", gt=0, lt=0):
|
||||
comments = g.db.query(Comment.id) \
|
||||
.join(Comment.post) \
|
||||
.join(Comment.author) \
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue