Show state of a previous submission. Fixes #590

- Legacy-Id: 2836
This commit is contained in:
Emilio A. Sánchez López 2011-02-09 17:14:50 +00:00
parent 86229aa478
commit 6aa16f2762
7 changed files with 282 additions and 41 deletions

View file

@ -6,8 +6,9 @@ from django import forms
from django.conf import settings
from django.template.loader import render_to_string
from ietf.idtracker.models import InternetDraft
from ietf.proceedings.models import Meeting
from ietf.submit.models import IdSubmissionDetail
from ietf.submit.models import IdSubmissionDetail, TempIdAuthors
from ietf.submit.parsers.pdf_parser import PDFParser
from ietf.submit.parsers.plain_parser import PlainParser
from ietf.submit.parsers.ps_parser import PSParser
@ -36,6 +37,7 @@ class UploadForm(forms.Form):
self.idnits_message = None
self.shutdown = False
self.draft = None
self.filesize = None
self.read_dates()
def read_dates(self):
@ -85,6 +87,7 @@ class UploadForm(forms.Form):
parsed_info = PlainParser(txt_file).critical_parse()
if parsed_info.errors:
raise forms.ValidationError(parsed_info.errors)
self.filesize=txt_file.size
return txt_file
def clean_pdf(self):
@ -168,13 +171,57 @@ class UploadForm(forms.Form):
self.idnits_message = p.stdout.read()
def save_draft_info(self, draft):
document_id = 0
existing_draft = InternetDraft.objects.filter(filename=draft.filename)
if existing_draft:
document_id = existing_draft[0].id_document_tag
detail = IdSubmissionDetail.objects.create(
id_document_name=draft.get_title(),
filename=draft.filename,
revision=draft.revision,
txt_page_count=draft.get_pagecount(),
filesize=self.filesize,
creation_date=draft.get_creation_date(),
submission_date=datetime.date.today(),
idnits_message=self.idnits_message,
temp_id_document_tag=document_id,
first_two_pages=''.join(draft.pages[:2]),
status_id=1, # Status 1 - upload
)
order = 0
for author in draft.get_authors():
name, email = author.rsplit(' ', 1)
first_name, last_name = name.split(' ', 1)
email = email.replace('<', '').replace('>', '')
order += 1
TempIdAuthors.objects.create(
id_document_tag=document_id,
first_name=first_name,
last_name=last_name,
email_address=email,
author_order=order,
submission=detail)
return detail
class AutoPostForm(forms.Form):
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)
def __init__(self, *args, **kwargs):
self.draft = kwargs.pop('draft', None)
self.validation = kwargs.pop('validation', None)
super(AutoPostForm, self).__init__(*args, **kwargs)
def get_author_buttons(self):
button_template = '<input type="button" onclick="jQuery(\'#id_first_name\').val(\'%(first_name)s\');jQuery(\'#id_last_name\').val(\'%(last_name)s\');jQuery(\'#id_email\').val(\'%(email)s\');" value="%(full_name)s" />'
buttons = []
for i in self.validation.authors:
full_name = '%s. %s' % (i.first_name[0], i.last_name)
buttons.append(button_template % {'first_name': i.first_name,
'last_name': i.last_name,
'email': i.email()[1],
'full_name': full_name})
return ''.join(buttons)

View file

@ -40,3 +40,20 @@ class IdSubmissionDetail(models.Model):
class Meta:
db_table = 'id_submission_detail'
class TempIdAuthors(models.Model):
id = models.AutoField(primary_key=True)
id_document_tag = models.IntegerField()
first_name = models.CharField(blank=True, max_length=255)
last_name = models.CharField(blank=True, max_length=255)
email_address = models.CharField(blank=True, max_length=255)
last_modified_date = models.DateField(null=True, blank=True)
last_modified_time = models.CharField(blank=True, max_length=100)
author_order = models.IntegerField(null=True, blank=True)
submission = models.ForeignKey(IdSubmissionDetail)
class Meta:
db_table = 'temp_id_authors'
def email(self):
return ('%s %s' % (self.first_name, self.last_name), self.email_address)

View file

@ -5,6 +5,7 @@ urlpatterns = patterns('ietf.submit.views',
url(r'^$', 'submit_index', name='submit_index'),
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'),
)
urlpatterns += patterns('django.views.generic.simple',

View file

@ -1,7 +1,88 @@
import re
def check_idnits_success(idnits_message):
success_re = re.compile('\s+Summary:\s+0\s+|No nits found')
if success_re.search(idnits_message):
from ietf.idtracker.models import InternetDraft, EmailAddress
class DraftValidation(object):
def __init__(self, draft):
self.draft = draft
self.warnings = {}
self.passes_idnits = self.passes_idnits()
self.wg = self.get_working_group()
self.authors = self.get_authors()
def passes_idnits(self):
passes_idnits = self.check_idnits_success(self.draft.idnits_message)
return passes_idnits
def get_working_group(self):
filename = self.draft.filename
existing_draft = InternetDraft.objects.filter(filename=filename)
if existing_draft:
return existing_draft[0].group and existing_draft[0].group.ietfwg or None
else:
if filename.startswith('draft-ietf-'):
# Extra check for WG that contains dashes
for group in IETFWG.objects.filter(group_acronym__acronym__contains='-'):
if filename.startswith('draft-ietf-%s-' % group.group_acronym.acronym):
return group
group_acronym = filename.split('-')[2]
try:
return IETFWG.objects.get(group_acronym__acronym=group_acronym)
except IETFWG.DoesNotExist:
self.add_warning('group', 'Invalid WG ID: %s' % group_acronym)
return None
else:
return None
def check_idnits_success(self, idnits_message):
success_re = re.compile('\s+Summary:\s+0\s+|No nits found')
if success_re.search(idnits_message):
return True
return False
def is_valid_attr(self, key):
if key in self.warnings.keys():
return False
return True
return False
def is_valid(self):
self.validate_metadata()
return not bool(self.warnings.keys()) and self.passes_idnits
def validate_metadata(self):
self.validate_revision()
self.validate_authors()
def add_warning(self, key, value):
self.warnings.update({key: value})
def validate_revision(self):
revision = self.draft.revision
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 int(revision) != expected:
self.add_warning('revision', 'Invalid Version Number (Version %00d is expected)' % expected)
def validate_authors(self):
if not self.authors:
self.add_warning('authors', 'No authors found')
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

View file

@ -6,8 +6,8 @@ from django.shortcuts import render_to_response
from django.template import RequestContext
from ietf.submit.models import IdSubmissionDetail
from ietf.submit.forms import UploadForm
from ietf.submit.utils import check_idnits_success
from ietf.submit.forms import UploadForm, AutoPostForm
from ietf.submit.utils import DraftValidation
def submit_index(request):
@ -43,10 +43,24 @@ def submit_status(request):
def draft_status(request, submission_id):
detail = get_object_or_404(IdSubmissionDetail, submission_id=submission_id)
idnits_success = check_idnits_success(detail.idnits_message)
validation = DraftValidation(detail)
is_valid = validation.is_valid()
if request.method=='POST':
if request.POST.get('autopost', False):
auto_post_form = AutoPostForm(draft=detail, validation=validation, data=request.POST)
else:
return HttpResponseRedirect(reverse(draft_edit, None, kwargs={'submission_id': detail.submission_id}))
else:
auto_post_form = AutoPostForm(draft=detail, validation=validation)
return render_to_response('submit/draft_status.html',
{'selected': 'status',
'detail': detail,
'idnits_success': idnits_success,
'validation': validation,
'auto_post_form': auto_post_form,
'is_valid': is_valid,
},
context_instance=RequestContext(request))
def draft_edit(request, submission_id):
pass

View file

@ -1,40 +1,58 @@
{% extends "submit/submit_base.html" %}
{% block title %}Submission status{% endblock %}
{% block morecss %}
{{ block.super }}
div.metadata-errors { border: 1px solid red; background-color: #ffeebb; padding: 5px 10px; margin: 1em 0px; }
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; }
table.metadata-table th, table.metadata-table td { text-align: left; background: #ddddff; padding: 5px 10px; }
table.metadata-table th.author { text-align: right; }
table.metadata-table tr { vertical-align: top; }
table.metadata-table tr.warning td, table.metadata-table tr.warning th { background-color: #ffaaaa; }
table.metadata-table div.warn_message { color: red; }
table.metadata-table ul.errorlist { color: red; padding: 0px; margin: 0px; list-style-type: none; }
{% endblock morecss %}
{% block pagehead %}
<script type="text/javascript" src="/js/lib/jquery-1.4.2.min.js"></script>
<script type="text/javascript">
(function ($) {
$.fn.IdnitsInfo = function() {
return this.each(function () {
var title = $(this).attr('title');
var handleClose = function() {
idnitsDialog.hide();
};
var buttons = [{text:"Close", handler:handleClose, isDefault:true}];
var kl = [new YAHOO.util.KeyListener(document, {keys:27}, handleClose)]
var idnitsDialog = new YAHOO.widget.Dialog("idnits_results", {
visible:false, draggable:false, close:true, modal:true,
width:"860px", fixedcenter:true, constraintoviewport:true,
buttons: buttons, keylisteners:kl});
idnitsDialog.render();
var showIdnits = function() {
idnitsDialog.show();
}
$(this).click(function() {
showIdnits();
return false;
});
});
};
$(document).ready(function () {
$('a.idnits_trigger').IdnitsInfo();
var handleClose = function() {
idnitsDialog.hide();
};
var buttons = [{text:"Close", handler:handleClose, isDefault:true}];
var kl = [new YAHOO.util.KeyListener(document, {keys:27}, handleClose)]
var idnitsDialog = new YAHOO.widget.Dialog("idnits_results", {
visible:false, draggable:false, close:true, modal:true,
width:"860px", fixedcenter:true, constraintoviewport:true,
buttons: buttons, keylisteners:kl});
idnitsDialog.render();
var showIdnits = function() {
$('#idnits_title').show();
$('#twopages_title').hide();
$('pre.idnits_message').show();
$('pre.twopages').hide();
idnitsDialog.show();
return false;
}
var showTwoPages = function() {
$('#idnits_title').hide();
$('#twopages_title').show();
$('pre.idnits_message').hide();
$('pre.twopages').show();
idnitsDialog.show();
return false;
}
$('a.idnits_trigger').click(showIdnits);
$('a.twopages_trigger').click(showTwoPages);
});
})(jQuery);
@ -44,7 +62,7 @@
{% block submit_content %}
<h2>Check Page</h2>
<p>
{% if idnits_success %}
{% if validation.passes_idnits %}
Your draft has been verified to meet IDNITS requirements.
{% else %}
Your draft has NOT been verified to meet IDNITS requirements.
@ -52,17 +70,80 @@ Your draft has NOT been verified to meet IDNITS requirements.
<a class="idnits_trigger" href="#">(View IDNITS Results)</a>
</p>
<div id="idnits_results" style="visibility:hidden;">
<div class="hd"><span id="idnits_title">Idnits results</span></div>
<div class="hd">
<span style="display: none;" id="idnits_title">Idnits results</span>
<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>{{ detail.idnits_message }}</pre>
<pre class="idnits_message" style="display: none;">{{ detail.idnits_message }}</pre>
<pre class="twopages" style="display: none;">{{ detail.first_two_pages }}</pre>
</div>
</div>
</div>
<h2>Meta-Data from the Draft</h2>
{% if validation.warnings %}
<div class="metadata-errors">
<h3>Meta-Data errors found</h3>
<p>
Please make sure that your Internet-Draft includes all of the required meta-data in the proper format.
</p>
<p>
If your Internet-Draft *does* include all of the required meta-data in the proper format, and if
the error(s) identified above are due to the failure of the tool to extract the meta-data correctly,
then please use the 'Adjust Meta-Data' button below, which will take you to the 'Adjust Screen' where
you can correct the improperly extracted meta-data. You will then be able to submit your Internet-Draft
to the Secretariat for manual posting.
</p>
<p>
If your Internet-Draft *does not* include all of the required meta-data in the proper format, then
please cancel this submission, update your Internet-Draft, and resubmit it.
</p>
<p>
<strong>NOTE:</strong> The Secretariat will NOT add any meta-data to your Internet-Draft or edit the meta-data. An
Internet-Draft that does not include all of the required meta-data in the proper format WILL be
returned to the submitter.
</p>
</div>
{% endif %}
<table class="metadata-table">
<tr><th>Document</th><td>{{ detail.filename }} <a class="twopages_trigger" href="#">[View first two pages]</a></td></tr>
<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:"" }}<div class="warn_message">{{ validation.warnings.group }}</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.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>
{% else %}
{% for author in validation.authors %}
<tr><th class="author">Author {{ forloop.counter }}</th><td>{{ author.email.0 }} &lt;{{ author.email.1 }}&gt;</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>
</table>
<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>
{% if is_valid %}
<h2>Please edit the following meta-data before proceeding to Auto-Post</h2>
<p>
If you are one of the authors of this document, then please click the button with your name on it to automatically fill in the submitter information as requested below. Otherwise, please manually enter your information.
</p>
<form method="post" action="">
{{ auto_post_form.get_author_buttons|safe }}
<table class="metadata-table">
{{ auto_post_form }}
</table>
<input type="submit" value="Post" name="autopost" />
</form>
{% 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>.

View file

@ -501,7 +501,7 @@ class Draft():
_debug("Not an author? '%s'" % (author))
authors = [ re.sub(r" +"," ", a) for a in authors if a != None ]
authors.sort()
# authors.sort()
_debug(" * Final author list: " + ", ".join(authors))
_debug("-"*72)
self._authors = authors