Begin mailing list system

This commit is contained in:
Antoine Bartuccio 2017-08-17 00:07:19 +02:00
parent df42617cda
commit feaf6b73b7
5 changed files with 243 additions and 3 deletions

View File

@ -0,0 +1,33 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
from django.conf import settings
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('club', '0008_auto_20170515_2214'),
]
operations = [
migrations.CreateModel(
name='Mailing',
fields=[
('id', models.AutoField(serialize=False, primary_key=True, auto_created=True, verbose_name='ID')),
('email', models.EmailField(verbose_name='Email address', unique=True, max_length=254)),
('club', models.ForeignKey(verbose_name='Club', related_name='mailings', to='club.Club')),
],
),
migrations.CreateModel(
name='MailingSubscription',
fields=[
('id', models.AutoField(serialize=False, primary_key=True, auto_created=True, verbose_name='ID')),
('email', models.EmailField(verbose_name='Email address', max_length=254, unique=True)),
('mailing', models.ForeignKey(verbose_name='Mailing', related_name='subscriptions', to='club.Mailing')),
('user', models.ForeignKey(null=True, verbose_name='User', related_name='mailing_subscriptions', to=settings.AUTH_USER_MODEL, blank=True)),
],
),
]

View File

@ -2,6 +2,7 @@
# #
# Copyright 2016,2017 # Copyright 2016,2017
# - Skia <skia@libskia.so> # - Skia <skia@libskia.so>
# - Sli <antoine@bartuccio.fr>
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
# http://ae.utbm.fr. # http://ae.utbm.fr.
@ -220,3 +221,36 @@ class Membership(models.Model):
def get_absolute_url(self): def get_absolute_url(self):
return reverse('club:club_members', kwargs={'club_id': self.club.id}) return reverse('club:club_members', kwargs={'club_id': self.club.id})
class Mailing(models.Model):
"""
This class correspond to a mailing list
"""
club = models.ForeignKey(Club, verbose_name=_('Club'), related_name="mailings", null=False, blank=False)
email = models.EmailField(_('Email address'), unique=True)
def is_owned_by(self, user):
return self.club.has_rights_in_club(user) or user.is_root
def can_be_edited_by(self, user):
return self.is_owned_by(user)
def __str__(self):
return "%s - %s" % (self.club, self.email)
class MailingSubscription(models.Model):
"""
This class make the link between user and mailing list
"""
mailing = models.ForeignKey(Mailing, verbose_name=_('Mailing'), related_name="subscriptions", null=False, blank=False)
user = models.ForeignKey(User, verbose_name=_('User'), related_name="mailing_subscriptions", null=True, blank=True)
email = models.EmailField(_('Email address'), unique=True)
def is_owned_by(self, user):
return self.mailing.club.has_rights_in_club(user) or user.is_root
def can_be_edited_by(self, user):
return self.is_owned_by(user) or (user is not None and user.id == self.user.id)

View File

@ -0,0 +1,56 @@
{% extends "core/base.jinja" %}
{% block title %}
{% trans %}Mailing lists{% endtrans %}
{% endblock %}
{% block content %}
{% if has_objects %}
{% for mailing in object_list %}
<h2>{% trans %}Mailing{% endtrans %} {{ mailing.email }}</h2>
<table>
<tr>
<th>{% trans %}User{% endtrans %}</th>
<th>{% trans %}Mail{%endtrans%}</th>
</tr>
{% for subscriber in mailing.subscriptions.all() %}
<tr>
{% if subscriber.user %}
<td>{{ subscriber.user }}</td>
{% else %}
<td>{% trans %}Unregistered user{% endtrans %}</td>
{% endif %}
<td>{{ subscriber.email }}</td>
</tr>
{% endfor %}
</table>
{% endfor %}
{% else %}
<p>{% trans %}No mailing list existing for this club{% endtrans %}</p>
{% endif %}
{% if club.has_rights_in_club(user) %}
{% if has_objects %}
<h2>{% trans %}New member{% endtrans %}</h2>
<form action="{{ url('club:mailing_subscription_create', club_id=club.id) }}" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ new_member.as_p() }}
<p><input type="submit" value="{% trans %}Add to mailing list{% endtrans %}" /></p>
</form>
{% endif %}
<h2>{% trans %}New mailing{% endtrans %}</h2>
<form action="{{ url('club:mailing_create', club_id=club.id) }}" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ new_mailing.as_p() }}
<p><input type="submit" value="{% trans %}Create mailing list{% endtrans %}" /></p>
</form>
{% endif %}
{% endblock %}

View File

@ -2,6 +2,7 @@
# #
# Copyright 2016,2017 # Copyright 2016,2017
# - Skia <skia@libskia.so> # - Skia <skia@libskia.so>
# - Sli <antoine@bartuccio.fr>
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
# http://ae.utbm.fr. # http://ae.utbm.fr.
@ -38,5 +39,8 @@ urlpatterns = [
url(r'^(?P<club_id>[0-9]+)/sellings/csv$', ClubSellingCSVView.as_view(), name='sellings_csv'), url(r'^(?P<club_id>[0-9]+)/sellings/csv$', ClubSellingCSVView.as_view(), name='sellings_csv'),
url(r'^(?P<club_id>[0-9]+)/prop$', ClubEditPropView.as_view(), name='club_prop'), url(r'^(?P<club_id>[0-9]+)/prop$', ClubEditPropView.as_view(), name='club_prop'),
url(r'^(?P<club_id>[0-9]+)/tools$', ClubToolsView.as_view(), name='tools'), url(r'^(?P<club_id>[0-9]+)/tools$', ClubToolsView.as_view(), name='tools'),
url(r'^(?P<club_id>[0-9]+)/mailing$', ClubMailingView.as_view(action=MailingFormType.DISPLAY), name='mailing'),
url(r'^(?P<club_id>[0-9]+)/mailing/new/mailing$', ClubMailingView.as_view(action=MailingFormType.MAILING), name='mailing_create'),
url(r'^(?P<club_id>[0-9]+)/mailing/new/subscription$', ClubMailingView.as_view(action=MailingFormType.MEMBER), name='mailing_subscription_create'),
url(r'^membership/(?P<membership_id>[0-9]+)/set_old$', MembershipSetOldView.as_view(), name='membership_set_old'), url(r'^membership/(?P<membership_id>[0-9]+)/set_old$', MembershipSetOldView.as_view(), name='membership_set_old'),
] ]

View File

@ -2,6 +2,7 @@
# #
# Copyright 2016,2017 # Copyright 2016,2017
# - Skia <skia@libskia.so> # - Skia <skia@libskia.so>
# - Sli <antoine@bartuccio.fr>
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
# http://ae.utbm.fr. # http://ae.utbm.fr.
@ -23,21 +24,53 @@
# #
from django import forms from django import forms
from enum import Enum
from django.views.generic import ListView, DetailView, TemplateView from django.views.generic import ListView, DetailView, TemplateView
from django.views.generic.edit import DeleteView, FormView
from django.views.generic.detail import SingleObjectMixin
from django.views.generic.edit import UpdateView, CreateView from django.views.generic.edit import UpdateView, CreateView
from django.http import HttpResponseRedirect, HttpResponse from django.http import HttpResponseRedirect, HttpResponse
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse, reverse_lazy
from django.utils import timezone from django.utils import timezone
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ugettext as _t from django.utils.translation import ugettext as _t
from ajax_select.fields import AutoCompleteSelectField from ajax_select.fields import AutoCompleteSelectField
from django.shortcuts import get_object_or_404
from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin, TabedViewMixin from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin, TabedViewMixin, CanCreateMixin
from core.views.forms import SelectDate, SelectDateTime from core.views.forms import SelectDate, SelectDateTime
from club.models import Club, Membership from club.models import Club, Membership, Mailing, MailingSubscription
from sith.settings import SITH_MAXIMUM_FREE_ROLE from sith.settings import SITH_MAXIMUM_FREE_ROLE
from counter.models import Selling, Counter from counter.models import Selling, Counter
# Custom forms
class MailingForm(forms.ModelForm):
class Meta:
model = Mailing
fields = ('email', 'club')
def __init__(self, *args, **kwargs):
club_id = kwargs.pop('club_id', None)
super(MailingForm, self).__init__(*args, **kwargs)
if club_id:
self.fields['club'].queryset = Club.objects.filter(id=club_id)
class MailingSubscriptionForm(forms.ModelForm):
class Meta:
model = MailingSubscription
fields = ('mailing', 'user', 'email')
def __init__(self, *args, **kwargs):
club_id = kwargs.pop('club_id', None)
super(MailingSubscriptionForm, self).__init__(*args, **kwargs)
if club_id:
self.fields['mailing'].queryset = Mailing.objects.filter(club__id=club_id)
user = AutoCompleteSelectField('users', label=_('User'), help_text=None, required=False)
class ClubTabsMixin(TabedViewMixin): class ClubTabsMixin(TabedViewMixin):
def get_tabs_title(self): def get_tabs_title(self):
@ -61,6 +94,11 @@ class ClubTabsMixin(TabedViewMixin):
'slug': 'elderlies', 'slug': 'elderlies',
'name': _("Old members"), 'name': _("Old members"),
}) })
tab_list.append({
'url': reverse('club:mailing', kwargs={'club_id': self.object.id}),
'slug': 'mailing',
'name': _("Mailing list"),
})
if self.request.user.can_edit(self.object): if self.request.user.can_edit(self.object):
tab_list.append({ tab_list.append({
'url': reverse('club:tools', kwargs={'club_id': self.object.id}), 'url': reverse('club:tools', kwargs={'club_id': self.object.id}),
@ -338,3 +376,78 @@ class ClubStatView(TemplateView):
kwargs = super(ClubStatView, self).get_context_data(**kwargs) kwargs = super(ClubStatView, self).get_context_data(**kwargs)
kwargs['club_list'] = Club.objects.all() kwargs['club_list'] = Club.objects.all()
return kwargs return kwargs
class MailingFormType(Enum):
DISPLAY = 0
MEMBER = 1
MAILING = 2
class ClubMailingView(CanViewMixin, ListView):
"""
A list of mailing for a given club
"""
action = None
model = Mailing
template_name = "club/mailing.jinja"
def dispatch(self, request, *args, **kwargs):
self.club = get_object_or_404(Club, pk=kwargs['club_id'])
self.user = request.user
self.member_form = MailingSubscriptionForm(club_id=self.club.id)
self.mailing_form = MailingForm(club_id=self.club.id)
return super(ClubMailingView, self).dispatch(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
res = super(ClubMailingView, self).get(request, *args, **kwargs)
if self.action != MailingFormType.DISPLAY:
if self.action == MailingFormType.MAILING:
form = MailingForm
string = 'new_mailing'
elif self.action == MailingFormType.MEMBER:
form = MailingSubscriptionForm
string = 'new_member'
return MailingGenericCreateView.as_view(list_view=self, form_class=form, form_kwarg_string=string)(request, *args, **kwargs)
return res
def get_queryset(self):
return Mailing.objects.filter(club_id=self.club.id).all()
def get_context_data(self, **kwargs):
kwargs = super(ClubMailingView, self).get_context_data(**kwargs)
kwargs['new_member'] = self.member_form
kwargs['new_mailing'] = self.mailing_form
kwargs['club'] = self.club
kwargs['user'] = self.user
kwargs['has_objects'] = len(kwargs['object_list']) > 0
return kwargs
class MailingGenericCreateView(CanCreateMixin, CreateView, SingleObjectMixin):
"""
Create a new mailing list
"""
model = Mailing
list_view = None
form_class = None
form_kwarg_string = None
def get_context_data(self, **kwargs):
view_kwargs = self.list_view.get_context_data(**kwargs)
for key, data in super(MailingGenericCreateView, self).get_context_data(**kwargs).items():
view_kwargs[key] = data
view_kwargs[self.form_kwarg_string] = view_kwargs['form']
return view_kwargs
def get_form_kwargs(self):
kwargs = super(MailingGenericCreateView, self).get_form_kwargs()
kwargs['club_id'] = self.list_view.club.id
return kwargs
def dispatch(self, request, *args, **kwargs):
self.template_name = self.list_view.template_name
return super(MailingGenericCreateView, self).dispatch(request, *args, **kwargs)
def get_success_url(self, **kwargs):
return reverse_lazy('club:mailing', kwargs={'club_id': self.list_view.club.id})