# -*- coding: utf-8 -*- # Copyright (C) 1998-2016 by the Free Software Foundation, Inc. # # This file is part of Postorius. # # Postorius is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free # Software Foundation, either version 3 of the License, or (at your option) # any later version. # # Postorius is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # more details. # # You should have received a copy of the GNU General Public License along with # Postorius. If not, see <http://www.gnu.org/licenses/>. from __future__ import absolute_import, unicode_literals import logging from django.utils.six.moves.urllib.error import HTTPError from allauth.account.models import EmailAddress from django.forms import formset_factory from django.contrib import messages from django.contrib.auth.decorators import login_required from django.shortcuts import redirect, render from django.utils.decorators import method_decorator from django.utils.translation import gettext as _ from django.http import Http404 from postorius import utils from postorius.models import ( MailmanApiError, List, MailmanUser, Mailman404Error) from postorius.forms import UserPreferences, ChangeSubscriptionForm from postorius.views.generic import MailmanUserView logger = logging.getLogger(__name__) class UserMailmanSettingsView(MailmanUserView): """The logged-in user's global Mailman Preferences.""" @method_decorator(login_required) def post(self, request): try: mm_user = MailmanUser.objects.get(address=request.user.email) form = UserPreferences(request.POST) if form.is_valid(): preferences = mm_user.preferences for key in form.fields.keys(): if form.cleaned_data[key] is not None: # None: nothing set yet. Remember to remove this test # when Mailman accepts None as a "reset to default" # value. preferences[key] = form.cleaned_data[key] preferences.save() messages.success(request, _('Your preferences have been updated.')) else: messages.error(request, _('Something went wrong.')) except MailmanApiError: return utils.render_api_error(request) except Mailman404Error as e: messages.error(request, e.msg) return redirect("user_mailmansettings") @method_decorator(login_required) def get(self, request): try: mm_user = MailmanUser.objects.get_or_create_from_django( request.user) except MailmanApiError: return utils.render_api_error(request) settingsform = UserPreferences(initial=mm_user.preferences) return render(request, 'postorius/user/mailman_settings.html', {'mm_user': mm_user, 'settingsform': settingsform}) class UserAddressPreferencesView(MailmanUserView): """The logged-in user's address-based Mailman Preferences.""" @method_decorator(login_required) def post(self, request): try: mm_user = MailmanUser.objects.get(address=request.user.email) formset_class = formset_factory(UserPreferences) formset = formset_class(request.POST) if formset.is_valid(): for form, address in zip(formset.forms, mm_user.addresses): preferences = address.preferences for key in form.fields.keys(): if (key in form.cleaned_data and form.cleaned_data[key] is not None): # None: nothing set yet. Remember to remove this # test when Mailman accepts None as a # "reset to default" value. preferences[key] = form.cleaned_data[key] preferences.save() messages.success(request, _('Your preferences have been updated.')) else: messages.error(request, _('Something went wrong.')) except MailmanApiError: return utils.render_api_error(request) except HTTPError as e: messages.error(request, e.msg) return redirect("user_address_preferences") @method_decorator(login_required) def get(self, request): try: helperform = UserPreferences() mm_user = MailmanUser.objects.get(address=request.user.email) addresses = mm_user.addresses AFormset = formset_factory(UserPreferences, extra=len(addresses)) formset = AFormset() zipped_data = zip(formset.forms, addresses) for form, address in zipped_data: form.initial = address.preferences except MailmanApiError: return utils.render_api_error(request) except Mailman404Error: return render(request, 'postorius/user/address_preferences.html', {'nolists': 'true'}) return render(request, 'postorius/user/address_preferences.html', {'mm_user': mm_user, 'addresses': addresses, 'helperform': helperform, 'formset': formset, 'zipped_data': zipped_data}) @login_required def user_list_options(request, list_id): mlist = List.objects.get_or_404(fqdn_listname=list_id) mm_user = MailmanUser.objects.get(address=request.user.email) subscription = None for s in mm_user.subscriptions: if s.role == 'member' and s.list_id == list_id: subscription = s break if not subscription: raise Http404(_('Subscription does not exist')) preferences = subscription.preferences if request.method == 'POST': form = UserPreferences(request.POST) if form.is_valid(): for key in form.cleaned_data.keys(): if form.cleaned_data[key] is not None: # None: nothing set yet. Remember to remove this test # when Mailman accepts None as a "reset to default" # value. preferences[key] = form.cleaned_data[key] preferences.save() messages.success(request, _('Your preferences have been updated.')) return redirect('user_list_options', list_id) else: messages.error(request, _('Something went wrong.')) else: form = UserPreferences(initial=subscription.preferences) user_emails = EmailAddress.objects.filter( user=request.user, verified=True).order_by( "email").values_list("email", flat=True) subscription_form = ChangeSubscriptionForm( user_emails, initial={'email': subscription.email}) return render(request, 'postorius/user/list_options.html', {'form': form, 'list': mlist, 'change_subscription_form': subscription_form}) class UserSubscriptionPreferencesView(MailmanUserView): """The logged-in user's subscription-based Mailman Preferences.""" @method_decorator(login_required) def post(self, request): try: subscriptions = self._get_memberships() formset_class = formset_factory(UserPreferences) formset = formset_class(request.POST) if formset.is_valid(): for form, subscription in zip(formset.forms, subscriptions): preferences = subscription.preferences for key in form.cleaned_data.keys(): if form.cleaned_data[key] is not None: # None: nothing set yet. Remember to remove this # test when Mailman accepts None as a # "reset to default" value. preferences[key] = form.cleaned_data[key] preferences.save() messages.success(request, _('Your preferences have been updated.')) else: messages.error(request, _('Something went wrong.')) except MailmanApiError: return utils.render_api_error(request) except HTTPError as e: messages.error(request, e.msg) return redirect("user_subscription_preferences") @method_decorator(login_required) def get(self, request): try: subscriptions = self._get_memberships() Mformset = formset_factory( UserPreferences, extra=len(subscriptions)) formset = Mformset() zipped_data = zip(formset.forms, subscriptions) for form, subscription in zipped_data: form.initial = subscription.preferences except MailmanApiError: return utils.render_api_error(request) except Mailman404Error: return render(request, 'postorius/user/subscription_preferences.html', {'nolists': 'true'}) return render(request, 'postorius/user/subscription_preferences.html', {'zipped_data': zipped_data, 'formset': formset}) @login_required def user_subscriptions(request): """Shows the subscriptions of a user.""" try: mm_user = MailmanUser.objects.get_or_create_from_django(request.user) except MailmanApiError: return utils.render_api_error(request) memberships = [m for m in mm_user.subscriptions if m.role == 'member'] return render(request, 'postorius/user/subscriptions.html', {'memberships': memberships})