Coverage for chalicelib/core/notifications.py: 56%
50 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-10 12:56 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-10 12:56 +0000
1import json
3from cachetools import TTLCache, cached
5from chalicelib.utils import pg_client, helper
6from chalicelib.utils.TimeUTC import TimeUTC
9def get_all(tenant_id, user_id):
10 with pg_client.PostgresClient() as cur:
11 cur.execute(
12 cur.mogrify(""" \
13 SELECT notifications.*,
14 user_viewed_notifications.notification_id NOTNULL AS viewed
15 FROM public.notifications
16 LEFT JOIN (SELECT notification_id
17 FROM public.user_viewed_notifications
18 WHERE user_viewed_notifications.user_id = %(user_id)s) AS user_viewed_notifications
19 USING (notification_id)
20 WHERE notifications.user_id IS NULL
21 OR notifications.user_id = %(user_id)s
22 ORDER BY created_at DESC LIMIT 100;""",
23 {"user_id": user_id})
24 )
25 rows = helper.list_to_camel_case(cur.fetchall())
26 for r in rows: 26 ↛ 27line 26 didn't jump to line 27 because the loop on line 26 never started
27 r["createdAt"] = TimeUTC.datetime_to_timestamp(r["createdAt"])
28 return rows
31cache = TTLCache(maxsize=1000, ttl=600)
34@cached(cache)
35def get_all_count(tenant_id, user_id):
36 with pg_client.PostgresClient() as cur:
37 cur.execute(
38 cur.mogrify(""" \
39 SELECT COALESCE(COUNT(notifications.*), 0) AS count
40 FROM public.notifications
41 LEFT JOIN (SELECT notification_id
42 FROM public.user_viewed_notifications
43 WHERE user_viewed_notifications.user_id = %(user_id)s) AS user_viewed_notifications USING (notification_id)
44 WHERE (notifications.user_id IS NULL
45 OR notifications.user_id =%(user_id)s)
46 AND user_viewed_notifications.notification_id IS NULL;""",
47 {"user_id": user_id})
48 )
49 row = cur.fetchone()
50 return row
53def view_notification(user_id, notification_ids=[], tenant_id=None, startTimestamp=None, endTimestamp=None):
54 if len(notification_ids) == 0 and endTimestamp is None:
55 return False
56 if startTimestamp is None:
57 startTimestamp = 0
58 notification_ids = [(user_id, id) for id in notification_ids]
59 with pg_client.PostgresClient() as cur:
60 if len(notification_ids) > 0:
61 cur.executemany(
62 "INSERT INTO public.user_viewed_notifications(user_id, notification_id) VALUES (%s,%s) ON CONFLICT DO NOTHING;",
63 notification_ids)
64 else:
65 query = """INSERT INTO public.user_viewed_notifications(user_id, notification_id)
66 SELECT %(user_id)s AS user_id, notification_id
67 FROM public.notifications
68 WHERE (user_id IS NULL OR user_id = %(user_id)s)
69 AND EXTRACT(EPOCH FROM created_at) * 1000 >= (%(startTimestamp)s)
70 AND EXTRACT(EPOCH FROM created_at) * 1000 <= (%(endTimestamp)s + 1000) ON CONFLICT DO NOTHING;"""
71 params = {"user_id": user_id, "startTimestamp": startTimestamp,
72 "endTimestamp": endTimestamp}
73 # print('-------------------')
74 # print(cur.mogrify(query, params))
75 cur.execute(cur.mogrify(query, params))
76 return True
79def create(notifications):
80 if len(notifications) == 0:
81 return []
82 with pg_client.PostgresClient() as cur:
83 values = []
84 for n in notifications:
85 clone = dict(n)
86 if "userId" not in clone:
87 clone["userId"] = None
88 if "options" not in clone:
89 clone["options"] = '{}'
90 else:
91 clone["options"] = json.dumps(clone["options"])
92 values.append(
93 cur.mogrify(
94 "(%(userId)s, %(title)s, %(description)s, %(buttonText)s, %(buttonUrl)s, %(imageUrl)s,%(options)s)",
95 clone).decode('UTF-8')
96 )
97 cur.execute(
98 f"""INSERT INTO public.notifications(user_id, title, description, button_text, button_url, image_url, options)
99 VALUES {",".join(values)} RETURNING *;""")
100 rows = helper.list_to_camel_case(cur.fetchall())
101 for r in rows:
102 r["createdAt"] = TimeUTC.datetime_to_timestamp(r["createdAt"])
103 r["viewed"] = False
104 return rows