Merge pull request #59 from Schlabonski/mailer-memberlists

pick individual recipient for a message (group, memberlist or single members)
v1-0-stable
Christian Merten 9 years ago committed by GitHub
commit 77ee6457ba

@ -5,7 +5,8 @@ from django.shortcuts import render
from django.db import models from django.db import models
from django import forms from django import forms
from .models import Message, Attachment from .models import Message, Attachment, MessageForm
from .mailutils import NOT_SENT, PARTLY_SENT
class AttachmentInline(admin.StackedInline): class AttachmentInline(admin.StackedInline):
@ -15,7 +16,7 @@ class AttachmentInline(admin.StackedInline):
class MessageAdmin(admin.ModelAdmin): class MessageAdmin(admin.ModelAdmin):
"""Message creation view""" """Message creation view"""
list_display = ('subject', 'from_addr', 'get_groups', 'sent') list_display = ('subject', 'from_addr', 'get_recipients', 'sent')
change_form_template = "mailer/change_form.html" change_form_template = "mailer/change_form.html"
formfield_overrides = { formfield_overrides = {
models.ManyToManyField: {'widget': forms.CheckboxSelectMultiple} models.ManyToManyField: {'widget': forms.CheckboxSelectMultiple}
@ -23,13 +24,13 @@ class MessageAdmin(admin.ModelAdmin):
inlines = [AttachmentInline] inlines = [AttachmentInline]
actions = ['send_message'] actions = ['send_message']
form = MessageForm
filter_horizontal = ('to_members',)
def send_message(self, request, queryset): def send_message(self, request, queryset):
print("calling send_message")
if request.POST.get('confirmed'): if request.POST.get('confirmed'):
for msg in queryset: for msg in queryset:
msg.submit() submit_message(msg, request)
self.message_user(request, _("Message sent"))
else: else:
context = { context = {
'action_checkbox_name': helpers.ACTION_CHECKBOX_NAME, 'action_checkbox_name': helpers.ACTION_CHECKBOX_NAME,
@ -41,19 +42,23 @@ class MessageAdmin(admin.ModelAdmin):
def response_change(self, request, obj): def response_change(self, request, obj):
if "_send" in request.POST: if "_send" in request.POST:
if not obj.submit(): submit_message(obj, request)
messages.error(request, _("Failed to send message"))
else:
messages.info(request, _("Successfully sent message"))
return super(MessageAdmin, self).response_change(request, obj) return super(MessageAdmin, self).response_change(request, obj)
def response_add(self, request, obj): def response_add(self, request, obj):
if "_send" in request.POST: if "_send" in request.POST:
if not obj.submit(): submit_message(obj, request)
messages.error(request, _("Failed to send message"))
else:
messages.info(request, _("Successfully sent message"))
return super(MessageAdmin, self).response_add(request, obj) return super(MessageAdmin, self).response_add(request, obj)
def submit_message(msg, request):
success = msg.submit()
if success == NOT_SENT:
messages.error(request, _("Failed to send message"))
elif success == PARTLY_SENT:
messages.warning(request, _("Failed to send some messages"))
else:
messages.info(request, _("Successfully sent message"))
admin.site.register(Message, MessageAdmin) admin.site.register(Message, MessageAdmin)

@ -1,8 +1,12 @@
from django.core.mail import EmailMessage from django.core.mail import EmailMessage
NOT_SENT, SENT, PARTLY_SENT = 0, 1, 2
def send(subject, content, sender, recipients, reply_to=None, def send(subject, content, sender, recipients, reply_to=None,
attachments=None): attachments=None):
failed, succeeded = False, False
if type(recipients) != list: if type(recipients) != list:
recipients = [recipients] recipients = [recipients]
if reply_to is not None: if reply_to is not None:
@ -18,9 +22,11 @@ def send(subject, content, sender, recipients, reply_to=None,
email.send() email.send()
except Exception as e: except Exception as e:
print("Error when sending mail:", e) print("Error when sending mail:", e)
return False failed = True
else: else:
return True succeeded = True
return NOT_SENT if failed and not succeeded else SENT if not failed\
and succeeded else PARTLY_SENT
def get_content(content): def get_content(content):

@ -1,7 +1,9 @@
from django.db import models from django.db import models
from django.forms import forms from django.core.exceptions import ValidationError
from django import forms
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from .mailutils import send, get_content from django.utils.translation import ugettext
from .mailutils import send, get_content, SENT, PARTLY_SENT
import os import os
@ -35,40 +37,67 @@ class Message(models.Model):
subject = models.CharField(_('subject'), max_length=50) subject = models.CharField(_('subject'), max_length=50)
content = models.TextField(_('content')) content = models.TextField(_('content'))
to_groups = models.ManyToManyField('members.Group', to_groups = models.ManyToManyField('members.Group',
verbose_name=_('to group')) verbose_name=_('to group'),
blank=True)
to_memberlist = models.ForeignKey('members.MemberList',
verbose_name=_('to member list'),
blank=True,
null=True)
to_members = models.ManyToManyField('members.Member',
verbose_name=_('to member'),
blank=True)
reply_to = models.ForeignKey('members.Member',
verbose_name=_('reply to'),
blank=True,
null=True,
related_name='reply_to')
sent = models.BooleanField(_('sent'), default=False) sent = models.BooleanField(_('sent'), default=False)
def __str__(self): def __str__(self):
return self.subject return self.subject
def get_groups(self): def get_recipients(self):
return ", ".join([g.name for g in self.to_groups.all()]) recipients = [g.name for g in self.to_groups.all()]
get_groups.short_description = _('recipients') if self.to_memberlist is not None:
recipients.append(self.to_memberlist.name)
if 3 > self.to_members.count() > 0:
recipients.extend([m.name for m in self.to_members.all()])
elif self.to_members.count() > 2:
recipients.append(ugettext('Some other members'))
return ", ".join(recipients)
get_recipients.short_description = _('recipients')
def submit(self): def submit(self):
"""Sends the mail to the specified group of members""" """Sends the mail to the specified group of members"""
# recipients
members = set() members = set()
for group in self.to_groups.all(): # get all the members of the selected groups
group_members = group.member_set.all() groups = [gr.member_set.all() for gr in self.to_groups.all()]
for member in group_members: members.update([m for gr in groups for m in gr])
if not member.gets_newsletter: # get all the individually picked members
continue members.update(self.to_members.all())
members.add(member) # get all the members of the selected member list
if self.to_memberlist is not None:
members.update([mol.member for mol in
self.to_memberlist.memberonlist_set.all()])
members.update(self.to_memberlist.jugendleiter.all())
filtered = [m for m in members if m.gets_newsletter]
print("sending mail to", filtered)
attach = [a.f.path for a in Attachment.objects.filter(msg__id=self.pk) attach = [a.f.path for a in Attachment.objects.filter(msg__id=self.pk)
if a.f.name] if a.f.name]
success = send(self.subject, get_content(self.content), success = send(self.subject, get_content(self.content),
self.from_addr, [member.email for member in members], self.from_addr,
attachments=attach) [member.email for member in filtered],
attachments=attach,
reply_to=self.reply_to.email if self.reply_to else None)
for a in Attachment.objects.filter(msg__id=self.pk): for a in Attachment.objects.filter(msg__id=self.pk):
if a.f.name: if a.f.name:
os.remove(a.f.path) os.remove(a.f.path)
a.delete() a.delete()
if success: if success == SENT or success == PARTLY_SENT:
self.sent = True self.sent = True
self.save() self.save()
return True return success
else:
return False
class Meta: class Meta:
verbose_name = _('message') verbose_name = _('message')
@ -78,10 +107,24 @@ class Message(models.Model):
) )
class MessageForm(forms.ModelForm):
class Meta:
model = Message
exclude = []
def clean(self):
group = self.cleaned_data.get('to_groups')
memberlist = self.cleaned_data.get('to_memberlist')
members = self.cleaned_data.get('to_members')
if not group and memberlist is None and not members:
raise ValidationError(_('Either a group, a memberlist or at least'
' one member is required as recipient'))
class Attachment(models.Model): class Attachment(models.Model):
"""Represents an attachment to an email""" """Represents an attachment to an email"""
msg = models.ForeignKey(Message, on_delete=models.CASCADE) msg = models.ForeignKey(Message, on_delete=models.CASCADE)
print("attachment class")
# file (not naming it file because of builtin) # file (not naming it file because of builtin)
f = RestrictedFileField(_('file'), f = RestrictedFileField(_('file'),
upload_to='attachments', upload_to='attachments',

Loading…
Cancel
Save