Skip to content

Commit 392535e

Browse files
authored
Merge pull request #11533 from Ostap-Zherebetskyi/hotfix/populate_subscriptions_script
[ENG-10019] Add populate_subscriptions script to set default subscriptions
2 parents 137f248 + 06c8340 commit 392535e

File tree

2 files changed

+113
-0
lines changed

2 files changed

+113
-0
lines changed
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
import django
2+
django.setup()
3+
4+
from website.app import init_app
5+
init_app(routes=False)
6+
7+
from framework.celery_tasks import app as celery_app
8+
from django.contrib.contenttypes.models import ContentType
9+
from django.db.models import Count, F, OuterRef, Subquery, IntegerField, CharField
10+
from django.db.models.functions import Cast
11+
from osf.models import OSFUser, Node, NotificationSubscription, NotificationType
12+
13+
14+
@celery_app.task(name='scripts.populate_notification_subscriptions')
15+
def populate_notification_subscriptions():
16+
created = 0
17+
user_file_nt = NotificationType.Type.USER_FILE_UPDATED.instance
18+
review_nt = NotificationType.Type.REVIEWS_SUBMISSION_STATUS.instance
19+
node_file_nt = NotificationType.Type.NODE_FILE_UPDATED.instance
20+
21+
user_ct = ContentType.objects.get_for_model(OSFUser)
22+
node_ct = ContentType.objects.get_for_model(Node)
23+
24+
reviews_qs = OSFUser.objects.exclude(subscriptions__notification_type__name=NotificationType.Type.REVIEWS_SUBMISSION_STATUS).distinct('id')
25+
files_qs = OSFUser.objects.exclude(subscriptions__notification_type__name=NotificationType.Type.USER_FILE_UPDATED).distinct('id')
26+
27+
node_notifications_sq = (
28+
NotificationSubscription.objects.filter(
29+
content_type=node_ct,
30+
notification_type=node_file_nt,
31+
object_id=Cast(OuterRef('pk'), CharField()),
32+
).values(
33+
'object_id'
34+
).annotate(
35+
cnt=Count('id')
36+
).values('cnt')[:1]
37+
)
38+
39+
nodes_qs = (
40+
Node.objects
41+
.annotate(
42+
contributors_count=Count('_contributors', distinct=True),
43+
notifications_count=Subquery(
44+
node_notifications_sq,
45+
output_field=IntegerField(),
46+
),
47+
).exclude(contributors_count=F('notifications_count'))
48+
)
49+
50+
print(f"Creating REVIEWS_SUBMISSION_STATUS subscriptions for {reviews_qs.count()} users.")
51+
for id, user in enumerate(reviews_qs, 1):
52+
print(f"Processing user {id} / {reviews_qs.count()}")
53+
try:
54+
_, is_created = NotificationSubscription.objects.get_or_create(
55+
notification_type=review_nt,
56+
user=user,
57+
content_type=user_ct,
58+
object_id=user.id,
59+
defaults={
60+
'message_frequency': 'none',
61+
},
62+
)
63+
if is_created:
64+
created += 1
65+
except Exception as exeption:
66+
print(exeption)
67+
continue
68+
69+
print(f"Creating USER_FILE_UPDATED subscriptions for {files_qs.count()} users.")
70+
for id, user in enumerate(files_qs, 1):
71+
print(f"Processing user {id} / {files_qs.count()}")
72+
try:
73+
_, is_created = NotificationSubscription.objects.get_or_create(
74+
notification_type=user_file_nt,
75+
user=user,
76+
content_type=user_ct,
77+
object_id=user.id,
78+
defaults={
79+
'message_frequency': 'none',
80+
},
81+
)
82+
if is_created:
83+
created += 1
84+
except Exception as exeption:
85+
print(exeption)
86+
continue
87+
88+
print(f"Creating NODE_FILE_UPDATED subscriptions for {nodes_qs.count()} nodes.")
89+
for id, node in enumerate(nodes_qs, 1):
90+
print(f"Processing node {id} / {nodes_qs.count()}")
91+
for contributor in node.contributors.all():
92+
try:
93+
_, is_created = NotificationSubscription.objects.get_or_create(
94+
notification_type=node_file_nt,
95+
user=contributor,
96+
content_type=node_ct,
97+
object_id=node.id,
98+
defaults={
99+
'message_frequency': 'none',
100+
},
101+
)
102+
if is_created:
103+
created += 1
104+
except Exception as exeption:
105+
print(exeption)
106+
continue
107+
108+
print(f"Created {created} subscriptions")
109+
110+
if __name__ == '__main__':
111+
populate_notification_subscriptions.delay()

website/settings/defaults.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,7 @@ class CeleryConfig:
450450
'osf.management.commands.monthly_reporters_go',
451451
'osf.management.commands.ingest_cedar_metadata_templates',
452452
'osf.metrics.reporters',
453+
'scripts.populate_notification_subscriptions',
453454
}
454455

455456
med_pri_modules = {
@@ -578,6 +579,7 @@ class CeleryConfig:
578579
'osf.management.commands.monthly_reporters_go',
579580
'osf.external.spam.tasks',
580581
'api.share.utils',
582+
'scripts.populate_notification_subscriptions',
581583
)
582584

583585
# Modules that need metrics and release requirements

0 commit comments

Comments
 (0)