from django import forms from django.core import validators from django.core.exceptions import ValidationError from django.urls import reverse from django.db.models import Q from django.utils.safestring import mark_safe from django.utils.translation import gettext_lazy as _ from orchestra.contrib.mailboxes.models import Mailbox from orchestra.forms.widgets import SpanWidget from .. import settings from ..forms import SaaSPasswordForm from .options import DBSoftwareService class PHPListForm(SaaSPasswordForm): admin_username = forms.CharField(label=_("Admin username"), required=False, widget=SpanWidget(display='admin')) database = forms.CharField(label=_("Database"), required=False, help_text=_("Database dedicated to this phpList instance."), widget=SpanWidget(display=settings.SAAS_PHPLIST_DB_NAME.replace( '%(', '<').replace(')s', '>'))) mailbox = forms.CharField(label=_("Bounces mailbox"), required=False, help_text=_("Dedicated mailbox used for reciving bounces."), widget=SpanWidget(display=settings.SAAS_PHPLIST_BOUNCES_MAILBOX_NAME.replace( '%(', '<').replace(')s', '>'))) def __init__(self, *args, **kwargs): super(PHPListForm, self).__init__(*args, **kwargs) self.fields['name'].label = _("Site name") context = { 'site_name': '<site_name>', 'name': '<site_name>', } domain = self.plugin.site_domain % context help_text = _("Admin URL http://{}/admin/").format(domain) self.fields['site_url'].help_text = help_text validator = validators.MaxLengthValidator(settings.SAAS_PHPLIST_NAME_MAX_LENGTH) self.fields['name'].validators.append(validator) class PHPListChangeForm(PHPListForm): def __init__(self, *args, **kwargs): super(PHPListChangeForm, self).__init__(*args, **kwargs) site_domain = self.instance.get_site_domain() admin_url = "http://%s/admin/" % site_domain help_text = _("Admin URL {0}").format(admin_url) self.fields['site_url'].help_text = help_text # DB link db = self.instance.database db_url = reverse('admin:databases_database_change', args=(db.pk,)) db_link = mark_safe('%s' % (db_url, db.name)) self.fields['database'].widget = SpanWidget(original=db.name, display=db_link) # Mailbox link mailbox_id = self.instance.data.get('mailbox_id') if mailbox_id: try: mailbox = Mailbox.objects.get(id=mailbox_id) except Mailbox.DoesNotExist: pass else: mailbox_url = reverse('admin:mailboxes_mailbox_change', args=(mailbox.pk,)) mailbox_link = mark_safe('%s' % (mailbox_url, mailbox.name)) self.fields['mailbox'].widget = SpanWidget( original=mailbox.name, display=mailbox_link) class PHPListService(DBSoftwareService): name = 'phplist' verbose_name = "phpList" form = PHPListForm change_form = PHPListChangeForm icon = 'orchestra/icons/apps/Phplist.png' site_domain = settings.SAAS_PHPLIST_DOMAIN allow_custom_url = settings.SAAS_PHPLIST_ALLOW_CUSTOM_URL db_name = settings.SAAS_PHPLIST_DB_NAME db_user = settings.SAAS_PHPLIST_DB_USER def get_mailbox_name(self): context = { 'name': self.instance.name, 'site_name': self.instance.name, } return settings.SAAS_PHPLIST_BOUNCES_MAILBOX_NAME % context def validate(self): super(PHPListService, self).validate() create = not self.instance.pk if create: account = self.get_account() # Validate mailbox mailbox = Mailbox(name=self.get_mailbox_name(), account=account) try: mailbox.full_clean() except ValidationError as e: raise ValidationError({ 'name': e.messages, }) def save(self): super(PHPListService, self).save() account = self.get_account() # Mailbox mailbox_name = self.get_mailbox_name() mailbox, mb_created = account.mailboxes.get_or_create(name=mailbox_name) if mb_created: mailbox.set_password(settings.SAAS_PHPLIST_BOUNCES_MAILBOX_PASSWORD) mailbox.save(update_fields=('password',)) self.instance.data.update({ 'mailbox_id': mailbox.pk, 'mailbox_name': mailbox_name, }) def delete(self): super(PHPListService, self).save() account = self.get_account() # delete Mailbox (database will be deleted by ORM's cascade behaviour mailbox_name = self.instance.data.get('mailbox_name') or self.get_mailbox_name() mailbox_id = self.instance.data.get('mailbox_id') qs = Q(Q(name=mailbox_name) | Q(id=mailbox_id)) account.mailboxes.filter(qs).delete()