Skip to content

Commit 2f6799e

Browse files
committed
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
1 parent 9a46f47 commit 2f6799e

7 files changed

Lines changed: 189 additions & 45 deletions

File tree

ietf/doc/tests_material.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ def test_upload_slides(self):
6666

6767
# post
6868
r = self.client.post(url, dict(title="Test File - with fancy title",
69+
abstract = "Test Abstract",
6970
name="slides-%s-test-file" % group.acronym,
7071
state=State.objects.get(type="slides", slug="active").pk,
7172
material=test_file))
@@ -125,6 +126,7 @@ def test_revise(self):
125126

126127
# post
127128
r = self.client.post(url, dict(title="New title",
129+
abstract="New abstract",
128130
state=State.objects.get(type="slides", slug="active").pk,
129131
material=test_file))
130132
self.assertEqual(r.status_code, 302)

ietf/doc/urls_material.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,11 @@
33
urlpatterns = patterns('ietf.doc.views_material',
44
url(r'^(?P<action>state|title|abstract|revise)/$', "edit_material", name="material_edit"),
55
url(r'^sessions/$', "material_presentations", name="material_presentations"),
6+
(r'^sessions/(?P<seq>\d+)/$', "material_presentations"),
7+
(r'^sessions/(?P<acronym>[A-Za-z0-9_\-\+]+)/$', "material_presentations"),
8+
(r'^sessions/(?P<acronym>[A-Za-z0-9_\-\+]+)/(?P<seq>\d+)/$', "material_presentations"),
9+
(r'^sessions/(?P<acronym>[A-Za-z0-9_\-\+]+)/(?P<week_day>[a-zA-Z]+)/$', "material_presentations"),
10+
(r'^sessions/(?P<acronym>[A-Za-z0-9_\-\+]+)/(?P<date>\d{4}-\d{2}-\d{2}(-\d{4})?)/$', "material_presentations"),
11+
(r'^sessions/(?P<acronym>[A-Za-z0-9_\-\+]+)/(?P<date>\d{4}-\d{2}-\d{2}(-\d{4})?)/(?P<seq>\d+)/$', "material_presentations"),
612
)
713

ietf/doc/views_material.py

Lines changed: 92 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -173,17 +173,18 @@ def edit_material(request, name=None, acronym=None, action=None, doc_type=None):
173173
'doc_name': doc.name if doc else "",
174174
})
175175

176-
class MaterialPresentationForm(forms.Form):
176+
class MaterialVersionForm(forms.Form):
177177

178-
sesspres = forms.MultipleChoiceField(required=False,widget=forms.CheckboxSelectMultiple,label='Place this document on the agenda for the selected sessions')
178+
version = forms.ChoiceField(required=False,
179+
label='Which version of this document will be presented at this session')
179180

180-
def __init__(self,*args,**kwargs):
181+
def __init__(self, *args, **kwargs):
181182
choices = kwargs.pop('choices')
182-
super(MaterialPresentationForm,self).__init__(*args,**kwargs)
183-
self.fields['sesspres'].choices=choices
183+
super(MaterialVersionForm,self).__init__(*args,**kwargs)
184+
self.fields['version'].choices = choices
184185

185186
@login_required
186-
def material_presentations(request, name):
187+
def material_presentations(request, name, acronym=None, date=None, seq=None, week_day=None):
187188

188189
doc = get_object_or_404(Document, name=name)
189190
if not (doc.type_id=='slides' and doc.get_state('slides').slug=='active'):
@@ -197,31 +198,93 @@ def material_presentations(request, name):
197198
# This motif is also in Document.future_presentations - it would be nice to consolodate it somehow
198199
candidate_sessions = Session.objects.filter(meeting__date__gte=datetime.date.today()-datetime.timedelta(days=15))
199200
refined_candidates = [ sess for sess in candidate_sessions if sess.meeting.end_date()>=datetime.date.today()]
201+
202+
if acronym:
203+
refined_candidates = [ sess for sess in refined_candidates if sess.group.acronym==acronym]
204+
205+
if date:
206+
if len(date)==15:
207+
start = datetime.datetime.strptime(date,"%Y-%m-%d-%H%M")
208+
refined_candidates = [ sess for sess in refined_candidates if sess.scheduledsession_set.filter(schedule=sess.meeting.agenda,timeslot__time=start) ]
209+
else:
210+
start = datetime.datetime.strptime(date,"%Y-%m-%d").date()
211+
end = start+datetime.timedelta(days=1)
212+
refined_candidates = [ sess for sess in refined_candidates if sess.scheduledsession_set.filter(schedule=sess.meeting.agenda,timeslot__time__range=(start,end)) ]
213+
214+
if week_day:
215+
try:
216+
dow = ['sun','mon','tue','wed','thu','fri','sat'].index(week_day.lower()[:3]) + 1
217+
except ValueError:
218+
raise Http404
219+
refined_candidates = [ sess for sess in refined_candidates if sess.scheduledsession_set.filter(schedule=sess.meeting.agenda,timeslot__time__week_day=dow) ]
220+
200221
changeable_sessions = [ sess for sess in refined_candidates if can_manage_materials(request.user, sess.group) ]
222+
223+
if not changeable_sessions:
224+
raise Http404
225+
201226
for sess in changeable_sessions:
202-
sess.has_presentation = sess.sessionpresentation_set.filter(document=doc)
203-
sorted_sessions = sorted(changeable_sessions,key=lambda x:'%s%s%s'%('0' if x.has_presentation else '1',x.meeting,x.short_name))
227+
sess.has_presentation = bool(sess.sessionpresentation_set.filter(document=doc))
228+
if sess.has_presentation:
229+
sess.version = sess.sessionpresentation_set.get(document=doc).rev
230+
231+
# Since Python 2.2 sorts are stable, so this series results in a list sorted first by whether
232+
# the session has any presentations, then by the meeting 'number', then by session's group
233+
# acronym, then by scheduled time (or the time of the session request if the session isn't
234+
# scheduled).
235+
236+
def time_sort_key(session):
237+
official_sessions = session.scheduledsession_set.filter(schedule=session.meeting.agenda)
238+
if official_sessions:
239+
return official_sessions.first().timeslot.time
240+
else:
241+
return session.requested
242+
243+
time_sorted = sorted(changeable_sessions,key=time_sort_key)
244+
acronym_sorted = sorted(time_sorted,key=lambda x: x.group.acronym)
245+
meeting_sorted = sorted(acronym_sorted,key=lambda x: x.meeting.number)
246+
sorted_sessions = sorted(meeting_sorted,key=lambda x: '0' if x.has_presentation else '1')
247+
248+
if seq:
249+
iseq = int(seq) - 1
250+
if not iseq in range(0,len(sorted_sessions)):
251+
raise Http404
252+
else:
253+
sorted_sessions = [sorted_sessions[iseq]]
254+
255+
for index,session in enumerate(sorted_sessions):
256+
session.sequence = index+1
257+
258+
if len(sorted_sessions)==1:
259+
session = sorted_sessions[0]
260+
choices = [('notpresented','Not Presented')]
261+
choices.extend([(x,x) for x in doc.docevent_set.filter(type='new_revision').values_list('newrevisiondocevent__rev',flat=True)])
262+
initial = {'version' : session.version if hasattr(session,'version') else 'notpresented'}
263+
264+
if request.method == 'POST':
265+
form = MaterialVersionForm(request.POST,choices=choices)
266+
if form.is_valid():
267+
if request.POST.get("action", "") == "Save":
268+
new_selection = form.cleaned_data['version']
269+
if initial['version'] != new_selection:
270+
if initial['version'] == 'notpresented':
271+
doc.sessionpresentation_set.create(session=session,rev=new_selection)
272+
elif new_selection == 'notpresented':
273+
doc.sessionpresentation_set.filter(session=session).delete()
274+
else:
275+
doc.sessionpresentation_set.filter(session=session).update(rev=new_selection)
276+
return redirect('doc_view',name=doc.name)
277+
else:
278+
form = MaterialVersionForm(choices=choices,initial=initial)
204279

205-
choices=[(sess.pk,'%s: %s'%(sess.meeting,sess.short_name)) for sess in sorted_sessions]
206-
initial = {'sesspres': [sess.pk for sess in sorted_sessions if sess.has_presentation]}
280+
return render(request, 'doc/material/edit_material_presentations.html', {
281+
'session': session,
282+
'doc': doc,
283+
'form': form,
284+
})
207285

208-
if request.method == 'POST':
209-
form = MaterialPresentationForm(request.POST,choices=choices)
210-
if form.is_valid():
211-
print "STUFF",request.POST.get("action","nothing to be gotten")
212-
if request.POST.get("action", "") == "Save":
213-
new_selections = form.cleaned_data['sesspres']
214-
doc.sessionpresentation_set.filter(session_id__in=(set(initial['sesspres'])-set(new_selections))).delete()
215-
for sess_pk in set(new_selections)-set(initial['sesspres']):
216-
doc.sessionpresentation_set.create(session_id=sess_pk,rev=doc.rev)
217-
return redirect('doc_view',name=doc.name)
218286
else:
219-
form = MaterialPresentationForm(choices=choices,
220-
initial=initial,
221-
)
222-
223-
return render(request, 'doc/material/material_presentations.html', {
224-
'sessions' : sorted_sessions,
225-
'doc': doc,
226-
'form': form,
227-
})
287+
return render(request, 'doc/material/material_presentations.html', {
288+
'sessions' : sorted_sessions,
289+
'doc': doc,
290+
})

ietf/meeting/models.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -839,10 +839,10 @@ def __unicode__(self):
839839
return self.meeting.number
840840

841841
ss0name = "(unscheduled)"
842-
ss = self.scheduledsession_set.order_by('timeslot__time')
842+
ss = self.scheduledsession_set.filter(schedule=self.meeting.agenda).order_by('timeslot__time')
843843
if ss:
844-
ss0name = ss[0].timeslot.time.strftime("%H%M")
845-
return u"%s: %s %s[%u]" % (self.meeting, self.group.acronym, ss0name, self.pk)
844+
ss0name = ','.join([x.timeslot.time.strftime("%a-%H%M") for x in ss])
845+
return u"%s: %s %s %s" % (self.meeting, self.group.acronym, self.name, ss0name)
846846

847847
def is_bof(self):
848848
return self.group.is_bof();

ietf/meeting/urls.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,13 @@
5353
(r'^(?P<num>\d+)/sessions.json', ajax.sessions_json),
5454
(r'^(?P<num>\d+)/session/(?P<sessionid>\d+).json', ajax.session_json),
5555
(r'^(?P<num>\d+)/session/(?P<sessionid>\d+)/constraints.json', ajax.session_constraints),
56+
57+
(r'^(?P<num>\d+)/session/(?P<acronym>[A-Za-z0-9_\-\+]+)/$', views.session_details),
58+
(r'^(?P<num>\d+)/session/(?P<acronym>[A-Za-z0-9_\-\+]+)/(?P<seq>\d+)/$', views.session_details),
59+
(r'^(?P<num>\d+)/session/(?P<acronym>[A-Za-z0-9_\-\+]+)/(?P<week_day>[a-zA-Z]+)/$', views.session_details),
60+
(r'^(?P<num>\d+)/session/(?P<acronym>[A-Za-z0-9_\-\+]+)/(?P<date>\d{4}-\d{2}-\d{2}(-\d{4})?)/$', views.session_details),
61+
(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),
62+
5663
(r'^(?P<num>\d+)/constraint/(?P<constraintid>\d+).json', ajax.constraint_json),
5764
(r'^(?P<num>\d+).json$', ajax.meeting_json),
5865
(r'^$', views.current_materials),

ietf/meeting/views.py

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import debug # pyflakes:ignore
1111

1212
from django import forms
13-
from django.shortcuts import render_to_response, redirect
13+
from django.shortcuts import render, render_to_response, redirect
1414
from django.http import HttpResponse, HttpResponseRedirect, HttpResponseForbidden, Http404
1515
from django.core.urlresolvers import reverse
1616
from django.db.models import Q
@@ -616,3 +616,64 @@ def meeting_requests(request, num=None) :
616616
"groups_not_meeting": groups_not_meeting},
617617
context_instance=RequestContext(request))
618618

619+
def session_details(request, num, acronym, date=None, week_day=None, seq=None) :
620+
meeting = get_meeting(num)
621+
sessions = Session.objects.filter(meeting=meeting,group__acronym=acronym)
622+
623+
if not sessions:
624+
sessions = Session.objects.filter(meeting=meeting,short=acronym)
625+
626+
if date:
627+
if len(date)==15:
628+
start = datetime.datetime.strptime(date,"%Y-%m-%d-%H%M")
629+
sessions = sessions.filter(scheduledsession__schedule=meeting.agenda,scheduledsession__timeslot__time=start)
630+
else:
631+
start = datetime.datetime.strptime(date,"%Y-%m-%d").date()
632+
end = start+datetime.timedelta(days=1)
633+
sessions = sessions.filter(scheduledsession__schedule=meeting.agenda,scheduledsession__timeslot__time__range=(start,end))
634+
635+
if week_day:
636+
try:
637+
dow = ['sun','mon','tue','wed','thu','fri','sat'].index(week_day.lower()[:3]) + 1
638+
except ValueError:
639+
raise Http404
640+
sessions = sessions.filter(scheduledsession__schedule=meeting.agenda,scheduledsession__timeslot__time__week_day=dow)
641+
642+
643+
def sort_key(session):
644+
official_sessions = session.scheduledsession_set.filter(schedule=session.meeting.agenda)
645+
if official_sessions:
646+
return official_sessions.first().timeslot.time
647+
else:
648+
return session.requested
649+
650+
sessions = sorted(sessions,key=sort_key)
651+
652+
if seq:
653+
iseq = int(seq) - 1
654+
if not iseq in range(0,len(sessions)):
655+
raise Http404
656+
else:
657+
sessions= [sessions[iseq]]
658+
659+
if not sessions:
660+
raise Http404
661+
662+
if len(sessions)==1:
663+
session = sessions[0]
664+
scheduled_time = "Not yet scheduled"
665+
ss = session.scheduledsession_set.filter(schedule=meeting.agenda).order_by('timeslot__time')
666+
if ss:
667+
scheduled_time = ','.join([x.timeslot.time.strftime("%A %b-%d %H%M") for x in ss])
668+
return render(request, "meeting/session_details.html",
669+
{ 'session':sessions[0] ,
670+
'meeting' :meeting ,
671+
'acronym' :acronym,
672+
'time': scheduled_time,
673+
})
674+
else:
675+
return render(request, "meeting/session_list.html",
676+
{ 'sessions':sessions ,
677+
'meeting' :meeting ,
678+
'acronym' :acronym,
679+
})
Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,28 @@
11
{% extends "base.html" %}
22

33
{% block title %}
4-
Edit Upcoming Presentations
5-
{% endblock %}
6-
7-
{% block morecss %}
8-
{{ block.super }}
9-
ul#id_sesspres { list-style-type: none; padding: 0px; margin: 0px; }
4+
Upcoming Presentations
105
{% endblock %}
116

127
{% block content %}
138
{% load ietf_filters %}
149

15-
<h1>Edit Upcoming Presentations of<br/>{{doc.title}}<br/>{{doc.name}}</h1>
10+
<h1>Upcoming Presentations of<br/>{{doc.title}}<br/>{{doc.name}}</h1>
1611

17-
<form class="session-presentations" action="" method="post">{% csrf_token %}
18-
{{form.as_p}}
19-
<input style="button" type="submit" name="action" value="Save">
20-
<input style="button" type="submit" name="action" value="Cancel">
21-
</form>
12+
<ul>
13+
{% regroup sessions by has_presentation as is_scheduled_list %}
14+
{% for is_scheduled in is_scheduled_list %}
15+
<li> {{ is_scheduled.grouper|yesno:"Presentation Scheduled,Presentation Not Scheduled"}}
16+
<ul>
17+
{% for session in is_scheduled.list %}
18+
<li>
19+
<a href="{{session.sequence}}">{{ session }}</a>
20+
{% if session.versions %} (version{{session.versions|pluralize}} {{session.versions|join:','}}) {% endif %}
21+
</li>
22+
{% endfor %}
23+
</ul>
24+
</li>
25+
{% endfor %}
26+
</ul>
2227

2328
{% endblock content %}

0 commit comments

Comments
 (0)