import os from datetime import datetime, date, timedelta from PIL import Image from PIL import ImageFont from PIL import ImageDraw from unidecode import unidecode 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.conf import settings from django.utils.text import slugify from apps.notification.models import UserNotification from apps.notification.utils import send_email from apps.payment.models import SchoolPayment, CoursePayment, Payment, UserGiftCertificate, UserBonus, DrawingCampPayment from project.celery import app from project.utils.db import format_sql, execute_sql from project.sengrid import get_sendgrid_client from apps.user.models import Child User = get_user_model() def draw_cert(path, email, first_name, last_name, x=None, y=900, color=(29, 115, 224), font_size=170, fn_prefix=''): img = Image.open(path) draw = ImageDraw.Draw(img) font = ImageFont.truetype(os.path.join(settings.STATIC_ROOT, 'ProximaNova-Reg.otf'), font_size) text = first_name.capitalize() if last_name: text += ' ' + last_name.capitalize() w, h = draw.textsize(text, font=font) _x = (img.width - w) // 2 if x is None else x draw.text((_x, y), text, color, font=font) fn = os.path.join(settings.MEDIA_ROOT, 'tmp') try: os.mkdir(fn) except: pass if first_name: name = '-'.join(filter(None, [first_name, last_name])) fn = os.path.join(fn, '%scertificate-for-%s-%s.jpg' % (fn_prefix, email, slugify(unidecode(name)))) else: fn = os.path.join(fn, '%scertificate-for-%s.jpg' % (fn_prefix, email)) img.save(fn) img.close() return fn @app.task def send_certificates(email=None, date_end=None, dry_run=False): signed_path_pattern = 'signed-user-certificates/%d.jpg' if email: fn = draw_cert(os.path.join(settings.RESOURCES_ROOT, signed_path_pattern % 1), email, 'Имя', 'Фамилия') file = open(fn, 'rb') try: send_email('Грамота от Lil School', email, 'notification/email/certificate.html', attachments=[(file.name, file.read(), 'image/jpeg')]) except: pass else: print('Email has been sent') finally: file.close() os.remove(fn) return date_end = datetime.strptime(date_end, '%d-%m-%Y').date() if date_end else now().date() today = now().date() users = set(list(SchoolPayment.objects.paid().filter(date_end=date_end, add_days=False).values_list('user_id', flat=True))) user_notifications_qs = UserNotification.objects.filter(user_id__in=users) user_notifications = {un.user_id: un for un in user_notifications_qs} notified_users = user_notifications_qs.filter(certificate_last_email__date=today).values_list( 'user_id', flat=True).distinct() for user_id in users: if user_id in notified_users: print('skip', user_id) continue un = user_notifications.get(user_id, UserNotification(user_id=user_id)) print(un.user.email) if dry_run: continue un.certificate_number = un.certificate_number + 1 \ if un.certificate_number and os.path.isfile(os.path.join(settings.RESOURCES_ROOT, signed_path_pattern % (un.certificate_number + 1))) \ else 1 un.save() try: send_email('Грамота от Lil School', un.user.email, 'notification/email/certificate.html', childs=un.user.childs.all(), user_notification=un, many_childs=un.user.childs.all().count() > 1, child_filled=un.user.child_filled) except Exception as e: print('Not OK') print(e) continue un.certificate_last_email = now() un.save() @app.task 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 = ''' 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: 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) courses_purchased = CoursePayment.objects.filter(user=user, status__in=CoursePayment.PW_PAID_STATUSES).values_list('course_id', flat=True) data.append({ 'first_name': user.first_name, 'last_name': user.last_name, 'email': user.email, '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] if user.gender else '', 'birthday': user.birthday and user.birthday.strftime(date_format), 'date_joined': user.date_joined.strftime(date_format), 'courses_purchased': ','.join(map(str, courses_purchased)) + ',' if courses_purchased else '', }) sg = get_sendgrid_client() response = sg.client.contactdb.recipients.patch(request_body=data) print(response.body) @app.task def send_gift_certificate(user_gift_certificate): user_gift_certificate = UserGiftCertificate.objects.get(id=user_gift_certificate) send_email('Подарочный сертификат от Lil School', user_gift_certificate.user.email, 'notification/email/gift_certificate.html', inline_images=[('twitter_icon', 'img/twitter.png'), ('fb_icon', 'img/fb.png'), ('instagram_icon', 'img/instagram.png'),], user_gift_certificate=user_gift_certificate, gift_certificate=user_gift_certificate.gift_certificate) @app.task def send_child_birthday_email_and_bonuses(): today = now().date() for user_id, email in set(Child.objects.filter(birthday__day=today.day, birthday__month=today.month).select_related('user') .values_list('user_id', 'user__email')): print('user', email) if not UserBonus.objects.filter(user_id=user_id, is_service=True, action_name=UserBonus.ACTION_CHILD_BIRTHDAY, created_at__year=today.year).count(): UserBonus.objects.create(user_id=user_id, amount=UserBonus.AMOUNT_CHILD_BIRTHDAY, is_service=True, action_name=UserBonus.ACTION_CHILD_BIRTHDAY) try: fn = staticfiles_storage.path('img/birthday_postcard.jpg') file = open(fn, 'rb') send_email('С Днем Рождения!', email, 'notification/email/birthday_postcard.html', attachments=[(file.name, file.read(), 'image/jpeg')],) print('email has been sent') finally: file.close() @app.task def send_camp_certificates(email=None, dry_run=False, certificate_number=None): path_pattern = 'camp-certificates/%d.jpg' signed_path_pattern = 'signed-camp-certificates/%d.jpg' color = (0, 27, 94) if certificate_number is None: certificate_number = 1 if certificate_number == 2: color = (106, 5, 163) if certificate_number == 3: color = (24, 57, 220) if email: fn = draw_cert(os.path.join(settings.RESOURCES_ROOT, signed_path_pattern % certificate_number), email, 'Имя', 'Фамилия', font_size=120, y=1000, color=color) file = open(fn, 'rb') try: send_email('Грамота от Lil School', email, 'notification/email/camp_certificate.html', attachments=[(file.name, file.read(), 'image/jpeg')], certificate_number=certificate_number) # send_email('Грамота от Lil School', email, 'notification/email/camp_certificate.html', # attachments=[('file', '', 'image/jpeg')], certificate_number=certificate_number) except Exception as e: print(e) else: print('Email has been sent') finally: file.close() return date_end = date(now().year, 6 + certificate_number, 1) - timedelta(1) users = set(list(DrawingCampPayment.objects.paid().filter(date_end=date_end).values_list('user_id', flat=True))) user_notifications_qs = UserNotification.objects.filter(user_id__in=users) user_notifications = {un.user_id: un for un in user_notifications_qs} notified_users = user_notifications_qs.filter(camp_certificate_last_email__date=date_end).values_list( 'user_id', flat=True).distinct() for user_id in users: if user_id in notified_users: print('skip', user_id) continue un = user_notifications.get(user_id, UserNotification(user_id=user_id)) print(un.user.email) if dry_run: continue file_names = [] if un.user.child_filled: fn = os.path.join(settings.RESOURCES_ROOT, signed_path_pattern % certificate_number) for child in un.user.childs.all(): file_names.append(draw_cert(fn, un.user.email, child.first_name, child.last_name, font_size=120, y=1000, color=color)) else: file_names.append(os.path.join(settings.RESOURCES_ROOT, path_pattern % certificate_number)) files = [open(fn, 'rb') for fn in file_names] try: send_email('Грамота от Lil School', un.user.email, 'notification/email/camp_certificate.html', attachments=[(f.name, f.read(), 'image/jpeg') for f in files], user_notification=un, certificate_number=certificate_number, many_childs=un.user.childs.all().count() > 1) except: print('Not OK') continue finally: un.camp_certificate_last_email = date_end un.save() for f in files: f.close() if un.user.child_filled: for fn in file_names: if os.path.isfile(fn): os.remove(fn)