From 242796253e245f16b90feeb6a1f40396b69a4e04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20A=2E=20S=C3=A1nchez=20L=C3=B3pez?= Date: Mon, 17 Jan 2011 18:20:06 +0000 Subject: [PATCH] Form to edit or upload a protocol write-up. See #561 - Legacy-Id: 2745 --- .../wgchairs/confirm_management_writeup.html | 55 ++++++++++++++ ietf/templates/wgchairs/draft_state.html | 1 + .../wgchairs/edit_management_writeup.html | 65 ++++++++++++++++ .../wgchairs/shepherd_document_row.html | 17 +++++ .../wgchairs/wg_shepherd_documents.html | 53 +++---------- ietf/wgchairs/accounts.py | 31 ++++++++ ietf/wgchairs/forms.py | 50 +++++++++++- ietf/wgchairs/templatetags/wgchairs_tags.py | 25 ++++++ ietf/wgchairs/urls.py | 1 + ietf/wgchairs/views.py | 76 ++++++++++++++++++- 10 files changed, 325 insertions(+), 49 deletions(-) create mode 100644 ietf/templates/wgchairs/confirm_management_writeup.html create mode 100644 ietf/templates/wgchairs/draft_state.html create mode 100644 ietf/templates/wgchairs/edit_management_writeup.html create mode 100644 ietf/templates/wgchairs/shepherd_document_row.html diff --git a/ietf/templates/wgchairs/confirm_management_writeup.html b/ietf/templates/wgchairs/confirm_management_writeup.html new file mode 100644 index 000000000..ae23f4a97 --- /dev/null +++ b/ietf/templates/wgchairs/confirm_management_writeup.html @@ -0,0 +1,55 @@ +{% extends "wginfo/wg_base.html" %} +{% load ietf_filters wgchairs_tags %} + +{% block title %}Chage shepherd for {{ doc }}{% endblock %} + +{% block wg_content %} + +

+Return to shepherd list +

+ +

Updatting write-up for {{ doc }}

+ +

+Before you modify the protocol write-up please revise the 'Doc Shepherd Follow-up Underway' annotation tag and set or reset it if appropriate. +

+

+Remember that you must provide a comment if you change the annotation tag state. +

+ +
+
+ + +{% if form.message %} + +{% endif %} + + +
Doc Shepherd Follow-up Underway
+ {{ form.message.value }} +
+ + + + +
+{{ form.comment }} +
+

+ Change write-up and ...
+ +
+ Cancel, I don't want to do any change! +

+ +
+ + + +
New protocol write-up
{{ form.get_writeup|linebreaksbr }}
+ +
+
+{% endblock %} diff --git a/ietf/templates/wgchairs/draft_state.html b/ietf/templates/wgchairs/draft_state.html new file mode 100644 index 000000000..956ebd44f --- /dev/null +++ b/ietf/templates/wgchairs/draft_state.html @@ -0,0 +1 @@ +{{ state.name }} diff --git a/ietf/templates/wgchairs/edit_management_writeup.html b/ietf/templates/wgchairs/edit_management_writeup.html new file mode 100644 index 000000000..3f8cc801b --- /dev/null +++ b/ietf/templates/wgchairs/edit_management_writeup.html @@ -0,0 +1,65 @@ +{% extends "wginfo/wg_base.html" %} +{% load ietf_filters wgchairs_tags %} + +{% block title %}Chage shepherd for {{ doc }}{% endblock %} + +{% block wg_content %} + +

+Return to shepherd list +

+ +

Change protocol write-up for {{ doc }}

+ + + + +
Draft stateActual protocol write-upLast updated
{% show_state doc %}{{ writeup.writeup|linebreaksbr }}{% if writeup %}{{ writeup.date }} by {{ writeup.person }}{% endif %}
+ +

+Please, note that the 'Doc Shepherd Follow-up Underway' annotation tag is {% if not followup %}NOT{% endif %} setted for {{ doc }}. +

+ +{% if can_edit %} +
+
+ + +{% if form.message %} + +{% endif %} + + +
Edit protocol write-up
+ {{ form.message.value }} +
+
+ +
+ +
+ +
+ + + +
Upload a new protocol write-up
+

Replace the current write-up with the contents of a plain ascii file:

+
+ +
+
+{% else %} + + + +
Edit protocol write-up
+

+ You can not edit or upload the protocol write-up for {{ doc }} cause the draft is not on "WG Consensus: Waiting for Write-Up" state. +

+

+ Please contact with the {{ wg }} Working Group chair. +

+
+{% endif %} +{% endblock %} diff --git a/ietf/templates/wgchairs/shepherd_document_row.html b/ietf/templates/wgchairs/shepherd_document_row.html new file mode 100644 index 000000000..dec1a12dc --- /dev/null +++ b/ietf/templates/wgchairs/shepherd_document_row.html @@ -0,0 +1,17 @@ +{% load wgchairs_tags %} + + + + {{ doc.title }} + + + {{ doc.status.status }} + + + {% writeup doc %} + [Edit] + + + {% writeupdate doc %} + + diff --git a/ietf/templates/wgchairs/wg_shepherd_documents.html b/ietf/templates/wgchairs/wg_shepherd_documents.html index 468970da2..9cb5fff36 100644 --- a/ietf/templates/wgchairs/wg_shepherd_documents.html +++ b/ietf/templates/wgchairs/wg_shepherd_documents.html @@ -56,25 +56,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - + + {% for doc in no_shepherd %} - - - - - - - + {% include "wgchairs/shepherd_document_row.html" %} {% endfor %}
DocumentDate StatusArea DirectorProtocol write-upProtocol write-up last update
- {{ doc.title }} - - {{ doc.status.start_date|date:"Y-m" }} - - {{ doc.status.status }} - {{ doc.ad_name|default:"" }}
@@ -84,25 +72,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - + + {% for doc in my_documents %} - - - - - - - + {% include "wgchairs/shepherd_document_row.html" %} {% endfor %}
DocumentDate StatusArea DirectorProtocol write-upProtocol write-up last update
- {{ doc.title }} - - {{ doc.status.start_date|date:"Y-m" }} - - {{ doc.status.status }} - {{ doc.ad_name|default:"" }}
@@ -115,23 +91,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - + + {% for doc in documents.list %} - - - - - - + {% include "wgchairs/shepherd_document_row.html" %} {% endfor %}
DocumentDate StatusArea DirectorProtocol write-upProtocol write-up last update
- {{ doc.title }} - - {{ doc.status.start_date|date:"Y-m" }} - - {{ doc.status.status }} - {{ doc.ad_name|default:"" }}
{% endfor %} diff --git a/ietf/wgchairs/accounts.py b/ietf/wgchairs/accounts.py index 2f751c00a..dd8ec110b 100644 --- a/ietf/wgchairs/accounts.py +++ b/ietf/wgchairs/accounts.py @@ -1,9 +1,21 @@ +def is_area_director_for_group(person, group): + return bool(group.area.area.areadirector_set.filter(person=person).count()) + + def is_group_chair(person, group): if group.chairs().filter(person=person): return True return False +def is_group_delegate(person, group): + return bool(group.wgdelegate_set.filter(person=person).count()) + + +def is_document_shepherd(person, document): + return person == document.shepherd + + def get_person_for_user(user): try: return user.get_profile().person() @@ -51,3 +63,22 @@ def can_manage_shepherd_of_a_document(user, document): if not person or not document.group: return False return can_manage_shepherds_in_group(user, document.group.ietfwg) + + +def can_manage_writeup_of_a_document_no_state(user, document): + person = get_person_for_user(user) + if not person or not document.group: + return False + group = document.group.ietfwg + return (is_group_chair(person, group) or + is_areadirector_for_group(person, group) or + is_group_delegate(person, group)) + + +def can_manage_writeup_of_a_document(user, document): + person = get_person_for_user(user) + if not person or not document.group: + return False + group = document.group.ietfwg + return (can_manage_writeup_of_a_document_no_state(user, document) or + is_document_shepherd(person, doc)) diff --git a/ietf/wgchairs/forms.py b/ietf/wgchairs/forms.py index 19b4965c5..fa7dcf3cc 100644 --- a/ietf/wgchairs/forms.py +++ b/ietf/wgchairs/forms.py @@ -6,9 +6,10 @@ from django.forms.models import BaseModelFormSet from django.template.loader import render_to_string from django.utils.safestring import mark_safe -from ietf.wgchairs.models import WGDelegate +from ietf.wgchairs.models import WGDelegate, ProtoWriteUp from ietf.wgchairs.accounts import get_person_for_user -from ietf.ietfworkflows.utils import get_default_workflow_for_wg, get_workflow_for_wg +from ietf.ietfworkflows.utils import (get_default_workflow_for_wg, get_workflow_for_wg, + update_tags, FOLLOWUP_TAG) from ietf.idtracker.models import PersonOrOrgInfo from workflows.models import Transition @@ -328,3 +329,48 @@ def add_form_factory(request, wg, user, shepherd=False): return AddDelegateForm(wg=wg, user=user, data=request.POST.copy(), shepherd=shepherd) return AddDelegateForm(wg=wg, user=user, shepherd=shepherd) + + +class WriteUpEditForm(RelatedWGForm): + + writeup = forms.CharField(widget=forms.Textarea, required=False) + followup = forms.BooleanField(required=False) + comment = forms.CharField(widget=forms.Textarea, required=False) + + + def __init__(self, *args, **kwargs): + self.doc = kwargs.pop('doc', None) + self.doc_writeup = self.doc.protowriteup_set.all() + if self.doc_writeup.count(): + self.doc_writeup=self.doc_writeup[0] + else: + self.doc_writeup=None + super(WriteUpEditForm, self).__init__(*args, **kwargs) + + def get_writeup(self): + return self.data.get('writeup', self.doc_writeup and self.doc_writeup.writeup or '') + + def save(self): + if not self.doc_writeup: + self.doc_writeup = ProtoWriteUp.objects.create( + person=get_person_for_user(self.user), + draft=self.doc, + writeup=self.cleaned_data['writeup']) + else: + self.doc_writeup.writeup = self.cleaned_data['writeup'] + self.doc_writeup.save() + if self.data.get('modify_tag', False): + followup = self.cleaned_data.get('followup', False) + comment = self.cleaned_data.get('comment', False) + if followup: + update_tags(self.doc, comment, set_tags=[FOLLOWUP_TAG]) + else: + update_tags(self.doc, comment, reset_tags=[FOLLOWUP_TAG]) + return self.doc_writeup + + def is_valid(self): + if self.data.get('confirm', False) and self.data.get('modify_tag', False): + self.fields['comment'].required = True + else: + self.fields['comment'].required = False + return super(WriteUpEditForm, self).is_valid() diff --git a/ietf/wgchairs/templatetags/wgchairs_tags.py b/ietf/wgchairs/templatetags/wgchairs_tags.py index 8cf9d9783..e81301c78 100644 --- a/ietf/wgchairs/templatetags/wgchairs_tags.py +++ b/ietf/wgchairs/templatetags/wgchairs_tags.py @@ -1,5 +1,6 @@ from django import template +from ietf.ietfworkflows.utils import get_state_for_draft from ietf.wgchairs.accounts import (can_manage_workflow_in_group, can_manage_delegates_in_group, can_manage_shepherds_in_group) @@ -19,3 +20,27 @@ def wgchairs_admin_options(context, wg): 'wg': wg, 'selected': context.get('selected', None), } + +@register.simple_tag +def writeup(doc): + writeup = doc.protowriteup_set.all() + if not writeup.count(): + return '' + else: + return writeup[0].writeup + + +@register.simple_tag +def writeupdate(doc): + writeup = doc.protowriteup_set.all() + if not writeup.count(): + return '' + else: + return writeup[0].date + + +@register.inclusion_tag('wgchairs/draft_state.html', takes_context=True) +def show_state(context, doc): + return {'doc': doc, + 'state': get_state_for_draft(doc), + } diff --git a/ietf/wgchairs/urls.py b/ietf/wgchairs/urls.py index ab69bf8d6..d60c7b61d 100644 --- a/ietf/wgchairs/urls.py +++ b/ietf/wgchairs/urls.py @@ -7,4 +7,5 @@ urlpatterns = patterns('ietf.wgchairs.views', url(r'^delegates/$', 'manage_delegates', name='manage_delegates'), url(r'^shepherds/$', 'wg_shepherd_documents', name='manage_shepherds'), url(r'^shepherds/(?P[^/]+)/$', 'managing_shepherd', name='doc_managing_shepherd'), + url(r'^shepherds/(?P[^/]+)/writeup/$', 'managing_writeup', name='doc_managing_writeup'), ) diff --git a/ietf/wgchairs/views.py b/ietf/wgchairs/views.py index ce353e511..b03c91b29 100644 --- a/ietf/wgchairs/views.py +++ b/ietf/wgchairs/views.py @@ -5,13 +5,21 @@ from django.http import HttpResponseForbidden, Http404 from ietf.idrfc.views_search import SearchForm, search_query from ietf.wgchairs.forms import (RemoveDelegateForm, add_form_factory, - workflow_form_factory, TransitionFormSet) + workflow_form_factory, TransitionFormSet, + WriteUpEditForm) from ietf.wgchairs.accounts import (can_manage_delegates_in_group, get_person_for_user, can_manage_shepherds_in_group, can_manage_workflow_in_group, - can_manage_shepherd_of_a_document) + can_manage_shepherd_of_a_document, + can_manage_writeup_of_a_document, + can_manage_writeup_of_a_document_no_state, + ) from ietf.ietfworkflows.utils import (get_workflow_for_wg, - get_default_workflow_for_wg) + get_default_workflow_for_wg, + get_state_by_name, + get_annotation_tags_for_draft, + get_state_for_draft, WAITING_WRITEUP, + FOLLOWUP_TAG) def manage_delegates(request, acronym): @@ -136,3 +144,65 @@ def wg_shepherd_documents(request, acronym): 'wg': wg, } return render_to_response('wgchairs/wg_shepherd_documents.html', context, RequestContext(request)) + +def managing_writeup(request, acronym, name): + wg = get_object_or_404(IETFWG, group_acronym__acronym=acronym, group_type=1) + user = request.user + person = get_person_for_user(user) + doc = get_object_or_404(InternetDraft, filename=name) + if not can_manage_writeup_of_a_document(user, doc): + raise Http404 + current_state = get_state_for_draft(doc) + can_edit = True + if current_state != get_state_by_name(WAITING_WRITEUP) and not can_manage_writeup_of_a_document_no_state(user,doc): + can_edit = False + writeup = doc.protowriteup_set.all() + if writeup.count(): + writeup = writeup[0] + else: + writeup = None + error = False + followup_tag = get_annotation_tags_for_draft(doc).filter(annotation_tag__name=FOLLOWUP_TAG) + followup = bool(followup_tag.count()) + if request.method == 'POST': + form = WriteUpEditForm(wg=wg, doc=doc, user=user, data=request.POST, files=request.FILES) + if request.FILES.get('uploaded_writeup', None): + try: + newwriteup = request.FILES['uploaded_writeup'].read().encode('ascii') + form.data.update({'writeup': newwriteup}) + except: + form.set_message('error', 'You have try to upload a non ascii file') + error = True + valid = form.is_valid() + if (valid and not error and not request.POST.get('confirm', None)) or (not valid and not error): + if not valid: + form.set_message('error', 'You have to specify a comment') + return render_to_response('wgchairs/confirm_management_writeup.html', + dict(doc=doc, + user=user, + selected='manage_shepherds', + wg=wg, + followup=followup, + form=form, + writeup=writeup, + can_edit=can_edit, + ), + context_instance=RequestContext(request)) + elif valid and not error: + writeup = form.save() + form = WriteUpEditForm(wg=wg, doc=doc, user=user) + followup_tag = get_annotation_tags_for_draft(doc).filter(annotation_tag__name=FOLLOWUP_TAG) + followup = bool(followup_tag.count()) + else: + form = WriteUpEditForm(wg=wg, doc=doc, user=user) + return render_to_response('wgchairs/edit_management_writeup.html', + dict(doc=doc, + user=user, + selected='manage_shepherds', + wg=wg, + form=form, + writeup=writeup, + followup=followup, + can_edit=can_edit, + ), + context_instance=RequestContext(request))