From f9ee750afd99a43a91e68e1cfa6c76fba137a43f Mon Sep 17 00:00:00 2001 From: Ole Laursen Date: Fri, 13 Jun 2014 12:30:42 +0000 Subject: [PATCH] Make it possible to adjust the name of new materials upon upload, also fix a couple of warnings from PyFlakes - Legacy-Id: 7914 --- ietf/doc/tests_material.py | 9 +++--- ietf/doc/utils.py | 16 ++++++++++ ietf/doc/views_material.py | 29 ++++++++++++------- ietf/group/tests_info.py | 4 +-- ietf/group/utils.py | 1 - ietf/templates/base.html | 2 +- .../templates/doc/material/edit_material.html | 15 ++++++++-- ietf/utils/tests.py | 1 + 8 files changed, 57 insertions(+), 20 deletions(-) diff --git a/ietf/doc/tests_material.py b/ietf/doc/tests_material.py index 297e6091e..4c175415e 100644 --- a/ietf/doc/tests_material.py +++ b/ietf/doc/tests_material.py @@ -1,6 +1,6 @@ # Copyright The IETF Trust 2011, All Rights Reserved -import os, shutil, datetime +import os, shutil from StringIO import StringIO from pyquery import PyQuery @@ -10,7 +10,6 @@ from django.core.urlresolvers import reverse as urlreverse from ietf.doc.models import Document, State, DocAlias from ietf.group.models import Group from ietf.utils.test_utils import TestCase, login_testing_unauthorized -from ietf.utils.test_data import make_test_data class GroupMaterialTests(TestCase): def setUp(self): @@ -57,7 +56,7 @@ class GroupMaterialTests(TestCase): test_file.name = "unnamed.pdf" # faulty post - r = self.client.post(url, dict(title="", state="", material=test_file)) + r = self.client.post(url, dict(title="", name="", state="", material=test_file)) self.assertEqual(r.status_code, 200) q = PyQuery(r.content) @@ -67,6 +66,7 @@ class GroupMaterialTests(TestCase): # post r = self.client.post(url, dict(title="Test File", + name="slides-%s-test-file" % group.acronym, state=State.objects.get(type="slides", slug="active").pk, material=test_file)) self.assertEqual(r.status_code, 302) @@ -79,10 +79,11 @@ class GroupMaterialTests(TestCase): with open(os.path.join(self.materials_dir, "slides", doc.name + "-" + doc.rev + ".pdf")) as f: self.assertEqual(f.read(), content) - # check that posting same title is prevented + # check that posting same name is prevented test_file.seek(0) r = self.client.post(url, dict(title="Test File", + name=doc.name, state=State.objects.get(type="slides", slug="active").pk, material=test_file)) self.assertEqual(r.status_code, 200) diff --git a/ietf/doc/utils.py b/ietf/doc/utils.py index ed1d0a247..91079a289 100644 --- a/ietf/doc/utils.py +++ b/ietf/doc/utils.py @@ -4,6 +4,7 @@ import urllib import math from django.conf import settings +from django.forms import ValidationError from ietf.utils import markup_txt from ietf.doc.models import DocAlias, RelatedDocument, BallotType, DocReminder @@ -377,3 +378,18 @@ def rebuild_reference_relations(doc): ret['unfound']=list(unfound) return ret + +def check_common_doc_name_rules(name): + """Check common rules for document names for use in forms, throws + ValidationError in case there's a problem.""" + + errors = [] + if re.search("[^a-z0-9-]", name): + errors.append("The name may only contain digits, lowercase letters and dashes.") + if re.search("--", name): + errors.append("Please do not put more than one hyphen between any two words in the name.") + if re.search("-[0-9]{2}$", name): + errors.append("This name looks like ends in a version number. -00 will be added automatically. Please adjust the end of the name.") + + if errors: + raise ValidationError(errors) diff --git a/ietf/doc/views_material.py b/ietf/doc/views_material.py index 235fcbb08..ae8efa1c7 100644 --- a/ietf/doc/views_material.py +++ b/ietf/doc/views_material.py @@ -1,6 +1,7 @@ # views for managing group materials (slides, ...) import os import datetime +import re from django import forms from django.shortcuts import render, get_object_or_404, redirect @@ -14,7 +15,7 @@ import debug # pyflakes:ignore from ietf.doc.models import Document, DocAlias, DocTypeName, DocEvent, State from ietf.doc.models import NewRevisionDocEvent, save_document_in_history -from ietf.doc.utils import add_state_change_event +from ietf.doc.utils import add_state_change_event, check_common_doc_name_rules from ietf.group.models import Group from ietf.group.utils import can_manage_materials @@ -34,6 +35,7 @@ def name_for_material(doc_type, group, title): class UploadMaterialForm(forms.Form): title = forms.CharField(max_length=Document._meta.get_field("title").max_length) + name = forms.CharField(max_length=Document._meta.get_field("name").max_length) state = forms.ModelChoiceField(State.objects.all(), empty_label=None) material = forms.FileField(label='File', help_text="PDF or text file (ASCII/UTF-8)") @@ -50,7 +52,10 @@ class UploadMaterialForm(forms.Form): self.fields["state"].widget = forms.HiddenInput() self.fields["state"].queryset = self.fields["state"].queryset.filter(slug="active") self.fields["state"].initial = self.fields["state"].queryset[0].pk + self.fields["name"].initial = u"%s-%s-" % (doc_type.slug, group.acronym) else: + del self.fields["name"] + self.fields["title"].initial = doc.title self.fields["state"].initial = doc.get_state().pk if doc.get_state() else None if doc.get_state_slug() == "deleted": @@ -63,16 +68,20 @@ class UploadMaterialForm(forms.Form): del self.fields["title"] del self.fields["material"] - def clean_title(self): - title = self.cleaned_data["title"] - if self.action == "new": - name = name_for_material(self.doc_type, self.group, title) - existing = Document.objects.filter(type=self.doc_type, name=name) - if existing: - url = urlreverse("material_edit", kwargs={ 'name': existing[0].name, 'action': 'revise' }) - raise forms.ValidationError(mark_safe("Can't upload: %s with name %s already exists. The name is derived from the title so you must either choose another title for what you're uploading or revise the existing %s." % (self.doc_type.name, name, url, name))) + def clean_name(self): + name = self.cleaned_data["name"].strip().rstrip("-") - return title + check_common_doc_name_rules(name) + + if not re.search("^%s-%s-[a-z0-9]+" % (self.doc_type.slug, self.group.acronym), name): + raise forms.ValidationError("The name must start with %s-%s- followed by descriptive dash-separated words." % (self.doc_type.slug, self.group.acronym)) + + existing = Document.objects.filter(type=self.doc_type, name=name) + if existing: + url = urlreverse("material_edit", kwargs={ 'name': existing[0].name, 'action': 'revise' }) + raise forms.ValidationError(mark_safe("Can't upload: %s with name %s already exists. Choose another title and name for what you're uploading or revise the existing %s." % (self.doc_type.name, name, url, name))) + + return name @login_required def edit_material(request, name=None, acronym=None, action=None, doc_type=None): diff --git a/ietf/group/tests_info.py b/ietf/group/tests_info.py index daa838e59..802eb6442 100644 --- a/ietf/group/tests_info.py +++ b/ietf/group/tests_info.py @@ -193,7 +193,7 @@ class GroupPagesTests(TestCase): self.assertTrue(milestone.docs.all()[0].name in r.content) def test_group_about(self): - draft = make_test_data() + make_test_data() group = Group.objects.create( type_id="team", acronym="testteam", @@ -210,7 +210,7 @@ class GroupPagesTests(TestCase): self.assertTrue(group.description in r.content) def test_materials(self): - draft = make_test_data() + make_test_data() group = Group.objects.create(type_id="team", acronym="testteam", name="Test Team", state_id="active") doc = Document.objects.create( diff --git a/ietf/group/utils.py b/ietf/group/utils.py index c4de6a8a7..d35df624f 100644 --- a/ietf/group/utils.py +++ b/ietf/group/utils.py @@ -1,6 +1,5 @@ import os -from django.conf import settings from django.shortcuts import get_object_or_404 from ietf.group.models import Group, RoleHistory diff --git a/ietf/templates/base.html b/ietf/templates/base.html index f9025f31f..02e765690 100644 --- a/ietf/templates/base.html +++ b/ietf/templates/base.html @@ -61,7 +61,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
{% if user.is_authenticated %} {{ user }} {% else %} -Sign In +Sign In {% endif %}
{% endif %} diff --git a/ietf/templates/doc/material/edit_material.html b/ietf/templates/doc/material/edit_material.html index b6cf6ab35..735761e50 100644 --- a/ietf/templates/doc/material/edit_material.html +++ b/ietf/templates/doc/material/edit_material.html @@ -5,7 +5,7 @@ {% block morecss %} {{ block.super }} form.upload-material td { padding-bottom: 0.6em; } -form.upload-material #id_title { width: 30em; } +form.upload-material #id_title, form.upload-material #id_name { width: 30em; } form.upload-material .submit-row td { padding-top: 1em; text-align: right; } {% endblock %} @@ -31,7 +31,7 @@ form.upload-material .submit-row td { padding-top: 1em; text-align: right; }

Upload New Revision

{% endif %} -
{% csrf_token %} +{% csrf_token %} {{ form.as_table }} @@ -45,3 +45,14 @@ form.upload-material .submit-row td { padding-top: 1em; text-align: right; } {% endblock content %} + +{% block scripts %} + jQuery(document).ready(function () { + jQuery("form.upload-material input#id_title").on("change keyup", function () { + var v = jQuery(this).val(); + var slug = jQuery(this).parents("form").data("nameprefix"); + slug += v.toLowerCase().replace(/ /g,'-').replace(/[-]+/g, '-').replace(/[^a-z-]+/g,''); + jQuery(this).parents("form").find("input#id_name").val(slug); + }); + }); +{% endblock %} diff --git a/ietf/utils/tests.py b/ietf/utils/tests.py index c6e087128..8f58e2c79 100644 --- a/ietf/utils/tests.py +++ b/ietf/utils/tests.py @@ -11,6 +11,7 @@ from ietf.utils.test_utils import TestCase class PyFlakesTestCase(TestCase): def test_pyflakes(self): + self.maxDiff = None path = os.path.join(settings.BASE_DIR) warnings = [] warnings = pyflakes.checkPaths([path], verbosity=0)