out nomcom.js is included in the wrong pages, and on the pages it is actually useful in, it's obsolete, so delete it together with the obsoleted AJAX view and the other JS left-over cruft in nomcom/, this fixes an include 404 and removes the remaining dependency on jquery-1.5.1 apart from the Secretariat tools - Legacy-Id: 7097
833 lines
35 KiB
Python
833 lines
35 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
import datetime, re, json
|
|
from collections import OrderedDict
|
|
|
|
from django.conf import settings
|
|
from django.contrib.auth.decorators import login_required
|
|
from django.contrib import messages
|
|
from django.core.urlresolvers import reverse
|
|
from django.http import HttpResponse, Http404, HttpResponseRedirect, HttpResponseForbidden
|
|
from django.shortcuts import render_to_response, get_object_or_404, render, redirect
|
|
from django.template import RequestContext
|
|
from django.template.loader import render_to_string
|
|
from django.db.models import Count
|
|
from django.forms.models import modelformset_factory, inlineformset_factory
|
|
|
|
|
|
from ietf.dbtemplate.models import DBTemplate
|
|
from ietf.dbtemplate.views import template_edit
|
|
from ietf.name.models import NomineePositionState, FeedbackType
|
|
from ietf.group.models import Group, GroupEvent
|
|
from ietf.message.models import Message
|
|
|
|
from ietf.nomcom.decorators import nomcom_private_key_required
|
|
from ietf.nomcom.forms import (NominateForm, FeedbackForm, QuestionnaireForm,
|
|
MergeForm, NomComTemplateForm, PositionForm,
|
|
PrivateKeyForm, EditNomcomForm, EditNomineeForm,
|
|
PendingFeedbackForm, ReminderDatesForm, FullFeedbackFormSet,
|
|
FeedbackEmailForm)
|
|
from ietf.nomcom.models import Position, NomineePosition, Nominee, Feedback, NomCom, ReminderDates
|
|
from ietf.nomcom.utils import (get_nomcom_by_year, store_nomcom_private_key,
|
|
get_hash_nominee_position, send_reminder_to_nominees,
|
|
HOME_TEMPLATE, NOMINEE_ACCEPT_REMINDER_TEMPLATE,NOMINEE_QUESTIONNAIRE_REMINDER_TEMPLATE)
|
|
from ietf.ietfauth.utils import role_required
|
|
|
|
def index(request):
|
|
nomcom_list = Group.objects.filter(type__slug='nomcom').order_by('acronym')
|
|
for nomcom in nomcom_list:
|
|
year = nomcom.acronym[6:]
|
|
try:
|
|
year = int(year)
|
|
except ValueError:
|
|
year = None
|
|
nomcom.year = year
|
|
nomcom.label = "%s/%s" % (year, year+1)
|
|
if year in [ 2005, 2006, 2007, 2008, 2009, 2010 ]:
|
|
nomcom.url = "https://tools.ietf.org/group/nomcom/%02d" % (year % 100)
|
|
elif year in [ 2011, 2012 ]:
|
|
nomcom.url = "https://www.ietf.org/nomcom/%04d" % year
|
|
elif year > 2012:
|
|
nomcom.url = "/nomcom/%04d" % year
|
|
else:
|
|
nomcom.url = None
|
|
if year >= 2002:
|
|
nomcom.ann_url = "/nomcom/ann/#%4d" % year
|
|
else:
|
|
nomcom.ann_url = None
|
|
return render_to_response('nomcom/index.html',
|
|
{'nomcom_list': nomcom_list,}, RequestContext(request))
|
|
|
|
|
|
def year_index(request, year):
|
|
nomcom = get_nomcom_by_year(year)
|
|
home_template = '/nomcom/%s/%s' % (nomcom.group.acronym, HOME_TEMPLATE)
|
|
template = render_to_string(home_template, {})
|
|
return render_to_response('nomcom/year_index.html',
|
|
{'nomcom': nomcom,
|
|
'year': year,
|
|
'selected': 'index',
|
|
'template': template}, RequestContext(request))
|
|
|
|
def announcements(request):
|
|
address_re = re.compile("<.*>")
|
|
|
|
nomcoms = Group.objects.filter(type="nomcom")
|
|
|
|
regimes = []
|
|
|
|
for n in nomcoms:
|
|
e = GroupEvent.objects.filter(group=n, type="changed_state", changestategroupevent__state="active").order_by('time')[:1]
|
|
n.start_year = e[0].time.year if e else 0
|
|
e = GroupEvent.objects.filter(group=n, type="changed_state", changestategroupevent__state="conclude").order_by('time')[:1]
|
|
n.end_year = e[0].time.year if e else n.start_year + 1
|
|
|
|
r = n.role_set.select_related().filter(name="chair")
|
|
chair = None
|
|
if r:
|
|
chair = r[0]
|
|
|
|
announcements = Message.objects.filter(related_groups=n).order_by('-time')
|
|
for a in announcements:
|
|
a.to_name = address_re.sub("", a.to)
|
|
|
|
if not announcements:
|
|
continue
|
|
|
|
regimes.append(dict(chair=chair,
|
|
announcements=announcements,
|
|
group=n))
|
|
|
|
regimes.sort(key=lambda x: x["group"].start_year, reverse=True)
|
|
|
|
return render_to_response("nomcom/announcements.html",
|
|
{ 'curr_chair' : regimes[0]["chair"] if regimes else None,
|
|
'regimes' : regimes },
|
|
context_instance=RequestContext(request))
|
|
|
|
@role_required("Nomcom")
|
|
def private_key(request, year):
|
|
nomcom = get_nomcom_by_year(year)
|
|
message = None
|
|
if request.session.get('NOMCOM_PRIVATE_KEY_%s' % year, None):
|
|
message = ('warning', 'You already have a private decryption key set for this session.')
|
|
else:
|
|
message = ('warning', "You don't have a private decryption key set for this session yet")
|
|
|
|
back_url = request.GET.get('back_to', reverse('nomcom_private_index', None, args=(year, )))
|
|
if request.method == 'POST':
|
|
form = PrivateKeyForm(data=request.POST)
|
|
if form.is_valid():
|
|
store_nomcom_private_key(request, year, form.cleaned_data.get('key', ''))
|
|
return HttpResponseRedirect(back_url)
|
|
else:
|
|
form = PrivateKeyForm()
|
|
return render_to_response('nomcom/private_key.html',
|
|
{'nomcom': nomcom,
|
|
'year': year,
|
|
'back_url': back_url,
|
|
'form': form,
|
|
'message': message,
|
|
'selected': 'private_key'}, RequestContext(request))
|
|
|
|
|
|
@role_required("Nomcom")
|
|
def private_index(request, year):
|
|
nomcom = get_nomcom_by_year(year)
|
|
all_nominee_positions = NomineePosition.objects.get_by_nomcom(nomcom).not_duplicated()
|
|
is_chair = nomcom.group.has_role(request.user, "chair")
|
|
message = None
|
|
if is_chair and request.method == 'POST':
|
|
action = request.POST.get('action')
|
|
nominations_to_modify = request.POST.getlist('selected')
|
|
if nominations_to_modify:
|
|
nominations = all_nominee_positions.filter(id__in=nominations_to_modify)
|
|
if action == "set_as_accepted":
|
|
nominations.update(state='accepted')
|
|
message = ('success', 'The selected nominations have been set as accepted')
|
|
elif action == "set_as_declined":
|
|
nominations.update(state='declined')
|
|
message = ('success', 'The selected nominations have been set as declined')
|
|
elif action == "set_as_pending":
|
|
nominations.update(state='pending')
|
|
message = ('success', 'The selected nominations have been set as pending')
|
|
else:
|
|
message = ('warning', "Please, select some nominations to work with")
|
|
|
|
filters = {}
|
|
questionnaire_state = "questionnaire"
|
|
selected_state = request.GET.get('state')
|
|
selected_position = request.GET.get('position')
|
|
|
|
if selected_state and not selected_state == questionnaire_state:
|
|
filters['state__slug'] = selected_state
|
|
|
|
if selected_position:
|
|
filters['position__id'] = selected_position
|
|
|
|
nominee_positions = all_nominee_positions
|
|
if filters:
|
|
nominee_positions = nominee_positions.filter(**filters)
|
|
|
|
if selected_state == questionnaire_state:
|
|
nominee_positions = [np for np in nominee_positions if np.questionnaires]
|
|
|
|
stats = all_nominee_positions.values('position__name', 'position__id').annotate(total=Count('position'))
|
|
states = list(NomineePositionState.objects.values('slug', 'name')) + [{'slug': questionnaire_state, 'name': u'Questionnaire'}]
|
|
positions = set([ n.position for n in all_nominee_positions.order_by('position__name') ])
|
|
for s in stats:
|
|
for state in states:
|
|
if state['slug'] == questionnaire_state:
|
|
s[state['slug']] = Feedback.objects.filter(positions__id=s['position__id'], type='questio').count()
|
|
else:
|
|
s[state['slug']] = all_nominee_positions.filter(position__name=s['position__name'],
|
|
state=state['slug']).count()
|
|
|
|
return render_to_response('nomcom/private_index.html',
|
|
{'nomcom': nomcom,
|
|
'year': year,
|
|
'nominee_positions': nominee_positions,
|
|
'stats': stats,
|
|
'states': states,
|
|
'positions': positions,
|
|
'selected_state': selected_state,
|
|
'selected_position': selected_position and int(selected_position) or None,
|
|
'selected': 'index',
|
|
'is_chair': is_chair,
|
|
'message': message}, RequestContext(request))
|
|
|
|
|
|
@role_required("Nomcom Chair", "Nomcom Advisor")
|
|
def send_reminder_mail(request, year, type):
|
|
nomcom = get_nomcom_by_year(year)
|
|
nomcom_template_path = '/nomcom/%s/' % nomcom.group.acronym
|
|
|
|
if type=='accept':
|
|
interesting_state = 'pending'
|
|
mail_path = nomcom_template_path + NOMINEE_ACCEPT_REMINDER_TEMPLATE
|
|
reminder_description = 'accept (or decline) a nomination'
|
|
selected_tab = 'send_accept_reminder'
|
|
state_description = NomineePositionState.objects.get(slug=interesting_state).name
|
|
elif type=='questionnaire':
|
|
interesting_state = 'accepted'
|
|
mail_path = nomcom_template_path + NOMINEE_QUESTIONNAIRE_REMINDER_TEMPLATE
|
|
reminder_description = 'complete the questionnaire for a nominated position'
|
|
selected_tab = 'send_questionnaire_reminder'
|
|
state_description = NomineePositionState.objects.get(slug=interesting_state).name+' but no questionnaire has been received'
|
|
else:
|
|
raise Http404
|
|
|
|
nominees = Nominee.objects.get_by_nomcom(nomcom).not_duplicated().filter(nomineeposition__state=interesting_state).distinct()
|
|
annotated_nominees = []
|
|
for nominee in nominees:
|
|
if type=='accept':
|
|
nominee.interesting_positions = [x.position.name for x in nominee.nomineeposition_set.pending()]
|
|
else:
|
|
nominee.interesting_positions = [x.position.name for x in nominee.nomineeposition_set.accepted().without_questionnaire_response()]
|
|
if nominee.interesting_positions:
|
|
annotated_nominees.append(nominee)
|
|
|
|
mail_template = DBTemplate.objects.filter(group=nomcom.group, path=mail_path)
|
|
mail_template = mail_template and mail_template[0] or None
|
|
message = None
|
|
|
|
if request.method == 'POST':
|
|
selected_nominees = request.POST.getlist('selected')
|
|
selected_nominees = nominees.filter(id__in=selected_nominees)
|
|
if selected_nominees:
|
|
addrs = send_reminder_to_nominees(selected_nominees,type)
|
|
if addrs:
|
|
message = ('success', 'A copy of "%s" has been sent to %s'%(mail_template.title,", ".join(addrs)))
|
|
else:
|
|
message = ('warning', 'No messages were sent.')
|
|
else:
|
|
message = ('warning', "Please, select at least one nominee")
|
|
return render_to_response('nomcom/send_reminder_mail.html',
|
|
{'nomcom': nomcom,
|
|
'year': year,
|
|
'nominees': annotated_nominees,
|
|
'mail_template': mail_template,
|
|
'selected': selected_tab,
|
|
'reminder_description': reminder_description,
|
|
'state_description': state_description,
|
|
'message': message}, RequestContext(request))
|
|
|
|
|
|
@role_required("Nomcom Chair", "Nomcom Advisor")
|
|
def private_merge(request, year):
|
|
nomcom = get_nomcom_by_year(year)
|
|
message = None
|
|
if request.method == 'POST':
|
|
form = MergeForm(request.POST, nomcom=nomcom)
|
|
if form.is_valid():
|
|
form.save()
|
|
message = ('success', 'The emails have been unified')
|
|
else:
|
|
form = MergeForm(nomcom=nomcom)
|
|
|
|
return render_to_response('nomcom/private_merge.html',
|
|
{'nomcom': nomcom,
|
|
'year': year,
|
|
'form': form,
|
|
'message': message,
|
|
'selected': 'merge'}, RequestContext(request))
|
|
|
|
|
|
def requirements(request, year):
|
|
nomcom = get_nomcom_by_year(year)
|
|
positions = nomcom.position_set.all()
|
|
return render_to_response('nomcom/requirements.html',
|
|
{'nomcom': nomcom,
|
|
'positions': positions,
|
|
'year': year,
|
|
'selected': 'requirements'}, RequestContext(request))
|
|
|
|
|
|
def questionnaires(request, year):
|
|
nomcom = get_nomcom_by_year(year)
|
|
positions = nomcom.position_set.all()
|
|
return render_to_response('nomcom/questionnaires.html',
|
|
{'nomcom': nomcom,
|
|
'positions': positions,
|
|
'year': year,
|
|
'selected': 'questionnaires'}, RequestContext(request))
|
|
|
|
|
|
@login_required
|
|
def public_nominate(request, year):
|
|
return nominate(request, year, True)
|
|
|
|
|
|
@role_required("Nomcom")
|
|
def private_nominate(request, year):
|
|
return nominate(request, year, False)
|
|
|
|
|
|
def nominate(request, year, public):
|
|
nomcom = get_nomcom_by_year(year)
|
|
has_publickey = nomcom.public_key and True or False
|
|
if public:
|
|
template = 'nomcom/public_nominate.html'
|
|
else:
|
|
template = 'nomcom/private_nominate.html'
|
|
|
|
if not has_publickey:
|
|
message = ('warning', "This Nomcom is not yet accepting nominations")
|
|
return render_to_response(template,
|
|
{'message': message,
|
|
'nomcom': nomcom,
|
|
'year': year,
|
|
'selected': 'nominate'}, RequestContext(request))
|
|
|
|
message = None
|
|
if request.method == 'POST':
|
|
form = NominateForm(data=request.POST, nomcom=nomcom, user=request.user, public=public)
|
|
if form.is_valid():
|
|
form.save()
|
|
message = ('success', 'Your nomination has been registered. Thank you for the nomination.')
|
|
else:
|
|
form = NominateForm(nomcom=nomcom, user=request.user, public=public)
|
|
|
|
return render_to_response(template,
|
|
{'form': form,
|
|
'message': message,
|
|
'nomcom': nomcom,
|
|
'year': year,
|
|
'selected': 'nominate'}, RequestContext(request))
|
|
|
|
|
|
@login_required
|
|
def public_feedback(request, year):
|
|
return feedback(request, year, True)
|
|
|
|
|
|
@role_required("Nomcom")
|
|
def private_feedback(request, year):
|
|
return feedback(request, year, False)
|
|
|
|
|
|
def feedback(request, year, public):
|
|
nomcom = get_nomcom_by_year(year)
|
|
has_publickey = nomcom.public_key and True or False
|
|
submit_disabled = True
|
|
nominee = None
|
|
position = None
|
|
selected_nominee = request.GET.get('nominee')
|
|
selected_position = request.GET.get('position')
|
|
if selected_nominee and selected_position:
|
|
nominee = get_object_or_404(Nominee, id=selected_nominee)
|
|
position = get_object_or_404(Position, id=selected_position)
|
|
submit_disabled = False
|
|
|
|
positions = Position.objects.get_by_nomcom(nomcom=nomcom).opened()
|
|
|
|
if public:
|
|
template = 'nomcom/public_feedback.html'
|
|
else:
|
|
template = 'nomcom/private_feedback.html'
|
|
|
|
if not has_publickey:
|
|
message = ('warning', "This Nomcom is not yet accepting comments")
|
|
return render_to_response(template,
|
|
{'message': message,
|
|
'nomcom': nomcom,
|
|
'year': year,
|
|
'selected': 'feedback'}, RequestContext(request))
|
|
|
|
message = None
|
|
if request.method == 'POST':
|
|
form = FeedbackForm(data=request.POST,
|
|
nomcom=nomcom, user=request.user,
|
|
public=public, position=position, nominee=nominee)
|
|
if form.is_valid():
|
|
form.save()
|
|
message = ('success', 'Your feedback has been registered.')
|
|
else:
|
|
form = FeedbackForm(nomcom=nomcom, user=request.user, public=public,
|
|
position=position, nominee=nominee)
|
|
|
|
return render_to_response(template,
|
|
{'form': form,
|
|
'message': message,
|
|
'nomcom': nomcom,
|
|
'year': year,
|
|
'positions': positions,
|
|
'submit_disabled': submit_disabled,
|
|
'selected': 'feedback'}, RequestContext(request))
|
|
|
|
|
|
@role_required("Nomcom Chair", "Nomcom Advisor")
|
|
def private_feedback_email(request, year):
|
|
nomcom = get_nomcom_by_year(year)
|
|
has_publickey = nomcom.public_key and True or False
|
|
message = None
|
|
template = 'nomcom/private_feedback_email.html'
|
|
|
|
if not has_publickey:
|
|
message = ('warning', "This Nomcom is not yet accepting feedback email")
|
|
return render_to_response(template,
|
|
{'message': message,
|
|
'nomcom': nomcom,
|
|
'year': year,
|
|
'selected': 'feedback_email'}, RequestContext(request))
|
|
|
|
form = FeedbackEmailForm(nomcom=nomcom)
|
|
|
|
if request.method == 'POST':
|
|
form = FeedbackEmailForm(data=request.POST,
|
|
nomcom=nomcom)
|
|
if form.is_valid():
|
|
form.save()
|
|
form = FeedbackEmailForm(nomcom=nomcom)
|
|
message = ('success', 'The feedback email has been registered.')
|
|
|
|
return render_to_response(template,
|
|
{'form': form,
|
|
'message': message,
|
|
'nomcom': nomcom,
|
|
'year': year,
|
|
'selected': 'feedback_email'}, RequestContext(request))
|
|
|
|
|
|
@role_required("Nomcom Chair", "Nomcom Advisor")
|
|
def private_questionnaire(request, year):
|
|
nomcom = get_nomcom_by_year(year)
|
|
has_publickey = nomcom.public_key and True or False
|
|
message = None
|
|
questionnaire_response = None
|
|
template = 'nomcom/private_questionnaire.html'
|
|
|
|
if not has_publickey:
|
|
message = ('warning', "This Nomcom is not yet accepting questionnaires")
|
|
return render_to_response(template,
|
|
{'message': message,
|
|
'nomcom': nomcom,
|
|
'year': year,
|
|
'selected': 'questionnaire'}, RequestContext(request))
|
|
|
|
if request.method == 'POST':
|
|
form = QuestionnaireForm(data=request.POST,
|
|
nomcom=nomcom, user=request.user)
|
|
if form.is_valid():
|
|
form.save()
|
|
message = ('success', 'The questionnaire response has been registered.')
|
|
questionnaire_response = form.cleaned_data['comments']
|
|
form = QuestionnaireForm(nomcom=nomcom, user=request.user)
|
|
else:
|
|
form = QuestionnaireForm(nomcom=nomcom, user=request.user)
|
|
|
|
return render_to_response(template,
|
|
{'form': form,
|
|
'questionnaire_response': questionnaire_response,
|
|
'message': message,
|
|
'nomcom': nomcom,
|
|
'year': year,
|
|
'selected': 'questionnaire'}, RequestContext(request))
|
|
|
|
|
|
def process_nomination_status(request, year, nominee_position_id, state, date, hash):
|
|
valid = get_hash_nominee_position(date, nominee_position_id) == hash
|
|
if not valid:
|
|
return HttpResponseForbidden("Bad hash!")
|
|
expiration_days = getattr(settings, 'DAYS_TO_EXPIRE_NOMINATION_LINK', None)
|
|
if expiration_days:
|
|
request_date = datetime.date(int(date[:4]), int(date[4:6]), int(date[6:]))
|
|
if datetime.date.today() > (request_date + datetime.timedelta(days=settings.DAYS_TO_EXPIRE_REGISTRATION_LINK)):
|
|
return HttpResponseForbidden("Link expired")
|
|
|
|
need_confirmation = True
|
|
nomcom = get_nomcom_by_year(year)
|
|
nominee_position = get_object_or_404(NomineePosition, id=nominee_position_id)
|
|
if nominee_position.state.slug != "pending":
|
|
return HttpResponseForbidden("The nomination already was %s" % nominee_position.state)
|
|
|
|
state = get_object_or_404(NomineePositionState, slug=state)
|
|
message = ('warning',
|
|
("Click on 'Save' to set the state of your nomination to %s to %s (this"+
|
|
"is not a final commitment - you can notify us later if you need to change this)") %
|
|
(nominee_position.position.name, state.name))
|
|
if request.method == 'POST':
|
|
nominee_position.state = state
|
|
nominee_position.save()
|
|
need_confirmation = False
|
|
message = message = ('success', 'Your nomination on %s has been set as %s' % (nominee_position.position.name,
|
|
state.name))
|
|
|
|
return render_to_response('nomcom/process_nomination_status.html',
|
|
{'message': message,
|
|
'nomcom': nomcom,
|
|
'year': year,
|
|
'nominee_position': nominee_position,
|
|
'state': state,
|
|
'need_confirmation': need_confirmation,
|
|
'selected': 'feedback'}, RequestContext(request))
|
|
|
|
|
|
@role_required("Nomcom")
|
|
@nomcom_private_key_required
|
|
def view_feedback(request, year):
|
|
nomcom = get_nomcom_by_year(year)
|
|
nominees = Nominee.objects.get_by_nomcom(nomcom).not_duplicated().distinct()
|
|
independent_feedback_types = []
|
|
feedback_types = []
|
|
for ft in FeedbackType.objects.all():
|
|
if ft.slug in settings.NOMINEE_FEEDBACK_TYPES:
|
|
feedback_types.append(ft)
|
|
else:
|
|
independent_feedback_types.append(ft)
|
|
nominees_feedback = {}
|
|
for nominee in nominees:
|
|
nominee_feedback = [(ft.name, nominee.feedback_set.by_type(ft.slug).count()) for ft in feedback_types]
|
|
nominees_feedback.update({nominee: nominee_feedback})
|
|
independent_feedback = [ft.feedback_set.get_by_nomcom(nomcom).count() for ft in independent_feedback_types]
|
|
|
|
return render_to_response('nomcom/view_feedback.html',
|
|
{'year': year,
|
|
'selected': 'view_feedback',
|
|
'nominees': nominees,
|
|
'feedback_types': feedback_types,
|
|
'independent_feedback_types': independent_feedback_types,
|
|
'independent_feedback': independent_feedback,
|
|
'nominees_feedback': nominees_feedback,
|
|
'nomcom': nomcom}, RequestContext(request))
|
|
|
|
|
|
@role_required("Nomcom Chair", "Nomcom Advisor")
|
|
@nomcom_private_key_required
|
|
def view_feedback_pending(request, year):
|
|
nomcom = get_nomcom_by_year(year)
|
|
extra_ids = None
|
|
message = None
|
|
for message in messages.get_messages(request):
|
|
message = ('success', message.message)
|
|
FeedbackFormSet = modelformset_factory(Feedback,
|
|
form=PendingFeedbackForm,
|
|
extra=0)
|
|
feedbacks = Feedback.objects.filter(type__isnull=True, nomcom=nomcom)
|
|
|
|
try:
|
|
default_type = FeedbackType.objects.get(slug=settings.DEFAULT_FEEDBACK_TYPE)
|
|
except FeedbackType.DoesNotExist:
|
|
default_type = None
|
|
|
|
extra_step = False
|
|
if request.method == 'POST' and request.POST.get('move_to_default'):
|
|
formset = FeedbackFormSet(request.POST)
|
|
if formset.is_valid():
|
|
for form in formset.forms:
|
|
form.set_nomcom(nomcom, request.user)
|
|
form.move_to_default()
|
|
formset = FeedbackFormSet(queryset=feedbacks)
|
|
for form in formset.forms:
|
|
form.set_nomcom(nomcom, request.user)
|
|
messages.success(request, 'Feedback saved')
|
|
return redirect('nomcom_view_feedback_pending', year=year)
|
|
elif request.method == 'POST' and request.POST.get('end'):
|
|
extra_ids = request.POST.get('extra_ids', None)
|
|
extra_step = True
|
|
formset = FullFeedbackFormSet(request.POST)
|
|
for form in formset.forms:
|
|
form.set_nomcom(nomcom, request.user)
|
|
if formset.is_valid():
|
|
formset.save()
|
|
if extra_ids:
|
|
extra = []
|
|
for key in extra_ids.split(','):
|
|
id, pk_type = key.split(':')
|
|
feedback = Feedback.objects.get(id=id)
|
|
feedback.type_id = pk_type
|
|
extra.append(feedback)
|
|
formset = FullFeedbackFormSet(queryset=Feedback.objects.filter(id__in=[i.id for i in extra]))
|
|
for form in formset.forms:
|
|
form.set_nomcom(nomcom, request.user, extra)
|
|
extra_ids = None
|
|
else:
|
|
messages.success(request, 'Feedback saved')
|
|
return redirect('nomcom_view_feedback_pending', year=year)
|
|
elif request.method == 'POST':
|
|
formset = FeedbackFormSet(request.POST)
|
|
for form in formset.forms:
|
|
form.set_nomcom(nomcom, request.user)
|
|
if formset.is_valid():
|
|
extra = []
|
|
nominations = []
|
|
moved = 0
|
|
for form in formset.forms:
|
|
if form.instance.type and form.instance.type.slug in settings.NOMINEE_FEEDBACK_TYPES:
|
|
if form.instance.type.slug == 'nomina':
|
|
nominations.append(form.instance)
|
|
else:
|
|
extra.append(form.instance)
|
|
else:
|
|
if form.instance.type:
|
|
moved += 1
|
|
form.save()
|
|
if extra or nominations:
|
|
extra_step = True
|
|
if nominations:
|
|
formset = FullFeedbackFormSet(queryset=Feedback.objects.filter(id__in=[i.id for i in nominations]))
|
|
for form in formset.forms:
|
|
form.set_nomcom(nomcom, request.user, nominations)
|
|
extra_ids = ','.join(['%s:%s' % (i.id, i.type.pk) for i in extra])
|
|
else:
|
|
formset = FullFeedbackFormSet(queryset=Feedback.objects.filter(id__in=[i.id for i in extra]))
|
|
for form in formset.forms:
|
|
form.set_nomcom(nomcom, request.user, extra)
|
|
if moved:
|
|
message = ('success', '%s messages classified. You must enter more information for the following feedback.' % moved)
|
|
else:
|
|
messages.success(request, 'Feedback saved')
|
|
return redirect('nomcom_view_feedback_pending', year=year)
|
|
else:
|
|
formset = FeedbackFormSet(queryset=feedbacks)
|
|
for form in formset.forms:
|
|
form.set_nomcom(nomcom, request.user)
|
|
type_dict = OrderedDict()
|
|
for t in FeedbackType.objects.all().order_by('pk'):
|
|
rest = t.name
|
|
slug = rest[0]
|
|
rest = rest[1:]
|
|
while slug in type_dict and rest:
|
|
slug = rest[0]
|
|
rest = rest[1]
|
|
type_dict[slug] = t
|
|
return render_to_response('nomcom/view_feedback_pending.html',
|
|
{'year': year,
|
|
'selected': 'feedback_pending',
|
|
'formset': formset,
|
|
'message': message,
|
|
'extra_step': extra_step,
|
|
'default_type': default_type,
|
|
'type_dict': type_dict,
|
|
'extra_ids': extra_ids,
|
|
'types': FeedbackType.objects.all().order_by('pk'),
|
|
'nomcom': nomcom}, RequestContext(request))
|
|
|
|
|
|
@role_required("Nomcom")
|
|
@nomcom_private_key_required
|
|
def view_feedback_unrelated(request, year):
|
|
nomcom = get_nomcom_by_year(year)
|
|
feedback_types = []
|
|
for ft in FeedbackType.objects.exclude(slug__in=settings.NOMINEE_FEEDBACK_TYPES):
|
|
feedback_types.append({'ft': ft,
|
|
'feedback': ft.feedback_set.get_by_nomcom(nomcom)})
|
|
|
|
return render_to_response('nomcom/view_feedback_unrelated.html',
|
|
{'year': year,
|
|
'selected': 'view_feedback',
|
|
'feedback_types': feedback_types,
|
|
'nomcom': nomcom}, RequestContext(request))
|
|
|
|
|
|
@role_required("Nomcom")
|
|
@nomcom_private_key_required
|
|
def view_feedback_nominee(request, year, nominee_id):
|
|
nomcom = get_nomcom_by_year(year)
|
|
nominee = get_object_or_404(Nominee, id=nominee_id)
|
|
feedback_types = FeedbackType.objects.filter(slug__in=settings.NOMINEE_FEEDBACK_TYPES)
|
|
|
|
return render_to_response('nomcom/view_feedback_nominee.html',
|
|
{'year': year,
|
|
'selected': 'view_feedback',
|
|
'nominee': nominee,
|
|
'feedback_types': feedback_types,
|
|
'nomcom': nomcom}, RequestContext(request))
|
|
|
|
|
|
@role_required("Nomcom Chair", "Nomcom Advisor")
|
|
def edit_nominee(request, year, nominee_id):
|
|
nomcom = get_nomcom_by_year(year)
|
|
nominee = get_object_or_404(Nominee, id=nominee_id)
|
|
message = None
|
|
|
|
if request.method == 'POST':
|
|
form = EditNomineeForm(request.POST,
|
|
instance=nominee)
|
|
if form.is_valid():
|
|
form.save()
|
|
message = ('success', 'The nominee has been changed')
|
|
else:
|
|
form = EditNomineeForm(instance=nominee)
|
|
|
|
return render_to_response('nomcom/edit_nominee.html',
|
|
{'year': year,
|
|
'selected': 'index',
|
|
'nominee': nominee,
|
|
'form': form,
|
|
'message': message,
|
|
'nomcom': nomcom}, RequestContext(request))
|
|
|
|
|
|
@role_required("Nomcom Chair", "Nomcom Advisor")
|
|
def edit_nomcom(request, year):
|
|
nomcom = get_nomcom_by_year(year)
|
|
|
|
if nomcom.public_key:
|
|
message = ('warning', 'Previous data will remain encrypted with the old key')
|
|
else:
|
|
message = ('warning', 'The nomcom has not a public key yet')
|
|
|
|
ReminderDateInlineFormSet = inlineformset_factory(parent_model=NomCom,
|
|
model=ReminderDates,
|
|
form=ReminderDatesForm)
|
|
if request.method == 'POST':
|
|
formset = ReminderDateInlineFormSet(request.POST, instance=nomcom)
|
|
form = EditNomcomForm(request.POST,
|
|
request.FILES,
|
|
instance=nomcom)
|
|
if form.is_valid() and formset.is_valid():
|
|
form.save()
|
|
formset.save()
|
|
formset = ReminderDateInlineFormSet(instance=nomcom)
|
|
message = ('success', 'The nomcom has been changed')
|
|
else:
|
|
formset = ReminderDateInlineFormSet(instance=nomcom)
|
|
form = EditNomcomForm(instance=nomcom)
|
|
|
|
return render_to_response('nomcom/edit_nomcom.html',
|
|
{'form': form,
|
|
'formset': formset,
|
|
'nomcom': nomcom,
|
|
'message': message,
|
|
'year': year,
|
|
'selected': 'edit_nomcom'}, RequestContext(request))
|
|
|
|
|
|
@role_required("Nomcom Chair", "Nomcom Advisor")
|
|
def delete_nomcom(request, year):
|
|
nomcom = get_nomcom_by_year(year)
|
|
|
|
if request.method == 'POST':
|
|
nomcom.delete()
|
|
messages.success(request, "Deleted NomCom data")
|
|
return redirect('nomcom_deleted')
|
|
|
|
return render(request, 'nomcom/delete_nomcom.html', {
|
|
'year': year,
|
|
'selected': 'edit_nomcom',
|
|
'nomcom': nomcom,
|
|
})
|
|
|
|
|
|
@role_required("Nomcom Chair", "Nomcom Advisor")
|
|
def list_templates(request, year):
|
|
nomcom = get_nomcom_by_year(year)
|
|
positions = nomcom.position_set.all()
|
|
template_list = DBTemplate.objects.filter(group=nomcom.group).exclude(path__contains='/position/')
|
|
|
|
return render_to_response('nomcom/list_templates.html',
|
|
{'template_list': template_list,
|
|
'positions': positions,
|
|
'year': year,
|
|
'selected': 'edit_templates',
|
|
'nomcom': nomcom}, RequestContext(request))
|
|
|
|
|
|
@role_required("Nomcom Chair", "Nomcom Advisor")
|
|
def edit_template(request, year, template_id):
|
|
nomcom = get_nomcom_by_year(year)
|
|
return_url = request.META.get('HTTP_REFERER', None)
|
|
|
|
return template_edit(request, nomcom.group.acronym, template_id,
|
|
base_template='nomcom/edit_template.html',
|
|
formclass=NomComTemplateForm,
|
|
extra_context={'year': year,
|
|
'return_url': return_url,
|
|
'nomcom': nomcom})
|
|
|
|
|
|
@role_required("Nomcom Chair", "Nomcom Advisor")
|
|
def list_positions(request, year):
|
|
nomcom = get_nomcom_by_year(year)
|
|
positions = nomcom.position_set.all()
|
|
|
|
return render_to_response('nomcom/list_positions.html',
|
|
{'positions': positions,
|
|
'year': year,
|
|
'selected': 'edit_positions',
|
|
'nomcom': nomcom}, RequestContext(request))
|
|
|
|
|
|
@role_required("Nomcom Chair", "Nomcom Advisor")
|
|
def remove_position(request, year, position_id):
|
|
nomcom = get_nomcom_by_year(year)
|
|
try:
|
|
position = nomcom.position_set.get(id=position_id)
|
|
except Position.DoesNotExist:
|
|
raise Http404
|
|
|
|
if request.POST.get('remove', None):
|
|
position.delete()
|
|
return redirect('nomcom_list_positions', year=year)
|
|
return render_to_response('nomcom/remove_position.html',
|
|
{'year': year,
|
|
'position': position,
|
|
'nomcom': nomcom}, RequestContext(request))
|
|
|
|
|
|
@role_required("Nomcom Chair", "Nomcom Advisor")
|
|
def edit_position(request, year, position_id=None):
|
|
nomcom = get_nomcom_by_year(year)
|
|
if position_id:
|
|
try:
|
|
position = nomcom.position_set.get(id=position_id)
|
|
except Position.DoesNotExist:
|
|
raise Http404
|
|
else:
|
|
position = None
|
|
|
|
if request.method == 'POST':
|
|
form = PositionForm(request.POST, instance=position, nomcom=nomcom)
|
|
if form.is_valid():
|
|
form.save()
|
|
return redirect('nomcom_list_positions', year=year)
|
|
else:
|
|
form = PositionForm(instance=position, nomcom=nomcom)
|
|
|
|
return render_to_response('nomcom/edit_position.html',
|
|
{'form': form,
|
|
'position': position,
|
|
'year': year,
|
|
'nomcom': nomcom}, RequestContext(request))
|