parent
c8e37d235e
commit
ca75c24861
92
ietf/community/forms.py
Normal file
92
ietf/community/forms.py
Normal 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)
|
|
@ -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),
|
||||
}
|
||||
|
|
|
@ -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'),
|
||||
)
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue