From 3c0bfe4d77b6975794a0f2139327861c8e3c65ed Mon Sep 17 00:00:00 2001 From: Serghei Mihai Date: Wed, 14 Sep 2016 16:25:27 +0200 Subject: [PATCH] newsletters: newsletter subscription cell (#12911) --- combo/apps/newsletters/forms.py | 9 +- .../migrations/0002_newslettersubscriptioncell.py | 37 ++++++ combo/apps/newsletters/models.py | 143 +++++++++++++-------- .../newsletters/newsletter_subscription.html | 18 +++ combo/apps/newsletters/urls.py | 4 +- combo/apps/newsletters/views.py | 35 ++++- 6 files changed, 185 insertions(+), 61 deletions(-) create mode 100644 combo/apps/newsletters/migrations/0002_newslettersubscriptioncell.py create mode 100644 combo/apps/newsletters/templates/newsletters/newsletter_subscription.html diff --git a/combo/apps/newsletters/forms.py b/combo/apps/newsletters/forms.py index 082b040..238f64b 100644 --- a/combo/apps/newsletters/forms.py +++ b/combo/apps/newsletters/forms.py @@ -25,6 +25,9 @@ class NewslettersManageForm(forms.Form): logger = logging.getLogger(__name__) self.user = kwargs.pop('user') self.instance = kwargs.pop('instance') + self.include_labels = None + if 'include_labels' in kwargs: + self.include_labels = kwargs.pop('include_labels') self.themes = set() super(NewslettersManageForm, self).__init__(*args, **kwargs) @@ -55,7 +58,11 @@ class NewslettersManageForm(forms.Form): if not self.instance.check_transport(transport['id']): continue self.themes.add((transport['id'], transport['text'])) - choices.append((transport['id'], '')) + if self.include_labels: + label = newsletter['text'] + else: + label = '' + choices.append((transport['id'], label)) if transport in newsletter['transports']: for subscription in subscriptions: if subscription['id'] == newsletter['id']: diff --git a/combo/apps/newsletters/migrations/0002_newslettersubscriptioncell.py b/combo/apps/newsletters/migrations/0002_newslettersubscriptioncell.py new file mode 100644 index 0000000..8f33d53 --- /dev/null +++ b/combo/apps/newsletters/migrations/0002_newslettersubscriptioncell.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations +import combo.apps.newsletters.models + + +class Migration(migrations.Migration): + + dependencies = [ + ('auth', '0001_initial'), + ('data', '0019_create_parent_cells'), + ('newsletters', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='NewsletterSubscriptionCell', + fields=[ + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ('placeholder', models.CharField(max_length=20)), + ('order', models.PositiveIntegerField()), + ('slug', models.SlugField(verbose_name='Slug', blank=True)), + ('public', models.BooleanField(default=True, verbose_name='Public')), + ('restricted_to_unlogged', models.BooleanField(default=False, verbose_name='Restrict to unlogged users')), + ('title', models.CharField(max_length=128, verbose_name='Title')), + ('url', models.URLField(max_length=128, verbose_name='Newsletters service url')), + ('newsletter', models.CharField(max_length=128, verbose_name='Newsletter')), + ('groups', models.ManyToManyField(to='auth.Group', verbose_name='Groups', blank=True)), + ('page', models.ForeignKey(to='data.Page')), + ], + options={ + 'verbose_name': 'Newsletter subscription', + }, + bases=(combo.apps.newsletters.models.NewslettersMixin, models.Model), + ), + ] diff --git a/combo/apps/newsletters/models.py b/combo/apps/newsletters/models.py index 153c4b0..4d04212 100644 --- a/combo/apps/newsletters/models.py +++ b/combo/apps/newsletters/models.py @@ -58,42 +58,25 @@ class SubscriptionsSaveError(Exception): pass -@register_cell_class -class NewslettersCell(CellBase): - title = models.CharField(verbose_name=_('Title'), max_length=128) - url = models.URLField(verbose_name=_('Newsletters service url'), - max_length=128) - resources_restrictions = models.CharField(_('resources restrictions'), - blank=True, max_length=1024, - help_text=_('list of resources(themes) separated by commas')) - transports_restrictions = models.CharField(_('transports restrictions'), - blank=True, max_length=1024, - help_text=_('list of transports separated by commas')) +class NewslettersMixin(object): - template_name = 'newsletters/newsletters.html' user_dependant = True @classmethod def is_enabled(cls): return True - class Meta: - verbose_name = _('Newsletters') - - def get_default_form_class(self): - model_fields = ('title', 'url', 'resources_restrictions', - 'transports_restrictions') - return model_forms.modelform_factory(self.__class__, fields=model_fields) - - - def simplify(self, name): - return slugify(name.strip()) - - def get_resources_restrictions(self): - return filter(None, map(self.simplify, self.resources_restrictions.strip().split(','))) + def is_relevant(self, context): + return bool(context.get('user').is_authenticated()) - def get_transports_restrictions(self): - return filter(None, map(self.simplify, self.transports_restrictions.strip().split(','))) + def get_newsletters(self, **kwargs): + endpoint = self.url + 'newsletters/' + url = get_signed_url(endpoint, self.url, **kwargs) + response = requests.get(url, verify=False) + if response.ok: + json_response = response.json() + return self.filter_data(json_response['data']) + return [] def check_resource(self, resource): restrictions = self.get_resources_restrictions() @@ -107,27 +90,6 @@ class NewslettersCell(CellBase): return True return False - def filter_data(self, data): - filtered = [] - for item in data: - if not self.check_resource(item['text']): - continue - if not self.transports_restrictions: - filtered.append(item) - for t in item['transports']: - if self.check_transport(t['id']): - filtered.append(item) - return filtered - - def get_newsletters(self, **kwargs): - endpoint = self.url + 'newsletters/' - url = get_signed_url(endpoint, self.url, **kwargs) - response = requests.get(url) - if response.ok: - json_response = response.json() - return self.filter_data(json_response['data']) - return [] - def get_subscriptions(self, **kwargs): endpoint = self.url + 'subscriptions/' url = get_signed_url(endpoint, self.url, **kwargs) @@ -137,6 +99,9 @@ class NewslettersCell(CellBase): return self.filter_data(json_response['data']) return [] + def simplify(self, name): + return slugify(name.strip()) + def set_subscriptions(self, subscriptions, **kwargs): logger = logging.getLogger(__name__) headers = {'Content-type': 'application/json', 'Accept': 'application/json'} @@ -161,7 +126,81 @@ class NewslettersCell(CellBase): if user.is_authenticated(): form = NewslettersManageForm(instance=self, user=user) context['form'] = form - return super(NewslettersCell, self).render(context) + return super(NewslettersMixin, self).render(context) - def is_relevant(self, context): - return bool(context.get('user').is_authenticated()) + +@register_cell_class +class NewslettersCell(NewslettersMixin, CellBase): + title = models.CharField(verbose_name=_('Title'), max_length=128) + url = models.URLField(verbose_name=_('Newsletters service url'), + max_length=128) + resources_restrictions = models.CharField(_('resources restrictions'), + blank=True, max_length=1024, + help_text=_('list of resources(themes) separated by commas')) + transports_restrictions = models.CharField(_('transports restrictions'), + blank=True, max_length=1024, + help_text=_('list of transports separated by commas')) + + template_name = 'newsletters/newsletters.html' + + class Meta: + verbose_name = _('Newsletters') + + def get_default_form_class(self): + model_fields = ('title', 'url', 'resources_restrictions', + 'transports_restrictions') + return model_forms.modelform_factory(self.__class__, fields=model_fields) + + def get_resources_restrictions(self): + return filter(None, map(self.simplify, self.resources_restrictions.strip().split(','))) + + def get_transports_restrictions(self): + return filter(None, map(self.simplify, self.transports_restrictions.strip().split(','))) + + def filter_data(self, data): + filtered = [] + for item in data: + if not self.check_resource(item['text']): + continue + if not self.transports_restrictions: + filtered.append(item) + for t in item['transports']: + if self.check_transport(t['id']): + filtered.append(item) + return filtered + + +@register_cell_class +class NewsletterSubscriptionCell(NewslettersMixin, CellBase): + title = models.CharField(verbose_name=_('Title'), max_length=128) + url = models.URLField(verbose_name=_('Newsletters service url'), + max_length=128) + newsletter = models.CharField(_('Newsletter'), max_length=128) + + template_name = 'newsletters/newsletter_subscription.html' + + class Meta: + verbose_name = _('Newsletter subscription') + + def filter_data(self, data): + return [i for i in data if i['text'] == self.newsletter] + + def get_resources_restrictions(self): + return [self.simplify(self.newsletter)] + + def get_transports_restrictions(self): + return ['mailto'] + + def set_subscription(self, subscription, **kwargs): + pass + + def get_default_form_class(self): + model_fields = ('title', 'url', 'newsletter') + return model_forms.modelform_factory(self.__class__, fields=model_fields) + + def render(self, context): + user = context.get('user') + if user.is_authenticated(): + form = NewslettersManageForm(instance=self, user=user, include_labels=True) + context['form'] = form + return super(NewslettersMixin, self).render(context) diff --git a/combo/apps/newsletters/templates/newsletters/newsletter_subscription.html b/combo/apps/newsletters/templates/newsletters/newsletter_subscription.html new file mode 100644 index 0000000..d93c9e9 --- /dev/null +++ b/combo/apps/newsletters/templates/newsletters/newsletter_subscription.html @@ -0,0 +1,18 @@ +{% load i18n %} + +

{{ cell.title }}

+{% if form %} +{% if form.non_field_errors %} +{{ form.non_field_errors }} +{% else %} +
+ {% csrf_token %} + {% for field in form %} + {% for w in field %} + {{ w }} + {% endfor %} + {% endfor %} + +
+{% endif %} +{% endif %} diff --git a/combo/apps/newsletters/urls.py b/combo/apps/newsletters/urls.py index 4cf5215..fb048ce 100644 --- a/combo/apps/newsletters/urls.py +++ b/combo/apps/newsletters/urls.py @@ -1,9 +1,11 @@ from django.contrib.auth.decorators import login_required from django.conf.urls import patterns, url -from .views import NewslettersView +from .views import NewslettersView, NewsletterSubscriptionView urlpatterns = patterns('', url('^newsletters/(?P\w+)/update$', login_required(NewslettersView.as_view()), name='newsletters-update'), + url('^subscription/(?P\w+)/update$', login_required(NewsletterSubscriptionView.as_view()), + name='newsletter-subscription-update'), ) diff --git a/combo/apps/newsletters/views.py b/combo/apps/newsletters/views.py index d365379..a061d09 100644 --- a/combo/apps/newsletters/views.py +++ b/combo/apps/newsletters/views.py @@ -20,12 +20,23 @@ from django.contrib import messages from django.http import HttpResponseRedirect from .forms import NewslettersManageForm -from .models import NewslettersCell, SubscriptionsSaveError +from .models import NewslettersCell, NewsletterSubscriptionCell, SubscriptionsSaveError -class NewslettersView(FormView): + +class NewslettersMixin(object): http_method_names = ['post'] form_class = NewslettersManageForm + def get_success_url(self): + return self.instance.page.get_online_url() + + def form_invalid(self, form): + messages.error(self.request, _('An error occured while saving your subscriptions. Please try later.')) + return HttpResponseRedirect(self.get_success_url()) + + +class NewslettersView(NewslettersMixin, FormView): + def form_valid(self, form): try: form.save() @@ -40,9 +51,19 @@ class NewslettersView(FormView): kwargs.update({'user': self.request.user, 'instance': self.instance}) return kwargs - def form_invalid(self, form): - messages.error(self.request, _('An error occured while saving your subscriptions. Please try later.')) - return HttpResponseRedirect(self.get_success_url()) - def get_success_url(self): - return self.instance.page.get_online_url() +class NewsletterSubscriptionView(NewslettersMixin, FormView): + + def form_valid(self, form): + try: + form.save() + messages.info(self.request, _('Your subscription is successfully saved')) + except SubscriptionsSaveError: + messages.error(self.request, _('An error occured while saving your subscription. Please try later.')) + return super(NewsletterSubscriptionView, self).form_valid(form) + + def get_form_kwargs(self): + kwargs = super(NewsletterSubscriptionView, self).get_form_kwargs() + self.instance = NewsletterSubscriptionCell.objects.get(pk=self.kwargs['pk']) + kwargs.update({'user': self.request.user, 'instance': self.instance}) + return kwargs -- 2.9.3