winding up: added ability to add drafts to a session while looking at the session.

- Legacy-Id: 10853
This commit is contained in:
Robert Sparks 2016-02-23 04:00:16 +00:00
parent 4a12225742
commit 114ba0ad13
5 changed files with 160 additions and 5 deletions

View file

@ -3,6 +3,8 @@ import shutil
import datetime
import urlparse
import debug # pyflakes:ignore
from django.core.urlresolvers import reverse as urlreverse
from django.conf import settings
@ -13,8 +15,10 @@ from ietf.meeting.models import Session, TimeSlot
from ietf.meeting.test_data import make_meeting_test_data
from ietf.utils.test_utils import TestCase, login_testing_unauthorized, unicontent
from ietf.person.factories import PersonFactory
from ietf.group.factories import GroupFactory
from ietf.meeting.factories import SessionFactory, SessionPresentationFactory
from ietf.doc.factories import DocumentFactory
class MeetingTests(TestCase):
def setUp(self):
@ -338,8 +342,51 @@ class SessionDetailsTests(TestCase):
SessionPresentationFactory.create(session=session,document__type_id='slides')
SessionPresentationFactory.create(session=session,document__type_id='agenda')
url = urlreverse("ietf.meeting.views.session_details", kwargs=dict(num=session.meeting.number, acronym=group.acronym))
url = urlreverse('ietf.meeting.views.session_details', kwargs=dict(num=session.meeting.number, acronym=group.acronym))
r = self.client.get(url)
self.assertTrue(all([x in unicontent(r) for x in ('slides','agenda','minutes','draft')]))
self.assertFalse('deleted' in unicontent(r))
def test_add_session_drafts(self):
group = GroupFactory.create(type_id='wg',state_id='active')
group_chair = PersonFactory.create()
group.role_set.create(name_id='chair',person = group_chair, email = group_chair.email())
session = SessionFactory.create(meeting__type_id='ietf',group=group, meeting__date=datetime.date.today()+datetime.timedelta(days=90))
SessionPresentationFactory.create(session=session,document__type_id='draft',rev=None)
old_draft = session.sessionpresentation_set.filter(document__type='draft').first().document
new_draft = DocumentFactory(type_id='draft')
url = urlreverse('ietf.meeting.views.add_session_drafts', kwargs=dict(num=session.meeting.number, session_id=session.pk))
r = self.client.get(url)
self.assertEqual(r.status_code, 404)
self.client.login(username="plain",password="plain+password")
r = self.client.get(url)
self.assertEqual(r.status_code, 404)
self.client.login(username=group_chair.user.username, password='%s+password'%group_chair.user.username)
r = self.client.get(url)
self.assertEqual(r.status_code, 200)
self.assertTrue(old_draft.name in unicontent(r))
r = self.client.post(url,dict(drafts=[new_draft.name,old_draft.name]))
self.assertTrue(r.status_code, 200)
q=PyQuery(r.content)
self.assertTrue(q('form .alert-danger:contains("Already linked:")'))
self.assertEqual(1,session.sessionpresentation_set.count())
r = self.client.post(url,dict(drafts=[new_draft.name,]))
self.assertTrue(r.status_code, 302)
self.assertEqual(2,session.sessionpresentation_set.count())
session.meeting.date -= datetime.timedelta(days=180)
session.meeting.save()
r = self.client.get(url)
self.assertEqual(r.status_code,404)
self.client.login(username='secretary',password='secretary+password')
r = self.client.get(url)
self.assertEqual(r.status_code,200)
q = PyQuery(r.content)
self.assertEqual(1,len(q(".alert-warning:contains('may affect published proceedings')")))

View file

@ -8,6 +8,7 @@ from ietf.meeting import ajax
safe_for_all_meeting_types = [
url(r'^session/(?P<acronym>[A-Za-z0-9_\-\+]+)/$', views.session_details),
url(r'^session/(?P<session_id>\d+)/drafts$', views.add_session_drafts),
]
type_ietf_only_patterns = [

View file

@ -13,7 +13,7 @@ import json
import debug # pyflakes:ignore
from django import forms
from django.shortcuts import render, redirect
from django.shortcuts import render, redirect, get_object_or_404
from django.http import HttpResponse, HttpResponseRedirect, HttpResponseForbidden, Http404
from django.contrib import messages
from django.core.urlresolvers import reverse
@ -23,7 +23,7 @@ from django.forms.models import modelform_factory
from django.forms import ModelForm
from django.views.decorators.csrf import ensure_csrf_cookie
from ietf.doc.models import Document, State
from ietf.doc.models import Document, State, DocEvent
from ietf.group.models import Group
from ietf.group.utils import can_manage_materials
from ietf.ietfauth.utils import role_required, has_role
@ -39,6 +39,8 @@ from ietf.meeting.helpers import convert_draft_to_pdf
from ietf.utils.pipe import pipe
from ietf.utils.pdf import pdf_pages
from ietf.doc.fields import SearchableDocumentsField
def materials(request, meeting_num=None):
meeting = get_meeting(meeting_num)
@ -874,3 +876,45 @@ def session_details(request, num, acronym ):
'can_manage_materials' : can_manage,
'type_counter': type_counter,
})
class SessionDraftsForm(forms.Form):
drafts = SearchableDocumentsField(required=False)
def __init__(self, *args, **kwargs):
self.already_linked = kwargs.pop('already_linked')
super(self.__class__, self).__init__(*args, **kwargs)
def clean(self):
selected = self.cleaned_data['drafts']
problems = set(selected).intersection(set(self.already_linked))
if problems:
raise forms.ValidationError("Already linked: %s" % ', '.join([d.name for d in problems]))
return self.cleaned_data
def add_session_drafts(request, session_id, num):
# num is redundant, but we're dragging it along an artifact of where we are in the current URL structure
session = get_object_or_404(Session,pk=session_id)
if not session.can_manage_materials(request.user):
raise Http404
if session.is_material_submission_cutoff() and not has_role(request.user, "Secretariat"):
raise Http404
already_linked = [sp.document for sp in session.sessionpresentation_set.filter(document__type_id='draft')]
if request.method == 'POST':
form = SessionDraftsForm(request.POST,already_linked=already_linked)
if form.is_valid():
for draft in form.cleaned_data['drafts']:
session.sessionpresentation_set.create(document=draft,rev=None)
c = DocEvent(type="added_comment", doc=draft, by=request.user.person)
c.desc = "Added to session: %s" % session
c.save()
return redirect('ietf.meeting.views.session_details', num=session.meeting.number, acronym=session.group.acronym)
else:
form = SessionDraftsForm(already_linked=already_linked)
return render(request, "meeting/add_session_drafts.html",
{ 'session': session,
'already_linked': session.sessionpresentation_set.filter(document__type_id='draft'),
'form': form,
})

View file

@ -0,0 +1,60 @@
{% extends "base.html" %}
{# Copyright The IETF Trust 2015, All Rights Reserved #}
{% load origin staticfiles bootstrap3 %}
{% block title %}Add drafts to {{ session.meeting }} : {{ session.group.acronym }}{% endblock %}
{% block pagehead %}
<link rel="stylesheet" href="{% static 'select2/select2.css' %}">
<link rel="stylesheet" href="{% static 'select2-bootstrap-css/select2-bootstrap.min.css' %}">
{% endblock %}
{% block content %}
{% origin %}
<h1>Add drafts to {{ session.meeting }} : {{ session.group.acronym }}</h1>
{% comment %} TODO: put the session name here or calculate the number at the meeting {% endcomment %}
{% if session.is_material_submission_cutoff %}
<div class="alert alert-warning">The deadline for submission corrections has passed. This may affect published proceedings.</div>
{% endif %}
<div class="alert alert-info">This form will link additional drafts to this session with a revision of "Current at time of presentation". For more fine grained control of versions, or to remove a draft from a session, adjust the sessions associated with a draft from the draft's main page.</div>
<div class="panel panel-default">
<div class="panel-heading">Drafts already linked to this sesssion</div>
<div class="panel-body">
<table class="table table-contensed table-striped">
<tr>
<th class="col-md-1">Revision</th>
<th>Document</th>
</tr>
{% for sp in already_linked %}
<tr>
<td>{% if sp.rev %}-{{sp.rev}}{% else %}(current){% endif %}</td>
<td>{{sp.document.title}} ({{sp.document.name}})</td>
</tr>
{% endfor %}
</table>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">Additional drafts to link to this session</div>
<div class="panel-body">
<form method="post">
{% csrf_token %}
{% bootstrap_form form %}
{% buttons %}
<button class="btn btn-{% if session.is_material_submission_cutoff %}warning{% else %}primary{% endif %}" type="submit">Save</button>
<a class="btn btn-default" href="{% url 'ietf.meeting.views.session_details' num=session.meeting.number acronym=session.group.acronym %}">Cancel</a>
{% endbuttons %}
</form>
</div>
</div>
{% endblock %}
{% block js %}
<script src="{% static 'select2/select2.min.js' %}"></script>
<script src="{% static 'ietf/js/select2-field.js' %}"></script>
{% endblock %}

View file

@ -15,7 +15,10 @@
{% if session.status.slug == 'sched' or session.status.slug == 'schedw' %}
<div class="buttonlist">
<a class="btn btn-default" href="{% url 'ietf.secr.proceedings.views.upload_unified' meeting_num=session.meeting.number acronym=session.group.acronym %}">
Upload/Edit Materials
Upload/Edit materials
</a>
<a class="btn btn-default" href="{% url 'ietf.meeting.views.add_session_drafts' session_id=session.pk num=session.meeting.number %}">
Link additional drafts to session
</a>
{% if not type_counter.agenda %}
<span class="label label-warning">This session does not yet have an agenda</span>
@ -38,7 +41,7 @@
{% else %}
{% url 'doc_view' name=pres.document.name as url %}
{% endif %}
<a href="{{url}}">{{pres.document.title}} ({{ pres.document.name }}-{{ pres.rev }})
<a href="{{url}}">{{pres.document.title}} ({{ pres.document.name }}{% if pres.rev %}-{{ pres.rev }}{% endif %})
</a>
</td>
</tr>