Views for configuring ID lists. See #701

- Legacy-Id: 3520
This commit is contained in:
Emilio A. Sánchez López 2011-10-25 22:57:50 +00:00
parent c8e37d235e
commit ca75c24861
4 changed files with 404 additions and 7 deletions

92
ietf/community/forms.py Normal file
View file

@ -0,0 +1,92 @@
import hashlib
import datetime
from django import forms
from django.conf import settings
from django.contrib.sites.models import Site
from ietf.utils.mail import send_mail
from ietf.community.models import Rule, DisplayConfiguration
from ietf.community.display import DisplayField
class RuleForm(forms.ModelForm):
class Meta:
model = Rule
fields = ('rule_type', 'value')
def __init__(self, *args, **kwargs):
self.clist = kwargs.pop('clist', None)
super(RuleForm, self).__init__(*args, **kwargs)
def save(self):
self.instance.community_list = self.clist
super(RuleForm, self).save()
class DisplayForm(forms.ModelForm):
class Meta:
model = DisplayConfiguration
fields = ('sort_method', )
def save(self):
data = self.data
fields = []
for i in DisplayField.__subclasses__():
if data.get(i.codename, None):
fields.append(i.codename)
self.instance.display_fields = ','.join(fields)
super(DisplayForm, self).save()
class SubscribeForm(forms.Form):
email = forms.EmailField("Your email")
def __init__(self, *args, **kwargs):
self.clist = kwargs.pop('clist')
self.significant = kwargs.pop('significant')
super(SubscribeForm, self).__init__(*args, **kwargs)
def save(self, *args, **kwargs):
self.send_email()
return True
def send_email(self):
domain = Site.objects.get_current().domain
today = datetime.date.today().strftime('%Y%m%d')
subject = 'Confirm list subscription: %s' % self.clist
from_email = settings.DEFAULT_FROM_EMAIL
to_email = self.cleaned_data['email']
auth = hashlib.md5('%s%s%s%s%s' % (settings.SECRET_KEY, today, to_email, 'subscribe', self.significant)).hexdigest()
context = {
'domain': domain,
'clist': self.clist,
'today': today,
'auth': auth,
'to_email': to_email,
'significant': self.significant,
}
send_mail(None, to_email, from_email, subject, 'community/public/subscribe_email.txt', context)
class UnSubscribeForm(SubscribeForm):
def send_email(self):
domain = Site.objects.get_current().domain
today = datetime.date.today().strftime('%Y%m%d')
subject = 'Confirm list subscription cancelation: %s' % self.clist
from_email = settings.DEFAULT_FROM_EMAIL
to_email = self.cleaned_data['email']
auth = hashlib.md5('%s%s%s%s%s' % (settings.SECRET_KEY, today, to_email, 'unsubscribe', self.significant)).hexdigest()
context = {
'domain': domain,
'clist': self.clist,
'today': today,
'auth': auth,
'to_email': to_email,
'significant': self.significant,
}
send_mail(None, to_email, from_email, subject, 'community/public/unsubscribe_email.txt', context)

View file

@ -22,9 +22,11 @@ class CommunityListNode(template.Node):
person = user.get_profile()
groups = []
managed_areas = [i.group for i in Role.objects.filter(name__slug='ad', email__in=person.email_set.all())]
groups += list(CommunityList.objects.filter(group__in=managed_areas))
for area in managed_areas:
groups.append(CommunityList.objects.get_or_create(group=area)[0])
managed_wg = [i.group for i in Role.objects.filter(name__slug='chair', group__type__slug='wg', email__in=person.email_set.all())]
groups += list(CommunityList.objects.filter(group__in=managed_wg))
for wg in managed_wg:
groups.append(CommunityList.objects.get_or_create(group=wg)[0])
lists['group'] = groups
except:
pass
@ -44,3 +46,10 @@ def get_user_managed_lists(parser, token):
" be 'as'")
var_name = lastbits_reversed[0][::-1]
return CommunityListNode(user, var_name)
@register.inclusion_tag('community/display_field.html', takes_context=False)
def show_field(field, doc):
return {'field': field,
'value': field().get_value(doc),
}

View file

@ -3,5 +3,30 @@ from django.conf.urls.defaults import patterns, url
urlpatterns = patterns('ietf.community.views',
url(r'^personal/(?P<username>[\w.@+-]+)/$', 'manage_personal_list', name='manage_personal_list'),
url(r'^personal/(?P<username>[\w.@+-]+)/view/$', 'view_personal_list', name='view_personal_list'),
url(r'^personal/(?P<username>[\w.@+-]+)/changes/feed/$', 'changes_personal_list', name='changes_personal_list'),
url(r'^personal/(?P<username>[\w.@+-]+)/changes/significant/feed/$', 'significant_personal_list', name='significant_personal_list'),
url(r'^personal/(?P<username>[\w.@+-]+)/csv/$', 'csv_personal_list', name='csv_personal_list'),
url(r'^personal/(?P<username>[\w.@+-]+)/subscribe/$', 'subscribe_personal_list', {'significant': False}, name='subscribe_personal_list'),
url(r'^personal/(?P<username>[\w.@+-]+)/subscribe/significant/$', 'subscribe_personal_list', {'significant': True}, name='subscribe_significant_personal_list'),
url(r'^personal/(?P<username>[\w.@+-]+)/unsubscribe/$', 'unsubscribe_personal_list', {'significant': False}, name='unsubscribe_personal_list'),
url(r'^personal/(?P<username>[\w.@+-]+)/unsubscribe/significant/$', 'unsubscribe_personal_list', {'significant': True}, name='unsubscribe_significant_personal_list'),
url(r'^group/(?P<acronym>[\w.@+-]+)/$', 'manage_group_list', name='manage_group_list'),
url(r'^group/(?P<acronym>[\w.@+-]+)/view/$', 'view_group_list', name='view_group_list'),
url(r'^group/(?P<acronym>[\w.@+-]+)/changes/feed/$', 'changes_group_list', name='changes_group_list'),
url(r'^group/(?P<acronym>[\w.@+-]+)/changes/significant/feed/$', 'significant_group_list', name='significant_group_list'),
url(r'^group/(?P<acronym>[\w.@+-]+)/csv/$', 'csv_group_list', name='csv_group_list'),
url(r'^group/(?P<acronym>[\w.@+-]+)/subscribe/$', 'subscribe_group_list', {'significant': False}, name='subscribe_group_list'),
url(r'^group/(?P<acronym>[\w.@+-]+)/subscribe/significant/$', 'subscribe_group_list', {'significant': True}, name='subscribe_significant_group_list'),
url(r'^group/(?P<acronym>[\w.@+-]+)/unsubscribe/$', 'unsubscribe_group_list', {'significant': False}, name='unsubscribe_group_list'),
url(r'^group/(?P<acronym>[\w.@+-]+)/unsubscribe/significant/$', 'unsubscribe_group_list', {'significant': True}, name='unsubscribe_significant_group_list'),
url(r'^add_document/(?P<document_name>[^/]+)/$', 'add_document', name='community_add_document'),
url(r'^(?P<list_id>[\d]+)/remove_document/(?P<document_name>[^/]+)/$', 'remove_document', name='community_remove_document'),
url(r'^(?P<list_id>[\d]+)/remove_rule/(?P<rule_id>[^/]+)/$', 'remove_rule', name='community_remove_rule'),
url(r'^(?P<list_id>[\d]+)/subscribe/confirm/(?P<email>[\w.@+-]+)/(?P<date>[\d]+)/(?P<confirm_hash>[a-f0-9]+)/$', 'confirm_subscription', name='confirm_subscription'),
url(r'^(?P<list_id>[\d]+)/subscribe/significant/confirm/(?P<email>[\w.@+-]+)/(?P<date>[\d]+)/(?P<confirm_hash>[a-f0-9]+)/$', 'confirm_significant_subscription', name='confirm_significant_subscription'),
url(r'^(?P<list_id>[\d]+)/unsubscribe/confirm/(?P<email>[\w.@+-]+)/(?P<date>[\d]+)/(?P<confirm_hash>[a-f0-9]+)/$', 'confirm_unsubscription', name='confirm_unsubscription'),
url(r'^(?P<list_id>[\d]+)/unsubscribe/significant/confirm/(?P<email>[\w.@+-]+)/(?P<date>[\d]+)/(?P<confirm_hash>[a-f0-9]+)/$', 'confirm_significant_unsubscription', name='confirm_significant_unsubscription'),
)

View file

@ -1,26 +1,51 @@
import csv
import uuid
import datetime
import hashlib
from django.conf import settings
from django.contrib.auth.models import User
from django.http import HttpResponse, Http404, HttpResponseForbidden
from django.http import HttpResponse, Http404, HttpResponseForbidden, HttpResponseRedirect
from django.shortcuts import get_object_or_404, render_to_response
from django.template import RequestContext
from django.utils import simplejson
from django.utils.translation import ugettext as _
from ietf.community.models import CommunityList
from ietf.community.models import CommunityList, Rule, EmailSubscription, ListNotification
from ietf.community.forms import RuleForm, DisplayForm, SubscribeForm, UnSubscribeForm
from redesign.group.models import Group
from redesign.doc.models import Document
def _manage_list(request, clist):
display_config = clist.get_display_config()
if request.method == 'POST' and request.POST.get('save_rule', None):
rule_form = RuleForm(request.POST, clist=clist)
display_form = DisplayForm(instance=display_config)
if rule_form.is_valid():
rule_form.save()
rule_form = RuleForm(clist=clist)
display_form = DisplayForm(instance=display_config)
elif request.method == 'POST' and request.POST.get('save_display', None):
display_form = DisplayForm(request.POST, instance=display_config)
rule_form = RuleForm(clist=clist)
if display_form.is_valid():
display_form.save()
rule_form = RuleForm(clist=clist)
display_form = DisplayForm(instance=display_config)
else:
rule_form = RuleForm(clist=clist)
display_form = DisplayForm(instance=display_config)
return render_to_response('community/manage_clist.html',
{'cl': clist},
{'cl': clist,
'dc': display_config,
'display_form': display_form,
'rule_form': rule_form},
context_instance=RequestContext(request))
def manage_personal_list(request, username):
user = get_object_or_404(User, username=username)
if not request.user.is_authenticated() or user != request.user:
return HttpResponseForbidden('You have no permission to access this view')
clist = CommunityList.objects.get_or_create(user=request.user)[0]
if not clist.check_manager(request.user):
return HttpResponseForbidden('You have no permission to access this view')
@ -35,3 +60,249 @@ def manage_group_list(request, acronym):
if not clist.check_manager(request.user):
return HttpResponseForbidden('You have no permission to access this view')
return _manage_list(request, clist)
def add_document(request, document_name):
if not request.user.is_authenticated():
return HttpResponseForbidden('You have no permission to access this view')
doc = get_object_or_404(Document, name=document_name)
clist = CommunityList.objects.get_or_create(user=request.user)[0]
return add_document_to_list(request, clist, doc)
def remove_document(request, list_id, document_name):
clist = get_object_or_404(CommunityList, pk=list_id)
if not clist.check_manager(request.user):
return HttpResponseForbidden('You have no permission to access this view')
doc = get_object_or_404(Document, name=document_name)
clist.added_ids.remove(doc)
return HttpResponseRedirect(clist.get_manage_url())
def add_document_to_list(request, clist, doc):
if not clist.check_manager(request.user):
return HttpResponseForbidden('You have no permission to access this view')
clist.added_ids.add(doc)
return HttpResponseRedirect(clist.get_manage_url())
def remove_rule(request, list_id, rule_id):
clist = get_object_or_404(CommunityList, pk=list_id)
if not clist.check_manager(request.user):
return HttpResponseForbidden('You have no permission to access this view')
rule = get_object_or_404(Rule, pk=rule_id)
rule.delete()
return HttpResponseRedirect(clist.get_manage_url())
def _view_list(request, clist):
display_config = clist.get_display_config()
return render_to_response('community/public/view_list.html',
{'cl': clist,
'dc': display_config,
},
context_instance=RequestContext(request))
def view_personal_list(request, username):
user = get_object_or_404(User, username=username)
clist = get_object_or_404(CommunityList, user=user)
return _view_list(request, clist)
def view_group_list(request, acronym):
group = get_object_or_404(Group, acronym=acronym)
clist = get_object_or_404(CommunityList, group=group)
return _view_list(request, clist)
def _atom_view(request, clist, significant=False):
documents = clist.get_documents().values('pk')
notifications = ListNotification.objects.filter(document__pk__in=documents)\
.distinct()\
.order_by('-notification_date')
if significant:
notifications = notifications.filter(significant=True)
host = request.get_host()
feed_url = 'http://%s%s' % (host, request.get_full_path())
feed_id = uuid.uuid5(uuid.NAMESPACE_URL, feed_url.encode('utf-8'))
title = '%s RSS Feed' % clist.long_name()
if significant:
subtitle = 'Document significant changes'
else:
subtitle = 'Document changes'
return render_to_response('community/public/atom.xml',
{'cl': clist,
'entries': notifications[:20],
'title': title,
'subtitle': subtitle,
'id': feed_id.get_urn(),
'updated': datetime.datetime.today(),
},
mimetype='text/xml',
context_instance=RequestContext(request))
def changes_personal_list(request, username):
user = get_object_or_404(User, username=username)
clist = get_object_or_404(CommunityList, user=user)
return _atom_view(request, clist)
def changes_group_list(request, acronym):
group = get_object_or_404(Group, acronym=acronym)
clist = get_object_or_404(CommunityList, group=group)
return _atom_view(request, clist)
def significant_personal_list(request, username):
user = get_object_or_404(User, username=username)
clist = get_object_or_404(CommunityList, user=user)
return _atom_view(request, clist, significant=True)
def significant_group_list(request, acronym):
group = get_object_or_404(Group, acronym=acronym)
clist = get_object_or_404(CommunityList, group=group)
return _atom_view(request, clist, significant=True)
def _csv_list(request, clist):
display_config = clist.get_display_config()
response = HttpResponse(mimetype='text/csv')
response['Content-Disposition'] = 'attachment; filename=draft-list.csv'
writer = csv.writer(response, dialect=csv.excel, delimiter=';')
header = []
fields = display_config.get_active_fields()
for field in fields:
header.append(field.description)
writer.writerow(header)
for doc in clist.get_documents():
row = []
for field in fields:
row.append(field().get_value(doc))
writer.writerow(row)
return response
def csv_personal_list(request, username):
user = get_object_or_404(User, username=username)
if not request.user.is_authenticated() or user != request.user:
return HttpResponseForbidden('You have no permission to access this view')
clist = CommunityList.objects.get_or_create(user=request.user)[0]
if not clist.check_manager(request.user):
return HttpResponseForbidden('You have no permission to access this view')
return _csv_list(request, clist)
def csv_group_list(request, acronym):
group = get_object_or_404(Group, acronym=acronym)
if group.type.slug not in ('area', 'wg'):
raise Http404
clist = CommunityList.objects.get_or_create(group=group)[0]
if not clist.check_manager(request.user):
return HttpResponseForbidden('You have no permission to access this view')
return _csv_list(request, clist)
def _subscribe_list(request, clist, significant):
success = False
if request.method == 'POST':
form = SubscribeForm(data=request.POST, clist=clist, significant=significant)
if form.is_valid():
form.save()
success = True
else:
form = SubscribeForm(clist=clist, significant=significant)
return render_to_response('community/public/subscribe.html',
{'cl': clist,
'form': form,
'success': success,
},
context_instance=RequestContext(request))
def _unsubscribe_list(request, clist, significant):
success = False
if request.method == 'POST':
form = UnSubscribeForm(data=request.POST, clist=clist, significant=significant)
if form.is_valid():
form.save()
success = True
else:
form = UnSubscribeForm(clist=clist, significant=significant)
return render_to_response('community/public/unsubscribe.html',
{'cl': clist,
'form': form,
'success': success,
'significant': significant,
},
context_instance=RequestContext(request))
def subscribe_personal_list(request, username, significant=False):
user = get_object_or_404(User, username=username)
clist = get_object_or_404(CommunityList, user=user)
return _subscribe_list(request, clist, significant=significant)
def subscribe_group_list(request, acronym, significant=False):
group = get_object_or_404(Group, acronym=acronym)
clist = get_object_or_404(CommunityList, group=group)
return _subscribe_list(request, clist, significant=significant)
def unsubscribe_personal_list(request, username, significant=False):
user = get_object_or_404(User, username=username)
clist = get_object_or_404(CommunityList, user=user)
return _unsubscribe_list(request, clist, significant=significant)
def unsubscribe_group_list(request, acronym, significant=False):
group = get_object_or_404(Group, acronym=acronym)
clist = get_object_or_404(CommunityList, group=group)
return _unsubscribe_list(request, clist, significant=significant)
def confirm_subscription(request, list_id, email, date, confirm_hash, significant=False):
clist = get_object_or_404(CommunityList, pk=list_id)
valid = hashlib.md5('%s%s%s%s%s' % (settings.SECRET_KEY, date, email, 'subscribe', significant)).hexdigest() == confirm_hash
if not valid:
raise Http404
(subscription, created) = EmailSubscription.objects.get_or_create(
community_list=clist,
email=email,
significant=significant)
return render_to_response('community/public/subscription_confirm.html',
{'cl': clist,
'significant': significant,
},
context_instance=RequestContext(request))
def confirm_significant_subscription(request, list_id, email, date, confirm_hash):
return confirm_subscription(request, list_id, email, date, confirm_hash, significant=True)
def confirm_unsubscription(request, list_id, email, date, confirm_hash, significant=False):
clist = get_object_or_404(CommunityList, pk=list_id)
valid = hashlib.md5('%s%s%s%s%s' % (settings.SECRET_KEY, date, email, 'unsubscribe', significant)).hexdigest() == confirm_hash
if not valid:
raise Http404
EmailSubscription.objects.filter(
community_list=clist,
email=email,
significant=significant).delete()
return render_to_response('community/public/unsubscription_confirm.html',
{'cl': clist,
'significant': significant,
},
context_instance=RequestContext(request))
def confirm_significant_unsubscription(request, list_id, email, date, confirm_hash):
return confirm_unsubscription(request, list_id, email, date, confirm_hash, significant=True)