Commit ed9d853e by benjaoming

Add notification interval to Article Settings page + New Notifications Settings page

parent 1d4faa9b
...@@ -35,7 +35,7 @@ WEEKLY = 7 * (24 - 1) * 60 ...@@ -35,7 +35,7 @@ WEEKLY = 7 * (24 - 1) * 60
# List of intervals available. In minutes # List of intervals available. In minutes
INTERVALS = getattr(django_settings, 'NOTIFY_INTERVALS', INTERVALS = getattr(django_settings, 'NOTIFY_INTERVALS',
[(INSTANTLY, _(u'instant')), [(INSTANTLY, _(u'instantly')),
(DAILY, _(u'daily')), (DAILY, _(u'daily')),
(WEEKLY, _(u'weekly'))] (WEEKLY, _(u'weekly'))]
) )
......
from django import forms from django import forms
from django.forms.models import modelformset_factory, BaseModelFormSet
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django_notify.models import Settings, NotificationType from django_notify.models import Settings, NotificationType
from django_notify import settings as notify_settings
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
from wiki.plugins.notifications.settings import ARTICLE_EDIT from wiki.plugins.notifications.settings import ARTICLE_EDIT
from wiki.core.plugins.base import PluginSettingsFormMixin from wiki.core.plugins.base import PluginSettingsFormMixin
class SettingsModelChoiceField(forms.ModelChoiceField):
def label_from_instance(self, obj):
return _(u"Receive notifications %(interval)s" % {
'interval': obj.get_interval_display()
}
)
class ArticleSubscriptionModelMultipleChoiceField(forms.ModelMultipleChoiceField):
def label_from_instance(self, obj):
return _(u"%(title)s - %(url)s" % {
'title': obj.article.current_revision.title,
'url': obj.article.get_absolute_url()
}
)
class SettingsModelForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(SettingsModelForm, self).__init__(*args, **kwargs)
import models
instance = kwargs.get('instance', None)
self.__editing_instance = False
if instance:
self.__editing_instance = True
self.fields['delete_subscriptions'] = ArticleSubscriptionModelMultipleChoiceField(
models.ArticleSubscription.objects.filter(settings=instance),
label=_(u"Remove subscriptions"),
required=False,
help_text=_(u"Select article subscriptions to remove from notifications"),
)
self.fields['email'] = forms.TypedChoiceField(
label=_(u"Email digests"),
choices = (
(0, _(u'Unchanged (selected on each article)')),
(1, _(u'No emails')),
(2, _(u'Email on any change')),
),
coerce=lambda x: int(x) if not x is None else None,
widget=forms.RadioSelect(),
required=False,
initial=0,
)
def save(self, *args, **kwargs):
instance = super(SettingsModelForm, self).save(*args, **kwargs)
if self.__editing_instance:
self.cleaned_data['delete_subscriptions'].delete()
if self.cleaned_data['email'] == 1:
instance.subscription_set.all().update(
send_emails=False,
)
if self.cleaned_data['email'] == 2:
instance.subscription_set.all().update(
send_emails=True,
)
return instance
class BaseSettingsFormSet(BaseModelFormSet):
def __init__(self, *args, **kwargs):
self.user = kwargs.pop('user')
super(BaseSettingsFormSet, self).__init__(*args, **kwargs)
def get_queryset(self):
return Settings.objects.filter(
user=self.user,
subscription__articlesubscription__article__current_revision__deleted=False,
).prefetch_related('subscription_set__articlesubscription',)
SettingsFormSet = modelformset_factory(
Settings,
form=SettingsModelForm,
formset=BaseSettingsFormSet,
extra=0,
fields=('interval', ),
)
class SubscriptionForm(PluginSettingsFormMixin, forms.Form): class SubscriptionForm(PluginSettingsFormMixin, forms.Form):
settings_form_headline = _(u'Notifications') settings_form_headline = _(u'Notifications')
settings_order = 1 settings_order = 1
settings_write_access = False settings_write_access = False
settings = SettingsModelChoiceField(
Settings,
empty_label=None,
)
edit = forms.BooleanField( edit = forms.BooleanField(
required=False, required=False,
label=_(u'When this article is edited') label=_(u'When this article is edited')
...@@ -34,23 +119,31 @@ class SubscriptionForm(PluginSettingsFormMixin, forms.Form): ...@@ -34,23 +119,31 @@ class SubscriptionForm(PluginSettingsFormMixin, forms.Form):
self.article = article self.article = article
self.user = request.user self.user = request.user
initial = kwargs.pop('initial', None) initial = kwargs.pop('initial', None)
self.settings = Settings.objects.get_or_create(user=request.user,)[0]
self.notification_type = NotificationType.objects.get_or_create( self.notification_type = NotificationType.objects.get_or_create(
key=ARTICLE_EDIT, key=ARTICLE_EDIT,
content_type=ContentType.objects.get_for_model(article) content_type=ContentType.objects.get_for_model(article)
)[0] )[0]
self.edit_notifications = models.ArticleSubscription.objects.filter( self.edit_notifications = models.ArticleSubscription.objects.filter(
settings=self.settings,
article=article, article=article,
notification_type=self.notification_type notification_type=self.notification_type
) )
self.default_settings = Settings.objects.get_or_create(
user=request.user,
interval=notify_settings.INTERVALS_DEFAULT
)[0]
if self.edit_notifications:
self.default_settings = self.edit_notifications[0].settings
if not initial: if not initial:
initial = { initial = {
'edit': bool(self.edit_notifications), 'edit': bool(self.edit_notifications),
'edit_email': bool(self.edit_notifications.filter(send_emails=True)) 'edit_email': bool(self.edit_notifications.filter(send_emails=True)),
'settings': self.default_settings,
} }
kwargs['initial'] = initial kwargs['initial'] = initial
super(SubscriptionForm, self).__init__(*args, **kwargs) super(SubscriptionForm, self).__init__(*args, **kwargs)
self.fields['settings'].queryset = Settings.objects.filter(
user=request.user,
)
def get_usermessage(self): def get_usermessage(self):
if self.changed_data: if self.changed_data:
...@@ -68,10 +161,10 @@ class SubscriptionForm(PluginSettingsFormMixin, forms.Form): ...@@ -68,10 +161,10 @@ class SubscriptionForm(PluginSettingsFormMixin, forms.Form):
return return
if cd['edit']: if cd['edit']:
edit_notification = models.ArticleSubscription.objects.get_or_create( edit_notification = models.ArticleSubscription.objects.get_or_create(
settings=self.settings,
article=self.article, article=self.article,
notification_type=self.notification_type notification_type=self.notification_type
)[0] )[0]
edit_notification.settings = cd['settings']
edit_notification.send_emails = cd['edit_email'] edit_notification.send_emails = cd['edit_email']
edit_notification.save() edit_notification.save()
else: else:
......
{% extends "wiki/base.html" %}
{% load wiki_tags i18n humanize %}
{% load url from future %}
{% block wiki_pagetitle %}{% trans "Notifications" %}: {{ article.current_revision.title }}{% endblock %}
{% block wiki_contents %}
<h1>{% trans "Your notification settings" %}</h1>
<p class="lead">
{% trans "Manage how often you receive notifications" %}
</p>
<form method="POST" class="form-horizontal">
{% include "wiki/includes/formerrors.html" with form=formset.management_form %}
{% csrf_token %}
{{ formset.management_form }}
{% for form in formset %}
<fieldset>
<legend>{% trans "Settings for" %} {{ form.instance.articlesubscriptions.count }} {% trans "articles" %}</legend>
{% include "wiki/includes/formerrors.html" with form=form %}
{% for field in form %}
{% include "wiki/includes/formfield.html" %}
{% endfor %}
</fieldset>
{% endfor %}
<div class="form-actions">
<button type="submit" class="btn btn-primary">
<span class="icon-ok"></span>
{% trans "Save changes" %}
</button>
</div>
</form>
<div class="row-fluid">
</div>
{% endblock %}
# Create your views here. # Create your views here.
from django.contrib import messages
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.shortcuts import redirect
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
from django.views.generic.list import ListView from django.utils.translation import ugettext as _
from django.views.generic.edit import FormView
from django_notify import models import forms
class NotificationSettings(ListView): class NotificationSettings(FormView):
template_name = 'wiki/plugins/notifications/settings.html' template_name = 'wiki/plugins/notifications/settings.html'
allow_empty = True form_class = forms.SettingsFormSet
context_object_name = 'settings'
paginate_by = 10
@method_decorator(login_required) @method_decorator(login_required)
def dispatch(self, request, *args, **kwargs): def dispatch(self, request, *args, **kwargs):
return super(NotificationSettings, self).dispatch(request, *args, **kwargs) return super(NotificationSettings, self).dispatch(request, *args, **kwargs)
def get_queryset(self): def form_valid(self, formset):
settings = models.Settings.objects.filter(user=self.request.user) for form in formset:
return settings settings = form.save()
import models
article_subscriptions = models.ArticleSubscription.objects.filter(
settings = form.instance,
article__current_revision__deleted=False,
).select_related('article', 'article__current_revision')
messages.info(
self.request,
_(u"You will receive notifications %(interval)s for "
"%(articles)d articles") %
{
'interval': settings.get_interval_display(),
'articles': article_subscriptions.count(),
}
)
return redirect('wiki:notification_settings')
def get_form_kwargs(self):
kwargs = FormView.get_form_kwargs(self)
kwargs['user'] = self.request.user
return kwargs
def get_context_data(self, **kwargs):
context = FormView.get_context_data(self, **kwargs)
context['formset'] = kwargs['form']
import models
for form in context['formset']:
if form.instance:
setattr(form.instance, 'articlesubscriptions',
models.ArticleSubscription.objects.filter(
settings = form.instance,
article__current_revision__deleted=False,
).select_related('article', 'article__current_revision')
)
return context
\ No newline at end of file
{% csrf_token %}{% load sekizai_tags %} {% csrf_token %}{% load sekizai_tags %}
{% if form.non_field_errors %}
{% if form_error_title %}<h4 class="alert-heading">{{ form_error_title }}</h4>{% endif %} {% include "wiki/includes/formerrors.html" %}
{% for error_message in form.non_field_errors %}
<div class="alert alert-block alert-error">
{{ error_message }}
</div>
{% endfor %}
{% endif %}
{% addtoblock "js" %} {% addtoblock "js" %}
{{ form.media.js }} {{ form.media.js }}
...@@ -18,28 +12,6 @@ ...@@ -18,28 +12,6 @@
{% for field in form %} {% for field in form %}
{% if field.is_hidden %} {% include "wiki/includes/formfield.html" %}
{{ field }}
{% else %}
<div id="div_{{ field.auto_id }}" class="clearfix control-group{% if field.errors %} error{% endif %}">
{% if field.label %}
<label for="{{ field.id_for_label }}" class="control-label {% if field.field.required %}requiredField{% endif %}">
{{ field.label|safe }}
</label>
{% endif %}
<div class="controls">
{{ field }} {% if field.field.required %}<span class="asteriskField">*</span>{% endif %}
{% if field.errors %}
{% for error in field.errors %}
<div id="error_{{ forloop.counter }}_{{ field.auto_id }}" class="help-block"><strong>{{ error }}</strong></div>
{% endfor %}
{% endif %}
{% if field.help_text %}
<p id="hint_{{ field.auto_id }}" class="help-block">{{ field.help_text|safe }}</p>
{% endif %}
</div>
</div>
{% endif %}
{% endfor %} {% endfor %}
{% if form.non_field_errors %}
{% if form_error_title %}<h4 class="alert-heading">{{ form_error_title }}</h4>{% endif %}
{% for error_message in form.non_field_errors %}
<div class="alert alert-block alert-error">
{{ error_message }}
</div>
{% endfor %}
{% endif %}
{% if field.is_hidden %}
{{ field }}
{% else %}
<div id="div_{{ field.auto_id }}" class="clearfix control-group{% if field.errors %} error{% endif %}">
{% if field.label %}
<label for="{{ field.id_for_label }}" class="control-label {% if field.field.required %}requiredField{% endif %}">
{{ field.label|safe }}
</label>
{% endif %}
<div class="controls">
{{ field }} {% if field.field.required %}<span class="asteriskField">*</span>{% endif %}
{% if field.errors %}
{% for error in field.errors %}
<div id="error_{{ forloop.counter }}_{{ field.auto_id }}" class="help-block"><strong>{{ error }}</strong></div>
{% endfor %}
{% endif %}
{% if field.help_text %}
<p id="hint_{{ field.auto_id }}" class="help-block">{{ field.help_text|safe }}</p>
{% endif %}
</div>
</div>
{% endif %}
...@@ -519,10 +519,12 @@ class Settings(ArticleMixin, TemplateView): ...@@ -519,10 +519,12 @@ class Settings(ArticleMixin, TemplateView):
""" """
Return all settings forms that can be filled in Return all settings forms that can be filled in
""" """
settings_forms = [F for F in plugin_registry.get_settings_forms()] settings_forms = []
if permissions.can_change_permissions(self.article, self.request.user): if permissions.can_change_permissions(self.article, self.request.user):
settings_forms.append(self.permission_form_class) settings_forms.append(self.permission_form_class)
settings_forms.sort(key=lambda form: form.settings_order) plugin_forms = [F for F in plugin_registry.get_settings_forms()]
plugin_forms.sort(key=lambda form: form.settings_order)
settings_forms += plugin_forms
for i in range(len(settings_forms)): for i in range(len(settings_forms)):
# TODO: Do not set an attribute on a form class - this # TODO: Do not set an attribute on a form class - this
# could be mixed up with a different instance # could be mixed up with a different instance
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment