wagtail-birdsong/birdsong/options.py

166 lines
6.2 KiB
Python

from django.conf.urls import url
from django.forms import modelform_factory
from django.http.response import HttpResponseRedirect
from django.urls import reverse
from wagtail.admin.edit_handlers import ObjectList, TabbedInterface
from wagtail.contrib.modeladmin.helpers import AdminURLHelper, ButtonHelper
from wagtail.contrib.modeladmin.options import ModelAdmin
from birdsong.backends.smtp import SMTPEmailBackend
from .models import CampaignStatus, Contact
from .views import actions
from .views import editor as editor_views
class EmailCampaignButtonHelper(ButtonHelper):
def get_buttons_for_obj(self, campaign, **kwargs):
url_helper = AdminURLHelper(self.model)
sent = campaign.status != CampaignStatus.UNSENT
def button(action_url, label, classnames):
return {
'url': url_helper.get_action_url(action_url, instance_pk=campaign.id),
'label': label,
'title': label,
'classname': 'button button-small ' + classnames
}
delete_btn = button('delete', 'Delete', 'no button-secondary')
copy_btn = button('copy', 'Copy', 'button-secondary')
if not sent:
buttons = [
button('edit', 'Edit', 'bicolor icon icon-edit'),
copy_btn,
button('confirm_send', 'Send', 'bicolor icon icon-mail'),
button('send_test', 'Send test', 'button-secondary icon icon-cog'),
button('preview', 'Preview', 'button-secondary icon icon-view'),
delete_btn
]
else:
buttons = [
button('inspect', 'View', 'button-secondary icon icon-view'),
copy_btn,
delete_btn,
]
return buttons
class CampaignAdmin(ModelAdmin):
campaign = None
list_display = ('name', 'status', 'sent_date')
button_helper_class = EmailCampaignButtonHelper
inspect_view_enabled = True
inspect_view_class = editor_views.InspectCampaign
inspect_template_name = 'birdsong/editor/inspect_campaign.html'
edit_template_name = 'birdsong/editor/edit_campaign.html'
edit_view_class = editor_views.EditCampaignView
create_view_class = editor_views.CreateCampaignView
create_template_name = 'birdsong/editor/create_campaign.html'
backend_class = SMTPEmailBackend
contact_class = Contact
contact_filter_class = None
# FIXME needs to be overwritable
form_view_extra_js = ['birdsong/js/preview_campaign.js']
form_view_extra_css = ['birdsong/css/campaign-editor.css']
def __init__(self, parent=None):
if not self.model and self.campaign:
self.model = self.campaign
super().__init__(parent=parent)
self.backend = self.backend_class()
def get_admin_urls_for_registration(self):
urls = super().get_admin_urls_for_registration()
def gen_url(pattern, view, name=None):
if not name:
name = pattern
return url(
self.url_helper.get_action_url_pattern(pattern),
view,
name=self.url_helper.get_action_url_name(name)
)
urls = (
gen_url('preview', self.preview),
gen_url('confirm_send', self.confirm_send),
gen_url('send_campaign', self.send_campaign),
gen_url('confirm_test', self.confirm_test),
gen_url('send_test', self.send_test),
gen_url('copy', self.copy)
) + urls
return urls
def preview(self, request, instance_pk):
campaign = self.model.objects.get(pk=instance_pk)
contact = self.contact_class.objects.first()
return editor_views.preview(request, campaign, contact)
def confirm_send(self, request, instance_pk):
campaign = self.model.objects.get(pk=instance_pk)
form = self.build_sending_form()
return editor_views.confirm_send(
request,
campaign,
form,
self.url_helper.get_action_url('send_campaign', instance_pk=instance_pk),
self.url_helper.get_action_url('index')
)
def build_sending_form(self):
if not self.contact_filter_class:
return None
contact_filter = self.contact_filter_class()
return contact_filter.form
def get_contacts_send_to(self, request):
if self.contact_filter_class:
Filter = self.contact_filter_class
contact_filter = Filter(request.POST)
return contact_filter.qs
return self.contact_class.objects.all()
def send_campaign(self, request, instance_pk):
campaign = self.model.objects.get(pk=instance_pk)
contacts = self.get_contacts_send_to(request)
return actions.send_campaign(self.backend, request, campaign, contacts)
def create_contact_form(self, data=None):
ContactForm = modelform_factory(self.contact_class, exclude=['id'])
if data:
return ContactForm(data)
return ContactForm()
def confirm_test(self, request, campaign, form):
return editor_views.confirm_test(
request,
campaign,
form,
self.url_helper.get_action_url('send_test', campaign.id),
self.url_helper.get_action_url('index')
)
def send_test(self, request, instance_pk):
campaign = self.model.objects.get(pk=instance_pk)
if request.method == 'GET':
form = self.create_contact_form()
return self.confirm_test(request, campaign, form)
form = self.create_contact_form(request.POST)
if not form.is_valid():
return self.confirm_test(request, campaign, form)
# Create fake contact, send test email
contact = form.save(commit=False)
return actions.send_test(self.backend, request, campaign, contact)
def copy(self, request, instance_pk):
instance = self.model.objects.get(pk=instance_pk)
instance.name = instance.name + ' (Copy)'
instance.pk = None
instance.id = None
instance.sent_date = None
instance.status = CampaignStatus.UNSENT
instance.save()
return HttpResponseRedirect(self.url_helper.get_action_url('index'))