From e5a7fe12a61592e6dbd4691ba9c93bef2462a39d Mon Sep 17 00:00:00 2001 From: gzbender Date: Wed, 10 Oct 2018 14:16:20 +0500 Subject: [PATCH 1/4] =?UTF-8?q?LIL-694=20=D0=98=D0=BD=D1=82=D0=B5=D0=B3?= =?UTF-8?q?=D1=80=D0=B0=D1=86=D0=B8=D1=8F=20SendGrid?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/notification/tasks.py | 33 ++++++++++++++++++++++++++++++++- project/utils.py | 17 ----------------- 2 files changed, 32 insertions(+), 18 deletions(-) delete mode 100644 project/utils.py diff --git a/apps/notification/tasks.py b/apps/notification/tasks.py index 642a0d7b..dddd8e6d 100644 --- a/apps/notification/tasks.py +++ b/apps/notification/tasks.py @@ -1,13 +1,16 @@ from datetime import datetime from django.contrib.auth import get_user_model +from django.contrib.contenttypes.models import ContentType from django.contrib.staticfiles.storage import staticfiles_storage from django.utils.timezone import now +from django.db.models import Max from apps.notification.models import UserNotification from apps.notification.utils import send_email -from apps.payment.models import SchoolPayment +from apps.payment.models import SchoolPayment, CoursePayment, Payment from project.celery import app +from project.utils.db import format_sql, execute_sql User = get_user_model() @@ -58,3 +61,31 @@ def send_certificates(email=None, date=None, dry_run=False): file.close() un.certificate_last_email = now() un.save() + + +@app.task +def sendgrid(): + ct_course = ContentType.objects.get_for_model(CoursePayment).id + ct_school = ContentType.objects.get_for_model(SchoolPayment).id + course_payments_sql = ''' + select {p.user}, max({p.created_at}) from {p} where {p}.polymorphic_ctype_id = {ct} group by {p.user} + ''' + course_payments = {p[0]: p[1] for p in execute_sql(format_sql(course_payments_sql, p=Payment, ct=ct_course))} + + school_payments_sql = ''' + select {p.user}, max({p.created_at}) from {p} where {p}.polymorphic_ctype_id = {ct} group by {p.user} + ''' + school_payments = {p[0]: p[1] for p in execute_sql(format_sql(school_payments_sql, p=Payment, ct=ct_school))} + users = list(User.objects.filter(role=User.USER_ROLE)) + data = [] + for user in users: + data.append({ + 'name': user.get_full_name(), + 'email': user.email, + 'last_login': user.last_login, + 'last_course_purchase': course_payments.get(user.id), + 'last_school_purchase': school_payments.get(user.id), + 'gender': user.gender, + 'birthday': user.birthday, + }) + print(data) diff --git a/project/utils.py b/project/utils.py deleted file mode 100644 index 23234b58..00000000 --- a/project/utils.py +++ /dev/null @@ -1,17 +0,0 @@ -from datetime import datetime, timedelta -from collections import Counter - - -def date_range(start, end): - if isinstance(start, datetime): - start = start.date() - if isinstance(end, datetime): - end = end.date() - delta = end - start - for d in range(delta.days + 1): - yield start + timedelta(days=d) - return - - -def weekdays_in_date_range(start, end): - return Counter([d.isoweekday() for d in date_range(start, end)]) From b07e841419b515db9739b6b6b5705a60be3ef491 Mon Sep 17 00:00:00 2001 From: gzbender Date: Thu, 11 Oct 2018 01:42:11 +0500 Subject: [PATCH 2/4] LIL-694 --- apps/notification/tasks.py | 22 ++++++++++++++------- project/sengrid.py | 7 +++++++ project/settings.py | 6 ++++++ project/utils/__init__.py | 17 +++++++++++++++++ project/utils/db.py | 39 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 84 insertions(+), 7 deletions(-) create mode 100644 project/sengrid.py create mode 100644 project/utils/__init__.py create mode 100644 project/utils/db.py diff --git a/apps/notification/tasks.py b/apps/notification/tasks.py index dddd8e6d..5f6b37a4 100644 --- a/apps/notification/tasks.py +++ b/apps/notification/tasks.py @@ -11,6 +11,7 @@ from apps.notification.utils import send_email from apps.payment.models import SchoolPayment, CoursePayment, Payment from project.celery import app from project.utils.db import format_sql, execute_sql +from project.sengrid import get_sendgrid_client User = get_user_model() @@ -64,7 +65,8 @@ def send_certificates(email=None, date=None, dry_run=False): @app.task -def sendgrid(): +def sendgrid_update_recipients(): + date_format = '%m/%d/%Y' ct_course = ContentType.objects.get_for_model(CoursePayment).id ct_school = ContentType.objects.get_for_model(SchoolPayment).id course_payments_sql = ''' @@ -79,13 +81,19 @@ def sendgrid(): users = list(User.objects.filter(role=User.USER_ROLE)) data = [] for user in users: + last_course_purchase = course_payments.get(user.id) and course_payments.get(user.id).strftime(date_format) + last_school_purchase = school_payments.get(user.id) and school_payments.get(user.id).strftime(date_format) data.append({ + 'first_name': user.first_name, + 'last_name': user.last_name, 'name': user.get_full_name(), 'email': user.email, - 'last_login': user.last_login, - 'last_course_purchase': course_payments.get(user.id), - 'last_school_purchase': school_payments.get(user.id), - 'gender': user.gender, - 'birthday': user.birthday, + 'last_login': user.last_login and user.last_login.strftime(date_format), + 'last_course_purchase': last_course_purchase, + 'last_school_purchase': last_school_purchase, + 'gender': {User.NOT_DEFINED: '', User.MALE: 'Мужчина', User.FEMALE: 'Женщина'}[user.gender], + 'birthday': user.birthday and user.birthday.strftime(date_format), }) - print(data) + + sg = get_sendgrid_client() + response = sg.client.contactdb.recipients.patch(request_body=data) diff --git a/project/sengrid.py b/project/sengrid.py new file mode 100644 index 00000000..dfcd4ae2 --- /dev/null +++ b/project/sengrid.py @@ -0,0 +1,7 @@ +import sendgrid + +from django.conf import settings + + +def get_sendgrid_client(): + return sendgrid.SendGridAPIClient(apikey=settings.SENDGRID_API_KEY) diff --git a/project/settings.py b/project/settings.py index 7f69b992..e92ac41b 100644 --- a/project/settings.py +++ b/project/settings.py @@ -191,6 +191,7 @@ ANYMAIL = { EMAIL_BACKEND = 'anymail.backends.mailgun.EmailBackend' DEFAULT_FROM_EMAIL = os.getenv('DEFAULT_FROM_EMAIL', 'postmaster@mail.9ev.ru') +SENDGRID_API_KEY = os.getenv('SENDGRID_API_KEY') # SMS # https://github.com/twilio/twilio-python @@ -254,6 +255,11 @@ CELERY_BEAT_SCHEDULE = { 'schedule': crontab(hour=19), 'args': (), }, + 'sendgrid_update_recipients': { + 'task': 'apps.notification.tasks.sendgrid_update_recipients', + 'schedule': crontab(minute=0, hour=3), + 'args': (), + }, } try: diff --git a/project/utils/__init__.py b/project/utils/__init__.py new file mode 100644 index 00000000..23234b58 --- /dev/null +++ b/project/utils/__init__.py @@ -0,0 +1,17 @@ +from datetime import datetime, timedelta +from collections import Counter + + +def date_range(start, end): + if isinstance(start, datetime): + start = start.date() + if isinstance(end, datetime): + end = end.date() + delta = end - start + for d in range(delta.days + 1): + yield start + timedelta(days=d) + return + + +def weekdays_in_date_range(start, end): + return Counter([d.isoweekday() for d in date_range(start, end)]) diff --git a/project/utils/db.py b/project/utils/db.py new file mode 100644 index 00000000..4a31f79a --- /dev/null +++ b/project/utils/db.py @@ -0,0 +1,39 @@ +from django.db.models.base import ModelBase +from django.db import connection + + +class ModelFieldsNames(object): + def __init__(self, model): + self.alias = None + self._meta = model._meta + + def __getattr__(self, name): + alias = '__as__' + if name.startswith(alias): + self.alias = name[len(alias):] + return '%s as %s' % (self._meta.db_table, self.alias) + field = self._meta.get_field(name).get_attname_column()[1] + if self.alias: + return u"%s.%s" % (self.alias, field) + else: + return u"%s.%s" % (self._meta.db_table, field) + + def __str__(self): + return '%s' % self._meta.db_table + + +def format_sql(sql, **kwargs): + for name, value in kwargs.items(): + if issubclass(type(value), ModelBase): + kwargs[name] = ModelFieldsNames(value) + elif isinstance(value, (tuple, list)): + kwargs[name] = ','.join(map(lambda x: repr(x) if isinstance(x, str) else str(x), value)) + elif not isinstance(value, str): + kwargs[name] = value + return sql.format(**kwargs) + + +def execute_sql(sql, args=()): + cursor = connection.cursor() + cursor.execute(sql, args) + return cursor.fetchall() From bc71eeb908f7e11f249fdb731512852756451d6a Mon Sep 17 00:00:00 2001 From: gzbender Date: Thu, 11 Oct 2018 15:41:02 +0500 Subject: [PATCH 3/4] LIL-694 --- apps/notification/tasks.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/notification/tasks.py b/apps/notification/tasks.py index 5f6b37a4..00d05710 100644 --- a/apps/notification/tasks.py +++ b/apps/notification/tasks.py @@ -93,7 +93,9 @@ def sendgrid_update_recipients(): 'last_school_purchase': last_school_purchase, 'gender': {User.NOT_DEFINED: '', User.MALE: 'Мужчина', User.FEMALE: 'Женщина'}[user.gender], 'birthday': user.birthday and user.birthday.strftime(date_format), + 'date_joined': user.date_joined.strftime(date_format), }) sg = get_sendgrid_client() response = sg.client.contactdb.recipients.patch(request_body=data) + print(response.body) From 8f31a1466824081f10389896ce6a472989a50f40 Mon Sep 17 00:00:00 2001 From: gzbender Date: Thu, 11 Oct 2018 15:41:52 +0500 Subject: [PATCH 4/4] LIL-694 --- apps/notification/tasks.py | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/notification/tasks.py b/apps/notification/tasks.py index 00d05710..58e8cb9b 100644 --- a/apps/notification/tasks.py +++ b/apps/notification/tasks.py @@ -86,7 +86,6 @@ def sendgrid_update_recipients(): data.append({ 'first_name': user.first_name, 'last_name': user.last_name, - 'name': user.get_full_name(), 'email': user.email, 'last_login': user.last_login and user.last_login.strftime(date_format), 'last_course_purchase': last_course_purchase,