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:
parent
d709af6ca2
commit
859f2ead3d
|
@ -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)
|
||||
|
|
|
@ -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')")))
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
||||
|
|
|
@ -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)),
|
||||
)
|
||||
|
|
|
@ -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"),
|
||||
)
|
||||
|
||||
|
|
|
@ -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 })
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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 %}
|
||||
|
|
28
ietf/templates/doc/edit_sessionpresentation.html
Normal file
28
ietf/templates/doc/edit_sessionpresentation.html
Normal 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 %}
|
|
@ -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 %}
|
|
@ -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 %}
|
|
@ -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 %}
|
||||
|
|
31
ietf/templates/doc/remove_sessionpresentation.html
Normal file
31
ietf/templates/doc/remove_sessionpresentation.html
Normal 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 %}
|
Loading…
Reference in a new issue