diff --git a/files/assets/css/main.css b/files/assets/css/main.css index fc926f89c..0f754b11e 100644 --- a/files/assets/css/main.css +++ b/files/assets/css/main.css @@ -5087,7 +5087,7 @@ html { display: block; } .comment-anchor:target, .unread { - background: #ffffff22; + background: #ffffff22 !important; padding: 12px; padding-bottom: 4px; } diff --git a/files/classes/user.py b/files/classes/user.py index 21c9d4b40..e6196a0c2 100644 --- a/files/classes/user.py +++ b/files/classes/user.py @@ -128,6 +128,7 @@ class User(Base): total_held_lottery_tickets = Column(Integer, default=0) total_lottery_winnings = Column(Integer, default=0) last_viewed_post_notifs = Column(Integer, default=0) + last_viewed_log_notifs = Column(Integer, default=0) pronouns = Column(String, default='they/them') badges = relationship("Badge", order_by="Badge.created_utc", back_populates="user") @@ -151,6 +152,7 @@ class User(Base): if "created_utc" not in kwargs: kwargs["created_utc"] = int(time.time()) kwargs["last_viewed_post_notifs"] = kwargs["created_utc"] + kwargs["last_viewed_log_notifs"] = kwargs["created_utc"] super().__init__(**kwargs) @@ -461,7 +463,7 @@ class User(Base): if not self.shadowbanned and self.admin_level < 3: notifs = notifs.join(Comment.author).filter(User.shadowbanned == None) - return notifs.count() + self.post_notifications_count + return notifs.count() + self.post_notifications_count + self.modaction_notifications_count @property @lazy @@ -492,11 +494,10 @@ class User(Base): @lazy def modaction_notifications_count(self): if not self.admin_level: return 0 - return g.db.query(Notification).join(Comment).filter( - Notification.user_id == self.id, Notification.read == False, - Comment.is_banned == False, Comment.deleted_utc == 0, - Comment.body_html.like(f'%

{NOTIF_MODACTION_PREFIX}%'), - Comment.parent_submission == None, Comment.author_id == AUTOJANNY_ID).count() + return g.db.query(ModAction).filter( + ModAction.created_utc > self.last_viewed_log_notifs, + ModAction.user_id != self.id, + ).count() @property @lazy diff --git a/files/helpers/alerts.py b/files/helpers/alerts.py index dd32c49f5..38871262f 100644 --- a/files/helpers/alerts.py +++ b/files/helpers/alerts.py @@ -109,26 +109,6 @@ def NOTIFY_USERS(text, v): return notify_users - bots -def notify_mod_action(by_id, msg): - body_html = sanitize(NOTIF_MODACTION_PREFIX + msg) - new_comment = Comment( - author_id=AUTOJANNY_ID, - parent_submission=None, - level=1, - body_html=body_html, - distinguish_level=6, - is_bot=True) - g.db.add(new_comment) - g.db.flush() - new_comment.top_comment_id = new_comment.id - - send_to = g.db.query(User).filter( - User.admin_level >= NOTIF_MODACTION_JL_MIN, User.id != by_id).all() - for admin in send_to: - notif = Notification(comment_id=new_comment.id, user_id=admin.id) - g.db.add(notif) - - if PUSHER_ID != 'blahblahblah': beams_client = PushNotifications(instance_id=PUSHER_ID, secret_key=PUSHER_KEY) diff --git a/files/helpers/const.py b/files/helpers/const.py index be072d258..1e639ca8f 100644 --- a/files/helpers/const.py +++ b/files/helpers/const.py @@ -852,7 +852,6 @@ EIGHTBALL_REPLIES = ('The 8-Ball Says: It is certain.": return {"message": "Under attack mode disabled!"} return {"error": "Failed to disable under attack mode."} else: @@ -922,7 +920,6 @@ def shadowban(user_id, v): g.db.add(ma) cache.delete_memoized(frontlist) - notify_mod_action(v.id, f"@{v.username} has shadowbanned @{user.username}") return {"message": "User shadowbanned!"} @@ -947,7 +944,6 @@ def unshadowban(user_id, v): g.db.add(ma) cache.delete_memoized(frontlist) - notify_mod_action(v.id, f"@{v.username} has unshadowbanned @{user.username}") return {"message": "User unshadowbanned!"} @@ -1049,8 +1045,6 @@ def ban_user(user_id, v): comment.bannedfor = f'{duration} by @{v.username}' g.db.add(comment) - notify_mod_action(v.id, f"@{v.username} has banned @{user.username} ({note})") - if 'redir' in request.values: return redirect(user.url) else: return {"message": f"@{user.username} was banned!"} @@ -1086,8 +1080,6 @@ def unban_user(user_id, v): ) g.db.add(ma) - notify_mod_action(v.id, f"@{v.username} has unbanned @{user.username}") - if "@" in request.referrer: return redirect(user.url) else: return {"message": f"@{user.username} was unbanned!"} @@ -1123,9 +1115,6 @@ def ban_post(post_id, v): v.coins += 1 g.db.add(v) - if v.id != post.author_id: - notify_mod_action(v.id, f"@{v.username} has removed [{post.title}]({post.shortlink}) by @{post.author.username}") - requests.post(f'https://api.cloudflare.com/client/v4/zones/{CF_ZONE}/purge_cache', headers=CF_HEADERS, json={'files': [f"{SITE_FULL}/logged_out/"]}, timeout=5) @@ -1164,10 +1153,6 @@ def unban_post(post_id, v): v.coins -= 1 g.db.add(v) - if v.id != post.author_id: - notify_mod_action(v.id, f"@{v.username} has approved [{post.title}]({post.shortlink}) by @{post.author.username}") - - return {"message": "Post approved!"} @@ -1327,9 +1312,6 @@ def api_ban_comment(c_id, v): ) g.db.add(ma) - if v.id != comment.author_id: - notify_mod_action(v.id, f"@{v.username} has removed [comment]({comment.shortlink}) by @{comment.author.username}") - return {"message": "Comment removed!"} @@ -1358,10 +1340,6 @@ def api_unban_comment(c_id, v): g.db.add(comment) - if v.id != comment.author_id: - notify_mod_action(v.id, f"@{v.username} has approved [comment]({comment.shortlink}) by @{comment.author.username}") - - return {"message": "Comment approved!"} @@ -1479,9 +1457,6 @@ def admin_nuke_user(v): ) g.db.add(ma) - notify_mod_action(v.id, f"@{v.username} has has removed all content of @{user.username}") - - return redirect(user.url) @@ -1517,7 +1492,4 @@ def admin_nunuke_user(v): ) g.db.add(ma) - notify_mod_action(v.id, f"@{v.username} has approved all of content of @{user.username}") - - return redirect(user.url) diff --git a/files/routes/awards.py b/files/routes/awards.py index 1dcf2e836..0047c8715 100644 --- a/files/routes/awards.py +++ b/files/routes/awards.py @@ -176,9 +176,17 @@ def award_thing(v, thing_type, id): send_repeatable_notification(author.id, f"Your account has been banned for **yet another day** for {link}. Seriously man?") if v.admin_level > 2: - text = f"@{v.username} has banned @{author.username} for 1 day for {link}." - if note: text += f" ({note})" - notify_mod_action(v.id, text) + log_link = f'/{thing_type}/{thing.id}' + reason = f'{log_link}' + + note = f'reason: "{reason}", duration: for 1 day' + ma=ModAction( + kind="ban_user", + user_id=v.id, + target_user_id=author.id, + _note=note + ) + g.db.add(ma) elif kind == "unban": if not author.is_suspended or not author.unban_utc or time.time() > author.unban_utc: abort(403) @@ -193,9 +201,12 @@ def award_thing(v, thing_type, id): send_repeatable_notification(author.id, "You have been unbanned!") if v.admin_level > 2: - text = f"@{v.username} has unbanned @{author.username} for {link}." - if note: text += f" ({note})" - notify_mod_action(v.id, text) + ma=ModAction( + kind="unban_user", + user_id=v.id, + target_user_id=author.id, + ) + g.db.add(ma) elif kind == "grass": author.is_banned = AUTOJANNY_ID author.ban_reason = f"grass award used by @{v.username} on /{thing_type}/{thing.id}" @@ -203,9 +214,17 @@ def award_thing(v, thing_type, id): send_repeatable_notification(author.id, f"Your account has been banned permanently for {link}. You must [provide the admins](/contact) a timestamped picture of you touching grass/snow/sand/ass to get unbanned!") if v.admin_level > 2: - text = f"@{v.username} has grassed @{author.username} for {link}." - if note: text += f" ({note})" - notify_mod_action(v.id, text) + log_link = f'/{thing_type}/{thing.id}' + reason = f'{log_link}' + + note = f'reason: "{reason}", duration: for 30 days' + ma=ModAction( + kind="ban_user", + user_id=v.id, + target_user_id=author.id, + _note=note + ) + g.db.add(ma) elif kind == "pin": if not FEATURES['PINS']: abort(403) diff --git a/files/routes/notifications.py b/files/routes/notifications.py index cbc1a0180..dbe5d83d8 100644 --- a/files/routes/notifications.py +++ b/files/routes/notifications.py @@ -12,6 +12,7 @@ def clear(v): n.read = True g.db.add(n) v.last_viewed_post_notifs = int(time.time()) + v.last_viewed_log_notifs = int(time.time()) g.db.add(v) return {"message": "Notifications cleared!"} @@ -134,29 +135,16 @@ def notifications_modactions(v): try: page = max(int(request.values.get("page", 1)), 1) except: page = 1 - notifications = g.db.query(Notification, Comment) \ - .join(Notification.comment) \ - .filter(Notification.user_id == v.id, - Comment.body_html.like(f'%

{NOTIF_MODACTION_PREFIX}%'), - Comment.parent_submission == None, Comment.author_id == AUTOJANNY_ID) \ - .order_by(Notification.created_utc.desc()).offset(25 * (page - 1)).limit(101).all() - listing = [] + listing = g.db.query(ModAction).filter(ModAction.user_id != v.id).order_by(ModAction.id.desc()).offset(25*(page-1)).limit(26).all() - for index, x in enumerate(notifications[:100]): - n, c = x - if n.read and index > 24: break - elif not n.read: - n.read = True - c.unread = True - g.db.add(n) - if n.created_utc > 1620391248: c.notif_utc = n.created_utc - listing.append(c) + next_exists = len(listing) > 25 + listing = listing[:25] - next_exists = (len(notifications) > len(listing)) + for ma in listing: + ma.unread = ma.created_utc > v.last_viewed_log_notifs - g.db.commit() - - if request.headers.get("Authorization"): return {"data":[x.json for x in listing]} + v.last_viewed_log_notifs = int(time.time()) + g.db.add(v) return render_template("notifications.html", v=v, @@ -225,7 +213,6 @@ def notifications(v): Comment.is_banned == False, Comment.deleted_utc == 0, Comment.body_html.notlike('%

New site mention%Blocked -

Top 25 by coins
-

+
Top 25 by coins
+
@@ -48,16 +48,8 @@ {% endif %}
+
Top 25 by coins spent in shop
-
-
-
-
-
Top 25 by coins spent in shop
-
-
-
-
@@ -83,16 +75,8 @@ {% endif %}
+
Top 25 by truescore
-
-
-
-
-
Top 25 by truescore
-
-
-
-
@@ -119,15 +103,8 @@
-
+
Top 25 by followers
- -
-
Top 25 by followers
-
-
-
-
@@ -151,15 +128,9 @@ {% endif %}
-
 
+
Top 25 by post count
-
-
Top 25 by post count
-
-
-
-
@@ -183,15 +154,9 @@ {% endif %}
-
 
+
Top 25 by comment count
-
-
Top 25 by comment count
-
-
-
-
@@ -216,16 +181,8 @@ {% endif %}
+
Top 25 by received awards
-
-
-
-
-
Top 25 by received awards
-
-
-
-
@@ -250,16 +207,7 @@ {% endif %}
- -
-
-
-
-
Top 25 by received downvotes
-
-
-
-
+
Top 25 by received downvotes
@@ -287,16 +235,7 @@
- -
-
-
-
-
Top 25 by badges
-
-
-
-
+
Top 25 by badges
@@ -327,15 +266,9 @@ {% if users6 %} -
-
-
-	
-
Top 25 by based count
-
-
-
-	
+ +
Top 25 by based count
+
@@ -362,16 +295,9 @@ {% endif %} {% if users12 %} -
-
-
-	
-
Top 25 by marseys made
-
-
-
-	
- + +
Top 25 by marseys made
+
@@ -400,16 +326,9 @@ {% endif %} {% if users13 %} -
-
-
-	
-
Top 25 by upvotes given
-
-
-
-	
- + +
Top 25 by upvotes given
+
@@ -437,8 +356,8 @@
{% endif %} -
Top 25 by winnings
-

+
Top 25 by winnings
+
@@ -463,13 +382,8 @@ {% endif %}
+
Bottom 25 by winnings
-
-
-
-
-
Bottom 25 by winnings
-

 
@@ -494,13 +408,8 @@ {% endif %}
+
Top 25 Most Blocked
-
-
-
-
-
Top 25 Most Blocked
-

 
@@ -518,11 +427,6 @@ {% endfor %}
- -
-
-
-
diff --git a/files/templates/log.html b/files/templates/log.html index b6b853824..96a150bf7 100644 --- a/files/templates/log.html +++ b/files/templates/log.html @@ -93,7 +93,7 @@
{% for ma in actions %} -
+
diff --git a/files/templates/notifications.html b/files/templates/notifications.html index 7ccc93b11..ad6da659f 100644 --- a/files/templates/notifications.html +++ b/files/templates/notifications.html @@ -65,6 +65,48 @@ {% include "submission_listing.html" %}
{% endwith %} + {% elif request.path == '/notifications/modactions' %} +
+ + + {% else %} {% with comments=notifications %} {% include "comments.html" %} diff --git a/files/templates/util/assetcache.html b/files/templates/util/assetcache.html index 80d23f44f..672fd5db7 100644 --- a/files/templates/util/assetcache.html +++ b/files/templates/util/assetcache.html @@ -1,6 +1,6 @@ {%- set CACHE_VER = { - 'css/main.css': 434, + 'css/main.css': 435, 'css/catalog.css': 2, 'css/4chan.css': 61, diff --git a/schema.sql b/schema.sql index c272c72d1..0171357ea 100644 --- a/schema.sql +++ b/schema.sql @@ -809,6 +809,7 @@ CREATE TABLE public.users ( last_active integer DEFAULT 0 NOT NULL, poorcel boolean DEFAULT false NOT NULL, last_viewed_post_notifs integer NOT NULL, + last_viewed_log_notifs integer NOT NULL, pronouns character varying(11) NOT NULL ); diff --git a/seed-db.sql b/seed-db.sql index 7e5439482..bfb3b669d 100644 --- a/seed-db.sql +++ b/seed-db.sql @@ -1,23 +1,23 @@ INSERT INTO public.users (username, passhash, created_utc, admin_level, over_18, is_activated, bio, bio_html, login_nonce, is_private, unban_utc, original_username, customtitle, defaultsorting, defaultsortingcomments, defaulttime, namecolor, titlecolor, customtitleplain, theme, themecolor, reddit, css, profilecss, coins, agendaposter, - post_count, comment_count, background, verified, truecoins, cardview, profileurl, highres, last_viewed_post_notifs, pronouns + post_count, comment_count, background, verified, truecoins, cardview, profileurl, highres, last_viewed_post_notifs, last_viewed_log_notifs, pronouns ) VALUES ('AutoJanny', '', extract(epoch from now()), 0, true, true, '', '', 0, false, 0, 'AutoJanny', '', 'hot', 'top', 'day', 'ff66ac', 'ff66ac', '', 'dark', 'ff66ac', 'old.reddit.com', '', '', 0, 0, - 0, 0, '', 'Verified', 0, false, '/i/pfps/1.webp', '/i/pfps/1.webp', 0, 'clean/itup'), + 0, 0, '', 'Verified', 0, false, '/i/pfps/1.webp', '/i/pfps/1.webp', 0, 0, 'clean/itup'), ('Snappy', '', extract(epoch from now()), 0, true, true, '', '', 0, false, 0, 'Snappy', '', 'hot', 'top', 'day', '62ca56', 'e4432d', '', 'dark', '30409f', 'old.reddit.com', '', '', 0, 0, - 0, 0, '', 'Verified', 0, false, '/i/pfps/2.webp', '/i/pfps/2.webp', 0, 'beep/boop'), + 0, 0, '', 'Verified', 0, false, '/i/pfps/2.webp', '/i/pfps/2.webp', 0, 0,'beep/boop'), ('longpostbot', '', extract(epoch from now()), 0, true, true, '', '', 0, false, 0, 'longpostbot', '', 'hot', 'top', 'day', '62ca56', 'e4432d', '', 'dark', '30409f', 'old.reddit.com', '', '', 0, 0, - 0, 0, '', 'Verified', 0, false, '/i/pfps/3.webp', '/i/pfps/3.webp', 0, 'tl/dr'), + 0, 0, '', 'Verified', 0, false, '/i/pfps/3.webp', '/i/pfps/3.webp', 0, 0, 'tl/dr'), ('zozbot', '', extract(epoch from now()), 0, true, true, '', '', 0, false, 0, 'zozbot', '', 'hot', 'top', 'day', '62ca56', 'e4432d', '', 'dark', '30409f', 'old.reddit.com', '', '', 0, 0, - 0, 0, '', 'Verified', 0, false, '/i/pfps/4.webp', '/i/pfps/4.webp', 0, 'zoz/zle'); + 0, 0, '', 'Verified', 0, false, '/i/pfps/4.webp', '/i/pfps/4.webp', 0, 0,'zoz/zle'); INSERT INTO public.marseys VALUES ('marseyvirus', 1, 'phage infect infection plagued', 0), diff --git a/sql/20220805-modaction-notifs-rework.sql b/sql/20220805-modaction-notifs-rework.sql new file mode 100644 index 000000000..d9998ecb6 --- /dev/null +++ b/sql/20220805-modaction-notifs-rework.sql @@ -0,0 +1,2 @@ +alter table users add column last_viewed_log_notifs int not null default 0; +alter table users alter column last_viewed_log_notifs drop default;