Skip to content

Commit

Permalink
[notifications] Add filters and more data
Browse files Browse the repository at this point in the history
* filters: unread, read
* related subscription data
  • Loading branch information
frankrousseau committed Oct 8, 2024
1 parent a80c6c4 commit 9e96c63
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 20 deletions.
5 changes: 5 additions & 0 deletions zou/app/blueprints/user/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
FilterGroupResource,
FilterGroupsResource,
DesktopLoginLogsResource,
MarkAllNotificationsAsReadResource,
NotificationsResource,
NotificationResource,
HasTaskSubscribedResource,
Expand Down Expand Up @@ -108,6 +109,10 @@
"/actions/user/sequences/<sequence_id>/task-types/<task_type_id>/unsubscribe",
SequenceUnsubscribeResource,
),
(
"/actions/user/notifications/mark-all-as-read",
MarkAllNotificationsAsReadResource,
),
]

blueprint = Blueprint("user", "user")
Expand Down
57 changes: 51 additions & 6 deletions zou/app/blueprints/user/resources.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from flask import abort
from flask import abort, request
from flask_restful import Resource

from zou.app.mixin import ArgsMixin
Expand Down Expand Up @@ -593,7 +593,6 @@ def put(self, filter_id):
("project_id", None, None),
]
)

data = self.clear_empty_fields(
data, ignored_fields=["search_filter_group_id"]
)
Expand Down Expand Up @@ -848,26 +847,36 @@ def get(self):
task_status_id,
notification_type,
) = self.get_arguments()

read = None
if request.args.get("read", None) is not None:
read = self.get_bool_parameter("read")
watching = None
if request.args.get("watching", None) is not None:
watching = self.get_bool_parameter("watching")
print("watching", watching)
notifications = user_service.get_last_notifications(
before=before,
task_type_id=task_type_id,
task_status_id=task_status_id,
notification_type=notification_type,
read=read,
watching=watching,
)
user_service.mark_notifications_as_read()
return notifications


def get_arguments(self):
return (
self.get_text_parameter("after"),
self.get_text_parameter("before"),
self.get_text_parameter("task_type_id"),
self.get_text_parameter("task_status_id"),
self.get_text_parameter("type"),
self.get_text_parameter("type")
)


class NotificationResource(Resource):
class NotificationResource(Resource, ArgsMixin):
"""
Return notification matching given id, only if it's a notification that
belongs to current user.
Expand All @@ -894,6 +903,42 @@ def get(self, notification_id):
"""
return user_service.get_notification(notification_id)

def put(self, notification_id):
"""
Change notification read status.
---
tags:
- User
parameters:
- in: path
name: notification_id
required: True
type: string
format: UUID
x-example: a24a6ea4-ce75-4665-a070-57453082c25
responses:
200:
description: Notification
"""
data = self.get_args([("read", None, False, bool)])
return user_service.update_notification(notification_id, data["read"])


class MarkAllNotificationsAsReadResource(Resource):

def post(self):
"""
Mark all notifications as read for the current user.
---
tags:
- User
responses:
200:
description: All notifications marked as read
"""
user_service.mark_notifications_as_read()
return {"success": True}


class HasTaskSubscribedResource(Resource):
"""
Expand All @@ -905,7 +950,7 @@ def get(self, task_id):
Return true if current user has subscribed to given task.
---
tags:
- User
- User
parameters:
- in: path
name: task_id
Expand Down
4 changes: 2 additions & 2 deletions zou/app/models/subscription.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ class Subscription(db.Model, BaseMixin, SerializerMixin):

entity_id = db.Column(
UUIDType(binary=False), db.ForeignKey("entity.id"), index=True
)
) # Deprecated
task_type_id = db.Column(
UUIDType(binary=False), db.ForeignKey("task_type.id"), index=True
)
) # Deprecated

__table_args__ = (
db.UniqueConstraint(
Expand Down
4 changes: 2 additions & 2 deletions zou/app/services/names_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def get_full_entity_name(entity_id):
asset_type = entities_service.get_entity_type(entity["entity_type_id"])
episode_id = entity["source_id"]
name = "%s / %s" % (asset_type["name"], entity["name"])
return (name, episode_id)
return (name, episode_id, entity["preview_file_id"])


def get_preview_file_name(preview_file_id):
Expand All @@ -66,7 +66,7 @@ def get_preview_file_name(preview_file_id):
task = tasks_service.get_task(preview_file["task_id"])
task_type = tasks_service.get_task_type(task["task_type_id"])
project = projects_service.get_project(task["project_id"])
(entity_name, _) = get_full_entity_name(task["entity_id"])
(entity_name, _, _) = get_full_entity_name(task["entity_id"])

if (
organisation["use_original_file_name"]
Expand Down
66 changes: 56 additions & 10 deletions zou/app/services/user_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from zou.app.models.person import Person
from zou.app.models.project import Project
from zou.app.models.project_status import ProjectStatus
from zou.app.models.subscription import Subscription
from zou.app.models.search_filter import SearchFilter
from zou.app.models.search_filter_group import SearchFilterGroup
from zou.app.models.task import Task
Expand Down Expand Up @@ -962,6 +963,9 @@ def update_filter(search_filter_id, data):
search_filter = SearchFilter.get_by(
id=search_filter_id, person_id=current_user["id"]
)
if current_user["role"] == "admin" and search_filter is None:
search_filter = SearchFilter.get_by(id=search_filter_id)

if search_filter is None:
raise SearchFilterNotFoundException

Expand Down Expand Up @@ -1182,6 +1186,18 @@ def get_notification(notification_id):
return notifications[0]


def update_notification(notification_id, read):
"""
Update read status of given notification.
"""
current_user = persons_service.get_current_user()
notification = Notification.get_by(
id=notification_id, person_id=current_user["id"]
)
notification.update({"read": read})
return notification.serialize()


def get_unread_notifications_count(notification_id=None):
"""
Return the number of unread notifications.
Expand All @@ -1192,13 +1208,17 @@ def get_unread_notifications_count(notification_id=None):
).count()


from sqlalchemy import and_, func

def get_last_notifications(
notification_id=None,
after=None,
before=None,
task_type_id=None,
task_status_id=None,
notification_type=None,
read=None,
watching=None,
):
"""
Return last 100 user notifications.
Expand All @@ -1213,6 +1233,12 @@ def get_last_notifications(
.join(Author, Author.id == Notification.author_id)
.join(Task, Task.id == Notification.task_id)
.join(Project, Project.id == Task.project_id)
.outerjoin(Subscription,
and_(
Subscription.task_id == Task.id,
Subscription.person_id == current_user["id"]
)
)
.outerjoin(Comment, Comment.id == Notification.comment_id)
.add_columns(
Project.id,
Expand All @@ -1223,6 +1249,7 @@ def get_last_notifications(
Comment.text,
Comment.replies,
Task.entity_id,
Subscription.id,
Author.role,
)
)
Expand Down Expand Up @@ -1251,6 +1278,16 @@ def get_last_notifications(
if notification_type is not None:
query = query.filter(Notification.type == notification_type)

if read is not None:
query = query.filter(Notification.read == read)

if watching is not None:
print(watching)
if watching:
query = query.filter(Subscription.id != None)
else:
query = query.filter(Subscription.id == None)

notifications = query.limit(100).all()

for (
Expand All @@ -1263,11 +1300,14 @@ def get_last_notifications(
comment_text,
comment_replies,
task_entity_id,
subscription_id,
role,
) in notifications:
(full_entity_name, episode_id) = names_service.get_full_entity_name(
task_entity_id
)
(
full_entity_name,
episode_id,
entity_preview_file_id
) = names_service.get_full_entity_name(task_entity_id)
preview_file_id = None
mentions = []
department_mentions = []
Expand Down Expand Up @@ -1326,6 +1366,8 @@ def get_last_notifications(
"change": notification.change,
"full_entity_name": full_entity_name,
"episode_id": episode_id,
"entity_preview_file_id": entity_preview_file_id,
"subscription_id": subscription_id,
}
)
)
Expand All @@ -1338,17 +1380,21 @@ def mark_notifications_as_read():
Mark all recent notifications for current_user as read. It is useful
to mark a list of notifications as read after an user retrieved them.
"""
from sqlalchemy import update
from zou.app import db

current_user = persons_service.get_current_user()
notifications = (
Notification.query.filter_by(person_id=current_user["id"], read=False)
.order_by(Notification.created_at)
.all()
update_stmt = (
update(Notification)
.where(Notification.person_id == current_user["id"])
.where(Notification.read == False)
.values(read=True)
)

for notification in notifications:
notification.update({"read": True})
db.session.execute(update_stmt)
db.session.commit()

return fields.serialize_list(notifications)
return True


def has_task_subscription(task_id):
Expand Down

0 comments on commit 9e96c63

Please sign in to comment.