From 97a6d4666a55433ad3ef5418441ba13103767fb3 Mon Sep 17 00:00:00 2001 From: RitwickRaj78 Date: Sun, 19 Jul 2020 00:06:43 +0530 Subject: [PATCH] feat: Scheduler and Jobs Added --- requirements/prod.txt | 3 +- systers_portal/meetup/signals.py | 25 ++++++- systers_portal/meetup/utils.py | 62 ++++++++++++++++++ .../systers_portal/settings/base.py | 9 +++ systers_portal/systers_portal/settings/dev.py | 2 + .../systers_portal/settings/testing.py | 1 + .../community/weekly_digest_email.html | 16 +++++ .../meetup/location_change_email.html | 15 +++++ systers_portal/templates/meetup/reminder.html | 15 +++++ .../templates/meetup/time_change_email.html | 15 +++++ systers_portal/users/apps.py | 4 ++ systers_portal/users/scheduler.py | 53 +++++++++++++++ workdir.0 | Bin 0 -> 1058 bytes 13 files changed, 218 insertions(+), 2 deletions(-) create mode 100644 systers_portal/templates/community/weekly_digest_email.html create mode 100644 systers_portal/templates/meetup/location_change_email.html create mode 100644 systers_portal/templates/meetup/reminder.html create mode 100644 systers_portal/templates/meetup/time_change_email.html create mode 100644 systers_portal/users/scheduler.py create mode 100644 workdir.0 diff --git a/requirements/prod.txt b/requirements/prod.txt index 4df0b737..990e17b3 100644 --- a/requirements/prod.txt +++ b/requirements/prod.txt @@ -10,4 +10,5 @@ django-imagekit==4.0.2 psycopg2==2.8.5 python3-openid==3.2.0 geoip2==4.0.1 -django-ipware==3.0.0 \ No newline at end of file +django-ipware==3.0.0 +django-apscheduler==0.3.1 diff --git a/systers_portal/meetup/signals.py b/systers_portal/meetup/signals.py index 28654f67..66386af1 100644 --- a/systers_portal/meetup/signals.py +++ b/systers_portal/meetup/signals.py @@ -1,4 +1,6 @@ -from django.db.models.signals import post_save, post_delete, post_migrate +from datetime import datetime, timedelta + +from django.db.models.signals import post_save, post_delete, post_migrate, pre_save from django.dispatch import receiver from pinax.notifications.models import NoticeType @@ -6,6 +8,9 @@ from meetup.constants import COMMUNITY_LEADER from meetup.utils import (create_groups, assign_permissions, remove_groups) +from users.scheduler import scheduler +from meetup.utils import notify_location, notify_time + @receiver(post_save, sender=Meetup, dispatch_uid="manage_groups") def manage_meetup_groups(sender, instance, created, **kwargs): @@ -37,3 +42,21 @@ def create_notice_types(sender, **kwargs): ("your support request has been approved")) NoticeType.create("new_meetup_request", ("New Meetup Request"), ("a user has added a meetup request")) + + +@receiver(pre_save, sender=Meetup, dispatch_uid="location_change") +def notify_change(sender, instance, **kwargs): + obj = Meetup.objects.filter(pk=instance.pk) + if obj: + if obj[0].date != instance.date or obj[0].time != instance.time: + name = "Time for {0} Change Notify".format(instance.title) + scheduler.add_job(notify_time, "date", + run_date=datetime.now() + timedelta(minutes=5), + args=[instance], + id=name, replace_existing=True) + if obj[0].meetup_location != instance.meetup_location: + name = "Location for {0} Change Notify".format(instance.title) + scheduler.add_job(notify_location, "date", + run_date=datetime.now() + timedelta(minutes=5), + args=[instance], + id=name, replace_existing=True) diff --git a/systers_portal/meetup/utils.py b/systers_portal/meetup/utils.py index 98279ce6..a371eeff 100644 --- a/systers_portal/meetup/utils.py +++ b/systers_portal/meetup/utils.py @@ -1,8 +1,16 @@ from django.contrib.auth.models import Group, Permission +from django.core.mail import send_mail from django.db import transaction +from django.template.loader import render_to_string from meetup.permissions import groups_templates, group_permissions +from meetup.models import Rsvp + +from users.models import UserSetting + +from systers_portal.settings.dev import FROM_EMAIL + @transaction.atomic def create_groups(meetup): @@ -48,3 +56,57 @@ def assign_permissions(meetup, groups): for perm in group_permissions[key]: group.permissions.add(Permission.objects.filter(codename=perm).first()) group.save() + + +def send_reminder(meetup): + rsvp_list = Rsvp.objects.filter(meetup=meetup) + subject = "Reminder for {0}".format(meetup) + for rsvp in rsvp_list: + setting = UserSetting.objects.get(user=rsvp.user) + if setting.reminder: + html_text = render_to_string("templates/meetup/reminder.html", + context={'meetup': meetup, + 'user': rsvp.user}) + send_mail( + subject, + 'Reminder Mail', + FROM_EMAIL, + [rsvp.user.user.email], + html_message=html_text, + ) + + +def notify_location(meetup): + rsvp_list = Rsvp.objects.filter(meetup=meetup) + subject = "Notification for change in location for {0}".format(meetup) + for rsvp in rsvp_list: + setting = UserSetting.objects.get(user=rsvp.user) + if setting.location_change: + html_text = render_to_string("templates/meetup/location_change_email.html", + context={'meetup': meetup, + 'user': rsvp.user}) + send_mail( + subject, + 'Change in Location', + FROM_EMAIL, + [rsvp.user.user.email], + html_message=html_text, + ) + + +def notify_time(meetup): + rsvp_list = Rsvp.objects.filter(meetup=meetup) + subject = "Notification for change in location for {0}".format(meetup) + for rsvp in rsvp_list: + setting = UserSetting.objects.get(user=rsvp.user) + if setting.time_change: + html_text = render_to_string("templates/meetup/time_change_email.html", + context={'meetup': meetup, + 'user': rsvp.user}) + send_mail( + subject, + 'Time Changed', + FROM_EMAIL, + [rsvp.user.user.email], + html_message=html_text, + ) diff --git a/systers_portal/systers_portal/settings/base.py b/systers_portal/systers_portal/settings/base.py index 203df2af..eb7516b7 100644 --- a/systers_portal/systers_portal/settings/base.py +++ b/systers_portal/systers_portal/settings/base.py @@ -55,8 +55,17 @@ 'users', 'rest_framework', 'pinax.notifications', + 'django_apscheduler', ) +SCHEDULER_CONFIG = { + "apscheduler.jobstores.default": { + "class": "django_apscheduler.jobstores:DjangoJobStore" + }, + 'apscheduler.executors.processpool': { + "type": "threadpool" + }, +} MIDDLEWARE = [ 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', diff --git a/systers_portal/systers_portal/settings/dev.py b/systers_portal/systers_portal/settings/dev.py index f41408fe..32dc98aa 100644 --- a/systers_portal/systers_portal/settings/dev.py +++ b/systers_portal/systers_portal/settings/dev.py @@ -1,5 +1,6 @@ from .base import * +SCHEDULER_AUTOSTART = True DEBUG = True TEMPLATES[0]['OPTIONS']['debug'] = DEBUG @@ -21,3 +22,4 @@ EMAIL_HOST = 'localhost' EMAIL_PORT = 25 EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' +FROM_EMAIL = os.environ.get('FROM_EMAIL') diff --git a/systers_portal/systers_portal/settings/testing.py b/systers_portal/systers_portal/settings/testing.py index a7071c71..399d3f80 100644 --- a/systers_portal/systers_portal/settings/testing.py +++ b/systers_portal/systers_portal/settings/testing.py @@ -1,5 +1,6 @@ from .base import * +SCHEDULER_AUTOSTART = False DEBUG = True TEMPLATES[0]['OPTIONS']['debug'] = DEBUG diff --git a/systers_portal/templates/community/weekly_digest_email.html b/systers_portal/templates/community/weekly_digest_email.html new file mode 100644 index 00000000..b3ef4d46 --- /dev/null +++ b/systers_portal/templates/community/weekly_digest_email.html @@ -0,0 +1,16 @@ + + + + + + + + + Hey {{user}}, We have details for {{community}} for you. + We have {{count}} members as of now!. Get the latest news and resources available at the community + by checking out the Systers Portal.
+Thank You,
+AnitaB.org + + diff --git a/systers_portal/templates/meetup/location_change_email.html b/systers_portal/templates/meetup/location_change_email.html new file mode 100644 index 00000000..b6b3272f --- /dev/null +++ b/systers_portal/templates/meetup/location_change_email.html @@ -0,0 +1,15 @@ + + + + + + + + + Hello {{user}},
+

This is to inform you that the location for {{meetup}} has been changed to {{meetup.meetup_location}}

+Thank You,
+AnitaB.org + + diff --git a/systers_portal/templates/meetup/reminder.html b/systers_portal/templates/meetup/reminder.html new file mode 100644 index 00000000..f8563a81 --- /dev/null +++ b/systers_portal/templates/meetup/reminder.html @@ -0,0 +1,15 @@ + + + + + + + + + Hello {{user}},
+

This is a gentle reminder for {{meetup}} which will begin on {{meetup.date}} {%if meetup.time%} at {{meetup.time}} {% endif %}

+Thank You,
+AnitaB.org + + diff --git a/systers_portal/templates/meetup/time_change_email.html b/systers_portal/templates/meetup/time_change_email.html new file mode 100644 index 00000000..acf3aa1b --- /dev/null +++ b/systers_portal/templates/meetup/time_change_email.html @@ -0,0 +1,15 @@ + + + + + + + + + Hello {{user}},
+

This is to inform you that the timing for {{meetup}} has been changed to {{meetup.date}} {%if meetup.time%} {{meetup.time}} {% endif %}

+Thank You,
+AnitaB.org + + diff --git a/systers_portal/users/apps.py b/systers_portal/users/apps.py index e2b7a889..fafa9f37 100644 --- a/systers_portal/users/apps.py +++ b/systers_portal/users/apps.py @@ -1,4 +1,5 @@ from django.apps import AppConfig +from django.conf import settings class UsersConfig(AppConfig): @@ -6,3 +7,6 @@ class UsersConfig(AppConfig): def ready(self): import users.signals # noqa # pylint: disable=unused-variable + from . import scheduler + if settings.SCHEDULER_AUTOSTART: + scheduler.start() diff --git a/systers_portal/users/scheduler.py b/systers_portal/users/scheduler.py new file mode 100644 index 00000000..75c930b8 --- /dev/null +++ b/systers_portal/users/scheduler.py @@ -0,0 +1,53 @@ +import datetime +import logging +from datetime import timedelta + +from apscheduler.schedulers.background import BackgroundScheduler +from django.core.mail import send_mail +from django.template.loader import render_to_string +from django_apscheduler.jobstores import register_events, register_job + +from django.conf import settings + +from meetup.utils import send_reminder +from meetup.models import Meetup + +from community.models import Community + +from systers_portal.settings.dev import FROM_EMAIL + +scheduler = BackgroundScheduler(settings.SCHEDULER_CONFIG) + + +@register_job(scheduler, 'cron', day_of_week='mon', hour=5, minute=30, replace_existing=True) +def weekly_digest(): + communities = Community.objects.all() + for community in communities: + subject = "Weekly update from {0}".format(community) + count = community.members.count() + for member in community.members: + html_text = \ + render_to_string("templates/community/weekly_digest_email.html", + {'user': member, + 'count': count, + 'community': community}) + send_mail( + subject, + 'Weekly Digest', + FROM_EMAIL, + [member.user.email], + html_message=html_text, + ) + + +def start(): + if settings.DEBUG: + logging.basicConfig() + logging.getLogger('apscheduler').setLevel(logging.DEBUG) + register_events(scheduler) + scheduler.start() + meetup_list = Meetup.objects.filter(date__gte=datetime.date.today()) + for meetup in meetup_list: + name = "Reminder for {0}".format(meetup.title) + scheduler.add_job(send_reminder, "date", run_date=meetup.date - timedelta(hours=1), + args=[meetup], id=name, replace_existing=True) diff --git a/workdir.0 b/workdir.0 new file mode 100644 index 0000000000000000000000000000000000000000..be09a8000a7a2ef31965f338483190d5e38596b4 GIT binary patch literal 1058 zcmbW0NpI6Y6o8ZNb@zRTvZoYWTFTz0aK&nb+>0-fWsis2B6jjTeRea4E_+3*`ME})-by6BmeW3GouNd`_FJ5|k&IV(p( z#tD-e3^Z10k=L-oppiL%A!f6($C=Q0M2ZH(Ru+A`FrpGEIWmZrVe}BjOc<}hgb9;5 zBWuhbz|@&TPgX0qZ`x|1oK|7x_^1Z6Cd}oGR^@9AE))ud=YQ~1!pKOt=pOsS);{i_ zXtc8xX+x-E)B>uIj)K~+Aw5Vh(uedT&GiGQ4_q-#D_e%*u{RC)UWA>x#Kb`z7nQ-TkM&RK z=lYL)bND&<;#_Z7(l6;rdXoR&pug_E-vLsY@kTLDV0P+J(ua%^h5f7yc(%ZJW+X5aJ;mO&IdPf4*im-0c&9LoY8y_h51mugb dVbO`(bomo}hCAFA&JHh?9W*~J!n4HHPXX)4U|9eF literal 0 HcmV?d00001