From 31622cb4aa846707efea27ac1f79ac64accbbb7a Mon Sep 17 00:00:00 2001 From: Aevann Date: Wed, 27 Mar 2024 00:32:13 +0200 Subject: [PATCH] remove redundancy and fix issues with private chats --- files/classes/private_chats.py | 16 ++------------- files/classes/user.py | 4 ++-- files/routes/chat.py | 20 +++++++++---------- files/routes/notifications.py | 11 +++++----- files/routes/private_chats.py | 18 ++++++++--------- files/templates/notifications.html | 6 +++--- ...40324-remove-redundancy-and-fix-issues.sql | 8 ++++++++ 7 files changed, 37 insertions(+), 46 deletions(-) create mode 100644 migrations/20240324-remove-redundancy-and-fix-issues.sql diff --git a/files/classes/private_chats.py b/files/classes/private_chats.py index 08da03353..9d55b5328 100644 --- a/files/classes/private_chats.py +++ b/files/classes/private_chats.py @@ -28,6 +28,8 @@ class ChatMembership(Base): __tablename__ = "chat_memberships" user_id = Column(Integer, ForeignKey("users.id"), primary_key=True) chat_id = Column(Integer, ForeignKey("chats.id"), primary_key=True) + notification = Column(Boolean, default=False) + last_notified = Column(Integer, default=0) created_utc = Column(Integer) user = relationship("User") @@ -54,20 +56,6 @@ class ChatLeave(Base): return f"<{self.__class__.__name__}(user_id={self.user_id}, chat_id={self.chat_id})>" -class ChatNotification(Base): - __tablename__ = "chat_notifications" - user_id = Column(Integer, ForeignKey("users.id"), primary_key=True) - chat_id = Column(Integer, ForeignKey("chats.id"), primary_key=True) - created_utc = Column(Integer) - - def __init__(self, *args, **kwargs): - if "created_utc" not in kwargs: kwargs["created_utc"] = int(time.time()) - super().__init__(*args, **kwargs) - - def __repr__(self): - return f"<{self.__class__.__name__}(user_id={self.user_id}, chat_id={self.chat_id})>" - - class ChatMessage(Base): __tablename__ = "chat_messages" id = Column(Integer, primary_key=True) diff --git a/files/classes/user.py b/files/classes/user.py index 33b91fe3c..5583dc244 100644 --- a/files/classes/user.py +++ b/files/classes/user.py @@ -14,7 +14,7 @@ from files.classes import Base from files.classes.casino_game import CasinoGame from files.classes.group import * from files.classes.hole import Hole -from files.classes.private_chats import ChatNotification +from files.classes.private_chats import ChatMembership from files.classes.currency_logs import CurrencyLog from files.helpers.config.const import * from files.helpers.config.modaction_types import * @@ -832,7 +832,7 @@ class User(Base): @property @lazy def chats_notifications_count(self): - return g.db.query(ChatNotification).filter_by(user_id=self.id).count() + return g.db.query(ChatMembership).filter_by(user_id=self.id, notification=True).count() @property @lazy diff --git a/files/routes/chat.py b/files/routes/chat.py index 801777e39..8ba5d5720 100644 --- a/files/routes/chat.py +++ b/files/routes/chat.py @@ -175,18 +175,16 @@ def speak(data, v): g.db.delete(existing) g.db.flush() - dont_notify = list(online[request.referrer].keys()) + [x[0] for x in g.db.query(ChatNotification.user_id).filter_by(chat_id=chat_id).all()] - dont_notify = set(dont_notify) - to_notify = [x[0] for x in g.db.query(ChatMembership.user_id).filter( + alrdy_here = list(online[request.referrer].keys()) + memberships = g.db.query(ChatMembership).filter( ChatMembership.chat_id == chat_id, - ChatMembership.user_id.notin_(dont_notify), - )] - for uid in to_notify: - n = ChatNotification( - user_id=uid, - chat_id=chat_id, - ) - g.db.add(n) + ChatMembership.user_id.notin_(alrdy_here), + ChatMembership.notification == False, + ) + for membership in memberships: + membership.notification = True + membership.last_notified = time.time() + g.db.add(membership) data = { "id": chat_message.id, diff --git a/files/routes/notifications.py b/files/routes/notifications.py index 706fa42ac..04a2b59b0 100644 --- a/files/routes/notifications.py +++ b/files/routes/notifications.py @@ -29,9 +29,10 @@ def clear(v): n.read = True g.db.add(n) - chat_notifs = g.db.query(ChatNotification).filter_by(user_id=v.id) - for chat_notif in chat_notifs: - g.db.delete(chat_notif) + chat_memberships = g.db.query(ChatMembership).filter_by(user_id=v.id, notification=True) + for membership in chat_memberships: + membership.notification = False + g.db.add(membership) v.last_viewed_modmail_notifs = int(time.time()) v.last_viewed_post_notifs = int(time.time()) @@ -140,9 +141,7 @@ def notifications_messages(v): @limiter.limit(DEFAULT_RATELIMIT, deduct_when=lambda response: response.status_code < 400, key_func=get_ID) @auth_required def notifications_chats(v): - criteria1 = (Chat.id == ChatMembership.chat_id, ChatMembership.user_id == v.id) - criteria2 = (Chat.id == ChatNotification.chat_id, ChatNotification.user_id == v.id) - chats = g.db.query(Chat, func.count(ChatNotification.chat_id)).join(ChatMembership, and_(*criteria1)).outerjoin(ChatNotification, and_(*criteria2)).group_by(Chat, ChatMembership.created_utc).order_by(func.count(ChatNotification.chat_id).desc(), ChatMembership.created_utc.desc()).all() + chats = g.db.query(Chat, ChatMembership.notification).join(ChatMembership, and_(Chat.id == ChatMembership.chat_id, ChatMembership.user_id == v.id)).order_by(ChatMembership.last_notified.desc()).all() return render_template("notifications.html", v=v, notifications=chats) @app.get("/notifications/modmail") diff --git a/files/routes/private_chats.py b/files/routes/private_chats.py index 28212bf63..9cb0857bc 100644 --- a/files/routes/private_chats.py +++ b/files/routes/private_chats.py @@ -58,18 +58,19 @@ def private_chat(v, chat_id): if not chat: abort(404, "Chat not found!") - if v.admin_level < PERMS['VIEW_CHATS']: - is_member = g.db.query(ChatMembership.user_id).filter_by(user_id=v.id, chat_id=chat_id).one_or_none() - if not is_member: - abort(403, "You're not a member of this chat!") + membership = g.db.query(ChatMembership).filter_by(user_id=v.id, chat_id=chat_id).one_or_none() + + if v.admin_level < PERMS['VIEW_CHATS'] and not membership: + abort(403, "You're not a member of this chat!") displayed_messages = reversed(g.db.query(ChatMessage).filter_by(chat_id=chat.id).order_by(ChatMessage.id.desc()).limit(250).all()) displayed_messages = {m.id: m for m in displayed_messages} - notif = g.db.query(ChatNotification).filter_by(user_id=v.id, chat_id=chat_id).one_or_none() - if notif: g.db.delete(notif) + if not session.get("GLOBAL"): + membership.notification = False + g.db.add(membership) + g.db.commit() #to clear notif count - g.db.commit() #to clear notif count return render_template("private_chat.html", v=v, messages=displayed_messages, chat=chat) @@ -119,7 +120,4 @@ def leave_chat(v, chat_id): ) g.db.add(chat_leave) - notif = g.db.query(ChatNotification).filter_by(user_id=v.id, chat_id=chat_id).one_or_none() - if notif: g.db.delete(notif) - return {"message": "Chat left successfully!"} diff --git a/files/templates/notifications.html b/files/templates/notifications.html index 9ab93e064..13b8408b4 100644 --- a/files/templates/notifications.html +++ b/files/templates/notifications.html @@ -64,13 +64,13 @@ {% if request.path == '/notifications/chats' %} - {% for chat, notif_count in notifications %} + {% for chat, notification in notifications %} diff --git a/migrations/20240324-remove-redundancy-and-fix-issues.sql b/migrations/20240324-remove-redundancy-and-fix-issues.sql new file mode 100644 index 000000000..7f359e09f --- /dev/null +++ b/migrations/20240324-remove-redundancy-and-fix-issues.sql @@ -0,0 +1,8 @@ +alter table chat_memberships add column notification bool not null default false; +alter table chat_memberships alter column notification drop default; + +alter table chat_memberships add column last_notified int not null default 0; +update chat_memberships a set last_notified=(select created_utc from chat_messages b where a.chat_id=b.chat_id order by created_utc desc limit 1); +alter table chat_memberships alter column last_notified drop default; + +drop table chat_notifications;
{{chat.name}} - {% if notif_count %} - {{notif_count}} + {% if notification %} + 1 {% endif %}