diff --git a/.gitignore b/.gitignore index 9b4a7d5..a1da0cd 100644 --- a/.gitignore +++ b/.gitignore @@ -93,6 +93,8 @@ jdav_web/db.sqlite3 # test images for file upload *.jpeg *.png +jdav_web/media +jdav_web/*/migrations *.py.swp # django database migrations diff --git a/jdav_web/jdav_web/settings.py b/jdav_web/jdav_web/settings.py index f67581e..c38a5db 100644 --- a/jdav_web/jdav_web/settings.py +++ b/jdav_web/jdav_web/settings.py @@ -37,6 +37,7 @@ INSTALLED_APPS = [ 'startpage.apps.StartpageConfig', 'material.apps.MaterialConfig', 'members.apps.MembersConfig', + 'mailer.apps.MailerConfig', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', @@ -133,3 +134,12 @@ STATIC_URL = '/static/' # Locale files (translations) LOCALE_PATHS = (os.path.join(BASE_DIR, 'locale'),) + + +# Email setup + +EMAIL_HOST = 'localhost' +EMAIL_PORT = 25 +EMAIL_HOST_USER = '' +EMAIL_HOST_PASSWORD = '' +EMAIL_USE_TLS = False diff --git a/jdav_web/jdav_web/urls.py b/jdav_web/jdav_web/urls.py index 9ebd7a6..9f394f0 100644 --- a/jdav_web/jdav_web/urls.py +++ b/jdav_web/jdav_web/urls.py @@ -23,6 +23,7 @@ urlpatterns = static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) urlpatterns += i18n_patterns( url(r'^admin/', admin.site.urls), + url(r'^newsletter/', include('mailer.urls', namespace="mailer")), url(r'^$', include('startpage.urls')), ) diff --git a/jdav_web/mailer/__init__.py b/jdav_web/mailer/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/jdav_web/mailer/admin.py b/jdav_web/mailer/admin.py new file mode 100644 index 0000000..ffb476a --- /dev/null +++ b/jdav_web/mailer/admin.py @@ -0,0 +1,42 @@ +from django.contrib import admin +from django.contrib.admin import helpers +from django.utils.translation import ugettext_lazy as _ +from django.shortcuts import render + +from .models import Message + + +class MessageAdmin(admin.ModelAdmin): + """Message creation view""" + list_display = ('subject', 'from_addr', 'get_groups', 'sent') + change_form_template = "mailer/change_form.html" + + actions = ['send_message'] + + def send_message(self, request, queryset): + print("calling send_message") + if request.POST.get('confirmed'): + for msg in queryset: + msg.submit() + self.message_user(request, _("Message sent")) + else: + context = { + 'action_checkbox_name': helpers.ACTION_CHECKBOX_NAME, + 'mails': queryset, + 'ids': queryset.values_list("id"), + 'some_sent': any(m.sent for m in queryset)} + return render(request, 'mailer/confirm_send.html', context) + send_message.short_description = _("Send message") + + def response_change(self, request, obj): + if "_send" in request.POST: + obj.submit() + return super(MessageAdmin, self).response_change(request, obj) + + def response_add(self, request, obj): + if "_send" in request.POST: + obj.submit() + return super(MessageAdmin, self).response_change(request, obj) + + +admin.site.register(Message, MessageAdmin) diff --git a/jdav_web/mailer/apps.py b/jdav_web/mailer/apps.py new file mode 100644 index 0000000..86c7e65 --- /dev/null +++ b/jdav_web/mailer/apps.py @@ -0,0 +1,7 @@ +from django.apps import AppConfig +from django.utils.translation import ugettext_lazy as _ + + +class MailerConfig(AppConfig): + name = 'mailer' + verbose_name = _('mailer') diff --git a/jdav_web/mailer/locale/de/LC_MESSAGES/django.po b/jdav_web/mailer/locale/de/LC_MESSAGES/django.po new file mode 100644 index 0000000..fd5005e --- /dev/null +++ b/jdav_web/mailer/locale/de/LC_MESSAGES/django.po @@ -0,0 +1,121 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-11-19 16:11+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: admin.py:20 +msgid "Message sent" +msgstr "Nachricht gesendet" + +#: admin.py:28 +msgid "Send message" +msgstr "Nachricht verschicken" + +#: apps.py:7 +msgid "mailer" +msgstr "Verteiler" + +#: models.py:9 +msgid "from email" +msgstr "Von Email" + +#: models.py:10 +msgid "subject" +msgstr "Betreff" + +#: models.py:11 +msgid "content" +msgstr "Inhalt" + +#: models.py:12 +msgid "to group" +msgstr "An Gruppe" + +#: models.py:13 +msgid "sent" +msgstr "Gesendet" + +#: models.py:29 +msgid "message" +msgstr "Nachricht" + +#: models.py:30 +msgid "messages" +msgstr "Nachrichten" + +#: models.py:32 +msgid "Can submit mails" +msgstr "Kann Mails verschicken" + +#: templates/admin/change_form.html:11 +msgid "Save and send mail" +msgstr "Speichern und Email senden" + +#: templates/mailer/confirm_send.html:7 +msgid "Do you really want to send these mails?" +msgstr "Möchtest du diese Emails wirklich verschicken?" + +#: templates/mailer/confirm_send.html:13 +msgid "already sent" +msgstr "schon verschickt" + +#: templates/mailer/confirm_send.html:19 +msgid "" +"Some messages have already been sent! Do you really want to resend them?" +msgstr "" +"Einige Emails wurden schon versendet! Möchtest du diese wirklich nochmal " +"senden?" + +#: templates/mailer/confirm_send.html:30 +msgid "Send" +msgstr "Senden" + +#: templates/mailer/confirm_send.html:35 +msgid "Cancel" +msgstr "Abbruch" + +#: templates/mailer/index.html:2 +msgid "This is the mailer app!" +msgstr "Das ist die Mailer App!" + +#: templates/mailer/send.html:2 +msgid "Here you can send new emails!" +msgstr "Hier kannst du neue Emails verschicken!" + +#: templates/mailer/send.html:11 +msgid "Subject:" +msgstr "Betreff" + +#: templates/mailer/send.html:14 +msgid "Content:" +msgstr "Inhalt:" + +#: templates/mailer/send.html:17 +msgid "Receiving group:" +msgstr "Erhaltende Gruppe" + +#: templates/mailer/send.html:24 +msgid "Send mail" +msgstr "Email senden" + +#: views.py:33 +msgid "Please fill in every field!" +msgstr "Bitte jedes Feld ausfüllen!" + +#~ msgid "History" +#~ msgstr "Geschichte" diff --git a/jdav_web/mailer/models.py b/jdav_web/mailer/models.py new file mode 100644 index 0000000..edabb55 --- /dev/null +++ b/jdav_web/mailer/models.py @@ -0,0 +1,43 @@ +from django.db import models +from django.utils.translation import ugettext_lazy as _ +from django.core.mail import send_mass_mail + + +# Create your models here. +class Message(models.Model): + """Represents a message that can be sent to some members""" + from_addr = models.EmailField(_('from email')) + subject = models.CharField(_('subject'), max_length=50) + content = models.TextField(_('content')) + to_groups = models.ManyToManyField('members.Group', + verbose_name=_('to group')) + sent = models.BooleanField(_('sent'), default=False) + + def __str__(self): + return self.subject + + def get_groups(self): + return ", ".join([g.name for g in self.to_groups.all()]) + get_groups.short_description = _('recipicients') + + def submit(self): + """Sends the mail to the specified group of members""" + members = set() + for group in self.to_groups.all(): + group_members = group.member_set.all() + for member in group_members: + members.add(member) + data = [ + (self.subject, self.content, self.from_addr, [member.email]) + for member in members + ] + send_mass_mail(data) + self.sent = True + self.save() + + class Meta: + verbose_name = _('message') + verbose_name_plural = _('messages') + permissions = ( + ("submit_mails", _("Can submit mails")), + ) diff --git a/jdav_web/mailer/templates/mailer/change_form.html b/jdav_web/mailer/templates/mailer/change_form.html new file mode 100644 index 0000000..c5be0e0 --- /dev/null +++ b/jdav_web/mailer/templates/mailer/change_form.html @@ -0,0 +1,15 @@ +{% extends "admin/change_form.html" %} +{% load i18n %} +{% block content %} +{{ block.super }} +{% load static %} + + + + +{% endblock %} diff --git a/jdav_web/mailer/templates/mailer/confirm_send.html b/jdav_web/mailer/templates/mailer/confirm_send.html new file mode 100644 index 0000000..82ae759 --- /dev/null +++ b/jdav_web/mailer/templates/mailer/confirm_send.html @@ -0,0 +1,38 @@ +{% extends "admin/base_site.html" %} +{% load i18n %} +{% load static %} + +{% block content %} + +

{% trans "Do you really want to send these mails?" %}

+
    +{% for mail in mails %} +
  • + {{mail.subject}} + {% if mail.sent %} + ({% trans "already sent" %}) + {%endif %} +
  • +{% endfor %} +
+{% if some_sent %} +

{% trans "Some messages have already been sent! Do you really want to resend them?" %}

+{% endif %} + +
+ {% csrf_token %} + + + + {% for id in ids %} + + {% endfor %} + +
+ +
+ {% csrf_token %} + +
+ +{% endblock %} diff --git a/jdav_web/mailer/templates/mailer/index.html b/jdav_web/mailer/templates/mailer/index.html new file mode 100644 index 0000000..c58684a --- /dev/null +++ b/jdav_web/mailer/templates/mailer/index.html @@ -0,0 +1,3 @@ +{% load i18n %} +{% trans "This is the mailer app!" %} +

New Mail

diff --git a/jdav_web/mailer/templates/mailer/send.html b/jdav_web/mailer/templates/mailer/send.html new file mode 100644 index 0000000..ad36842 --- /dev/null +++ b/jdav_web/mailer/templates/mailer/send.html @@ -0,0 +1,25 @@ +{% load i18n %} +{% trans "Here you can send new emails!" %} + +{% if error_message %} +

{{ error_message }}

+{% endif %} + +
+ {% csrf_token %} + + {% trans "Subject:" %}
+
+ + {% trans "Content:" %}
+
+ + {% trans "Receiving group:" %}
+
+ + +
diff --git a/jdav_web/mailer/tests.py b/jdav_web/mailer/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/jdav_web/mailer/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/jdav_web/mailer/urls.py b/jdav_web/mailer/urls.py new file mode 100644 index 0000000..03ad286 --- /dev/null +++ b/jdav_web/mailer/urls.py @@ -0,0 +1,10 @@ +from django.conf.urls import url + +from . import views + +app_name = "mailer" +urlpatterns = [ + url(r'^$', views.index, name='index'), + url(r'^send_mail', views.send_mail, name='send_mail'), + url(r'^send', views.send, name='send') +] diff --git a/jdav_web/mailer/views.py b/jdav_web/mailer/views.py new file mode 100644 index 0000000..9bc0fcb --- /dev/null +++ b/jdav_web/mailer/views.py @@ -0,0 +1,40 @@ +from django.shortcuts import render +from django.utils.translation import ugettext_lazy as _ +from django.urls import reverse +from django.http import HttpResponseRedirect +from django.contrib.auth.decorators import permission_required + +from members.models import Group + +from .models import Message + + +@permission_required('mailer.submit_mails', login_url='/admin/') +def index(request): + """This is the main newsletter view""" + return render(request, 'mailer/index.html') + + +@permission_required('mailer.submit_mails', login_url='/admin/') +def send(request): + return render(request, 'mailer/send.html', { + 'groups': Group.objects.all() + }) + + +@permission_required('mailer.submit_mails', login_url='/admin/') +def send_mail(request): + try: + subject = request.POST['subject'] + content = request.POST['content'] + to_group = Group.objects.get(pk=request.POST['to_group']) + except (KeyError, Group.DoesNotExist): + return render(request, 'mailer/send.html', { + 'error_message': _("Please fill in every field!"), + 'groups': Group.objects.all() + }) + else: + msg = Message(subject=subject, content=content, to_group=to_group) + msg.submit() + msg.save() + return HttpResponseRedirect(reverse('mailer:index')) diff --git a/requirements.txt b/requirements.txt index 6c4722e..19e4b8f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ Django==1.10.2 +Pillow==3.4.2 mysqlclient==1.3.9 -PyMySQL==0.7.9