import logging from datetime import timedelta import pytz from django.contrib import messages from django.db.models import Q from django.http import Http404 from django.shortcuts import redirect from django.utils.formats import date_format from django.utils.timezone import now from django.utils.translation import ugettext_lazy as _ from django.views.generic import FormView, ListView from pretix.base.i18n import LazyI18nString, language from pretix.base.models import InvoiceAddress, LogEntry, Order from pretix.base.models.event import SubEvent from pretix.base.services.mail import SendMailException, mail from pretix.control.permissions import EventPermissionRequiredMixin from pretix.multidomain.urlreverse import build_absolute_uri from . import forms logger = logging.getLogger('pretix.plugins.sendmail') class SenderView(EventPermissionRequiredMixin, FormView): template_name = 'pretixplugins/sendmail/send_form.html' permission = 'can_change_orders' form_class = forms.MailForm def get_form_kwargs(self): kwargs = super().get_form_kwargs() kwargs['event'] = self.request.event if 'from_log' in self.request.GET: try: from_log_id = self.request.GET.get('from_log') logentry = LogEntry.objects.get( id=from_log_id, event=self.request.event, action_type='pretix.plugins.sendmail.sent' ) kwargs['initial'] = { 'message': LazyI18nString(logentry.parsed_data['message']), 'subject': LazyI18nString(logentry.parsed_data['subject']), 'sendto': logentry.parsed_data['sendto'], } if logentry.parsed_data.get('subevent'): try: kwargs['initial']['subevent'] = self.request.event.subevents.get( pk=logentry.parsed_data['subevent']['id'] ) except SubEvent.DoesNotExist: pass except LogEntry.DoesNotExist: raise Http404(_('You supplied an invalid log entry ID')) return kwargs def form_invalid(self, form): messages.error(self.request, _('We could not send the email. See below for details.')) return super().form_invalid(form) def form_valid(self, form): qs = Order.objects.filter(event=self.request.event) statusq = Q(status__in=form.cleaned_data['sendto']) if 'overdue' in form.cleaned_data['sendto']: statusq |= Q(status=Order.STATUS_PENDING, expires__lt=now()) orders = qs.filter(statusq) if form.cleaned_data.get('subevent'): orders = orders.filter(positions__subevent__in=(form.cleaned_data.get('subevent'),)).distinct() tz = pytz.timezone(self.request.event.settings.timezone) failures = [] self.output = {} if not orders: messages.error(self.request, _('There are no orders matching this selection.')) return self.get(self.request, *self.args, **self.kwargs) if self.request.POST.get("action") == "preview": for l in self.request.event.settings.locales: with language(l): self.output[l] = [] self.output[l].append( _('Subject: {subject}').format(subject=form.cleaned_data['subject'].localize(l))) message = form.cleaned_data['message'].localize(l) preview_text = message.format( order='ORDER1234', event=self.request.event.name, order_date=date_format(now(), 'SHORT_DATE_FORMAT'), due_date=date_format(now() + timedelta(days=7), 'SHORT_DATE_FORMAT'), order_url=build_absolute_uri(self.request.event, 'presale:event.order', kwargs={ 'order': 'ORDER1234', 'secret': 'longrandomsecretabcdef123456' }), invoice_name=_('John Doe'), invoice_company=_('Sample Company LLC'), ) self.output[l].append(preview_text) return self.get(self.request, *self.args, **self.kwargs) for o in orders: try: invoice_name = o.invoice_address.name invoice_company = o.invoice_address.company except InvoiceAddress.DoesNotExist: invoice_name = "" invoice_company = "" try: with language(o.locale): mail( o.email, form.cleaned_data['subject'], form.cleaned_data['message'], { 'event': o.event, 'order': o.code, 'order_date': date_format(o.datetime.astimezone(tz), 'SHORT_DATETIME_FORMAT'), 'due_date': date_format(o.expires, 'SHORT_DATE_FORMAT'), 'order_url': build_absolute_uri(o.event, 'presale:event.order', kwargs={ 'order': o.code, 'secret': o.secret }), 'invoice_name': invoice_name, 'invoice_company': invoice_company, }, self.request.event, locale=o.locale, order=o) o.log_action( 'pretix.plugins.sendmail.order.email.sent', user=self.request.user, data={ 'subject': form.cleaned_data['subject'], 'message': form.cleaned_data['message'], 'recipient': o.email, } ) except SendMailException: failures.append(o.email) self.request.event.log_action('pretix.plugins.sendmail.sent', user=self.request.user, data=dict(form.cleaned_data)) if failures: messages.error(self.request, _('Failed to send mails to the following users: {}'.format(' '.join(failures)))) else: messages.success(self.request, _('Your message has been queued and will be sent to the selected users.')) return redirect( 'plugins:sendmail:send', event=self.request.event.slug, organizer=self.request.event.organizer.slug ) def get_context_data(self, *args, **kwargs): ctx = super().get_context_data(*args, **kwargs) ctx['output'] = getattr(self, 'output', None) return ctx class EmailHistoryView(EventPermissionRequiredMixin, ListView): template_name = 'pretixplugins/sendmail/history.html' permission = 'can_change_orders' model = LogEntry context_object_name = 'logs' paginate_by = 5 def get_queryset(self): qs = LogEntry.objects.filter( event=self.request.event, action_type='pretix.plugins.sendmail.sent' ) return qs def get_context_data(self, **kwargs): ctx = super().get_context_data() status = dict(Order.STATUS_CHOICE) status['overdue'] = _('pending with payment overdue') for log in ctx['logs']: log.pdata = log.parsed_data log.pdata['locales'] = {} for locale, msg in log.pdata['message'].items(): log.pdata['locales'][locale] = { 'message': msg, 'subject': log.pdata['subject'][locale] } log.pdata['sendto'] = [ status[s] for s in log.pdata['sendto'] ] if log.pdata.get('subevent'): try: log.pdata['subevent_obj'] = self.request.event.subevents.get(pk=log.pdata['subevent']['id']) except SubEvent.DoesNotExist: pass return ctx