Skip to content

Commit 20320ea

Browse files
committed
Views for manage nomcom positions
Views for edit templates related to nomcom group and nomcom positions Refactored some strings in html templates Allow the secretariat to access the same views and view the same links as the chair Fixes ietf-tools#914 - Legacy-Id: 5334
1 parent 51f24f0 commit 20320ea

13 files changed

Lines changed: 282 additions & 18 deletions

File tree

ietf/dbtemplate/views.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,23 +21,26 @@ def template_list(request, acronym):
2121
}, RequestContext(request))
2222

2323

24-
def template_edit(request, acronym, template_id):
24+
def template_edit(request, acronym, template_id, base_template='dbtemplate/template_edit.html', formclass=DBTemplateForm, extra_context=None):
2525
group = get_object_or_404(Group, acronym=acronym)
2626
chairs = group.role_set.filter(name__slug='chair')
27+
extra_context = extra_context or {}
2728

2829
if not has_role(request.user, "Secretariat") and not chairs.filter(person__user=request.user).count():
2930
return HttpResponseForbidden("You are not authorized to access this view")
3031

3132
template = get_object_or_404(DBTemplate, id=template_id, group=group)
3233
if request.method == 'POST':
33-
form = DBTemplateForm(instance=template, data=request.POST)
34+
form = formclass(instance=template, data=request.POST)
3435
if form.is_valid():
3536
form.save()
3637
return HttpResponseRedirect('..')
3738
else:
38-
form = DBTemplateForm(instance=template)
39-
return render_to_response('dbtemplate/template_edit.html',
40-
{'template': template,
41-
'group': group,
42-
'form': form,
43-
}, RequestContext(request))
39+
form = formclass(instance=template)
40+
41+
context = {'template': template,
42+
'group': group,
43+
'form': form,
44+
}
45+
context.update(extra_context)
46+
return render_to_response(base_template, context, RequestContext(request))

ietf/nomcom/decorators.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from ietf.ietfauth.decorators import passes_test_decorator
1+
from ietf.ietfauth.decorators import passes_test_decorator, has_role
22

33
from ietf.nomcom.utils import get_nomcom_by_year
44

@@ -8,6 +8,8 @@ def _is_nomcom_member(user, *args, **kwargs):
88
year = kwargs.get('year', None)
99
if year:
1010
nomcom = get_nomcom_by_year(year=year)
11+
if has_role(user, "Secretariat"):
12+
return True
1113
if role == 'chair':
1214
return nomcom.group.is_chair(user)
1315
else:

ietf/nomcom/forms.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from django.shortcuts import render_to_response
1010
from django.template.context import RequestContext
1111

12+
from ietf.dbtemplate.forms import DBTemplateForm
1213
from ietf.utils import unaccent
1314
from ietf.utils.mail import send_mail
1415
from ietf.ietfauth.decorators import role_required
@@ -415,3 +416,27 @@ class Meta:
415416
class Media:
416417
js = ("/js/jquery-1.5.1.min.js",
417418
"/js/nomcom.js", )
419+
420+
421+
class NomComTemplateForm(BaseNomcomForm, DBTemplateForm):
422+
423+
fieldsets = [('Template content', ('content', )),
424+
]
425+
426+
427+
class PositionForm(BaseNomcomForm, forms.ModelForm):
428+
429+
fieldsets = [('Position', ('name', 'description',
430+
'is_open', 'incumbent'))]
431+
432+
class Meta:
433+
model = Position
434+
fields = ('name', 'description', 'is_open', 'incumbent')
435+
436+
def __init__(self, *args, **kwargs):
437+
self.nomcom = kwargs.pop('nomcom', None)
438+
super(PositionForm, self).__init__(*args, **kwargs)
439+
440+
def save(self, *args, **kwargs):
441+
self.instance.nomcom = self.nomcom
442+
super(PositionForm, self).save(*args, **kwargs)

ietf/nomcom/models.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ def __unicode__(self):
100100
class Position(models.Model):
101101
nomcom = models.ForeignKey('NomCom')
102102
name = models.CharField(verbose_name='Name', max_length=255)
103-
description = models.TextField(verbose_name='Despcription')
103+
description = models.TextField(verbose_name='Description')
104104
initial_text = models.TextField(verbose_name='Initial text for nominations',
105105
blank=True)
106106
requirement = models.ForeignKey(DBTemplate, related_name='requirement', null=True, editable=False)
@@ -127,6 +127,13 @@ def save(self, *args, **kwargs):
127127
if changed:
128128
self.save()
129129

130+
def get_templates(self):
131+
if hasattr(self, '_templates'):
132+
return self._templates
133+
from ietf.dbtemplate.models import DBTemplate
134+
self._templates = DBTemplate.objects.filter(group=self.nomcom.group).filter(path__contains='/%s/position/' % self.id).order_by('title')
135+
return self._templates
136+
130137

131138
class Feedback(models.Model):
132139
author = models.EmailField(verbose_name='Author', blank=True)

ietf/nomcom/templatetags/nomcom_tags.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from django import template
22

3+
from ietf.ietfauth.decorators import has_role
34
from ietf.nomcom.utils import get_nomcom_by_year
45

56
register = template.Library()
@@ -10,4 +11,6 @@ def is_chair(user, year):
1011
if not user or not year:
1112
return False
1213
nomcom = get_nomcom_by_year(year=year)
14+
if has_role(user, "Secretariat"):
15+
return True
1316
return nomcom.group.is_chair(user)

ietf/nomcom/urls.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@
99
url(r'^(?P<year>\d{4})/private/edit-members/$', EditMembersFormPreview(EditMembersForm), name='nomcom_edit_members'),
1010
url(r'^(?P<year>\d{4})/private/edit-chair/$', EditChairFormPreview(EditChairForm), name='nomcom_edit_chair'),
1111
url(r'^(?P<year>\d{4})/private/edit-publickey/$', 'edit_publickey', name='nomcom_edit_publickey'),
12+
url(r'^(?P<year>\d{4})/private/chair/templates/$', 'list_templates', name='nomcom_list_templates'),
13+
url(r'^(?P<year>\d{4})/private/chair/templates/(?P<template_id>\d+)/$', 'edit_template', name='nomcom_edit_template'),
14+
url(r'^(?P<year>\d{4})/private/chair/position/$', 'list_positions', name='nomcom_list_positions'),
15+
url(r'^(?P<year>\d{4})/private/chair/position/add/$', 'edit_position', name='nomcom_add_position'),
16+
url(r'^(?P<year>\d{4})/private/chair/position/(?P<position_id>\d+)/$', 'edit_position', name='nomcom_edit_position'),
17+
url(r'^(?P<year>\d{4})/private/chair/position/(?P<position_id>\d+)/remove/$', 'remove_position', name='nomcom_remove_position'),
1218

1319
url(r'^(?P<year>\d{4})/$', 'index', name='nomcom_index'),
1420
url(r'^(?P<year>\d{4})/requirements/$', 'requirements', name='nomcom_requirements'),

ietf/nomcom/views.py

Lines changed: 90 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
# -*- coding: utf-8 -*-
2+
from django.contrib.auth.decorators import login_required
3+
from django.core.urlresolvers import reverse
4+
from django.http import HttpResponse, Http404, HttpResponseRedirect
25
from django.shortcuts import render_to_response
36
from django.template import RequestContext
4-
from django.http import HttpResponse
5-
from django.contrib.auth.decorators import login_required
67
from django.template.loader import render_to_string
78
from django.utils import simplejson
89

9-
from ietf.nomcom.utils import get_nomcom_by_year, HOME_TEMPLATE
10+
from ietf.dbtemplate.models import DBTemplate
11+
from ietf.dbtemplate.views import template_edit
1012
from ietf.nomcom.decorators import member_required
11-
from ietf.nomcom.forms import EditPublicKeyForm, NominateForm, MergeForm
13+
from ietf.nomcom.forms import (EditPublicKeyForm, NominateForm, MergeForm,
14+
NomComTemplateForm, PositionForm)
1215
from ietf.nomcom.models import Position
16+
from ietf.nomcom.utils import get_nomcom_by_year, HOME_TEMPLATE
1317

1418

1519
def index(request, year):
@@ -151,6 +155,88 @@ def edit_publickey(request, year):
151155
'selected': 'edit_publickey'}, RequestContext(request))
152156

153157

158+
@member_required(role='chair')
159+
def list_templates(request, year):
160+
nomcom = get_nomcom_by_year(year)
161+
positions = nomcom.position_set.all()
162+
template_list = DBTemplate.objects.filter(group=nomcom.group).exclude(path__contains='/position/')
163+
164+
return render_to_response('nomcom/list_templates.html',
165+
{'template_list': template_list,
166+
'positions': positions,
167+
'year': year,
168+
'selected': 'edit_templates',
169+
'nomcom': nomcom}, RequestContext(request))
170+
171+
172+
@member_required(role='chair')
173+
def edit_template(request, year, template_id):
174+
nomcom = get_nomcom_by_year(year)
175+
return_url = request.META.get('HTTP_REFERER', None)
176+
177+
return template_edit(request, nomcom.group.acronym, template_id,
178+
base_template='nomcom/edit_template.html',
179+
formclass=NomComTemplateForm,
180+
extra_context={'year': year,
181+
'return_url': return_url,
182+
'nomcom': nomcom})
183+
184+
185+
@member_required(role='chair')
186+
def list_positions(request, year):
187+
nomcom = get_nomcom_by_year(year)
188+
positions = nomcom.position_set.all()
189+
190+
return render_to_response('nomcom/list_positions.html',
191+
{'positions': positions,
192+
'year': year,
193+
'selected': 'edit_positions',
194+
'nomcom': nomcom}, RequestContext(request))
195+
196+
197+
@member_required(role='chair')
198+
def remove_position(request, year, position_id):
199+
nomcom = get_nomcom_by_year(year)
200+
try:
201+
position = nomcom.position_set.get(id=position_id)
202+
except Position.DoesNotExist:
203+
raise Http404
204+
205+
if request.POST.get('remove', None):
206+
position.delete()
207+
return HttpResponseRedirect(reverse('nomcom_list_positions', None, args=(year, )))
208+
return render_to_response('nomcom/remove_position.html',
209+
{'year': year,
210+
'position': position,
211+
'nomcom': nomcom}, RequestContext(request))
212+
213+
214+
@member_required(role='chair')
215+
def edit_position(request, year, position_id=None):
216+
nomcom = get_nomcom_by_year(year)
217+
if position_id:
218+
try:
219+
position = nomcom.position_set.get(id=position_id)
220+
except Position.DoesNotExist:
221+
raise Http404
222+
else:
223+
position = None
224+
225+
if request.method == 'POST':
226+
form = PositionForm(request.POST, instance=position, nomcom=nomcom)
227+
if form.is_valid():
228+
form.save()
229+
return HttpResponseRedirect(reverse('nomcom_list_positions', None, args=(year, )))
230+
else:
231+
form = PositionForm(instance=position, nomcom=nomcom)
232+
233+
return render_to_response('nomcom/edit_position.html',
234+
{'form': form,
235+
'position': position,
236+
'year': year,
237+
'nomcom': nomcom}, RequestContext(request))
238+
239+
154240
def ajax_position_text(request, position_id):
155241
try:
156242
position_text = Position.objects.get(id=position_id).initial_text
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{% extends "nomcom/nomcom_private_base.html" %}
2+
3+
{% block nomcom_content %}
4+
<h3>{% if position %}Edit{% else %}Add{% endif %} position</h3>
5+
6+
{% if form.errors %}<div class="info-message-error">Please correct the following errors</div>{% endif %}
7+
8+
<form action="" method="post">
9+
{{ form }}
10+
<p><input type="submit" value="{% if position %}Edit{% else %}Add{% endif %}" /> <a href="../">Cancel</a></p>
11+
</form>
12+
{% endblock nomcom_content %}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
{% extends "nomcom/nomcom_private_base.html" %}
2+
3+
{% block nomcom_content %}
4+
<h2>Template: {{ template }}</h2>
5+
6+
<h3>Meta information</h3>
7+
<dl>
8+
<dt>Title</dt>
9+
<dd>{{ template.title }}</dt>
10+
<dt>Group</dt>
11+
<dd>{{ template.group }}</dd>
12+
<dt>Template type</dt>
13+
<dd>{{ template.type.name }}
14+
{% ifequal template.type.slug "rst" %}
15+
<p>This template uses the syntax of reStructuredText. Get a quick reference at <a href="http://docutils.sourceforge.net/docs/user/rst/quickref.html">http://docutils.sourceforge.net/docs/user/rst/quickref.html</a>.</p>
16+
<p>You can do variable interpolation with $varialbe if the template allows any variable.</p>
17+
{% endifequal %}
18+
{% ifequal template.type.slug "django" %}
19+
<p>This template uses the syntax of the default django template framework. Get more info at <a href="https://docs.djangoproject.com/en/dev/topics/templates/">https://docs.djangoproject.com/en/dev/topics/templates/</a>.</p>
20+
<p>You can do variable interpolation with the current django markup &#123;&#123;variable&#125;&#125; if the template allows any variable.</p>
21+
{% endifequal %}
22+
{% ifequal template.type.slug "plain" %}
23+
<p>This template uses plain text, so no markup is used. You can do variable interpolation with $variable if the template allows any variable.</p>
24+
{% endifequal %}
25+
</dd>
26+
{% if template.variables %}
27+
<dt>Variables allowed in this template</dt>
28+
<dd>{{ template.variables|linebreaks }}</dd>
29+
{% endif %}
30+
</dl>
31+
32+
<h3>Edit template content</h3>
33+
34+
{% if form.errors %}<div class="info-message-error">Please correct the following errors</div>{% endif %}
35+
36+
<form action="" method="post">
37+
{{ form }}
38+
<p><input type="submit" value="Save template" /> <a href="{% if return_url %}{{ return_url }}{% else %}../{% endif %}">Cancel</a></p>
39+
</form>
40+
{% endblock nomcom_content %}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{% extends "nomcom/nomcom_private_base.html" %}
2+
3+
{% block nomcom_content %}
4+
5+
<h2>Positions in {{ nomcom.group }}</h2>
6+
<a href="{% url nomcom_add_position year %}">Add a new position</a>
7+
{% if positions %}
8+
{% for position in positions %}
9+
<h3>{{ position.name }} <a href="{% url nomcom_edit_position year position.id %}">[Edit]</a> <a href="{% url nomcom_remove_position year position.id %}">[Remove]</a></h3>
10+
<dl>
11+
<dt>Description:</dt>
12+
<dd>{{ position.description }}</dd>
13+
<dt>Incumbent:</dt>
14+
<dd>{{ position.incumbent }}</dd>
15+
<dt>Is open:</dt>
16+
<dd>{{ position.is_open }}</dd>
17+
<dt>Templates:</dt>
18+
<dd>
19+
<ul>
20+
{% for template in position.get_templates %}
21+
<li><a href="{% url nomcom_edit_template year template.id %}">{{ template }}</a></li>
22+
{% endfor %}
23+
</ul>
24+
</dd>
25+
</dl>
26+
{% endfor %}
27+
{% else %}
28+
<p>There are no positions defined.</p>
29+
{% endif %}
30+
{% endblock nomcom_content %}

0 commit comments

Comments
 (0)