diff --git a/apps/notification/management/commands/send_certificates.py b/apps/notification/management/commands/send_certificates.py index 343b451b..ee1e4b3b 100644 --- a/apps/notification/management/commands/send_certificates.py +++ b/apps/notification/management/commands/send_certificates.py @@ -1,11 +1,73 @@ from django.core.management.base import BaseCommand from email.mime.image import MIMEImage +from django.contrib.staticfiles.storage import staticfiles_storage +from django.utils.timezone import now +from django.contrib.auth import get_user_model +from apps.notification.models import UserNotification from apps.notification.utils import send_email +from apps.payment.models import Payment, SchoolPayment, CoursePayment + + +User = get_user_model() class Command(BaseCommand): help = 'Send certificates at the end of subscription' + def add_arguments(self, parser): + # Named (optional) arguments + parser.add_argument( + '--email', + dest='email', + help='Test email', + ) + parser.add_argument( + '--dry-run', + action='store_true', + dest='dry_run', + help='Only display emails', + ) + def handle(self, *args, **options): - image = MIMEImage(cms.image.open().read()) + path_pattern = 'img/user-certificates/%d.jpg' + if options.get('email'): + file = open(staticfiles_storage.path(path_pattern % 1), 'rb') + try: + send_email('Грамота от Lil School', options['email'], 'notification/email/certificate.html', + attachments=[(file.name, file.read(), 'image/jpeg')]) + except: + pass + else: + print('Email has been sent') + finally: + file.close() + return + + today = now().date() + users = SchoolPayment.objects.filter(date_end=today, 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) + for user_id in users: + if user_id in notified_users: + continue + un = user_notifications.get(user_id, UserNotification(user_id=user_id)) + print(un.user.email) + if options.get('dry_run'): + continue + + un.certificate_number = un.certificate_number + 1 \ + if un.certificate_number and staticfiles_storage.exists(path_pattern % (un.certificate_number + 1)) \ + else 1 + file = open(staticfiles_storage.path(path_pattern % un.certificate_number), 'rb') + try: + send_email('Грамота от Lil School', un.user.email, 'notification/email/certificate.html', + attachments=[(file.name, file.read(), 'image/jpeg')]) + except: + print('Not OK') + continue + finally: + file.close() + un.certificate_last_email = now() + un.save() diff --git a/apps/notification/migrations/0001_initial.py b/apps/notification/migrations/0001_initial.py new file mode 100644 index 00000000..f531bd53 --- /dev/null +++ b/apps/notification/migrations/0001_initial.py @@ -0,0 +1,26 @@ +# Generated by Django 2.0.6 on 2018-10-02 03:38 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='UserNotification', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('certificate_number', models.SmallIntegerField(blank=True, null=True)), + ('certificate_last_email', models.DateTimeField(blank=True, null=True)), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + ), + ] diff --git a/apps/notification/models.py b/apps/notification/models.py index 6e4e18f5..6aa5d513 100644 --- a/apps/notification/models.py +++ b/apps/notification/models.py @@ -4,6 +4,7 @@ from django.contrib.auth import get_user_model User = get_user_model() + class UserNotification(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE) certificate_number = models.SmallIntegerField(blank=True, null=True) diff --git a/apps/payment/migrations/0024_auto_20181002_0338.py b/apps/payment/migrations/0024_auto_20181002_0338.py new file mode 100644 index 00000000..a3f72da9 --- /dev/null +++ b/apps/payment/migrations/0024_auto_20181002_0338.py @@ -0,0 +1,17 @@ +# Generated by Django 2.0.6 on 2018-10-02 03:38 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('payment', '0023_payment_bonus'), + ] + + operations = [ + migrations.AlterModelOptions( + name='userbonus', + options={'ordering': ('created_at',)}, + ), + ] diff --git a/web/webpack.config.js b/web/webpack.config.js index f91b4e9e..7455fec9 100644 --- a/web/webpack.config.js +++ b/web/webpack.config.js @@ -12,7 +12,8 @@ module.exports = { contestRedactor: "./src/js/contest-redactor.js", mixpanel: "./src/js/third_party/mixpanel-2-latest.js", sprite: glob('./src/icons/*.svg'), - images: glob('./src/img/*'), + images: glob('./src/img/*.*'), + imagesCertificates: glob('./src/img/user-certificates/*'), fonts: glob('./src/fonts/*') }, output: { @@ -84,9 +85,14 @@ module.exports = { }, { test: /\.(png|gif|jpg|svg)$/, - exclude: path.resolve(__dirname, 'src/icons'), + exclude: [path.resolve(__dirname, 'src/icons'), path.resolve(__dirname, 'src/img/user-certificates')], loader: 'file-loader?name=[name].[ext]&outputPath=./img/' }, + { + test: /\.(png|jpg)$/, + include: path.resolve(__dirname, 'src/img/user-certificates'), + loader: 'file-loader?name=[name].[ext]&outputPath=./img/user-certificates/' + }, { test: /\.(ttf|otf|eot|woff(2)?)(\?[a-z0-9]+)?$/, loader: 'file-loader?name=[name].[ext]'