рисовальный лагерь

remotes/origin/hotfix/delete-image-error-30-05-19
gzbender 7 years ago
parent c0bbd01926
commit 7d083bb534
  1. 32
      apps/notification/management/commands/send_camp_certificates.py
  2. 2
      apps/notification/management/commands/send_certificates.py
  3. 18
      apps/notification/migrations/0002_usernotification_camp_certificate_last_email.py
  4. 1
      apps/notification/models.py
  5. 80
      apps/notification/tasks.py
  6. 25
      apps/notification/templates/notification/email/camp_certificate.html
  7. 10
      project/settings.py
  8. BIN
      web/src/img/camp-certificates/1.jpg
  9. BIN
      web/src/img/camp-certificates/2.jpg
  10. 8
      web/webpack.config.js

@ -0,0 +1,32 @@
from django.core.management.base import BaseCommand
from apps.notification.tasks import send_camp_certificates
class Command(BaseCommand):
help = 'Send camp certificates at the end of month'
def add_arguments(self, parser):
# Named (optional) arguments
parser.add_argument(
'--email',
dest='email',
help='Test email',
)
parser.add_argument(
'--cert',
dest='certificate_number',
type=int,
help='Certificate number',
)
parser.add_argument(
'--dry-run',
action='store_true',
dest='dry_run',
help='Only display emails',
)
def handle(self, *args, **options):
send_camp_certificates(email=options.get('email'), certificate_number=options.get('certificate_number'),
dry_run=options.get('dry_run'))

@ -26,5 +26,5 @@ class Command(BaseCommand):
) )
def handle(self, *args, **options): def handle(self, *args, **options):
send_certificates(email=options.get('email'), date=options.get('date'), dry_run=options.get('dry_run')) send_certificates(email=options.get('email'), date_end=options.get('date'), dry_run=options.get('dry_run'))

@ -0,0 +1,18 @@
# Generated by Django 2.0.7 on 2019-05-23 01:53
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('notification', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='usernotification',
name='camp_certificate_last_email',
field=models.DateTimeField(blank=True, null=True),
),
]

@ -9,3 +9,4 @@ class UserNotification(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE) user = models.ForeignKey(User, on_delete=models.CASCADE)
certificate_number = models.SmallIntegerField(blank=True, null=True) certificate_number = models.SmallIntegerField(blank=True, null=True)
certificate_last_email = models.DateTimeField(blank=True, null=True) certificate_last_email = models.DateTimeField(blank=True, null=True)
camp_certificate_last_email = models.DateTimeField(blank=True, null=True)

@ -1,5 +1,5 @@
import os import os
from datetime import datetime from datetime import datetime, date, timedelta
from PIL import Image from PIL import Image
from PIL import ImageFont from PIL import ImageFont
from PIL import ImageDraw from PIL import ImageDraw
@ -12,7 +12,7 @@ from django.conf import settings
from apps.notification.models import UserNotification from apps.notification.models import UserNotification
from apps.notification.utils import send_email from apps.notification.utils import send_email
from apps.payment.models import SchoolPayment, CoursePayment, Payment, UserGiftCertificate, UserBonus from apps.payment.models import SchoolPayment, CoursePayment, Payment, UserGiftCertificate, UserBonus, DrawingCampPayment
from project.celery import app from project.celery import app
from project.utils.db import format_sql, execute_sql from project.utils.db import format_sql, execute_sql
from project.sengrid import get_sendgrid_client from project.sengrid import get_sendgrid_client
@ -21,27 +21,28 @@ from project.sengrid import get_sendgrid_client
User = get_user_model() User = get_user_model()
def draw_cert(path, email, first_name, last_name): 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) img = Image.open(path)
draw = ImageDraw.Draw(img) draw = ImageDraw.Draw(img)
font = ImageFont.truetype(os.path.join(settings.STATIC_ROOT, 'ProximaNova-Reg.otf'), 170) font = ImageFont.truetype(os.path.join(settings.STATIC_ROOT, 'ProximaNova-Reg.otf'), font_size)
text = first_name.capitalize() text = first_name.capitalize()
if last_name: if last_name:
text += ' ' + last_name.capitalize() text += ' ' + last_name.capitalize()
w, h = draw.textsize(text, font=font) w, h = draw.textsize(text, font=font)
draw.text(((img.width - w) // 2, 900), text, (29, 115, 224), 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') fn = os.path.join(settings.MEDIA_ROOT, 'tmp')
try: try:
os.mkdir(fn) os.mkdir(fn)
except: except:
pass pass
fn = os.path.join(fn, 'certificate-for-%s.jpg' % email) fn = os.path.join(fn, '%scertificate-for-%s.jpg' % (fn_prefix, email))
img.save(fn) img.save(fn)
img.close() img.close()
return fn return fn
@app.task @app.task
def send_certificates(email=None, date=None, dry_run=False): def send_certificates(email=None, date_end=None, dry_run=False):
path_pattern = 'img/user-certificates/%d.jpg' path_pattern = 'img/user-certificates/%d.jpg'
signed_path_pattern = 'img/signed-user-certificates/%d.jpg' signed_path_pattern = 'img/signed-user-certificates/%d.jpg'
if email: if email:
@ -59,9 +60,9 @@ def send_certificates(email=None, date=None, dry_run=False):
os.remove(fn) os.remove(fn)
return return
date = datetime.strptime(date, '%d-%m-%Y').date() if date else now().date() date_end = datetime.strptime(date_end, '%d-%m-%Y').date() if date_end else now().date()
today = now().date() today = now().date()
users = set(list(SchoolPayment.objects.paid().filter(date_end=date, add_days=False).values_list('user_id', flat=True))) 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_qs = UserNotification.objects.filter(user_id__in=users)
user_notifications = {un.user_id: un for un in user_notifications_qs} 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( notified_users = user_notifications_qs.filter(certificate_last_email__date=today).values_list(
@ -160,3 +161,64 @@ def send_child_birthday_email_and_bonuses():
print('email has been sent') print('email has been sent')
finally: finally:
file.close() file.close()
@app.task
def send_camp_certificates(email=None, dry_run=False, certificate_number=None):
path_pattern = 'img/camp-certificates/%d.jpg'
color = (35, 59, 227)
if certificate_number is None:
certificate_number = 1
if certificate_number == 2:
color = (0, 27, 94)
if email:
fn = draw_cert(staticfiles_storage.path(path_pattern % certificate_number), email, 'Имя', 'Фамилия',
font_size=70, y=550, color=color)
file = open(fn, 'rb')
try:
pass
send_email('Грамота от Lil School', email, 'notification/email/camp_certificate.html',
attachments=[(file.name, file.read(), 'image/jpeg')], certificate_number=certificate_number)
except:
pass
else:
print('Email has been sent')
finally:
file.close()
os.remove(fn)
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
if un.user.child_first_name:
fn = staticfiles_storage.path(path_pattern % certificate_number)
fn = draw_cert(fn, un.user.email, un.user.child_first_name, un.user.child_last_name,
font_size=70, y=550, color=color)
else:
fn = staticfiles_storage.path(path_pattern % certificate_number)
file = open(fn, 'rb')
try:
send_email('Грамота от Lil School', un.user.email, 'notification/email/camp_certificate.html',
attachments=[(file.name, file.read(), 'image/jpeg')], user_notification=un,
certificate_number=certificate_number)
except:
print('Not OK')
continue
finally:
file.close()
if un.user.child_first_name:
os.remove(fn)
un.camp_certificate_last_email = date_end
un.save()

@ -0,0 +1,25 @@
{% extends "notification/email/_base.html" %}
{% block content %}
<p style="margin: 0 0 20px">Привет!</p>
<div style="margin-bottom: 10px;">
{% if certificate_number == 1 %}
<p>
Поздравляем! Вы прошли месяц обучения в лагере Lil School.<br>
К письму прикреплена грамота. Распечатайте её и вручите вашим детям.<br>
Ждём вас в следующем месяце на наших творческих занятиях!
</p>
{% endif %}
{% if certificate_number == 2 %}
<p>
Вы помните, что каждый месяц вам приходит грамота за прекрасную учебу в рсиовальном лагере?<br>
Скачивайте. Распечатывайте. И соберите свою коллекцию!
</p>
{% endif %}
</div>
<div style="margin-bottom: 10px;">
<p>
Команда «Lil School».
</p>
</div>
{% endblock content %}

@ -267,6 +267,16 @@ CELERY_BEAT_SCHEDULE = {
'schedule': crontab(minute=0, hour=0), 'schedule': crontab(minute=0, hour=0),
'args': (), 'args': (),
}, },
'send_june_camp_certificates': {
'task': 'apps.notification.tasks.send_camp_certificates',
'schedule': crontab(0, 9, day_of_month='1', month_of_year='7'),
'kwargs': {'certificate_number': 2},
},
'send_jule_camp_certificates': {
'task': 'apps.notification.tasks.send_camp_certificates',
'schedule': crontab(0, 9, day_of_month='1', month_of_year='8'),
'kwargs': {'certificate_number': 2},
},
} }
try: try:

Binary file not shown.

After

Width:  |  Height:  |  Size: 473 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

@ -20,6 +20,7 @@ module.exports = {
imagesCertificates: glob('./src/img/user-certificates/*'), imagesCertificates: glob('./src/img/user-certificates/*'),
imagesSignedCertificates: glob('./src/img/signed-user-certificates/*'), imagesSignedCertificates: glob('./src/img/signed-user-certificates/*'),
imagesGiftCertificates: glob('./src/img/gift-certificates/*'), imagesGiftCertificates: glob('./src/img/gift-certificates/*'),
imagesCampCertificates: glob('./src/img/camp-certificates/*'),
imagesReviews: glob('./src/img/reviews/*'), imagesReviews: glob('./src/img/reviews/*'),
fonts: glob('./src/fonts/*'), fonts: glob('./src/fonts/*'),
sounds: glob('./src/sounds/*'), sounds: glob('./src/sounds/*'),
@ -93,7 +94,7 @@ module.exports = {
test: /\.(png|gif|jpg|svg)$/, test: /\.(png|gif|jpg|svg)$/,
exclude: [path.resolve(__dirname, 'src/icons'), path.resolve(__dirname, 'src/img/user-certificates'), exclude: [path.resolve(__dirname, 'src/icons'), path.resolve(__dirname, 'src/img/user-certificates'),
path.resolve(__dirname, 'src/img/gift-certificates'), path.resolve(__dirname, 'src/img/reviews'), path.resolve(__dirname, 'src/img/gift-certificates'), path.resolve(__dirname, 'src/img/reviews'),
path.resolve(__dirname, 'src/img/signed-user-certificates')], path.resolve(__dirname, 'src/img/signed-user-certificates'), path.resolve(__dirname, 'src/img/camp-certificates')],
loader: 'file-loader?name=[name].[ext]&outputPath=./img/' loader: 'file-loader?name=[name].[ext]&outputPath=./img/'
}, },
{ {
@ -111,6 +112,11 @@ module.exports = {
include: path.resolve(__dirname, 'src/img/gift-certificates'), include: path.resolve(__dirname, 'src/img/gift-certificates'),
loader: 'file-loader?name=[name].[ext]&outputPath=./img/gift-certificates/' loader: 'file-loader?name=[name].[ext]&outputPath=./img/gift-certificates/'
}, },
{
test: /\.(png|jpg)$/,
include: path.resolve(__dirname, 'src/img/camp-certificates'),
loader: 'file-loader?name=[name].[ext]&outputPath=./img/camp-certificates/'
},
{ {
test: /\.(png|jpg)$/, test: /\.(png|jpg)$/,
include: path.resolve(__dirname, 'src/img/reviews'), include: path.resolve(__dirname, 'src/img/reviews'),

Loading…
Cancel
Save