Have working selectors for sessions related to a meeting and sessions related to a document, views for listing such sections that can be edited, and an edit form for changing the presented version. Checkpointing before big refactor to move the URI components around

- Legacy-Id: 8453
This commit is contained in:
Robert Sparks 2014-10-21 21:16:27 +00:00
parent 9a46f47168
commit 2f6799ece6
7 changed files with 189 additions and 45 deletions

View file

@ -66,6 +66,7 @@ class GroupMaterialTests(TestCase):
# post
r = self.client.post(url, dict(title="Test File - with fancy title",
abstract = "Test Abstract",
name="slides-%s-test-file" % group.acronym,
state=State.objects.get(type="slides", slug="active").pk,
material=test_file))
@ -125,6 +126,7 @@ class GroupMaterialTests(TestCase):
# post
r = self.client.post(url, dict(title="New title",
abstract="New abstract",
state=State.objects.get(type="slides", slug="active").pk,
material=test_file))
self.assertEqual(r.status_code, 302)

View file

@ -3,5 +3,11 @@ from django.conf.urls import patterns, url
urlpatterns = patterns('ietf.doc.views_material',
url(r'^(?P<action>state|title|abstract|revise)/$', "edit_material", name="material_edit"),
url(r'^sessions/$', "material_presentations", name="material_presentations"),
(r'^sessions/(?P<seq>\d+)/$', "material_presentations"),
(r'^sessions/(?P<acronym>[A-Za-z0-9_\-\+]+)/$', "material_presentations"),
(r'^sessions/(?P<acronym>[A-Za-z0-9_\-\+]+)/(?P<seq>\d+)/$', "material_presentations"),
(r'^sessions/(?P<acronym>[A-Za-z0-9_\-\+]+)/(?P<week_day>[a-zA-Z]+)/$', "material_presentations"),
(r'^sessions/(?P<acronym>[A-Za-z0-9_\-\+]+)/(?P<date>\d{4}-\d{2}-\d{2}(-\d{4})?)/$', "material_presentations"),
(r'^sessions/(?P<acronym>[A-Za-z0-9_\-\+]+)/(?P<date>\d{4}-\d{2}-\d{2}(-\d{4})?)/(?P<seq>\d+)/$', "material_presentations"),
)

View file

@ -173,17 +173,18 @@ def edit_material(request, name=None, acronym=None, action=None, doc_type=None):
'doc_name': doc.name if doc else "",
})
class MaterialPresentationForm(forms.Form):
class MaterialVersionForm(forms.Form):
sesspres = forms.MultipleChoiceField(required=False,widget=forms.CheckboxSelectMultiple,label='Place this document on the agenda for the selected sessions')
version = forms.ChoiceField(required=False,
label='Which version of this document will be presented at this session')
def __init__(self,*args,**kwargs):
def __init__(self, *args, **kwargs):
choices = kwargs.pop('choices')
super(MaterialPresentationForm,self).__init__(*args,**kwargs)
self.fields['sesspres'].choices=choices
super(MaterialVersionForm,self).__init__(*args,**kwargs)
self.fields['version'].choices = choices
@login_required
def material_presentations(request, name):
def material_presentations(request, name, acronym=None, date=None, seq=None, week_day=None):
doc = get_object_or_404(Document, name=name)
if not (doc.type_id=='slides' and doc.get_state('slides').slug=='active'):
@ -197,31 +198,93 @@ def material_presentations(request, name):
# This motif is also in Document.future_presentations - it would be nice to consolodate it somehow
candidate_sessions = Session.objects.filter(meeting__date__gte=datetime.date.today()-datetime.timedelta(days=15))
refined_candidates = [ sess for sess in candidate_sessions if sess.meeting.end_date()>=datetime.date.today()]
if acronym:
refined_candidates = [ sess for sess in refined_candidates if sess.group.acronym==acronym]
if date:
if len(date)==15:
start = datetime.datetime.strptime(date,"%Y-%m-%d-%H%M")
refined_candidates = [ sess for sess in refined_candidates if sess.scheduledsession_set.filter(schedule=sess.meeting.agenda,timeslot__time=start) ]
else:
start = datetime.datetime.strptime(date,"%Y-%m-%d").date()
end = start+datetime.timedelta(days=1)
refined_candidates = [ sess for sess in refined_candidates if sess.scheduledsession_set.filter(schedule=sess.meeting.agenda,timeslot__time__range=(start,end)) ]
if week_day:
try:
dow = ['sun','mon','tue','wed','thu','fri','sat'].index(week_day.lower()[:3]) + 1
except ValueError:
raise Http404
refined_candidates = [ sess for sess in refined_candidates if sess.scheduledsession_set.filter(schedule=sess.meeting.agenda,timeslot__time__week_day=dow) ]
changeable_sessions = [ sess for sess in refined_candidates if can_manage_materials(request.user, sess.group) ]
if not changeable_sessions:
raise Http404
for sess in changeable_sessions:
sess.has_presentation = sess.sessionpresentation_set.filter(document=doc)
sorted_sessions = sorted(changeable_sessions,key=lambda x:'%s%s%s'%('0' if x.has_presentation else '1',x.meeting,x.short_name))
sess.has_presentation = bool(sess.sessionpresentation_set.filter(document=doc))
if sess.has_presentation:
sess.version = sess.sessionpresentation_set.get(document=doc).rev
choices=[(sess.pk,'%s: %s'%(sess.meeting,sess.short_name)) for sess in sorted_sessions]
initial = {'sesspres': [sess.pk for sess in sorted_sessions if sess.has_presentation]}
# Since Python 2.2 sorts are stable, so this series results in a list sorted first by whether
# the session has any presentations, then by the meeting 'number', then by session's group
# acronym, then by scheduled time (or the time of the session request if the session isn't
# scheduled).
def time_sort_key(session):
official_sessions = session.scheduledsession_set.filter(schedule=session.meeting.agenda)
if official_sessions:
return official_sessions.first().timeslot.time
else:
return session.requested
time_sorted = sorted(changeable_sessions,key=time_sort_key)
acronym_sorted = sorted(time_sorted,key=lambda x: x.group.acronym)
meeting_sorted = sorted(acronym_sorted,key=lambda x: x.meeting.number)
sorted_sessions = sorted(meeting_sorted,key=lambda x: '0' if x.has_presentation else '1')
if seq:
iseq = int(seq) - 1
if not iseq in range(0,len(sorted_sessions)):
raise Http404
else:
sorted_sessions = [sorted_sessions[iseq]]
for index,session in enumerate(sorted_sessions):
session.sequence = index+1
if len(sorted_sessions)==1:
session = sorted_sessions[0]
choices = [('notpresented','Not Presented')]
choices.extend([(x,x) for x in doc.docevent_set.filter(type='new_revision').values_list('newrevisiondocevent__rev',flat=True)])
initial = {'version' : session.version if hasattr(session,'version') else 'notpresented'}
if request.method == 'POST':
form = MaterialVersionForm(request.POST,choices=choices)
if form.is_valid():
if request.POST.get("action", "") == "Save":
new_selection = form.cleaned_data['version']
if initial['version'] != new_selection:
if initial['version'] == 'notpresented':
doc.sessionpresentation_set.create(session=session,rev=new_selection)
elif new_selection == 'notpresented':
doc.sessionpresentation_set.filter(session=session).delete()
else:
doc.sessionpresentation_set.filter(session=session).update(rev=new_selection)
return redirect('doc_view',name=doc.name)
else:
form = MaterialVersionForm(choices=choices,initial=initial)
return render(request, 'doc/material/edit_material_presentations.html', {
'session': session,
'doc': doc,
'form': form,
})
if request.method == 'POST':
form = MaterialPresentationForm(request.POST,choices=choices)
if form.is_valid():
print "STUFF",request.POST.get("action","nothing to be gotten")
if request.POST.get("action", "") == "Save":
new_selections = form.cleaned_data['sesspres']
doc.sessionpresentation_set.filter(session_id__in=(set(initial['sesspres'])-set(new_selections))).delete()
for sess_pk in set(new_selections)-set(initial['sesspres']):
doc.sessionpresentation_set.create(session_id=sess_pk,rev=doc.rev)
return redirect('doc_view',name=doc.name)
else:
form = MaterialPresentationForm(choices=choices,
initial=initial,
)
return render(request, 'doc/material/material_presentations.html', {
'sessions' : sorted_sessions,
'doc': doc,
'form': form,
})
return render(request, 'doc/material/material_presentations.html', {
'sessions' : sorted_sessions,
'doc': doc,
})

View file

@ -839,10 +839,10 @@ class Session(models.Model):
return self.meeting.number
ss0name = "(unscheduled)"
ss = self.scheduledsession_set.order_by('timeslot__time')
ss = self.scheduledsession_set.filter(schedule=self.meeting.agenda).order_by('timeslot__time')
if ss:
ss0name = ss[0].timeslot.time.strftime("%H%M")
return u"%s: %s %s[%u]" % (self.meeting, self.group.acronym, ss0name, self.pk)
ss0name = ','.join([x.timeslot.time.strftime("%a-%H%M") for x in ss])
return u"%s: %s %s %s" % (self.meeting, self.group.acronym, self.name, ss0name)
def is_bof(self):
return self.group.is_bof();

View file

@ -53,6 +53,13 @@ urlpatterns = patterns('',
(r'^(?P<num>\d+)/sessions.json', ajax.sessions_json),
(r'^(?P<num>\d+)/session/(?P<sessionid>\d+).json', ajax.session_json),
(r'^(?P<num>\d+)/session/(?P<sessionid>\d+)/constraints.json', ajax.session_constraints),
(r'^(?P<num>\d+)/session/(?P<acronym>[A-Za-z0-9_\-\+]+)/$', views.session_details),
(r'^(?P<num>\d+)/session/(?P<acronym>[A-Za-z0-9_\-\+]+)/(?P<seq>\d+)/$', views.session_details),
(r'^(?P<num>\d+)/session/(?P<acronym>[A-Za-z0-9_\-\+]+)/(?P<week_day>[a-zA-Z]+)/$', views.session_details),
(r'^(?P<num>\d+)/session/(?P<acronym>[A-Za-z0-9_\-\+]+)/(?P<date>\d{4}-\d{2}-\d{2}(-\d{4})?)/$', views.session_details),
(r'^(?P<num>\d+)/session/(?P<acronym>[A-Za-z0-9_\-\+]+)/(?P<date>\d{4}-\d{2}-\d{2}(-\d{4})?)/(?P<seq>\d+)/$', views.session_details),
(r'^(?P<num>\d+)/constraint/(?P<constraintid>\d+).json', ajax.constraint_json),
(r'^(?P<num>\d+).json$', ajax.meeting_json),
(r'^$', views.current_materials),

View file

@ -10,7 +10,7 @@ from tempfile import mkstemp
import debug # pyflakes:ignore
from django import forms
from django.shortcuts import render_to_response, redirect
from django.shortcuts import render, render_to_response, redirect
from django.http import HttpResponse, HttpResponseRedirect, HttpResponseForbidden, Http404
from django.core.urlresolvers import reverse
from django.db.models import Q
@ -616,3 +616,64 @@ def meeting_requests(request, num=None) :
"groups_not_meeting": groups_not_meeting},
context_instance=RequestContext(request))
def session_details(request, num, acronym, date=None, week_day=None, seq=None) :
meeting = get_meeting(num)
sessions = Session.objects.filter(meeting=meeting,group__acronym=acronym)
if not sessions:
sessions = Session.objects.filter(meeting=meeting,short=acronym)
if date:
if len(date)==15:
start = datetime.datetime.strptime(date,"%Y-%m-%d-%H%M")
sessions = sessions.filter(scheduledsession__schedule=meeting.agenda,scheduledsession__timeslot__time=start)
else:
start = datetime.datetime.strptime(date,"%Y-%m-%d").date()
end = start+datetime.timedelta(days=1)
sessions = sessions.filter(scheduledsession__schedule=meeting.agenda,scheduledsession__timeslot__time__range=(start,end))
if week_day:
try:
dow = ['sun','mon','tue','wed','thu','fri','sat'].index(week_day.lower()[:3]) + 1
except ValueError:
raise Http404
sessions = sessions.filter(scheduledsession__schedule=meeting.agenda,scheduledsession__timeslot__time__week_day=dow)
def sort_key(session):
official_sessions = session.scheduledsession_set.filter(schedule=session.meeting.agenda)
if official_sessions:
return official_sessions.first().timeslot.time
else:
return session.requested
sessions = sorted(sessions,key=sort_key)
if seq:
iseq = int(seq) - 1
if not iseq in range(0,len(sessions)):
raise Http404
else:
sessions= [sessions[iseq]]
if not sessions:
raise Http404
if len(sessions)==1:
session = sessions[0]
scheduled_time = "Not yet scheduled"
ss = session.scheduledsession_set.filter(schedule=meeting.agenda).order_by('timeslot__time')
if ss:
scheduled_time = ','.join([x.timeslot.time.strftime("%A %b-%d %H%M") for x in ss])
return render(request, "meeting/session_details.html",
{ 'session':sessions[0] ,
'meeting' :meeting ,
'acronym' :acronym,
'time': scheduled_time,
})
else:
return render(request, "meeting/session_list.html",
{ 'sessions':sessions ,
'meeting' :meeting ,
'acronym' :acronym,
})

View file

@ -1,23 +1,28 @@
{% extends "base.html" %}
{% block title %}
Edit Upcoming Presentations
{% endblock %}
{% block morecss %}
{{ block.super }}
ul#id_sesspres { list-style-type: none; padding: 0px; margin: 0px; }
Upcoming Presentations
{% endblock %}
{% block content %}
{% load ietf_filters %}
<h1>Edit Upcoming Presentations of<br/>{{doc.title}}<br/>{{doc.name}}</h1>
<h1>Upcoming Presentations of<br/>{{doc.title}}<br/>{{doc.name}}</h1>
<form class="session-presentations" action="" method="post">{% csrf_token %}
{{form.as_p}}
<input style="button" type="submit" name="action" value="Save">
<input style="button" type="submit" name="action" value="Cancel">
</form>
<ul>
{% regroup sessions by has_presentation as is_scheduled_list %}
{% for is_scheduled in is_scheduled_list %}
<li> {{ is_scheduled.grouper|yesno:"Presentation Scheduled,Presentation Not Scheduled"}}
<ul>
{% for session in is_scheduled.list %}
<li>
<a href="{{session.sequence}}">{{ session }}</a>
{% if session.versions %} (version{{session.versions|pluralize}} {{session.versions|join:','}}) {% endif %}
</li>
{% endfor %}
</ul>
</li>
{% endfor %}
</ul>
{% endblock content %}