Skip to content

Commit f9ee750

Browse files
committed
Make it possible to adjust the name of new materials upon upload, also fix a couple of warnings from PyFlakes
- Legacy-Id: 7914
1 parent 602feff commit f9ee750

8 files changed

Lines changed: 57 additions & 20 deletions

File tree

ietf/doc/tests_material.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Copyright The IETF Trust 2011, All Rights Reserved
22

3-
import os, shutil, datetime
3+
import os, shutil
44
from StringIO import StringIO
55
from pyquery import PyQuery
66

@@ -10,7 +10,6 @@
1010
from ietf.doc.models import Document, State, DocAlias
1111
from ietf.group.models import Group
1212
from ietf.utils.test_utils import TestCase, login_testing_unauthorized
13-
from ietf.utils.test_data import make_test_data
1413

1514
class GroupMaterialTests(TestCase):
1615
def setUp(self):
@@ -57,7 +56,7 @@ def test_upload_slides(self):
5756
test_file.name = "unnamed.pdf"
5857

5958
# faulty post
60-
r = self.client.post(url, dict(title="", state="", material=test_file))
59+
r = self.client.post(url, dict(title="", name="", state="", material=test_file))
6160

6261
self.assertEqual(r.status_code, 200)
6362
q = PyQuery(r.content)
@@ -67,6 +66,7 @@ def test_upload_slides(self):
6766

6867
# post
6968
r = self.client.post(url, dict(title="Test File",
69+
name="slides-%s-test-file" % group.acronym,
7070
state=State.objects.get(type="slides", slug="active").pk,
7171
material=test_file))
7272
self.assertEqual(r.status_code, 302)
@@ -79,10 +79,11 @@ def test_upload_slides(self):
7979
with open(os.path.join(self.materials_dir, "slides", doc.name + "-" + doc.rev + ".pdf")) as f:
8080
self.assertEqual(f.read(), content)
8181

82-
# check that posting same title is prevented
82+
# check that posting same name is prevented
8383
test_file.seek(0)
8484

8585
r = self.client.post(url, dict(title="Test File",
86+
name=doc.name,
8687
state=State.objects.get(type="slides", slug="active").pk,
8788
material=test_file))
8889
self.assertEqual(r.status_code, 200)

ietf/doc/utils.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import math
55

66
from django.conf import settings
7+
from django.forms import ValidationError
78

89
from ietf.utils import markup_txt
910
from ietf.doc.models import DocAlias, RelatedDocument, BallotType, DocReminder
@@ -377,3 +378,18 @@ def rebuild_reference_relations(doc):
377378
ret['unfound']=list(unfound)
378379

379380
return ret
381+
382+
def check_common_doc_name_rules(name):
383+
"""Check common rules for document names for use in forms, throws
384+
ValidationError in case there's a problem."""
385+
386+
errors = []
387+
if re.search("[^a-z0-9-]", name):
388+
errors.append("The name may only contain digits, lowercase letters and dashes.")
389+
if re.search("--", name):
390+
errors.append("Please do not put more than one hyphen between any two words in the name.")
391+
if re.search("-[0-9]{2}$", name):
392+
errors.append("This name looks like ends in a version number. -00 will be added automatically. Please adjust the end of the name.")
393+
394+
if errors:
395+
raise ValidationError(errors)

ietf/doc/views_material.py

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# views for managing group materials (slides, ...)
22
import os
33
import datetime
4+
import re
45

56
from django import forms
67
from django.shortcuts import render, get_object_or_404, redirect
@@ -14,7 +15,7 @@
1415

1516
from ietf.doc.models import Document, DocAlias, DocTypeName, DocEvent, State
1617
from ietf.doc.models import NewRevisionDocEvent, save_document_in_history
17-
from ietf.doc.utils import add_state_change_event
18+
from ietf.doc.utils import add_state_change_event, check_common_doc_name_rules
1819
from ietf.group.models import Group
1920
from ietf.group.utils import can_manage_materials
2021

@@ -34,6 +35,7 @@ def name_for_material(doc_type, group, title):
3435

3536
class UploadMaterialForm(forms.Form):
3637
title = forms.CharField(max_length=Document._meta.get_field("title").max_length)
38+
name = forms.CharField(max_length=Document._meta.get_field("name").max_length)
3739
state = forms.ModelChoiceField(State.objects.all(), empty_label=None)
3840
material = forms.FileField(label='File', help_text="PDF or text file (ASCII/UTF-8)")
3941

@@ -50,7 +52,10 @@ def __init__(self, doc_type, action, group, doc, *args, **kwargs):
5052
self.fields["state"].widget = forms.HiddenInput()
5153
self.fields["state"].queryset = self.fields["state"].queryset.filter(slug="active")
5254
self.fields["state"].initial = self.fields["state"].queryset[0].pk
55+
self.fields["name"].initial = u"%s-%s-" % (doc_type.slug, group.acronym)
5356
else:
57+
del self.fields["name"]
58+
5459
self.fields["title"].initial = doc.title
5560
self.fields["state"].initial = doc.get_state().pk if doc.get_state() else None
5661
if doc.get_state_slug() == "deleted":
@@ -63,16 +68,20 @@ def __init__(self, doc_type, action, group, doc, *args, **kwargs):
6368
del self.fields["title"]
6469
del self.fields["material"]
6570

66-
def clean_title(self):
67-
title = self.cleaned_data["title"]
68-
if self.action == "new":
69-
name = name_for_material(self.doc_type, self.group, title)
70-
existing = Document.objects.filter(type=self.doc_type, name=name)
71-
if existing:
72-
url = urlreverse("material_edit", kwargs={ 'name': existing[0].name, 'action': 'revise' })
73-
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 <a href=\"%s\">revise the existing %s</a>." % (self.doc_type.name, name, url, name)))
71+
def clean_name(self):
72+
name = self.cleaned_data["name"].strip().rstrip("-")
73+
74+
check_common_doc_name_rules(name)
75+
76+
if not re.search("^%s-%s-[a-z0-9]+" % (self.doc_type.slug, self.group.acronym), name):
77+
raise forms.ValidationError("The name must start with %s-%s- followed by descriptive dash-separated words." % (self.doc_type.slug, self.group.acronym))
78+
79+
existing = Document.objects.filter(type=self.doc_type, name=name)
80+
if existing:
81+
url = urlreverse("material_edit", kwargs={ 'name': existing[0].name, 'action': 'revise' })
82+
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 <a href=\"%s\">revise the existing %s</a>." % (self.doc_type.name, name, url, name)))
7483

75-
return title
84+
return name
7685

7786
@login_required
7887
def edit_material(request, name=None, acronym=None, action=None, doc_type=None):

ietf/group/tests_info.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ def test_group_charter(self):
193193
self.assertTrue(milestone.docs.all()[0].name in r.content)
194194

195195
def test_group_about(self):
196-
draft = make_test_data()
196+
make_test_data()
197197
group = Group.objects.create(
198198
type_id="team",
199199
acronym="testteam",
@@ -210,7 +210,7 @@ def test_group_about(self):
210210
self.assertTrue(group.description in r.content)
211211

212212
def test_materials(self):
213-
draft = make_test_data()
213+
make_test_data()
214214
group = Group.objects.create(type_id="team", acronym="testteam", name="Test Team", state_id="active")
215215

216216
doc = Document.objects.create(

ietf/group/utils.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import os
22

3-
from django.conf import settings
43
from django.shortcuts import get_object_or_404
54

65
from ietf.group.models import Group, RoleHistory

ietf/templates/base.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@
6161
<div id="ietf-login" class="noprint">{% if user.is_authenticated %}
6262
{{ user }}
6363
{% else %}
64-
<a href="https://{{ request.get_host }}/accounts/login/?next={{request.get_full_path|urlencode}}" rel="nofollow">Sign In</a>
64+
<a href="//{{ request.get_host }}/accounts/login/?next={{request.get_full_path|urlencode}}" rel="nofollow">Sign In</a>
6565
{% endif %}</div>
6666
{% endif %}
6767

ietf/templates/doc/material/edit_material.html

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
{% block morecss %}
66
{{ block.super }}
77
form.upload-material td { padding-bottom: 0.6em; }
8-
form.upload-material #id_title { width: 30em; }
8+
form.upload-material #id_title, form.upload-material #id_name { width: 30em; }
99
form.upload-material .submit-row td { padding-top: 1em; text-align: right; }
1010
{% endblock %}
1111

@@ -31,7 +31,7 @@ <h3>Upload</h3>
3131
<h3>Upload New Revision</h3>
3232
{% endif %}
3333

34-
<form class="upload-material" method="post" enctype="multipart/form-data">{% csrf_token %}
34+
<form class="upload-material" method="post" enctype="multipart/form-data" data-nameprefix="{{ document_type.slug }}-{{ group.acronym }}-">{% csrf_token %}
3535
<table>
3636
{{ form.as_table }}
3737

@@ -45,3 +45,14 @@ <h3>Upload New Revision</h3>
4545
</form>
4646

4747
{% endblock content %}
48+
49+
{% block scripts %}
50+
jQuery(document).ready(function () {
51+
jQuery("form.upload-material input#id_title").on("change keyup", function () {
52+
var v = jQuery(this).val();
53+
var slug = jQuery(this).parents("form").data("nameprefix");
54+
slug += v.toLowerCase().replace(/ /g,'-').replace(/[-]+/g, '-').replace(/[^a-z-]+/g,'');
55+
jQuery(this).parents("form").find("input#id_name").val(slug);
56+
});
57+
});
58+
{% endblock %}

ietf/utils/tests.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
class PyFlakesTestCase(TestCase):
1212

1313
def test_pyflakes(self):
14+
self.maxDiff = None
1415
path = os.path.join(settings.BASE_DIR)
1516
warnings = []
1617
warnings = pyflakes.checkPaths([path], verbosity=0)

0 commit comments

Comments
 (0)