parent
21bccc85b7
commit
7c79a4d707
|
@ -189,6 +189,9 @@ LIAISON_ATTACH_PATH = '/a/www/ietf-datatracker/documents/LIAISON/'
|
|||
LIAISON_ATTACH_URL = '/documents/LIAISON/'
|
||||
|
||||
# ID Submission Tool settings
|
||||
IDST_FROM_EMAIL = 'IETF I-D Submission Tool <idsubmission@ietf.org>'
|
||||
IDST_TO_EMAIL = 'internet-drafts@ietf.org'
|
||||
|
||||
# Days from meeting to cut off dates on submit
|
||||
FIRST_CUTOFF_DAYS = 5
|
||||
SECOND_CUTOFF_DAYS = 3
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
import sha
|
||||
import random
|
||||
import os
|
||||
import subprocess
|
||||
import datetime
|
||||
|
||||
from django import forms
|
||||
from django.forms.fields import email_re
|
||||
from django.conf import settings
|
||||
from django.template.loader import render_to_string
|
||||
from django.utils.html import mark_safe
|
||||
|
@ -10,10 +13,12 @@ from django.utils.html import mark_safe
|
|||
from ietf.idtracker.models import InternetDraft, IETFWG
|
||||
from ietf.proceedings.models import Meeting
|
||||
from ietf.submit.models import IdSubmissionDetail, TempIdAuthors
|
||||
from ietf.submit.utils import MANUAL_POST_REQUESTED, NONE_WG, UPLOADED, WAITING_AUTHENTICATION
|
||||
from ietf.submit.parsers.pdf_parser import PDFParser
|
||||
from ietf.submit.parsers.plain_parser import PlainParser
|
||||
from ietf.submit.parsers.ps_parser import PSParser
|
||||
from ietf.submit.parsers.xml_parser import XMLParser
|
||||
from ietf.utils.mail import send_mail
|
||||
from ietf.utils.draft import Draft
|
||||
|
||||
|
||||
|
@ -42,6 +47,7 @@ class UploadForm(forms.Form):
|
|||
self.draft = None
|
||||
self.filesize = None
|
||||
self.group = None
|
||||
self.file_type = []
|
||||
self.read_dates()
|
||||
|
||||
def read_dates(self):
|
||||
|
@ -200,15 +206,16 @@ class UploadForm(forms.Form):
|
|||
return self.draft
|
||||
|
||||
def save(self):
|
||||
for fd in [self.cleaned_data['txt'], self.cleaned_data['pdf'],
|
||||
self.cleaned_data['xml'], self.cleaned_data['ps']]:
|
||||
for ext in ['txt', 'pdf', 'xml', 'ps']:
|
||||
fd = self.cleaned_data[ext]
|
||||
if not fd:
|
||||
continue
|
||||
filename = os.path.join(self.staging_path, fd.name)
|
||||
self.file_type.append('.%s' % ext)
|
||||
filename = os.path.join(self.staging_path, '%s-%s.%s' % (self.draft.filename, self.draft.revision, ext))
|
||||
destination = open(filename, 'wb+')
|
||||
for chunk in fd.chunks():
|
||||
destination.write(chunk)
|
||||
destination.close()
|
||||
destination.close()
|
||||
self.check_idnits()
|
||||
return self.save_draft_info(self.draft)
|
||||
|
||||
|
@ -222,7 +229,7 @@ class UploadForm(forms.Form):
|
|||
existing_draft = InternetDraft.objects.filter(filename=filename)
|
||||
if existing_draft:
|
||||
group = existing_draft[0].group and existing_draft[0].group.ietfwg or None
|
||||
if group and group.pk != 1027:
|
||||
if group and group.pk != NONE_WG:
|
||||
return group
|
||||
else:
|
||||
return None
|
||||
|
@ -258,7 +265,9 @@ class UploadForm(forms.Form):
|
|||
group_acronym=self.group,
|
||||
remote_ip=self.remote_ip,
|
||||
first_two_pages=''.join(draft.pages[:2]),
|
||||
status_id=1, # Status 1 - upload
|
||||
status_id=UPLOADED,
|
||||
abstract=draft.get_abstract(),
|
||||
file_type=','.join(self.file_type),
|
||||
)
|
||||
order = 0
|
||||
for author in draft.get_authors():
|
||||
|
@ -297,3 +306,163 @@ class AutoPostForm(forms.Form):
|
|||
'email': i.email()[1],
|
||||
'full_name': full_name})
|
||||
return ''.join(buttons)
|
||||
|
||||
def save(self, request):
|
||||
self.save_submitter_info()
|
||||
self.save_new_draft_info()
|
||||
self.send_confirmation_mail(request)
|
||||
|
||||
def send_confirmation_mail(self, request):
|
||||
subject = 'Confirmation for Auto-Post of I-D %s' % self.draft.filename
|
||||
from_email = settings.IDST_FROM_EMAIL
|
||||
to_email = self.cleaned_data['email']
|
||||
send_mail(request, from_email, to_email, subject, 'submit/confirm_autopost.txt',
|
||||
{'draft': self.draft })
|
||||
|
||||
def save_submitter_info(self):
|
||||
TempIdAuthors.objects.create(
|
||||
id_document_tag=self.draft.temp_id_document_tag,
|
||||
first_name=self.cleaned_data['first_name'],
|
||||
last_name=self.cleaned_data['last_name'],
|
||||
email_address=self.cleaned_data['email'],
|
||||
author_order=0,
|
||||
submission=self.draft)
|
||||
|
||||
def save_new_draft_info(self):
|
||||
salt = sha.new(str(random.random())).hexdigest()[:5]
|
||||
self.draft.auth_key = sha.new(salt+self.cleaned_data['email']).hexdigest()
|
||||
self.draft.status_id = WAITING_AUTHENTICATION
|
||||
self.draft.save()
|
||||
|
||||
|
||||
class MetaDataForm(AutoPostForm):
|
||||
|
||||
title = forms.CharField(label=u'Title', required=True)
|
||||
version = forms.CharField(label=u'Version', required=True)
|
||||
creation_date = forms.DateField(label=u'Creation date', required=True)
|
||||
pages = forms.IntegerField(label=u'Pages', required=True)
|
||||
abstract = forms.CharField(label=u'Abstract', widget=forms.Textarea, required=True)
|
||||
first_name = forms.CharField(label=u'Given name', required=True)
|
||||
last_name = forms.CharField(label=u'Last name', required=True)
|
||||
email = forms.EmailField(label=u'Email address', required=True)
|
||||
comments = forms.CharField(label=u'Comments to the secretariat', widget=forms.Textarea, required=False)
|
||||
fields = ['title', 'version', 'creation_date', 'pages', 'abstract', 'first_name', 'last_name', 'email', 'comments']
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(MetaDataForm, self).__init__(*args, **kwargs)
|
||||
self.set_initials()
|
||||
self.authors = self.get_initial_authors()
|
||||
|
||||
def get_initial_authors(self):
|
||||
authors=[]
|
||||
if self.is_bound:
|
||||
for key, value in self.data.items():
|
||||
if key.startswith('first_name_'):
|
||||
author = {'errors': {}}
|
||||
index = key.replace('first_name_', '')
|
||||
first_name = value.strip()
|
||||
if not first_name:
|
||||
author['errors']['first_name'] = 'This field is required'
|
||||
last_name = self.data.get('last_name_%s' % index, '').strip()
|
||||
if not last_name:
|
||||
author['errors']['last_name'] = 'This field is required'
|
||||
email = self.data.get('email_%s' % index, '').strip()
|
||||
if not email:
|
||||
author['errors']['email'] = 'This field is required'
|
||||
elif not email_re.search(email):
|
||||
author['errors']['email'] = 'Enter a valid e-mail address'
|
||||
if first_name or last_name or email:
|
||||
author.update({'first_name': first_name,
|
||||
'last_name': last_name,
|
||||
'email': ('%s %s' % (first_name, last_name), email),
|
||||
'index': index,
|
||||
})
|
||||
authors.append(author)
|
||||
authors.sort(lambda x,y: cmp(int(x['index']), int(y['index'])))
|
||||
return authors
|
||||
|
||||
def set_initials(self):
|
||||
self.fields['pages'].initial=self.draft.txt_page_count
|
||||
self.fields['creation_date'].initial=self.draft.creation_date
|
||||
self.fields['version'].initial=self.draft.revision
|
||||
self.fields['abstract'].initial=self.draft.abstract
|
||||
self.fields['title'].initial=self.draft.id_document_name
|
||||
|
||||
def clean_creation_date(self):
|
||||
creation_date = self.cleaned_data.get('creation_date', None)
|
||||
if not creation_date:
|
||||
return None
|
||||
submit_date = self.draft.submission_date
|
||||
if creation_date > submit_date:
|
||||
raise forms.ValidationError('Creation Date must not be set after submission date')
|
||||
if creation_date + datetime.timedelta(days=3) < submit_date:
|
||||
raise forms.ValidationError('Creation Date must be within 3 days of submission date')
|
||||
return creation_date
|
||||
|
||||
def clean_version(self):
|
||||
version = self.cleaned_data.get('version', None)
|
||||
if not version:
|
||||
return None
|
||||
if len(version) > 2:
|
||||
raise forms.ValidationError('Version field is not in NN format')
|
||||
try:
|
||||
version_int = int(version)
|
||||
except ValueError:
|
||||
raise forms.ValidationError('Version field is not in NN format')
|
||||
if version_int > 99 or version_int < 0:
|
||||
raise forms.ValidationError('Version must be set between 00 and 99')
|
||||
existing_revisions = [int(i.revision) for i in InternetDraft.objects.filter(filename=self.draft.filename)]
|
||||
expected = 0
|
||||
if existing_revisions:
|
||||
expected = max(existing_revisions) + 1
|
||||
if version_int != expected:
|
||||
raise forms.ValidationError('Invalid Version Number (Version %00d is expected)' % expected)
|
||||
return version
|
||||
|
||||
def clean(self):
|
||||
if bool([i for i in self.authors if i['errors']]):
|
||||
raise forms.ValidationError('Please fix errors in author list')
|
||||
return super(MetaDataForm, self).clean()
|
||||
|
||||
def get_authors(self):
|
||||
if not self.is_bound:
|
||||
return self.validation.get_authors()
|
||||
else:
|
||||
return self.authors
|
||||
|
||||
def move_docs(self, draft, revision):
|
||||
old_revision = draft.revision
|
||||
for ext in draft.file_type.split(','):
|
||||
source = os.path.join(settings.STAGING_PATH, '%s-%s%s' % (draft.filename, old_revision, ext))
|
||||
dest = os.path.join(settings.STAGING_PATH, '%s-%s%s' % (draft.filename, revision, ext))
|
||||
os.rename(source, dest)
|
||||
|
||||
def save_new_draft_info(self):
|
||||
draft = self.draft
|
||||
draft.id_documen_name = self.cleaned_data['title']
|
||||
if draft.revision != self.cleaned_data['version']:
|
||||
self.move_docs(draft, self.cleaned_data['version'])
|
||||
draft.revision = self.cleaned_data['version']
|
||||
draft.creation_date = self.cleaned_data['creation_date']
|
||||
draft.txt_page_count = self.cleaned_data['pages']
|
||||
draft.abstract = self.cleaned_data['abstract']
|
||||
draft.comment_to_sec = self.cleaned_data['comments']
|
||||
draft.status_id = MANUAL_POST_REQUESTED
|
||||
draft.save()
|
||||
self.save_submitter_info()
|
||||
|
||||
def save(self, request):
|
||||
self.save_new_draft_info()
|
||||
self.send_mail_to_secretariat(request)
|
||||
|
||||
def send_mail_to_secretariat(self, request):
|
||||
subject = 'Manual Post Requested for %s' % self.draft.filename
|
||||
from_email = settings.IDST_FROM_EMAIL
|
||||
to_email = settings.IDST_TO_EMAIL
|
||||
cc = [self.cleaned_data['email']]
|
||||
cc += [i['email'][1] for i in self.authors]
|
||||
if self.draft.group_acronym:
|
||||
cc += [i.person.email()[1] for i in self.draft.group_acronym.wgchair_set.all()]
|
||||
cc = list(set(cc))
|
||||
send_mail(request, from_email, to_email, subject, 'submit/manual_post_mail.txt',
|
||||
{'form': self, 'draft': self.draft }, cc=cc)
|
||||
|
|
|
@ -6,6 +6,7 @@ urlpatterns = patterns('ietf.submit.views',
|
|||
url(r'^status/$', 'submit_status', name='submit_status'),
|
||||
url(r'^status/(?P<submission_id>\d+)/$', 'draft_status', name='draft_status'),
|
||||
url(r'^status/(?P<submission_id>\d+)/edit/$', 'draft_edit', name='draft_edit'),
|
||||
url(r'^status/(?P<submission_id>\d+)/confirm/(?P<auth_key>[a-f\d]+)/$', 'draft_confirm', name='draft_confirm'),
|
||||
)
|
||||
|
||||
urlpatterns += patterns('django.views.generic.simple',
|
||||
|
|
|
@ -1,7 +1,62 @@
|
|||
import os
|
||||
import re
|
||||
import datetime
|
||||
|
||||
from ietf.idtracker.models import InternetDraft, EmailAddress
|
||||
from ietf.idtracker.models import InternetDraft, EmailAddress, PersonOrOrgInfo
|
||||
|
||||
|
||||
# Some usefull states
|
||||
UPLOADED = 1
|
||||
WAITING_AUTHENTICATION = 4
|
||||
MANUAL_POST_REQUESTED = 5
|
||||
POSTED = -1
|
||||
POSTED_BY_SECRETARIAT = -2
|
||||
|
||||
|
||||
# Not a real WG
|
||||
NONE_WG = 1027
|
||||
|
||||
|
||||
def perform_post(submission):
|
||||
group_id = submission.group_acronym and submission.group_acronym.pk or NONE_WG
|
||||
updated = False
|
||||
try:
|
||||
draft = InternetDraft.objects.get(filename=submission.filename)
|
||||
draft.title = submission.id_document_name
|
||||
draft.group_id = group_id
|
||||
draft.filename = submission.filename
|
||||
draft.revision = submission.revision
|
||||
draft.revision_date = submission.creation_date
|
||||
draft.file_type = submission.file_type
|
||||
draft.txt_page_count = submission.txt_page_count
|
||||
draft.last_modified_date = datetime.date.today()
|
||||
draft.abstract = submission.abstract
|
||||
draft.save()
|
||||
updated = True
|
||||
except InternetDraft.DoesNotExist:
|
||||
draft = InternetDraft.objects.create(
|
||||
title = submission.id_document_name,
|
||||
group_id = group_id,
|
||||
filename = submission.filename,
|
||||
revision = submission.revision,
|
||||
revision_date = submission.creation_date,
|
||||
file_type = submission.file_type,
|
||||
txt_page_count = submission.txt_page_count,
|
||||
start_date = datetime.date.today(),
|
||||
last_modified_date = datetime.date.today(),
|
||||
abstract = submission.abstract,
|
||||
status_id = 1, # Active
|
||||
intended_status_id = 8, # None
|
||||
)
|
||||
move_docs(submission)
|
||||
submission.status_id = POSTED
|
||||
submission.save()
|
||||
|
||||
def move_docs(submission):
|
||||
for ext in submission.file_type.split(','):
|
||||
source = os.path.join(settings.STAGING_PATH, '%s-%s%s' % (submission.filename, submission.revision, ext))
|
||||
dest = os.path.join(settings.INTERNET_DRAFT_PATH, '%s-%s%s' % (submission.filename, submission.revision, ext))
|
||||
os.rename(source, dest)
|
||||
|
||||
|
||||
class DraftValidation(object):
|
||||
|
@ -12,13 +67,14 @@ class DraftValidation(object):
|
|||
self.passes_idnits = self.passes_idnits()
|
||||
self.wg = self.get_working_group()
|
||||
self.authors = self.get_authors()
|
||||
self.submitter = self.get_submitter()
|
||||
|
||||
def passes_idnits(self):
|
||||
passes_idnits = self.check_idnits_success(self.draft.idnits_message)
|
||||
return passes_idnits
|
||||
|
||||
def get_working_group(self):
|
||||
if self.draft.group_acronym and self.draft.group_acronym.pk == 1027:
|
||||
if self.draft.group_acronym and self.draft.group_acronym.pk == NONE_WG:
|
||||
return None
|
||||
return self.draft.group_acronym
|
||||
|
||||
|
@ -40,12 +96,19 @@ class DraftValidation(object):
|
|||
def validate_metadata(self):
|
||||
self.validate_revision()
|
||||
self.validate_authors()
|
||||
self.validate_abstract()
|
||||
self.validate_creation_date()
|
||||
|
||||
def validate_abstract(self):
|
||||
if not self.draft.abstract:
|
||||
self.add_warning('abstract', 'Abstract is empty or was not found')
|
||||
|
||||
def add_warning(self, key, value):
|
||||
self.warnings.update({key: value})
|
||||
|
||||
def validate_revision(self):
|
||||
if self.draft.status_id in [POSTED, POSTED_BY_SECRETARIAT]:
|
||||
return
|
||||
revision = self.draft.revision
|
||||
existing_revisions = [int(i.revision) for i in InternetDraft.objects.filter(filename=self.draft.filename)]
|
||||
expected = 0
|
||||
|
@ -61,24 +124,25 @@ class DraftValidation(object):
|
|||
def validate_creation_date(self):
|
||||
date = self.draft.creation_date
|
||||
if not date:
|
||||
self.add_warning('creation_date', 'Creation Date field is empty or the creation date is not in a proper format.')
|
||||
self.add_warning('creation_date', 'Creation Date field is empty or the creation date is not in a proper format')
|
||||
return
|
||||
submit_date = self.draft.submission_date
|
||||
if date + datetime.timedelta(days=3) > submit_date:
|
||||
self.add_warning('creation_date', 'Creation Date must be within 3 days of submission date.')
|
||||
if date > submit_date:
|
||||
self.add_warning('creation_date', 'Creation Date must not be set after submission date')
|
||||
if date + datetime.timedelta(days=3) < submit_date:
|
||||
self.add_warning('creation_date', 'Creation Date must be within 3 days of submission date')
|
||||
|
||||
def get_authors(self):
|
||||
tmpauthors = self.draft.tempidauthors_set.all().order_by('author_order')
|
||||
authors = []
|
||||
for i in tmpauthors:
|
||||
person = None
|
||||
for existing in EmailAddress.objects.filter(address=i.email_address):
|
||||
try:
|
||||
person = existing.person_or_org
|
||||
except PersonOrOrgInfo.DoesNotExist:
|
||||
pass
|
||||
if not person:
|
||||
authors.append(i)
|
||||
else:
|
||||
authors.append(person)
|
||||
return authors
|
||||
tmpauthors = self.draft.tempidauthors_set.exclude(author_order=0).order_by('author_order')
|
||||
return tmpauthors
|
||||
|
||||
def get_submitter(self):
|
||||
submitter = self.draft.tempidauthors_set.filter(author_order=0)
|
||||
if submitter:
|
||||
return submitter[0]
|
||||
elif self.draft.submitter_tag:
|
||||
try:
|
||||
return PersonOrOrgInfo.objects.get(pk=self.draft.submitter_tag)
|
||||
except PersonOrOrgInfo.DoesNotExist:
|
||||
return False
|
||||
return None
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
# Copyright The IETF Trust 2007, All Rights Reserved
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.http import HttpResponseRedirect, Http404
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.shortcuts import render_to_response
|
||||
from django.template import RequestContext
|
||||
|
||||
from ietf.submit.models import IdSubmissionDetail
|
||||
from ietf.submit.forms import UploadForm, AutoPostForm
|
||||
from ietf.submit.utils import DraftValidation
|
||||
from ietf.submit.forms import UploadForm, AutoPostForm, MetaDataForm
|
||||
from ietf.submit.utils import (DraftValidation, UPLOADED, WAITING_AUTHENTICATION,
|
||||
perform_post)
|
||||
|
||||
|
||||
def submit_index(request):
|
||||
|
@ -41,13 +42,21 @@ def submit_status(request):
|
|||
|
||||
|
||||
|
||||
def draft_status(request, submission_id):
|
||||
def draft_status(request, submission_id, message=None):
|
||||
detail = get_object_or_404(IdSubmissionDetail, submission_id=submission_id)
|
||||
validation = DraftValidation(detail)
|
||||
is_valid = validation.is_valid()
|
||||
if request.method=='POST':
|
||||
status = None
|
||||
allow_edit = True
|
||||
if detail.status_id != UPLOADED:
|
||||
status = detail.status
|
||||
allow_edit = None
|
||||
if request.method=='POST' and allow_edit:
|
||||
if request.POST.get('autopost', False):
|
||||
auto_post_form = AutoPostForm(draft=detail, validation=validation, data=request.POST)
|
||||
if auto_post_form.is_valid():
|
||||
auto_post_form.save(request)
|
||||
return HttpResponseRedirect(reverse(draft_status, None, kwargs={'submission_id': detail.submission_id}))
|
||||
else:
|
||||
return HttpResponseRedirect(reverse(draft_edit, None, kwargs={'submission_id': detail.submission_id}))
|
||||
else:
|
||||
|
@ -58,9 +67,41 @@ def draft_status(request, submission_id):
|
|||
'validation': validation,
|
||||
'auto_post_form': auto_post_form,
|
||||
'is_valid': is_valid,
|
||||
'status': status,
|
||||
'allow_edit': allow_edit,
|
||||
'message': message,
|
||||
},
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
|
||||
def draft_edit(request, submission_id):
|
||||
pass
|
||||
detail = get_object_or_404(IdSubmissionDetail, submission_id=submission_id)
|
||||
if detail.status_id != UPLOADED:
|
||||
raise Http404
|
||||
validation = DraftValidation(detail)
|
||||
if request.method=='POST':
|
||||
form = MetaDataForm(draft=detail, validation=validation, data=request.POST)
|
||||
if form.is_valid():
|
||||
form.save(request)
|
||||
else:
|
||||
form = MetaDataForm(draft=detail, validation=validation)
|
||||
return render_to_response('submit/draft_edit.html',
|
||||
{'selected': 'status',
|
||||
'detail': detail,
|
||||
'validation': validation,
|
||||
'form': form,
|
||||
},
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
|
||||
def draft_confirm(request, submission_id, auth_key):
|
||||
detail = get_object_or_404(IdSubmissionDetail, submission_id=submission_id)
|
||||
message = None
|
||||
if auth_key != detail.auth_key:
|
||||
message = ('error', 'Incorrect authorization key')
|
||||
elif detail.status_id != WAITING_AUTHENTICATION:
|
||||
message = ('error', 'The submission can not be autoposted because it is in state: %s' % detail.status.status_value)
|
||||
else:
|
||||
message = ('success', 'Authorization key accepted. Auto-Post complete')
|
||||
perform_post(detail)
|
||||
return draft_status(request, submission_id, message)
|
||||
|
|
3
ietf/templates/submit/confirm_autopost.txt
Normal file
3
ietf/templates/submit/confirm_autopost.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
Follow this link to confirm you Auto-Post of I-D {{ draft.filename }}-{{ draft.revision }}
|
||||
|
||||
I-D Submission Tool URL: /submit/status/{{ draft.submission_id }}/confirm/{{ draft.auth_key }}/
|
145
ietf/templates/submit/draft_edit.html
Normal file
145
ietf/templates/submit/draft_edit.html
Normal file
|
@ -0,0 +1,145 @@
|
|||
{% extends "submit/draft_status.html" %}
|
||||
{% block title %}Adjust Meta-Data{% endblock %}
|
||||
|
||||
{% block morecss %}
|
||||
{{ block.super }}
|
||||
table.metadata-table #id_title, table.metadata-table #id_abstract, table.metadata-table #id_comments { width: 500px; }
|
||||
table.metadata-table tr.warning th, table.metadata-table tr.warning td { background-color: #ffeebb; }
|
||||
table.ietf-table tr { vertical-align: top; }
|
||||
table.ietf-table tr.error { background-color: #ffeebb; border-top: 1px dashed red; border-bottom: 1px dashed red;}
|
||||
table.ietf-table span.field-error { display: block; color: red; }
|
||||
{% endblock %}
|
||||
|
||||
{% block pagehead %}
|
||||
{{ block.super }}
|
||||
|
||||
<script type="text/javascript">
|
||||
(function ($) {
|
||||
|
||||
$.fn.AuthorList = function() {
|
||||
return this.each(function () {
|
||||
var table = $(this);
|
||||
var makeEditable = function() {
|
||||
table.find('tbody tr').each(function(index, value) {
|
||||
var tr = $(this);
|
||||
tr.find('td').each(function() {
|
||||
var td = $(this);
|
||||
var text = td.find('.fieldValue');
|
||||
var name = td.attr('name');
|
||||
if (tr.hasClass('non_editable')) {
|
||||
td.prepend('<input style="display: none;" type="text" name="' + name + '_' + index + '" value="' + text.text() + '" />');
|
||||
} else {
|
||||
td.prepend('<input type="text" name="' + name + '_' + index + '" value="' + text.text() + '" />');
|
||||
text.html('');
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
var addNewEntry = function() {
|
||||
table.append(table.find('tbody tr').last().clone());
|
||||
var new_tr = table.find('tbody tr').last();
|
||||
new_tr.toggleClass('evenrow').toggleClass('oddrow');
|
||||
new_tr.removeClass('error').find('.field-error').remove();
|
||||
new_tr.find('input').each(function() {
|
||||
var name = $(this).attr('name');
|
||||
var splitted = name.split('_');
|
||||
splitted.reverse();
|
||||
name = name.replace(splitted[0], (parseInt(splitted[0]) + 1).toString(10));
|
||||
$(this).attr('name', name);
|
||||
$(this).val('');
|
||||
});
|
||||
};
|
||||
|
||||
var bindTriggers = function() {
|
||||
$('.new_author').click(addNewEntry);
|
||||
};
|
||||
|
||||
var initialize = function() {
|
||||
makeEditable();
|
||||
bindTriggers();
|
||||
};
|
||||
|
||||
initialize();
|
||||
});
|
||||
};
|
||||
|
||||
$(document).ready(function () {
|
||||
$('table.author_list').AuthorList();
|
||||
});
|
||||
|
||||
})(jQuery);
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
{% block submit_content %}
|
||||
<h2>Adjust External Meta-Data</h2>
|
||||
|
||||
<div id="idnits_results" style="visibility:hidden;">
|
||||
<div class="hd">
|
||||
<span style="display: none;" id="twopages_title">First two pages</span>
|
||||
</div>
|
||||
<div class="bd">
|
||||
<div id="stream_dialog_body" style="padding: 0em 5em; height: 400px; overflow: auto;">
|
||||
<pre class="twopages" style="display: none;">{{ detail.first_two_pages }}</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class="metadata-table">
|
||||
<tr><th>Document</th><td>{{ detail.filename }} <a class="twopages_trigger" href="#">[View first two pages]</a></td></tr>
|
||||
<tr><th>Submission date</th><td>{{ detail.submission_date }}</td></tr>
|
||||
<tr><th>WG</th><td>{{ validation.wg|default:"Individual Submission" }}</td></tr>
|
||||
<tr><th>File size</th><td>{{ detail.filesize|filesizeformat }}</td></tr>
|
||||
</table>
|
||||
|
||||
<h3>Adjust data</h3>
|
||||
{% if form.errors %}
|
||||
<div class="metadata-errors">
|
||||
Please fix the following errors.
|
||||
</div>
|
||||
{% endif %}
|
||||
<form method="post" action="">
|
||||
<table class="metadata-table">
|
||||
<tr{% if form.errors.title %} class="warning"{% endif %}><th>Title</th><td>{{ form.title }}{{ form.errors.title }}</td></tr>
|
||||
<tr{% if form.errors.version %} class="warning"{% endif %}><th>Version</th><td>{{ form.version }}{{ form.errors.version }}</td></tr>
|
||||
<tr{% if form.errors.creation_date %} class="warning"{% endif %}><th>Creation date</th><td>{{ form.creation_date }}{{ form.errors.creation_date }}</td></tr>
|
||||
<tr{% if form.errors.pages %} class="warning"{% endif %}><th>Pages</th><td>{{ form.pages }}{{ form.errors.pages }}</td></tr>
|
||||
<tr{% if form.errors.abstract %} class="warning"{% endif %}><th>Abstract</th><td>{{ form.abstract }}{{ form.errors.abstract }}</td></tr>
|
||||
<tr><th>Submitter</th>
|
||||
<td>
|
||||
If you are one of the authors, then please click a button by your name to automatically fill in the submitter's information as requested below. Otherwise, Please manually enter your information.<br />
|
||||
{{ form.get_author_buttons|safe }}
|
||||
</td></tr>
|
||||
<tr{% if form.errors.first_name %} class="warning"{% endif %}><th class="author">First name</th><td>{{ form.first_name }}{{ form.errors.first_name }}</td></tr>
|
||||
<tr{% if form.errors.last_name %} class="warning"{% endif %}><th class="author">Last name</th><td>{{ form.last_name }}{{ form.errors.last_name }}</td></tr>
|
||||
<tr{% if form.errors.email %} class="warning"{% endif %}><th class="author">Email address</th><td>{{ form.email }}{{ form.errors.email }}</td></tr>
|
||||
<tr{% if form.errors.comments %} class="warning"{% endif %}><th>Comments to the secretariat</th><td>{{ form.comments }}{{ form.errors.comments }}</td></tr>
|
||||
</table>
|
||||
|
||||
<h3>Authors</h3>
|
||||
<table class="author_list ietf-table" style="width: 100%;">
|
||||
<thead>
|
||||
<tr><th>First name</th><th>Last name</th><th>Email address</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for author in form.get_authors %}
|
||||
<tr class="editable {% cycle oddrow,evenrow %}{% if author.errors %} error{% endif %}">
|
||||
<td name="first_name"><span class="fieldValue">{{ author.first_name }}</span><span class="field-error">{{ author.errors.first_name }}</span></td>
|
||||
<td name="last_name"><span class="fieldValue">{{ author.last_name }}</span><span class="field-error">{{ author.errors.last_name }}</span></td>
|
||||
<td name="email"><span class="fieldValue">{{ author.email.1 }}</span><span class="field-error">{{ author.errors.email }}</span></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<div style="text-align: right; margin-bottom: 1em;">
|
||||
<input type="button" value="Add another author" class="new_author" />
|
||||
</div>
|
||||
<input type="submit" value="Submit for manual posting" />
|
||||
</form>
|
||||
|
||||
<p>
|
||||
The IETF is an organized activity of the <a href="http://www.isoc.org">Internet Society</a>
|
||||
<br>Please send problem reports to <a href="mailto:ietf-action@ietf.org">ietf-action@ietf.org</a>.
|
||||
</p>
|
||||
{% endblock %}
|
|
@ -4,6 +4,8 @@
|
|||
{% block morecss %}
|
||||
{{ block.super }}
|
||||
div.metadata-errors { border: 1px solid red; background-color: #ffeebb; padding: 5px 10px; margin: 1em 0px; }
|
||||
div.info-message-error { border: 1px solid red; background-color: #ffeebb; padding: 5px 10px; margin: 1em 0px; color: red; }
|
||||
div.info-message-success { border: 1px solid green; background-color: #eeffbb; padding: 5px 10px; margin: 1em 0px; color: green; }
|
||||
table.metadata-table th { white-space: nowrap; font-weight: bold; }
|
||||
table.metadata-table #id_first_name, table.metadata-table #id_last_name { width: 200px; }
|
||||
table.metadata-table #id_email { width: 400px; }
|
||||
|
@ -60,6 +62,14 @@ table.metadata-table ul.errorlist { color: red; padding: 0px; margin: 0px; list-
|
|||
{% endblock %}
|
||||
|
||||
{% block submit_content %}
|
||||
{% if status %}
|
||||
<h2>Status of the submission: {{ status.status_value }}</h2>
|
||||
{% endif %}
|
||||
|
||||
{% if message %}
|
||||
<div class="info-message-{{ message.0 }}">{{ message.1 }}</div>
|
||||
{% endif %}
|
||||
|
||||
<h2>Check Page</h2>
|
||||
<p>
|
||||
{% if validation.passes_idnits %}
|
||||
|
@ -114,9 +124,9 @@ returned to the submitter.
|
|||
<tr{% if validation.warnings.revision %} class="warning"{% endif %}><th>Revision</th><td>{{ detail.revision }}<div class="warn_message">{{ validation.warnings.revision }}</div></td></tr>
|
||||
<tr><th>Submission date</th><td>{{ detail.submission_date }}</td></tr>
|
||||
<tr><th>Title</th><td>{{ detail.id_document_name }}</td></tr>
|
||||
<tr{% if validation.warnings.group %} class="warning"{% endif %}><th>WG</th><td>{{ validation.wg|default:"Individual Submission" }}<div class="warn_message">{{ validation.warnings.group }}</td></tr>
|
||||
<tr{% if validation.warnings.group %} class="warning"{% endif %}><th>WG</th><td>{{ validation.wg|default:"Individual Submission" }}<div class="warn_message">{{ validation.warnings.group }}</div></td></tr>
|
||||
<tr><th>File size</th><td>{{ detail.filesize|filesizeformat }}</td></tr>
|
||||
<tr{% if validation.warnings.creation_date %} class="warning"{% endif %}><th>Creation date</th><td>{{ detail.creation_date }}<div class="warn_message">{{ validation.warnings.creation_date }}</td></tr>
|
||||
<tr{% if validation.warnings.creation_date %} class="warning"{% endif %}><th>Creation date</th><td>{{ detail.creation_date }}<div class="warn_message">{{ validation.warnings.creation_date }}</div></td></tr>
|
||||
<tr{% if validation.warnings.authors %} class="warning"{% endif %}><th colspan="2">Author(s) information</th></tr>
|
||||
{% if not validation.authors %}
|
||||
<tr class="warning"><td colspan="2"><div class="warn_message">{{ validation.warning.authors }}</div></td></tr>
|
||||
|
@ -125,9 +135,20 @@ returned to the submitter.
|
|||
<tr><th class="author">Author {{ forloop.counter }}</th><td>{{ author.email.0 }} <{{ author.email.1 }}></td></tr>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
<tr{% if validation.warnings.pages %} class="warning"{% endif %}><th>Pages</th><td>{{ detail.txt_page_count }}<div class="warn_message">{{ validation.warnings.pages }}</td></tr>
|
||||
<tr><th>Abstract</th><td>{{ detail.abstract|linebreaksbr }}</td></tr>
|
||||
<tr{% if validation.warnings.pages %} class="warning"{% endif %}><th>Pages</th><td>{{ detail.txt_page_count }}<div class="warn_message">{{ validation.warnings.pages }}</div></td></tr>
|
||||
<tr{% if validation.warnings.abstract %} class="warning"{% endif %}><th>Abstract</th><td>{{ detail.abstract|linebreaksbr }}<div class="warn_message">{{ validation.warnings.abstract }}</div></td></tr>
|
||||
</table>
|
||||
|
||||
{% if validation.submitter %}
|
||||
<h3>Submitter information</h3>
|
||||
<table class="metadata-table">
|
||||
<tr><th>First name</th><td>{{ validation.submitter.first_name }}</td></tr>
|
||||
<tr><th>Last name</th><td>{{ validation.submitter.last_name }}</td></tr>
|
||||
<tr><th>Email addres</th><td>{{ validation.submitter.email_address }}</td></tr>
|
||||
</table>
|
||||
{% endif %}
|
||||
|
||||
{% if allow_edit %}
|
||||
<form method="post" action="" name="auto_post_form">
|
||||
<input type="submit" value="Adjust Meta-Data" value="adjust" /> (Leads to manual post by the Secretariat)
|
||||
</form>
|
||||
|
@ -144,6 +165,8 @@ If you are one of the authors of this document, then please click the button wit
|
|||
<input type="submit" value="Post" name="autopost" />
|
||||
</form>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
<p>
|
||||
The IETF is an organized activity of the <a href="http://www.isoc.org">Internet Society</a>
|
||||
<br>Please send problem reports to <a href="mailto:ietf-action@ietf.org">ietf-action@ietf.org</a>.
|
||||
|
|
21
ietf/templates/submit/manual_post_mail.txt
Normal file
21
ietf/templates/submit/manual_post_mail.txt
Normal file
|
@ -0,0 +1,21 @@
|
|||
Manual Posting Requested for following Internet-Draft:
|
||||
|
||||
I-D Submission Tool URL: /submit/status/{{ draft.submission_id }}/
|
||||
|
||||
File name: {{ draft.filename }}
|
||||
Submission date: {{ draft.submission_date }}
|
||||
WG: {{ draft.wg|default:"Individual Submission" }}
|
||||
File size: {{ draft.filesize }}
|
||||
|
||||
Title: {{ draft.id_document_name }}
|
||||
Version: {{ draft.revision }}
|
||||
Creation date: {{ draft.id_document_name }}
|
||||
Pages: {{ draft.txt_page_count }}
|
||||
Abstract: {{ draft.abstract }}
|
||||
Submitter: {{ form.cleaned_data.first_name }} {{ form.cleaned_data.last_name }} <{{ form.cleaned_data.email }}>
|
||||
|
||||
Author(s):
|
||||
{% for author in form.get_authors %}{{ author.first_name }} {{ author.last_name }} <{{ author.email.1 }}>
|
||||
{% endfor %}
|
||||
|
||||
{{ draft.comment_to_sec }}
|
Loading…
Reference in a new issue