checkpoint: purged the rest of the day/seq URLs. Streamlined workflows to focus on "current" versions as a default. Plumbed editing and deleting sessionpresentations from a document perspective. Started adding meat to document factories.

- Legacy-Id: 10847
This commit is contained in:
Robert Sparks 2016-02-19 04:20:57 +00:00
parent d709af6ca2
commit 859f2ead3d
13 changed files with 276 additions and 303 deletions

View file

@ -1,6 +1,7 @@
import factory
from ietf.doc.models import Document
from ietf.doc.models import Document, DocEvent, NewRevisionDocEvent
from ietf.person.factories import PersonFactory
class DocumentFactory(factory.DjangoModelFactory):
class Meta:
@ -20,3 +21,25 @@ class DocumentFactory(factory.DjangoModelFactory):
'musings',
n,
)
newrevisiondocevent = factory.RelatedFactory('ietf.doc.factories.NewRevisionDocEventFactory','doc')
class DocEventFactory(factory.DjangoModelFactory):
class Meta:
model = DocEvent
type = 'added_comment'
by = factory.SubFactory(PersonFactory)
doc = factory.SubFactory(DocumentFactory)
desc = factory.Faker('sentence',nb_words=6)
class NewRevisionDocEventFactory(DocEventFactory):
class Meta:
model = NewRevisionDocEvent
type = 'new_revision'
rev = '00'
@factory.lazy_attribute
def desc(self):
return 'New version available %s-%s'%(self.doc.name,self.rev)

View file

@ -913,25 +913,32 @@ class DocumentMeetingTests(TestCase):
def setUp(self):
self.group = GroupFactory(type_id='wg',state_id='active')
self.group_chair = PersonFactory()
self.group.role_set.create(name_id='chair',person=self.group_chair,email=self.group_chair.email())
self.other_group = GroupFactory(type_id='wg',state_id='active')
self.other_chair = PersonFactory()
self.other_group.role_set.create(name_id='chair',person=self.other_chair,email=self.other_chair.email())
today = datetime.date.today()
cut_days = settings.MEETING_MATERIALS_SUBMISSION_CORRECTION_DAYS
self.past_cutoff = SessionFactory.create(meeting__type_id='ietf',group=self.group,meeting__date=today-datetime.timedelta(days=1+cut_days))
self.past = SessionFactory.create(meeting__type_id='ietf',group=self.group,meeting__date=today-datetime.timedelta(days=cut_days/2))
self.inprog = SessionFactory.create(meeting__type_id='ietf',group=self.group,meeting__date=today-datetime.timedelta(days=1))
SessionFactory.create(meeting__type_id='ietf',group=self.group,meeting__date=today+datetime.timedelta(days=90))
SessionFactory.create(meeting__type_id='interim',group=self.group,meeting__date=today+datetime.timedelta(days=45))
self.future = SessionFactory.create(meeting__type_id='ietf',group=self.group,meeting__date=today+datetime.timedelta(days=90))
self.interim = SessionFactory.create(meeting__type_id='interim',group=self.group,meeting__date=today+datetime.timedelta(days=45))
def test_view_document_meetings(self):
doc = DocumentFactory.create()
doc.sessionpresentation_set.create(session=self.inprog,rev=None)
doc.sessionpresentation_set.create(session=self.interim,rev=None)
url = urlreverse('ietf.doc.views_material.all_presentations', kwargs=dict(name=doc.name))
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
q = PyQuery(response.content)
self.assertTrue(q('#inprogressmeets'))
self.assertFalse(any([q(id) for id in ['#pastmeets','#futuremeets']]))
self.assertTrue(all([q(id) for id in ['#inprogressmeets','#futuremeets']]))
self.assertFalse(any([q(id) for id in ['#pastmeets',]]))
self.assertFalse(q('#addsessionsbutton'))
self.assertFalse(q("a.btn:contains('Remove document')"))
@ -944,29 +951,130 @@ class DocumentMeetingTests(TestCase):
q = PyQuery(response.content)
self.assertTrue(q('#addsessionsbutton'))
self.assertEqual(1,len(q("#inprogressmeets a.btn-default:contains('Remove document')")))
self.assertEqual(1,len(q("#futuremeets a.btn-default:contains('Remove document')")))
self.assertEqual(1,len(q("#pastmeets a.btn-default:contains('Remove document')")))
self.assertEqual(1,len(q("#pastmeets a.btn-warning:contains('Remove document')")))
group_chair = PersonFactory()
self.group.role_set.create(name_id='chair',person=group_chair,email=group_chair.email())
self.client.login(username=group_chair.user.username,password='%s+password'%group_chair.user.username)
self.client.login(username=self.group_chair.user.username,password='%s+password'%self.group_chair.user.username)
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
q = PyQuery(response.content)
self.assertTrue(q('#addsessionsbutton'))
self.assertEqual(1,len(q("#inprogressmeets a.btn-default:contains('Remove document')")))
self.assertEqual(1,len(q("#futuremeets a.btn-default:contains('Remove document')")))
self.assertEqual(1,len(q("#pastmeets a.btn-default:contains('Remove document')")))
self.assertTrue(q('#pastmeets'))
self.assertFalse(q("#pastmeets a.btn-warning:contains('Remove document')"))
other_group = GroupFactory(type_id='wg',state_id='active')
other_chair = PersonFactory()
other_group.role_set.create(name_id='chair',person=other_chair,email=group_chair.email())
self.client.login(username=other_chair.user.username,password='%s+password'%other_chair.user.username)
self.client.login(username=self.other_chair.user.username,password='%s+password'%self.other_chair.user.username)
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
q = PyQuery(response.content)
self.assertTrue(q('#addsessionsbutton'))
self.assertTrue(all([q(id) for id in ['#pastmeets','#inprogressmeets']]))
self.assertTrue(all([q(id) for id in ['#futuremeets','#pastmeets','#inprogressmeets']]))
self.assertFalse(q("#inprogressmeets a.btn:contains('Remove document')"))
self.assertFalse(q("#futuremeets a.btn:contains('Remove document')"))
self.assertFalse(q("#pastmeets a.btn:contains('Remove document')"))
def test_edit_document_session(self):
doc = DocumentFactory.create()
sp = doc.sessionpresentation_set.create(session=self.future,rev=None)
url = urlreverse('ietf.doc.views_doc.edit_sessionpresentation',kwargs=dict(name='no-such-doc',session_id=sp.session_id))
response = self.client.get(url)
self.assertEqual(response.status_code, 404)
url = urlreverse('ietf.doc.views_doc.edit_sessionpresentation',kwargs=dict(name=doc.name,session_id=0))
response = self.client.get(url)
self.assertEqual(response.status_code, 404)
url = urlreverse('ietf.doc.views_doc.edit_sessionpresentation',kwargs=dict(name=doc.name,session_id=sp.session_id))
response = self.client.get(url)
self.assertEqual(response.status_code, 404)
self.client.login(username=self.other_chair.user.username,password='%s+password'%self.other_chair.user.username)
response = self.client.get(url)
self.assertEqual(response.status_code, 404)
self.client.login(username=self.group_chair.user.username,password='%s+password'%self.group_chair.user.username)
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
q = PyQuery(response.content)
self.assertEqual(2,len(q('select#id_version option')))
# Simulate the cancel button
response = self.client.post(url,{})
self.assertEqual(response.status_code, 302)
self.assertEqual(doc.sessionpresentation_set.get(pk=sp.pk).rev,None)
self.assertEqual(1,doc.docevent_set.count())
response = self.client.post(url,{'version':'00','save':''})
response = self.client.post(url,{})
self.assertEqual(response.status_code, 302)
self.assertEqual(doc.sessionpresentation_set.get(pk=sp.pk).rev,'00')
self.assertEqual(2,doc.docevent_set.count())
def test_edit_document_session_after_proceedings_closed(self):
doc = DocumentFactory.create()
sp = doc.sessionpresentation_set.create(session=self.past_cutoff,rev=None)
url = urlreverse('ietf.doc.views_doc.edit_sessionpresentation',kwargs=dict(name=doc.name,session_id=sp.session_id))
self.client.login(username=self.group_chair.user.username,password='%s+password'%self.group_chair.user.username)
response = self.client.get(url)
self.assertEqual(response.status_code, 404)
self.client.login(username='secretary',password='secretary+password')
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
q=PyQuery(response.content)
self.assertEqual(1,len(q(".alert-warning:contains('may affect published proceedings')")))
def test_remove_document_self(self):
doc = DocumentFactory.create()
sp = doc.sessionpresentation_set.create(session=self.future,rev=None)
url = urlreverse('ietf.doc.views_doc.remove_sessionpresentation',kwargs=dict(name='no-such-doc',session_id=sp.session_id))
response = self.client.get(url)
self.assertEqual(response.status_code, 404)
url = urlreverse('ietf.doc.views_doc.remove_sessionpresentation',kwargs=dict(name=doc.name,session_id=0))
response = self.client.get(url)
self.assertEqual(response.status_code, 404)
url = urlreverse('ietf.doc.views_doc.remove_sessionpresentation',kwargs=dict(name=doc.name,session_id=sp.session_id))
response = self.client.get(url)
self.assertEqual(response.status_code, 404)
self.client.login(username=self.other_chair.user.username,password='%s+password'%self.other_chair.user.username)
response = self.client.get(url)
self.assertEqual(response.status_code, 404)
self.client.login(username=self.group_chair.user.username,password='%s+password'%self.group_chair.user.username)
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
# Simulate the cancel button
response = self.client.post(url,{})
self.assertEqual(response.status_code, 302)
self.assertTrue(doc.sessionpresentation_set.filter(pk=sp.pk).exists())
self.assertEqual(1,doc.docevent_set.count())
response = self.client.post(url,{'remove_session':''})
self.assertEqual(response.status_code, 302)
self.assertFalse(doc.sessionpresentation_set.filter(pk=sp.pk).exists())
self.assertEqual(2,doc.docevent_set.count())
def test_remove_document_session_after_proceedings_closed(self):
doc = DocumentFactory.create()
sp = doc.sessionpresentation_set.create(session=self.past_cutoff,rev=None)
url = urlreverse('ietf.doc.views_doc.remove_sessionpresentation',kwargs=dict(name=doc.name,session_id=sp.session_id))
self.client.login(username=self.group_chair.user.username,password='%s+password'%self.group_chair.user.username)
response = self.client.get(url)
self.assertEqual(response.status_code, 404)
self.client.login(username='secretary',password='secretary+password')
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
q=PyQuery(response.content)
self.assertEqual(1,len(q(".alert-warning:contains('may affect published proceedings')")))

View file

@ -10,7 +10,7 @@ from django.conf import settings
from django.core.urlresolvers import reverse as urlreverse
from ietf.doc.models import Document, State, DocAlias, NewRevisionDocEvent
from ietf.doc.views_material import material_presentations, edit_material_presentations
#from ietf.doc.views_material import material_presentations, edit_material_presentations
from ietf.group.models import Group
from ietf.meeting.models import Meeting, Session, SessionPresentation
from ietf.name.models import SessionStatusName
@ -18,8 +18,6 @@ from ietf.person.models import Person
from ietf.utils.test_utils import TestCase, login_testing_unauthorized, unicontent
from ietf.utils.test_data import make_test_data
from ietf.meeting.test_data import make_meeting_test_data
class GroupMaterialTests(TestCase):
def setUp(self):
self.materials_dir = os.path.abspath("tmp-document-dir")
@ -173,67 +171,3 @@ class GroupMaterialTests(TestCase):
with open(os.path.join(doc.get_file_path(), doc.name + "-" + doc.rev + ".txt")) as f:
self.assertEqual(f.read(), content)
def test_material_presentations(self):
doc = self.create_slides()
meeting = make_meeting_test_data()
meeting.session_set.filter(group__acronym='mars').update(group=doc.group)
url = urlreverse(material_presentations,kwargs=dict(name=doc.name))
login_testing_unauthorized(self, "secretary", url)
r = self.client.get(url)
self.assertEqual(r.status_code, 200)
url = urlreverse(material_presentations,kwargs=dict(name=doc.name,seq=1))
r = self.client.get(url)
self.assertEqual(r.status_code, 200)
when = meeting.agenda.assignments.filter(session__group__acronym='testteam').first().timeslot.time
mdw = when.date().isoformat()
dow = ['mon','tue','wed','thu','fri','sat','sun'][when.weekday()]
for kw in [ dict(),
dict(seq=1),
dict(week_day=dow),
dict(week_day=dow,seq=1),
dict(date=mdw),
dict(date=mdw,seq=1),
dict(date=mdw+'-0930'),
dict(date=mdw+'-0930',seq=1),
]:
kw['name'] = doc.name
kw['acronym'] = 'testteam'
url = urlreverse(material_presentations,kwargs=kw)
r = self.client.get(url)
self.assertEqual(r.status_code, 200)
def test_edit_material_presentations(self):
doc = self.create_slides()
meeting = make_meeting_test_data()
meeting.session_set.filter(group__acronym='mars').update(group=doc.group)
session = meeting.agenda.assignments.filter(session__group__acronym='testteam').first().session
url = urlreverse(edit_material_presentations,kwargs=dict(name=doc.name,acronym='testteam',seq=1))
login_testing_unauthorized(self, "secretary", url)
r = self.client.get(url)
self.assertEqual(r.status_code, 200)
self.assertEqual(doc.sessionpresentation_set.count(),0)
# add the materials to a session
r = self.client.post(url, dict(action="Save",version="00"))
self.assertEqual(r.status_code, 302)
self.assertEqual(doc.sessionpresentation_set.first().session , session)
# change the version
r = self.client.post(url, dict(action="Save",version="01"))
self.assertEqual(r.status_code, 302)
self.assertEqual(doc.sessionpresentation_set.first().session , session)
# take the slides back off that meeting
r = self.client.post(url, dict(action="Save",version="notpresented"))
self.assertEqual(r.status_code, 302)
self.assertEqual(doc.sessionpresentation_set.count(),0)

View file

@ -37,6 +37,11 @@ from ietf.doc import views_search, views_draft, views_ballot
from ietf.doc import views_status_change
from ietf.doc import views_doc
session_patterns = [
url(r'^(?P<session_id>\d+)/edit$', views_doc.edit_sessionpresentation),
url(r'^(?P<session_id>\d+)/remove$', views_doc.remove_sessionpresentation),
]
urlpatterns = patterns('',
(r'^/?$', views_search.search),
url(r'^(?P<name>[A-Za-z0-9\._\+\-]+)$', views_search.search_for_name, name="doc_search_for_name"),
@ -113,4 +118,5 @@ urlpatterns = patterns('',
(r'^(?P<name>[A-Za-z0-9._+-]+)/conflict-review/', include('ietf.doc.urls_conflict_review')),
(r'^(?P<name>[A-Za-z0-9._+-]+)/status-change/', include('ietf.doc.urls_status_change')),
(r'^(?P<name>[A-Za-z0-9._+-]+)/material/', include('ietf.doc.urls_material')),
url(r'^(?P<name>[A-Za-z0-9._+-]+)/session/', include(session_patterns)),
)

View file

@ -3,20 +3,5 @@ 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'^meetings/$', "all_presentations", name="all_presentations"),
url(r'^sessions/$', "material_presentations", name="material_presentations"),
(r'^sessions/(?P<seq>\d+)/edit/$', "edit_material_presentations"),
(r'^sessions/(?P<acronym>[A-Za-z0-9_\-\+]+)/edit/$', "edit_material_presentations"),
(r'^sessions/(?P<acronym>[A-Za-z0-9_\-\+]+)/(?P<seq>\d+)/edit/$', "edit_material_presentations"),
(r'^sessions/(?P<acronym>[A-Za-z0-9_\-\+]+)/(?P<week_day>[a-zA-Z]+)/edit/$', "edit_material_presentations"),
(r'^sessions/(?P<acronym>[A-Za-z0-9_\-\+]+)/(?P<week_day>[a-zA-Z]+)/(?P<seq>\d+)/edit/$', "edit_material_presentations"),
(r'^sessions/(?P<acronym>[A-Za-z0-9_\-\+]+)/(?P<date>\d{4}-\d{2}-\d{2}(-\d{4})?)/edit/$', "edit_material_presentations"),
(r'^sessions/(?P<acronym>[A-Za-z0-9_\-\+]+)/(?P<date>\d{4}-\d{2}-\d{2}(-\d{4})?)/(?P<seq>\d+)/edit/$', "edit_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<week_day>[a-zA-Z]+)/(?P<seq>\d+)/$', "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

@ -1091,3 +1091,65 @@ def email_aliases(request,name=''):
return render(request,'doc/email_aliases.html',{'aliases':aliases,'ietf_domain':settings.IETF_DOMAIN,'doc':doc})
class SessionPresentationForm(forms.Form):
version = forms.ChoiceField(required=False,
label='Which version of this document will be discussed at this session?')
def __init__(self, *args, **kwargs):
choices = kwargs.pop('choices')
super(SessionPresentationForm,self).__init__(*args,**kwargs)
self.fields['version'].choices = choices
def edit_sessionpresentation(request,name,session_id):
doc = get_object_or_404(Document, name=name)
sp = get_object_or_404(doc.sessionpresentation_set, session_id=session_id)
if not sp.session.can_manage_materials(request.user):
raise Http404
if sp.session.is_material_submission_cutoff() and not has_role(request.user, "Secretariat"):
raise Http404
choices = [(x,x) for x in doc.docevent_set.filter(type='new_revision').values_list('newrevisiondocevent__rev',flat=True)]
choices.insert(0,('current','Current at the time of the session'))
initial = {'version' : sp.rev if sp.rev else 'current'}
if request.method == 'POST':
if 'save' in request.POST:
form = SessionPresentationForm(request.POST,choices=choices)
if form.is_valid():
new_selection = form.cleaned_data['version']
if initial['version'] != new_selection:
doc.sessionpresentation_set.filter(pk=sp.pk).update(rev=None if new_selection=='current' else new_selection)
c = DocEvent(type="added_comment", doc=doc, by=request.user.person)
c.desc = "Revision for session %s changed to %s" % (sp.session,new_selection)
c.save()
return redirect('ietf.doc.views_material.all_presentations', name=name)
else:
return redirect('ietf.doc.views_material.all_presentations', name=name)
else:
form = SessionPresentationForm(choices=choices,initial=initial)
return render(request,'doc/edit_sessionpresentation.html', {'sp': sp, 'form': form })
def remove_sessionpresentation(request,name,session_id):
doc = get_object_or_404(Document, name=name)
sp = get_object_or_404(doc.sessionpresentation_set, session_id=session_id)
if not sp.session.can_manage_materials(request.user):
raise Http404
if sp.session.is_material_submission_cutoff() and not has_role(request.user, "Secretariat"):
raise Http404
if request.method == 'POST':
if 'remove_session' in request.POST:
doc.sessionpresentation_set.filter(pk=sp.pk).delete()
c = DocEvent(type="added_comment", doc=doc, by=request.user.person)
c.desc = "Removed from session: %s" % (sp.session)
c.save()
return redirect('ietf.doc.views_material.all_presentations', name=name)
return render(request,'doc/remove_sessionpresentation.html', {'sp': sp })

View file

@ -17,7 +17,6 @@ from ietf.doc.models import NewRevisionDocEvent, save_document_in_history
from ietf.doc.utils import add_state_change_event, check_common_doc_name_rules
from ietf.group.models import Group
from ietf.group.utils import can_manage_materials
from ietf.meeting.models import Session
from ietf.meeting.utils import group_sessions
@login_required
@ -174,152 +173,6 @@ def edit_material(request, name=None, acronym=None, action=None, doc_type=None):
'doc_name': doc.name if doc else "",
})
class MaterialVersionForm(forms.Form):
version = forms.ChoiceField(required=False,
label='Which version of this document will be presented at this session')
def __init__(self, *args, **kwargs):
choices = kwargs.pop('choices')
super(MaterialVersionForm,self).__init__(*args,**kwargs)
self.fields['version'].choices = choices
def get_upcoming_manageable_sessions(user, doc, acronym=None, date=None, seq=None, week_day = None):
# Find all the sessions for meetings that haven't ended that the user could affect
# This motif is also in Document.future_presentations - it would be nice to consolodate it somehow
candidate_sessions = Session.objects.exclude(status__in=['canceled','disappr','notmeet','deleted']).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.timeslotassignments.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.timeslotassignments.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.timeslotassignments.filter(schedule=sess.meeting.agenda,timeslot__time__week_day=dow) ]
changeable_sessions = [ sess for sess in refined_candidates if can_manage_materials(user, sess.group) ]
if not changeable_sessions:
raise Http404
for sess in changeable_sessions:
sess.has_presentation = bool(sess.sessionpresentation_set.filter(document=doc))
if sess.has_presentation:
sess.version = sess.sessionpresentation_set.get(document=doc).rev
# 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.timeslotassignments.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]]
return sorted_sessions
@login_required
def edit_material_presentations(request, name, acronym=None, date=None, seq=None, week_day=None):
doc = get_object_or_404(Document, name=name)
group = doc.group
if not can_manage_materials(request.user,group):
raise Http404
sorted_sessions = get_upcoming_manageable_sessions(request.user, doc, acronym, date, seq, week_day)
if len(sorted_sessions)!=1:
raise Http404
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():
new_selection = form.cleaned_data['version']
if initial['version'] != new_selection:
if initial['version'] == 'notpresented':
doc.sessionpresentation_set.create(session=session,rev=new_selection)
c = DocEvent(type="added_comment", doc=doc, by=request.user.person)
c.desc = "Added version %s to session: %s" % (new_selection,session)
c.save()
elif new_selection == 'notpresented':
doc.sessionpresentation_set.filter(session=session).delete()
c = DocEvent(type="added_comment", doc=doc, by=request.user.person)
c.desc = "Removed from session: %s" % (session)
c.save()
else:
doc.sessionpresentation_set.filter(session=session).update(rev=new_selection)
c = DocEvent(type="added_comment", doc=doc, by=request.user.person)
c.desc = "Revision for session %s changed to %s" % (session,new_selection)
c.save()
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,
})
@login_required
def material_presentations(request, name, acronym=None, date=None, seq=None, week_day=None):
doc = get_object_or_404(Document, name=name)
group = doc.group
if not can_manage_materials(request.user,group):
raise Http404
sorted_sessions = get_upcoming_manageable_sessions(request.user, doc, acronym, date, seq, week_day)
#for index,session in enumerate(sorted_sessions):
# session.sequence = index+1
return render(request, 'doc/material/material_presentations.html', {
'sessions' : sorted_sessions,
'doc': doc,
'date': date,
'week_day': week_day,
})
def all_presentations(request, name):
doc = get_object_or_404(Document, name=name)

View file

@ -250,13 +250,13 @@
<th>On Agenda</th>
<td class="edit">
{% if not snapshot and can_edit_stream_info %}
{% doc_edit_button "material_presentations" name=doc.name %}
{% doc_edit_button "ietf.doc.views_material.all_presentations" name=doc.name %}
{% endif %}
</td>
<td>
{% if presentations %}
{% for pres in presentations %}{{ pres.session.short_name }} at {{ pres.session.meeting }} {% if pres.rev != doc.rev %}(version -{{ pres.rev }}){% endif %}{% if not forloop.last %}, {% endif %}{% endfor %}
{% for pres in presentations %}{{ pres.session.short_name }} at {{ pres.session.meeting }} {% if pres.rev and pres.rev != doc.rev %}(version -{{ pres.rev }}){% endif %}{% if not forloop.last %}, {% endif %}{% endfor %}
{% else %}
None
{% endif %}

View file

@ -0,0 +1,28 @@
{% extends "base.html" %}
{# Copyright The IETF Trust 2015, All Rights Reserved #}
{% load origin %}
{% load bootstrap3 %}
{% block title %}Change revision for session{% endblock %}
{% block content %}
{% origin %}
<h1>Change document revision for session<br><small>{{sp.document.name}}<br>{{sp.document.title}}<br>at {{sp.session}}</small></h1>
{% if sp.session.is_material_submission_cutoff %}
<p class="alert alert-warning">The deadline for submission corrections has passed. This may affect published proceedings.</p>
{% endif %}
<form method="post">
{% csrf_token %}
{% bootstrap_form form %}
{% buttons %}
<button class="btn btn-primary" type="submit" name="save">Save</button>
<button class="btn btn-default">Cancel</button>
{% endbuttons %}
</form>
{% endblock content %}

View file

@ -1,23 +0,0 @@
{% extends "base.html" %}
{# Copyright The IETF Trust 2015, All Rights Reserved #}
{% load origin %}
{% load bootstrap3 %}
{% block title %}Edit Upcoming Presentations{% endblock %}
{% block content %}
{% origin %}
<h1>Edit Upcoming Presentations<br><small>{{doc.title}}<br>{{doc.name}}<br>at {{session}}</small></h1>
<form method="post">
{% csrf_token %}
{% bootstrap_form form %}
{% buttons %}
<a class="btn btn-default pull-right" href="{% url "doc_view" name=doc.name %}">Back</a>
<button class="btn btn-primary" type="submit">Save</button>
{% endbuttons %}
</form>
{% endblock content %}

View file

@ -1,35 +0,0 @@
{% extends "base.html" %}
{# Copyright The IETF Trust 2015, All Rights Reserved #}
{% load origin %}
{% block title %}Upcoming Presentations{% endblock %}
{% block content %}
{% origin %}
<h1>Upcoming Presentations<br><small>{{doc.title}}<br>{{doc.name}}</small></h1>
<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>
{% regroup is_scheduled.list by group as group_list %}
{% for group in group_list %}
{% for session in group.list %}
<li>
{% if week_day %}
<a href="{% url 'ietf.doc.views_material.edit_material_presentations' name=doc.name acronym=group.grouper.acronym seq=forloop.counter week_day=week_day %}">{{ session }}</a>
{% elif date %}
<a href="{% url 'ietf.doc.views_material.edit_material_presentations' name=doc.name acronym=group.grouper.acronym seq=forloop.counter date=date %}">{{ session }}</a>
{% else %}
<a href="{% url 'ietf.doc.views_material.edit_material_presentations' name=doc.name acronym=group.grouper.acronym seq=forloop.counter %}">{{ session }}</a>
{% endif %}
{% if session.versions %} (version{{session.versions|pluralize}} {{session.versions|join:','}}) {% endif %}
</li>
{% endfor %}
{% endfor %}
</ul>
</li>
{% endfor %}
</ul>
{% endblock content %}

View file

@ -32,7 +32,8 @@
<td><a href="{% url 'ietf.meeting.views.session_details' num=s.meeting.number acronym=s.group.acronym %}">Materials</a></td>
<td>
{% if user|has_role:"Secretariat" or s|can_manage_materials:user and not s.is_material_submission_cutoff %}
<a class="btn btn-{% if s.is_material_submission_cutoff %}warning{% else %}default{% endif %} btn-xs" href="">Remove document from session</a>
<a class="btn btn-{% if s.is_material_submission_cutoff %}warning{% else %}default{% endif %} btn-xs" href="{% url 'ietf.doc.views_doc.remove_sessionpresentation' name=doc.name session_id=s.pk %}">Remove document from session</a>
<a class="btn btn-{% if s.is_material_submission_cutoff %}warning{% else %}default{% endif %} btn-xs" href="{% url 'ietf.doc.views_doc.edit_sessionpresentation' name=doc.name session_id=s.pk %}">Change revision</a>
{% endif %}
</td>
{% endfor %}

View file

@ -0,0 +1,31 @@
{% extends "base.html" %}
{# Copyright The IETF Trust 2015, All Rights Reserved #}
{% load origin %}
{% load bootstrap3 %}
{% block title %}Remove {{doc}} from session{% endblock %}
{% block content %}
{% origin %}
<h1>Confirm removing document from session</h1>
{% if sp.session.is_material_submission_cutoff %}
<p class="alert alert-warning">The deadline for submission corrections has passed. This may affect published proceedings.</p>
{% endif %}
<h2>Document</h2>
<p><strong>{{sp.document.name}}{% if sp.rev %}-{{sp.rev}}{% else %} (current version){% endif %}</strong></p>
<p>{{sp.document.title}}</p>
<h2>Session</h2>
<p>{{sp.session}}</p>
<form method="post">
{% csrf_token %}
{% buttons %}
<button type="submit" class="btn btn-{% if sp.session.is_material_submission_cutoff %}warning{% else %}primary{% endif %}" name="remove_session">Remove document from session</button>
<button type="submit" class="btn btn-default">Cancel</button>
{% endbuttons %}
</form>
{% endblock %}