Remove duplicate functionality in secr/drafts. Fixes #2540. Commit ready for merge.
- Legacy-Id: 15345
This commit is contained in:
parent
9e09a1b531
commit
2d6083060a
|
@ -97,40 +97,6 @@ def get_revision(name):
|
|||
base,ext = os.path.splitext(name)
|
||||
return base[-2:]
|
||||
|
||||
def get_revision_emails(draft):
|
||||
"""
|
||||
Dervied from the ColdFusion legacy app, we accumulate To: emails for a new
|
||||
revision by adding:
|
||||
1) the conents of id_internal.state_change_notice_to, this appears to be largely
|
||||
custom mail lists for the document or group
|
||||
2) the main AD, via id_internal.job_owner
|
||||
3) any ad who has marked "discuss" in the ballot associated with this id_internal
|
||||
4) And now, also, the RFC Editor if the draft is in the RFC Editor Queue
|
||||
"""
|
||||
# from legacy
|
||||
if not draft.get_state('draft-iesg'):
|
||||
return ''
|
||||
|
||||
emails = []
|
||||
if draft.notify:
|
||||
emails.append(draft.notify)
|
||||
if draft.ad:
|
||||
emails.append(draft.ad.role_email("ad").address)
|
||||
|
||||
if draft.active_ballot():
|
||||
for ad, pos in draft.active_ballot().active_ad_positions().iteritems():
|
||||
if pos and pos.pos_id == "discuss":
|
||||
emails.append(ad.role_email("ad").address)
|
||||
|
||||
if draft.get_state('draft-iesg').slug == "rfcqueue":
|
||||
emails.append('rfc-editor@rfc-editor.org')
|
||||
|
||||
return ', '.join(emails)
|
||||
|
||||
def add_email(emails,person):
|
||||
if person.email() not in emails:
|
||||
emails[person.email()] = '"%s %s"' % (person.first_name,person.last_name)
|
||||
|
||||
def get_fullcc_list(draft):
|
||||
"""
|
||||
This function takes a draft object and returns a string of emails to use in cc field
|
||||
|
@ -179,8 +145,6 @@ def get_email_initial(draft, action=None, input=None):
|
|||
|
||||
"""
|
||||
expiration_date = (datetime.date.today() + datetime.timedelta(185)).strftime('%B %d, %Y')
|
||||
new_revision = str(int(draft.rev)+1).zfill(2)
|
||||
new_filename = draft.name + '-' + new_revision + '.txt'
|
||||
curr_filename = draft.name + '-' + draft.rev + '.txt'
|
||||
data = {}
|
||||
data['cc'] = get_fullcc_list(draft)
|
||||
|
@ -201,19 +165,6 @@ def get_email_initial(draft, action=None, input=None):
|
|||
data['body'] = render_to_string('drafts/message_resurrect.txt', context)
|
||||
data['action'] = action
|
||||
|
||||
elif action == 'revision':
|
||||
context = {'rev':new_revision,'doc':new_filename,'doc_base':new_filename[:-4]}
|
||||
data['to'] = get_revision_emails(draft)
|
||||
data['cc'] = ''
|
||||
data['subject'] = 'New Version Notification - %s' % (new_filename)
|
||||
data['body'] = render_to_string('drafts/message_revision.txt', context)
|
||||
|
||||
elif action == 'update':
|
||||
context = {'doc':input['filename'],'expire_date':expiration_date}
|
||||
data['subject'] = 'Posting of %s' % (input['filename'])
|
||||
data['body'] = render_to_string('drafts/message_update.txt', context)
|
||||
data['action'] = action
|
||||
|
||||
elif action == 'withdraw':
|
||||
context = {'doc':curr_filename,'by':input['withdraw_type']}
|
||||
data['subject'] = 'Withdrawl of %s' % (curr_filename)
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import datetime
|
||||
import re
|
||||
import os
|
||||
|
||||
|
@ -80,22 +79,6 @@ class AliasModelChoiceField(forms.ModelChoiceField):
|
|||
# ---------------------------------------------
|
||||
# Forms
|
||||
# ---------------------------------------------
|
||||
class AddModelForm(forms.ModelForm):
|
||||
start_date = forms.DateField()
|
||||
group = GroupModelChoiceField(required=True,help_text='Use group "none" for Individual Submissions.')
|
||||
|
||||
class Meta:
|
||||
model = Document
|
||||
fields = ('title','group','stream','start_date','pages','abstract','internal_comments')
|
||||
|
||||
# use this method to set attrs which keeps other meta info from model.
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(AddModelForm, self).__init__(*args, **kwargs)
|
||||
self.fields['title'].label='Document Name'
|
||||
self.fields['title'].widget=forms.Textarea()
|
||||
self.fields['start_date'].initial=datetime.date.today
|
||||
self.fields['pages'].label='Number of Pages'
|
||||
self.fields['internal_comments'].label='Comments'
|
||||
|
||||
class AuthorForm(forms.Form):
|
||||
'''
|
||||
|
@ -245,73 +228,6 @@ class ExtendForm(forms.Form):
|
|||
action = forms.CharField(max_length=255, widget=forms.HiddenInput(),initial='extend')
|
||||
expiration_date = forms.DateField()
|
||||
|
||||
class BaseRevisionModelForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Document
|
||||
fields = ('title','pages','abstract')
|
||||
|
||||
class RevisionModelForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Document
|
||||
fields = ('title','pages','abstract')
|
||||
|
||||
# use this method to set attrs which keeps other meta info from model.
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(RevisionModelForm, self).__init__(*args, **kwargs)
|
||||
self.fields['title'].label='Document Name'
|
||||
self.fields['title'].widget=forms.Textarea()
|
||||
self.fields['pages'].label='Number of Pages'
|
||||
|
||||
# class RfcModelForm(forms.ModelForm):
|
||||
# rfc_number = forms.IntegerField()
|
||||
# rfc_published_date = forms.DateField(initial=datetime.datetime.now)
|
||||
# group = GroupModelChoiceField(required=True)
|
||||
#
|
||||
# class Meta:
|
||||
# model = Document
|
||||
# fields = ('title','group','pages','std_level','internal_comments')
|
||||
#
|
||||
# # use this method to set attrs which keeps other meta info from model.
|
||||
# def __init__(self, *args, **kwargs):
|
||||
# super(RfcModelForm, self).__init__(*args, **kwargs)
|
||||
# self.fields['title'].widget = forms.Textarea()
|
||||
# self.fields['std_level'].required = True
|
||||
#
|
||||
# def save(self, force_insert=False, force_update=False, commit=False):
|
||||
# obj = super(RfcModelForm, self).save(commit=False)
|
||||
#
|
||||
# # create DocAlias
|
||||
# DocAlias.objects.create(document=self.instance,name="rfc%d" % self.cleaned_data['rfc_number'])
|
||||
#
|
||||
# return obj
|
||||
#
|
||||
# def clean_rfc_number(self):
|
||||
# rfc_number = self.cleaned_data['rfc_number']
|
||||
# if DocAlias.objects.filter(name='rfc' + str(rfc_number)):
|
||||
# raise forms.ValidationError("RFC %d already exists" % rfc_number)
|
||||
# return rfc_number
|
||||
|
||||
# class RfcObsoletesForm(forms.Form):
|
||||
# relation = forms.ModelChoiceField(queryset=DocRelationshipName.objects.filter(slug__in=('updates','obs')),required=False)
|
||||
# rfc = forms.IntegerField(required=False)
|
||||
#
|
||||
# # ensure that RFC exists
|
||||
# def clean_rfc(self):
|
||||
# rfc = self.cleaned_data.get('rfc','')
|
||||
# if rfc:
|
||||
# if not Document.objects.filter(docalias__name="rfc%s" % rfc):
|
||||
# raise forms.ValidationError("RFC does not exist")
|
||||
# return rfc
|
||||
#
|
||||
# def clean(self):
|
||||
# super(RfcObsoletesForm, self).clean()
|
||||
# cleaned_data = self.cleaned_data
|
||||
# relation = cleaned_data.get('relation','')
|
||||
# rfc = cleaned_data.get('rfc','')
|
||||
# if (relation and not rfc) or (rfc and not relation):
|
||||
# raise forms.ValidationError('You must select a relation and enter RFC #')
|
||||
# return cleaned_data
|
||||
|
||||
class SearchForm(forms.Form):
|
||||
intended_std_level = forms.ModelChoiceField(queryset=IntendedStdLevelName.objects,label="Intended Status",required=False)
|
||||
document_title = forms.CharField(max_length=80,label='Document Title',required=False)
|
||||
|
@ -321,57 +237,6 @@ class SearchForm(forms.Form):
|
|||
revision_date_start = forms.DateField(label='Revision Date (start)',required=False)
|
||||
revision_date_end = forms.DateField(label='Revision Date (end)',required=False)
|
||||
|
||||
class UploadForm(forms.Form):
|
||||
txt = DocumentField(label=u'.txt format', required=True,extension='.txt',filename=None,rev=None)
|
||||
xml = DocumentField(label=u'.xml format', required=False,extension='.xml',filename=None,rev=None)
|
||||
pdf = DocumentField(label=u'.pdf format', required=False,extension='.pdf',filename=None,rev=None)
|
||||
ps = DocumentField(label=u'.ps format', required=False,extension='.ps',filename=None,rev=None)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
if 'draft' in kwargs:
|
||||
self.draft = kwargs.pop('draft')
|
||||
else:
|
||||
self.draft = None
|
||||
super(UploadForm, self).__init__(*args, **kwargs)
|
||||
if self.draft:
|
||||
for field in self.fields.itervalues():
|
||||
field.filename = self.draft.name
|
||||
field.rev = self.draft.rev
|
||||
|
||||
|
||||
def clean(self):
|
||||
# Checks that all files have the same base
|
||||
if any(self.errors):
|
||||
# Don't bother validating unless each field is valid on its own
|
||||
return
|
||||
txt = self.cleaned_data['txt']
|
||||
xml = self.cleaned_data['xml']
|
||||
pdf = self.cleaned_data['pdf']
|
||||
ps = self.cleaned_data['ps']
|
||||
|
||||
# we only need to do these validations for new drafts
|
||||
if not self.draft:
|
||||
names = []
|
||||
for file in (txt,xml,pdf,ps):
|
||||
if file:
|
||||
base = os.path.splitext(file.name)[0]
|
||||
if base not in names:
|
||||
names.append(base)
|
||||
|
||||
if len(names) > 1:
|
||||
raise forms.ValidationError, "All files must have the same base name"
|
||||
|
||||
# ensure that the basename is unique
|
||||
base = os.path.splitext(txt.name)[0]
|
||||
if Document.objects.filter(name=base[:-3]):
|
||||
raise forms.ValidationError, "This document filename already exists: %s" % base[:-3]
|
||||
|
||||
# ensure that rev is 00
|
||||
if base[-2:] != '00':
|
||||
raise forms.ValidationError, "New Drafts must start with 00 revision number."
|
||||
|
||||
return self.cleaned_data
|
||||
|
||||
class WithdrawForm(forms.Form):
|
||||
withdraw_type = forms.CharField(widget=forms.Select(choices=WITHDRAW_CHOICES),help_text='Select which type of withdraw to perform.')
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@ import datetime
|
|||
import os
|
||||
import shutil
|
||||
|
||||
from StringIO import StringIO
|
||||
from django.conf import settings
|
||||
from django.urls import reverse as urlreverse
|
||||
from django.utils.http import urlencode
|
||||
|
@ -11,15 +10,13 @@ import debug # pyflakes:ignore
|
|||
|
||||
from ietf.doc.expire import expire_draft
|
||||
from ietf.doc.factories import DocumentFactory
|
||||
from ietf.doc.models import State, Document
|
||||
from ietf.doc.models import Document
|
||||
from ietf.meeting.factories import MeetingFactory
|
||||
from ietf.person.factories import PersonFactory
|
||||
from ietf.person.models import Person
|
||||
from ietf.submit.models import Preapproval
|
||||
from ietf.submit.tests import submission_file
|
||||
from ietf.utils.test_utils import TestCase, login_testing_unauthorized
|
||||
from ietf.utils.test_data import make_test_data
|
||||
from ietf.utils.mail import empty_outbox
|
||||
from ietf.secr.drafts.email import get_email_initial
|
||||
|
||||
|
||||
|
@ -54,26 +51,6 @@ class SecrDraftsTestCase(TestCase):
|
|||
response = self.client.get(url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_add(self):
|
||||
draft = make_test_data()
|
||||
url = urlreverse('ietf.secr.drafts.views.add')
|
||||
self.client.login(username="secretary", password="secretary+password")
|
||||
response = self.client.get(url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
# dummy upload file
|
||||
txt_file = StringIO('This is a simple text file.')
|
||||
txt_file.name = "draft-dummy-00.txt"
|
||||
|
||||
post = dict(title='A test draft',
|
||||
group=draft.group.pk,
|
||||
start_date='2015-01-01',
|
||||
pages='10',
|
||||
txt=txt_file
|
||||
)
|
||||
response = self.client.post(url,post)
|
||||
self.assertEqual(response.status_code, 302)
|
||||
|
||||
def test_approvals(self):
|
||||
make_test_data()
|
||||
Preapproval.objects.create(name='draft-dummy',
|
||||
|
@ -104,48 +81,8 @@ class SecrDraftsTestCase(TestCase):
|
|||
# Makes sure that a manual posting by the Secretariat of an I-D that is
|
||||
# in the RFC Editor Queue will result in notification of the RFC Editor
|
||||
draft = make_test_data()
|
||||
state = State.objects.get(type='draft-iesg',slug='rfcqueue')
|
||||
draft.set_state(state)
|
||||
data = get_email_initial(draft,action='revision')
|
||||
self.assertTrue('rfc-editor@rfc-editor.org' in data['to'])
|
||||
|
||||
def test_revision(self):
|
||||
draft = make_test_data()
|
||||
url = urlreverse('ietf.secr.drafts.views.revision', kwargs={'id':draft.name})
|
||||
view_url = urlreverse('ietf.secr.drafts.views.view', kwargs={'id':draft.name})
|
||||
self.client.login(username="secretary", password="secretary+password")
|
||||
response = self.client.get(url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
post_data = {
|
||||
'title': draft.title,
|
||||
'pages': str(draft.pages),
|
||||
'abstract': draft.abstract,
|
||||
}
|
||||
files = {}
|
||||
files['txt'] = submission_file(draft.name, '02', draft.group, 'txt', "test_submission.txt")
|
||||
post_data.update(files)
|
||||
response = self.client.post(url, post_data)
|
||||
self.assertRedirects(response, view_url)
|
||||
draft = Document.objects.get(name=draft.name)
|
||||
self.assertEqual(draft.rev, '02')
|
||||
|
||||
def test_revision_rfcqueue(self):
|
||||
# Makes sure that a manual posting by the Secretariat of an I-D that is
|
||||
# in the RFC Editor Queue will result in notification of the RFC Editor
|
||||
draft = make_test_data()
|
||||
empty_outbox()
|
||||
state = State.objects.get(type='draft-iesg',slug='rfcqueue')
|
||||
draft.set_state(state)
|
||||
url = urlreverse('ietf.secr.drafts.views.revision', kwargs={'id':draft.name})
|
||||
self.client.login(username="secretary", password="secretary+password")
|
||||
rev = str(int(draft.rev) + 1).zfill(2)
|
||||
file = StringIO("This is a test.")
|
||||
file.name = "%s-%s.txt" % (draft.name, rev)
|
||||
post = {'title':'The Title','pages':'10','txt':file}
|
||||
response = self.client.post(url,post,follow=True)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
# addresses = ','.join([ m['To'] for m in outbox ])
|
||||
# self.assertTrue('rfc-editor@rfc-editor.org' in addresses)
|
||||
data = get_email_initial(draft,action='extend',input={'expiration_date': '2050-01-01'})
|
||||
self.assertTrue('Extension of Expiration Date' in data['subject'])
|
||||
|
||||
def test_makerfc(self):
|
||||
draft = make_test_data()
|
||||
|
@ -166,51 +103,6 @@ class SecrDraftsTestCase(TestCase):
|
|||
response = self.client.post(url, post)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertTrue(draft.name in response.content)
|
||||
|
||||
def test_update(self):
|
||||
draft = make_test_data()
|
||||
path = os.path.join(self.repository_dir, draft.filename_with_rev())
|
||||
with open(path, 'w') as file:
|
||||
file.write('test')
|
||||
expire_draft(draft)
|
||||
url = urlreverse('ietf.secr.drafts.views.update', kwargs={'id':draft.name})
|
||||
email_url = urlreverse('ietf.secr.drafts.views.email', kwargs={'id':draft.name})
|
||||
confirm_url = urlreverse('ietf.secr.drafts.views.confirm', kwargs={'id':draft.name})
|
||||
do_action_url = urlreverse('ietf.secr.drafts.views.do_action', kwargs={'id':draft.name})
|
||||
view_url = urlreverse('ietf.secr.drafts.views.view', kwargs={'id':draft.name})
|
||||
self.client.login(username="secretary", password="secretary+password")
|
||||
response = self.client.get(url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
post_data = {
|
||||
'title': draft.title,
|
||||
'pages': str(draft.pages),
|
||||
'abstract': draft.abstract,
|
||||
}
|
||||
formats = ['txt',]
|
||||
files = {}
|
||||
for format in formats:
|
||||
files[format] = submission_file(draft.name, '02', draft.group, format, "test_submission.%s" % format)
|
||||
post_data.update(files)
|
||||
response = self.client.post(url, post_data)
|
||||
self.assertRedirects(response, email_url + '?action=update&filename=%s-02' % (draft.name))
|
||||
post_data = {
|
||||
'action': 'update',
|
||||
'to': 'john@example.com',
|
||||
'cc': 'joe@example.com',
|
||||
'subject': 'test',
|
||||
'body': 'text',
|
||||
'submit': 'Save'
|
||||
}
|
||||
response = self.client.post(email_url + '?action=update&filename=%s-02' % (draft.name), post_data)
|
||||
response = self.client.post(confirm_url, post_data)
|
||||
response = self.client.post(do_action_url, post_data)
|
||||
self.assertRedirects(response, view_url)
|
||||
draft = Document.objects.get(name=draft.name)
|
||||
expires = datetime.datetime.now() + datetime.timedelta(settings.INTERNET_DRAFT_DAYS_TO_EXPIRE)
|
||||
self.assertTrue(draft.get_state_slug('draft') == 'active')
|
||||
self.assertEqual(draft.rev, '02')
|
||||
expiration_discrepancy_seconds = abs((draft.expires - expires).total_seconds())
|
||||
self.assertLess(expiration_discrepancy_seconds, 60)
|
||||
|
||||
def test_view(self):
|
||||
draft = make_test_data()
|
||||
|
|
|
@ -4,7 +4,6 @@ from ietf.utils.urls import url
|
|||
|
||||
urlpatterns = [
|
||||
url(r'^$', views.search),
|
||||
url(r'^add/$', views.add),
|
||||
url(r'^approvals/$', views.approvals),
|
||||
url(r'^dates/$', views.dates),
|
||||
url(r'^nudge-report/$', views.nudge_report),
|
||||
|
@ -17,7 +16,5 @@ urlpatterns = [
|
|||
url(r'^(?P<id>[A-Za-z0-9._\-\+]+)/edit/$', views.edit),
|
||||
url(r'^(?P<id>[A-Za-z0-9._\-\+]+)/extend/$', views.extend),
|
||||
url(r'^(?P<id>[A-Za-z0-9._\-\+]+)/email/$', views.email),
|
||||
url(r'^(?P<id>[A-Za-z0-9._\-\+]+)/revision/$', views.revision),
|
||||
url(r'^(?P<id>[A-Za-z0-9._\-\+]+)/update/$', views.update),
|
||||
url(r'^(?P<id>[A-Za-z0-9._\-\+]+)/withdraw/$', views.withdraw),
|
||||
]
|
||||
|
|
|
@ -11,38 +11,21 @@ from django.shortcuts import render, get_object_or_404, redirect
|
|||
from django.urls import reverse
|
||||
from django.utils.http import urlencode
|
||||
|
||||
from ietf.doc.models import Document, DocumentAuthor, DocAlias, State
|
||||
from ietf.doc.models import Document, DocumentAuthor, State
|
||||
from ietf.doc.models import DocEvent, NewRevisionDocEvent
|
||||
from ietf.doc.utils import add_state_change_event
|
||||
from ietf.ietfauth.utils import role_required
|
||||
from ietf.meeting.helpers import get_meeting
|
||||
from ietf.name.models import StreamName
|
||||
from ietf.person.models import Person
|
||||
from ietf.secr.drafts.email import announcement_from_form, get_email_initial
|
||||
from ietf.secr.drafts.forms import ( AddModelForm, AuthorForm, BaseRevisionModelForm, EditModelForm,
|
||||
EmailForm, ExtendForm, RevisionModelForm,
|
||||
SearchForm, UploadForm, WithdrawForm )
|
||||
from ietf.secr.utils.ams_utils import get_base
|
||||
from ietf.secr.drafts.forms import AuthorForm, EditModelForm, EmailForm, ExtendForm, SearchForm, WithdrawForm
|
||||
from ietf.secr.utils.document import get_rfc_num, get_start_date
|
||||
from ietf.submit.models import Submission, Preapproval, DraftSubmissionStateName, SubmissionEvent
|
||||
from ietf.submit.mail import announce_new_version, announce_to_lists, announce_to_authors
|
||||
from ietf.utils.draft import Draft
|
||||
from ietf.submit.models import Preapproval
|
||||
from ietf.utils.log import log
|
||||
|
||||
# -------------------------------------------------
|
||||
# Helper Functions
|
||||
# -------------------------------------------------
|
||||
|
||||
def archive_draft_files(filename):
|
||||
'''
|
||||
Takes a string representing the old draft filename, without extensions.
|
||||
Moves any matching files to archive directory.
|
||||
'''
|
||||
files = glob.glob(os.path.join(settings.INTERNET_DRAFT_PATH,filename) + '.*')
|
||||
for file in files:
|
||||
shutil.move(file,settings.INTERNET_DRAFT_ARCHIVE_DIR)
|
||||
return
|
||||
|
||||
def get_action_details(draft, request):
|
||||
'''
|
||||
This function takes a draft object and request object and returns a list of dictionaries
|
||||
|
@ -71,72 +54,6 @@ def handle_uploaded_file(f):
|
|||
destination.write(chunk)
|
||||
destination.close()
|
||||
|
||||
def handle_substate(doc):
|
||||
'''
|
||||
This function checks to see if the document has a revision needed tag, if so the
|
||||
tag gets changed to ad followup, and a DocEvent is created.
|
||||
'''
|
||||
qs = doc.tags.filter(slug__in=('need-rev','rev-wglc','rev-ad','rev-iesg'))
|
||||
if qs:
|
||||
for tag in qs:
|
||||
doc.tags.remove(tag)
|
||||
doc.tags.add('ad-f-up')
|
||||
|
||||
# add DocEvent
|
||||
system = Person.objects.get(name="(system)")
|
||||
DocEvent.objects.create(type="changed_document",
|
||||
doc=doc,
|
||||
rev=doc.rev,
|
||||
desc="Sub state has been changed to <b>AD Followup</b> from <b>Revised ID Needed</b>",
|
||||
by=system)
|
||||
|
||||
def process_files(request,draft):
|
||||
'''
|
||||
This function takes a request object and draft object.
|
||||
It obtains the list of file objects (ie from request.FILES), uploads
|
||||
the files by calling handle_file_upload() and returns
|
||||
the basename, revision number and a list of file types. Basename and revision
|
||||
are assumed to be the same for all because this is part of the validation process.
|
||||
'''
|
||||
files = request.FILES
|
||||
file = files[files.keys()[0]]
|
||||
filename = os.path.splitext(file.name)[0]
|
||||
revision = os.path.splitext(file.name)[0][-2:]
|
||||
file_type_list = []
|
||||
for file in files.values():
|
||||
extension = os.path.splitext(file.name)[1]
|
||||
file_type_list.append(extension)
|
||||
handle_uploaded_file(file)
|
||||
|
||||
return (filename,revision,file_type_list)
|
||||
|
||||
def post_submission(request, draft):
|
||||
with open(draft.get_file_name()) as file:
|
||||
wrapper = Draft(file.read().decode('utf8'), file.name)
|
||||
submission = Submission(
|
||||
name=draft.name,
|
||||
title=draft.title,
|
||||
rev=draft.rev,
|
||||
pages=draft.pages,
|
||||
file_size=os.path.getsize(draft.get_file_name()),
|
||||
document_date=wrapper.get_creation_date(),
|
||||
submission_date=datetime.date.today(),
|
||||
group_id=draft.group.id,
|
||||
remote_ip=request.META['REMOTE_ADDR'],
|
||||
first_two_pages=''.join(wrapper.pages[:2]),
|
||||
state=DraftSubmissionStateName.objects.get(slug="posted"),
|
||||
abstract=draft.abstract,
|
||||
file_types=','.join(file_types_for_draft(draft)),
|
||||
)
|
||||
submission.save()
|
||||
|
||||
SubmissionEvent.objects.create(
|
||||
submission=submission,
|
||||
by=request.user.person,
|
||||
desc="Submitted and posted manually")
|
||||
|
||||
return submission
|
||||
|
||||
def file_types_for_draft(draft):
|
||||
'''Returns list of file extensions that exist for this draft'''
|
||||
basename, ext = os.path.splitext(draft.get_file_name())
|
||||
|
@ -148,16 +65,6 @@ def file_types_for_draft(draft):
|
|||
file_types.append(ext)
|
||||
return file_types
|
||||
|
||||
def promote_files(draft, types):
|
||||
'''
|
||||
This function takes one argument, a draft object. It then moves the draft files from
|
||||
the temporary upload directory to the production directory.
|
||||
'''
|
||||
filename = '%s-%s' % (draft.name,draft.rev)
|
||||
for ext in types:
|
||||
path = os.path.join(settings.IDSUBMIT_MANUAL_STAGING_DIR, filename + ext)
|
||||
shutil.move(path,settings.INTERNET_DRAFT_PATH)
|
||||
|
||||
# -------------------------------------------------
|
||||
# Action Button Functions
|
||||
# -------------------------------------------------
|
||||
|
@ -235,109 +142,6 @@ def do_resurrect(draft, request):
|
|||
|
||||
return
|
||||
|
||||
def do_revision(draft, request, filename, file_type_list):
|
||||
'''
|
||||
This function handles adding a new revision of an existing Internet-Draft.
|
||||
Prerequisites: draft must be active
|
||||
Input: title, revision_date, pages, abstract, file input fields to upload new
|
||||
draft document(s)
|
||||
Actions
|
||||
- move current doc(s) to archive directory
|
||||
- upload new docs to live dir
|
||||
- save doc in history
|
||||
- increment revision
|
||||
- reset expires
|
||||
- create DocEvent
|
||||
- handle sub-state
|
||||
- schedule notification
|
||||
'''
|
||||
|
||||
# TODO this behavior may change with archive strategy
|
||||
archive_draft_files(draft.name + '-' + draft.rev)
|
||||
|
||||
# save form data
|
||||
form = BaseRevisionModelForm(request.POST,instance=draft)
|
||||
if form.is_valid():
|
||||
new_draft = form.save(commit=False)
|
||||
else:
|
||||
raise Exception(form.errors)
|
||||
raise Exception('Problem with input data %s' % form.data)
|
||||
|
||||
# set revision and expires
|
||||
new_draft.rev = filename[-2:]
|
||||
new_draft.expires = datetime.datetime.now() + datetime.timedelta(settings.INTERNET_DRAFT_DAYS_TO_EXPIRE)
|
||||
|
||||
# create DocEvent
|
||||
e = NewRevisionDocEvent.objects.create(type='new_revision',
|
||||
by=request.user.person,
|
||||
doc=draft,
|
||||
rev=new_draft.rev,
|
||||
desc='New revision available',
|
||||
time=draft.time)
|
||||
|
||||
new_draft.save_with_history([e])
|
||||
|
||||
handle_substate(new_draft)
|
||||
|
||||
# move uploaded files to production directory
|
||||
promote_files(new_draft, file_type_list)
|
||||
|
||||
# save the submission record
|
||||
submission = post_submission(request, new_draft)
|
||||
|
||||
announce_to_lists(request, submission)
|
||||
announce_new_version(request, submission, draft, '')
|
||||
announce_to_authors(request, submission)
|
||||
|
||||
return
|
||||
|
||||
def do_update(draft,request,filename,file_type_list):
|
||||
'''
|
||||
Actions
|
||||
- increment revision #
|
||||
- reset expires
|
||||
- create DocEvent
|
||||
- do substate check
|
||||
- change state to Active
|
||||
'''
|
||||
# save form data
|
||||
form = BaseRevisionModelForm(request.POST,instance=draft)
|
||||
if form.is_valid():
|
||||
new_draft = form.save(commit=False)
|
||||
else:
|
||||
raise Exception('Problem with input data %s' % form.data)
|
||||
|
||||
handle_substate(new_draft)
|
||||
|
||||
# update draft record
|
||||
new_draft.rev = os.path.splitext(filename)[0][-2:]
|
||||
new_draft.expires = datetime.datetime.now() + datetime.timedelta(settings.INTERNET_DRAFT_DAYS_TO_EXPIRE)
|
||||
|
||||
new_draft.set_state(State.objects.get(type="draft", slug="active"))
|
||||
|
||||
# create DocEvent
|
||||
e = NewRevisionDocEvent.objects.create(type='new_revision',
|
||||
by=request.user.person,
|
||||
doc=new_draft,
|
||||
rev=new_draft.rev,
|
||||
desc='New revision available',
|
||||
time=new_draft.time)
|
||||
|
||||
new_draft.save_with_history([e])
|
||||
|
||||
# move uploaded files to production directory
|
||||
promote_files(new_draft, file_type_list)
|
||||
|
||||
# save the submission record
|
||||
post_submission(request, new_draft)
|
||||
|
||||
def do_update_announce(draft, request):
|
||||
# send announcement
|
||||
form = EmailForm(request.POST)
|
||||
announcement_from_form(form.data,by=request.user.person)
|
||||
|
||||
return
|
||||
|
||||
def do_withdraw(draft,request):
|
||||
'''
|
||||
Actions
|
||||
|
@ -390,96 +194,6 @@ def abstract(request, id):
|
|||
'draft': draft},
|
||||
)
|
||||
|
||||
@role_required('Secretariat')
|
||||
def add(request):
|
||||
'''
|
||||
Add Internet Draft
|
||||
|
||||
**Templates:**
|
||||
|
||||
* ``drafts/add.html``
|
||||
|
||||
**Template Variables:**
|
||||
|
||||
* form
|
||||
'''
|
||||
|
||||
if request.method == 'POST':
|
||||
button_text = request.POST.get('submit', '')
|
||||
if button_text == 'Cancel':
|
||||
return redirect('drafts')
|
||||
|
||||
upload_form = UploadForm(request.POST, request.FILES)
|
||||
form = AddModelForm(request.POST)
|
||||
if form.is_valid() and upload_form.is_valid():
|
||||
draft = form.save(commit=False)
|
||||
|
||||
# process files
|
||||
filename,revision,file_type_list = process_files(request, draft)
|
||||
name = get_base(filename)
|
||||
|
||||
# set fields (set stream or intended status?)
|
||||
draft.rev = revision
|
||||
draft.name = name
|
||||
draft.type_id = 'draft'
|
||||
|
||||
# set stream based on document name
|
||||
if not draft.stream:
|
||||
stream_slug = None
|
||||
if draft.name.startswith("draft-iab-"):
|
||||
stream_slug = "iab"
|
||||
elif draft.name.startswith("draft-irtf-"):
|
||||
stream_slug = "irtf"
|
||||
elif draft.name.startswith("draft-ietf-") and (draft.group.type_id != "individ"):
|
||||
stream_slug = "ietf"
|
||||
|
||||
if stream_slug:
|
||||
draft.stream = StreamName.objects.get(slug=stream_slug)
|
||||
|
||||
# set expires
|
||||
draft.expires = datetime.datetime.now() + datetime.timedelta(settings.INTERNET_DRAFT_DAYS_TO_EXPIRE)
|
||||
|
||||
draft.save(force_insert=True)
|
||||
|
||||
# set state
|
||||
draft.set_state(State.objects.get(type="draft", slug="active"))
|
||||
|
||||
# automatically set state "WG Document"
|
||||
if draft.stream_id == "ietf" and draft.group.type_id == "wg":
|
||||
draft.set_state(State.objects.get(type="draft-stream-%s" % draft.stream_id, slug="wg-doc"))
|
||||
|
||||
# create DocAlias
|
||||
DocAlias.objects.get_or_create(name=name, document=draft)
|
||||
|
||||
# create DocEvent
|
||||
NewRevisionDocEvent.objects.create(type='new_revision',
|
||||
by=request.user.person,
|
||||
doc=draft,
|
||||
rev=draft.rev,
|
||||
time=draft.time,
|
||||
desc="New revision available")
|
||||
|
||||
# move uploaded files to production directory
|
||||
promote_files(draft, file_type_list)
|
||||
|
||||
# save the submission record
|
||||
post_submission(request, draft)
|
||||
|
||||
messages.success(request, 'New draft added successfully!')
|
||||
params = dict(action='add')
|
||||
url = reverse('ietf.secr.drafts.views.authors', kwargs={'id':draft.pk})
|
||||
url = url + '?' + urlencode(params)
|
||||
return redirect(url)
|
||||
|
||||
else:
|
||||
form = AddModelForm()
|
||||
upload_form = UploadForm()
|
||||
|
||||
return render(request, 'drafts/add.html', {
|
||||
'form': form,
|
||||
'upload_form': upload_form},
|
||||
)
|
||||
|
||||
@role_required('Secretariat')
|
||||
def approvals(request):
|
||||
'''
|
||||
|
@ -603,12 +317,8 @@ def do_action(request, id):
|
|||
|
||||
action = request.POST.get('action')
|
||||
|
||||
if action == 'revision':
|
||||
func = do_revision
|
||||
elif action == 'resurrect':
|
||||
if action == 'resurrect':
|
||||
func = do_resurrect
|
||||
elif action == 'update':
|
||||
func = do_update_announce
|
||||
elif action == 'extend':
|
||||
func = do_extend
|
||||
elif action == 'withdraw':
|
||||
|
@ -758,41 +468,6 @@ def nudge_report(request):
|
|||
return render(request, 'drafts/report_nudge.html', {
|
||||
'docs': docs},
|
||||
)
|
||||
|
||||
@role_required('Secretariat')
|
||||
def revision(request, id):
|
||||
'''
|
||||
This function presents the input form for the New Revision action.
|
||||
on POST, updates draft to new revision and sends notification.
|
||||
'''
|
||||
|
||||
draft = get_object_or_404(Document, name=id)
|
||||
|
||||
if request.method == 'POST':
|
||||
button_text = request.POST.get('submit', '')
|
||||
if button_text == 'Cancel':
|
||||
return redirect('ietf.secr.drafts.views.view', id=id)
|
||||
|
||||
upload_form = UploadForm(request.POST, request.FILES, draft=draft)
|
||||
form = RevisionModelForm(request.POST, instance=draft)
|
||||
if form.is_valid() and upload_form.is_valid():
|
||||
# process files
|
||||
filename,revision,file_type_list = process_files(request,draft)
|
||||
|
||||
do_revision(draft, request, filename, file_type_list)
|
||||
|
||||
messages.success(request, 'New Revision successful!')
|
||||
return redirect('ietf.secr.drafts.views.view', id=id)
|
||||
|
||||
else:
|
||||
form = RevisionModelForm(instance=draft,initial={'revision_date':datetime.date.today().isoformat()})
|
||||
upload_form = UploadForm(draft=draft)
|
||||
|
||||
return render(request, 'drafts/revision.html', {
|
||||
'form': form,
|
||||
'upload_form': upload_form,
|
||||
'draft': draft},
|
||||
)
|
||||
|
||||
@role_required('Secretariat')
|
||||
def search(request):
|
||||
|
@ -863,46 +538,6 @@ def search(request):
|
|||
'form': form},
|
||||
)
|
||||
|
||||
@role_required('Secretariat')
|
||||
def update(request, id):
|
||||
'''
|
||||
This view handles the Update action for an Internet-Draft
|
||||
Update is when an expired draft gets a new revision, (the state does not change?)
|
||||
Prerequisites: draft must be expired
|
||||
Input: upload new files, pages, abstract, title
|
||||
'''
|
||||
|
||||
draft = get_object_or_404(Document, name=id)
|
||||
|
||||
if request.method == 'POST':
|
||||
button_text = request.POST.get('submit', '')
|
||||
if button_text == 'Cancel':
|
||||
return redirect('ietf.secr.drafts.views.view', id=id)
|
||||
|
||||
upload_form = UploadForm(request.POST, request.FILES, draft=draft)
|
||||
form = RevisionModelForm(request.POST, instance=draft)
|
||||
if form.is_valid() and upload_form.is_valid():
|
||||
# process files
|
||||
filename,revision,file_type_list = process_files(request,draft)
|
||||
|
||||
do_update(draft, request, filename, file_type_list)
|
||||
|
||||
params = dict(action='update')
|
||||
params['filename'] = filename
|
||||
url = reverse('ietf.secr.drafts.views.email', kwargs={'id':id})
|
||||
url = url + '?' + urlencode(params)
|
||||
return redirect(url)
|
||||
|
||||
else:
|
||||
form = RevisionModelForm(instance=draft,initial={'revision_date':datetime.date.today().isoformat()})
|
||||
upload_form = UploadForm(draft=draft)
|
||||
|
||||
return render(request, 'drafts/revision.html', {
|
||||
'form': form,
|
||||
'upload_form':upload_form,
|
||||
'draft': draft},
|
||||
)
|
||||
|
||||
@role_required('Secretariat')
|
||||
def view(request, id):
|
||||
'''
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
{% extends "base_site.html" %}
|
||||
{% load staticfiles %}
|
||||
|
||||
{% block title %}Drafts - Add{% endblock %}
|
||||
|
||||
{% block extrahead %}{{ block.super }}
|
||||
<script type="text/javascript" src="{% static 'secr/js/utils.js' %}"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block breadcrumbs %}{{ block.super }}
|
||||
» <a href="../">Drafts</a>
|
||||
» Add
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div class="module draft-container">
|
||||
<h2>Draft - Add</h2>
|
||||
<form id="drafts-add-form" enctype="multipart/form-data" action="" method="post">{% csrf_token %}
|
||||
<table class="full-width amstable">
|
||||
<col width="150">
|
||||
{{ form.as_table }}
|
||||
</table>
|
||||
|
||||
{% include "includes/draft_upload_form.html" %}
|
||||
|
||||
{% include "includes/buttons_save_cancel.html" %}
|
||||
|
||||
</form>
|
||||
</div> <!-- module -->
|
||||
|
||||
{% endblock %}
|
|
@ -1,7 +0,0 @@
|
|||
A new version (-{{ rev }}) has been submitted for {{ doc }}:
|
||||
https://www.ietf.org/internet-drafts/{{ doc }}
|
||||
|
||||
Diff from previous version:
|
||||
https://tools.ietf.org/rfcdiff?url2={{ doc_base }}
|
||||
|
||||
The IETF Secretariat.
|
|
@ -1,8 +0,0 @@
|
|||
As you requested, {{ doc }} an updated
|
||||
version of an expired Internet-Draft, has been posted. The draft will expire
|
||||
on {{ expire_date }} unless it is replaced by an updated version, or the
|
||||
Secretariat has been notified that the document is under official review by the
|
||||
IESG or has been passed to the IRSG or RFC Editor for review and/or publication
|
||||
as an RFC.
|
||||
|
||||
IETF Secretariat.
|
|
@ -1,32 +0,0 @@
|
|||
{% extends "base_site.html" %}
|
||||
{% load staticfiles %}
|
||||
|
||||
{% block title %}Drafts - Revision{% endblock %}
|
||||
|
||||
{% block extrahead %}{{ block.super }}
|
||||
<script type="text/javascript" src="{% static 'secr/js/utils.js' %}"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block breadcrumbs %}{{ block.super }}
|
||||
» <a href="../../">Drafts</a>
|
||||
» <a href="../">{{ draft.name }}</a>
|
||||
» Revision
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div class="module draft-container">
|
||||
<h2>Draft - Revision Data</h2>
|
||||
<form enctype="multipart/form-data" action="" method="post">{% csrf_token %}
|
||||
<table class="full-width">
|
||||
{{ form.as_table }}
|
||||
</table>
|
||||
|
||||
{% include "includes/draft_upload_form.html" %}
|
||||
|
||||
{% include "includes/buttons_save_cancel.html" %}
|
||||
|
||||
</form>
|
||||
</div> <!-- module -->
|
||||
|
||||
{% endblock %}
|
|
@ -14,7 +14,7 @@
|
|||
{% block content %}
|
||||
|
||||
<div class="module draft-container">
|
||||
<h2>Draft - Search <span class="unlocked"><a href="add/" class="addlink">Add</a></span></h2>
|
||||
<h2>Draft - Search</h2>
|
||||
<form id="draft-search-form" enctype="multipart/form-data" action="" method="post">{% csrf_token %}
|
||||
<table id="draft-search-table" class="full-width amstable">
|
||||
{{ form.as_table }}
|
||||
|
|
|
@ -80,8 +80,6 @@
|
|||
<div class="inline-related action-group">
|
||||
<h2>Actions</h2>
|
||||
<ul>
|
||||
<li><button {% if is_active %}{% else %}disabled="disabled"{% endif %}onclick="window.location='revision/'">New Revision</button></li>
|
||||
<li><button {% if is_expired %}{% else %}disabled="disabled"{% endif %}onclick="window.location='update/'">Update Expired</button></li>
|
||||
<li><button {% if is_expired or is_withdrawn %}{% else %}disabled="disabled"{% endif %}onclick="window.location='{% url "ietf.secr.drafts.views.email" id=draft.name %}?action=resurrect'">Resurrect</button></li>
|
||||
<li><button {% if is_active %}{% else %}disabled="disabled"{% endif %}onclick="window.location='extend/'">Extend Expiry</button></li>
|
||||
<li><button {% if is_active %}{% else %}disabled="disabled"{% endif %}onclick="window.location='withdraw/'">Withdraw</button></li>
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
<div class="inline-group add-form">
|
||||
<h2>Files</h2>
|
||||
<table id="draft-file-table" class="full-width amstable">
|
||||
<col width="150">
|
||||
{{ upload_form.non_field_errors }}
|
||||
<tr><th><label for="id_txt">.txt format<span class="required"> *</span></label></th><td>{{ upload_form.txt.errors }}{{ upload_form.txt }}</td></tr>
|
||||
<tr><th><label for="id_xml">.xml format</label></th><td>{{ upload_form.xml.errors }}{{ upload_form.xml }}</td></tr>
|
||||
<tr><th><label for="id_pdf">.pdf format</label></th><td>{{ upload_form.pdf.errors }}{{ upload_form.pdf }}</td></tr>
|
||||
<tr><th><label for="id_ps">.ps format</label></th><td>{{ upload_form.ps.errors }}{{ upload_form.ps }}</td></tr>
|
||||
</table>
|
||||
</div>
|
Loading…
Reference in a new issue