diff --git a/files/classes/group.py b/files/classes/group.py index 2b2ec2796..c304a25b3 100644 --- a/files/classes/group.py +++ b/files/classes/group.py @@ -37,7 +37,7 @@ class Group(Base): @property @lazy def member_ids(self): - return [x.user_id for x in self.memberships if x.approved_utc] + return set([x.user_id for x in self.memberships if x.approved_utc]) @property @lazy diff --git a/files/classes/user.py b/files/classes/user.py index 258ec6540..8568936c7 100644 --- a/files/classes/user.py +++ b/files/classes/user.py @@ -480,8 +480,8 @@ class User(Base): @property @lazy def all_twoway_blocks(self): - return [x[0] for x in g.db.query(UserBlock.target_id).filter_by(user_id=self.id).all() + \ - g.db.query(UserBlock.user_id).filter_by(target_id=self.id).all()] + return set([x[0] for x in g.db.query(UserBlock.target_id).filter_by(user_id=self.id).all() + \ + g.db.query(UserBlock.user_id).filter_by(target_id=self.id).all()]) def validate_2fa(self, token): diff --git a/files/helpers/alerts.py b/files/helpers/alerts.py index e07df6a97..6f9886e4f 100644 --- a/files/helpers/alerts.py +++ b/files/helpers/alerts.py @@ -122,7 +122,7 @@ def add_notif(cid, uid, text, pushnotif_url=''): push_notif({uid}, 'New notification', text, pushnotif_url) -def NOTIFY_USERS(text, v): +def NOTIFY_USERS(text, v, oldtext=None): # Restrict young accounts from generating notifications if v.age < NOTIFICATION_SPAM_AGE_THRESHOLD: return set() @@ -130,37 +130,6 @@ def NOTIFY_USERS(text, v): text = text.lower() notify_users = set() - if FEATURES['PING_GROUPS']: - billed = set() - everyone = False - for i in group_mention_regex.finditer(text): - if i.group(2) == 'everyone' and not v.shadowbanned: - everyone = True - break - else: - group = g.db.get(Group, i.group(2)) - if group: - if v.id not in group.member_ids: - billed.update(group.member_ids) - notify_users.update(group.member_ids) - - if everyone: - cost = g.db.query(User).count() * 5 - if cost > v.coins: - abort(403, f"You need {cost} coins for this!") - g.db.query(User).update({ User.coins: User.coins + 5 }) - v.coins -= cost - g.db.add(v) - return 'everyone' - - if billed: - cost = len(billed) * 5 - if cost > v.coins: - abort(403, f"You need {cost} coins for this!") - g.db.query(User).filter(User.id.in_(billed)).update({ User.coins: User.coins + 5 }) - v.coins -= cost - g.db.add(v) - for word, id in NOTIFIED_USERS.items(): if word in text: notify_users.add(id) @@ -173,9 +142,49 @@ def NOTIFY_USERS(text, v): admin_ids = [x[0] for x in g.db.query(User.id).filter(User.admin_level >= PERMS['NOTIFICATIONS_SPECIFIC_WPD_COMMENTS']).all()] notify_users.update(admin_ids) - notify_users = set([id for id in notify_users if id not in v.all_twoway_blocks]) - return notify_users - bots - {v.id, 0} + + + if FEATURES['PING_GROUPS']: + cost = 0 + + for i in group_mention_regex.finditer(text): + if oldtext and i.group(2) in oldtext: + continue + + if i.group(2) == 'everyone' and not v.shadowbanned: + cost = g.db.query(User).count() * 5 + if cost > v.coins: + abort(403, f"You need {cost} coins for this!") + g.db.query(User).update({ User.coins: User.coins + 5 }) + v.coins -= cost + g.db.add(v) + return 'everyone' + else: + group = g.db.get(Group, i.group(2)) + if not group: continue + + members = group.member_ids - notify_users - v.all_twoway_blocks + + notify_users.update(members) + + if v.id not in members: + if group.name == 'biofoids': mul = 10 + else: mul = 5 + + cost += len(members) * mul + if cost > v.coins: + abort(403, f"You need {cost} coins for this!") + + g.db.query(User).filter(User.id.in_(members)).update({ User.coins: User.coins + mul }) + + v.coins -= cost + g.db.add(v) + + + + + return notify_users - bots - {v.id, 0} - v.all_twoway_blocks def push_notif(uids, title, body, url_or_comment): diff --git a/files/routes/comments.py b/files/routes/comments.py index 31c077774..94facb84d 100644 --- a/files/routes/comments.py +++ b/files/routes/comments.py @@ -644,6 +644,19 @@ def edit_comment(cid, v): if v.marseyawarded and marseyaward_body_regex.search(body_html): abort(403, "You can only type marseys!") + notify_users = NOTIFY_USERS(body, v, c.body) + + if notify_users == 'everyone': + alert_everyone(c.id) + else: + for x in notify_users-bots: + 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) + if not v.shadowbanned: + push_notif({x}, f'New mention of you by @{c.author_name}', c.body, c) + c.body = body process_poll_options(v, c) @@ -661,18 +674,6 @@ def edit_comment(cid, v): g.db.add(c) - notify_users = NOTIFY_USERS(body, v) - - if notify_users == 'everyone': - alert_everyone(c.id) - else: - for x in notify_users-bots: - 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) - if not v.shadowbanned: - push_notif({x}, f'New mention of you by @{c.author_name}', c.body, c) g.db.commit() return {"body": c.body, "comment": c.realbody(v)} diff --git a/files/routes/posts.py b/files/routes/posts.py index 05b0e2636..27a4f5d99 100644 --- a/files/routes/posts.py +++ b/files/routes/posts.py @@ -984,6 +984,19 @@ def edit_post(pid, v): if not title: abort(400, "Please enter a better title!") + + + if not p.private: + notify_users = NOTIFY_USERS(f'{title} {body}', v, f'{p.title} {p.body}') + if notify_users: + cid, text = notif_comment2(p) + if notify_users == 'everyone': + alert_everyone(cid) + else: + for x in notify_users: + add_notif(cid, x, text, pushnotif_url=p.permalink) + + if title != p.title: torture = (v.agendaposter and not v.marseyawarded and p.sub != 'chudrama' and v.id == p.author_id) @@ -1028,16 +1041,6 @@ def edit_post(pid, v): abort(403, f'You have to include "{AGENDAPOSTER_PHRASE}" in your post!') - if not p.private: - notify_users = NOTIFY_USERS(f'{p.title} {p.body}', v) - if notify_users: - cid, text = notif_comment2(p) - if notify_users == 'everyone': - alert_everyone(cid) - else: - for x in notify_users: - add_notif(cid, x, text, pushnotif_url=p.permalink) - if v.id == p.author_id: if int(time.time()) - p.created_utc > 60 * 3: p.edited_utc = int(time.time()) g.db.add(p) diff --git a/files/routes/settings.py b/files/routes/settings.py index 6ff09f4bf..bb50ab13a 100644 --- a/files/routes/settings.py +++ b/files/routes/settings.py @@ -254,7 +254,9 @@ def settings_personal_post(v): v=v, error="Your friends list is too long") - notify_users = NOTIFY_USERS(friends, v) + friends = friends[:1000] + + notify_users = NOTIFY_USERS(friends, v, v.friends) if notify_users: text = f"@{v.username} has added you to their friends list!" @@ -265,7 +267,7 @@ def settings_personal_post(v): for x in notify_users: add_notif(cid, x, text) - v.friends = friends[:1000] + v.friends = friends v.friends_html=friends_html g.db.add(v) return render_template("settings/personal.html", @@ -283,7 +285,9 @@ def settings_personal_post(v): v=v, error="Your enemies list is too long") - notify_users = NOTIFY_USERS(enemies, v) + enemies = enemies[:1000] + + notify_users = NOTIFY_USERS(enemies, v, v.enemies) if notify_users: text = f"@{v.username} has added you to their enemies list!" cid = notif_comment(text) @@ -293,7 +297,7 @@ def settings_personal_post(v): for x in notify_users: add_notif(cid, x, text) - v.enemies = enemies[:1000] + v.enemies = enemies v.enemies_html=enemies_html g.db.add(v) return render_template("settings/personal.html",