You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
247 lines
11 KiB
247 lines
11 KiB
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):
|
|
path_pattern = 'img/user-certificates/%d.jpg'
|
|
signed_path_pattern = 'img/signed-user-certificates/%d.jpg'
|
|
if email:
|
|
fn = draw_cert(staticfiles_storage.path(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
|
|
|
|
file_names = []
|
|
un.certificate_number = un.certificate_number + 1 \
|
|
if un.certificate_number and staticfiles_storage.exists(path_pattern % (un.certificate_number + 1)) \
|
|
else 1
|
|
if un.user.child_filled:
|
|
fn = staticfiles_storage.path(signed_path_pattern % un.certificate_number)
|
|
for child in un.user.childs.all():
|
|
file_names.append(draw_cert(fn, un.user.email, child.first_name, child.last_name))
|
|
else:
|
|
file_names.append(staticfiles_storage.path(signed_path_pattern % un.certificate_number))
|
|
files = [open(fn, 'rb') for fn in file_names]
|
|
try:
|
|
send_email('Грамота от Lil School', un.user.email, 'notification/email/certificate.html',
|
|
attachments=[(f.name, f.read(), 'image/jpeg') for f in files], user_notification=un,
|
|
many_childs=un.user.childs.all().count() > 1, child_filled=un.user.child_filled)
|
|
except:
|
|
print('Not OK')
|
|
continue
|
|
finally:
|
|
for f in files:
|
|
f.close()
|
|
if un.user.child_filled:
|
|
for fn in file_names:
|
|
os.remove(fn)
|
|
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)
|
|
|