From aa5e61d958b48996379c35f588bc01b03f2b8edb Mon Sep 17 00:00:00 2001 From: Henrik Levkowetz Date: Sat, 11 Feb 2017 14:43:01 +0000 Subject: [PATCH] Updated all urlpatterns to use ietf.utils.urls.url() instead of django's, in order to autogenerate dotted path url pattern names. Updated a number of url reverses to use dotted path, and removed explicit url pattern names as needed. Changed some imports to prevent import of ietf.urls before django initialization was complete. Changed 3 cases of form classes being curried to functions; django 1.10 didn't accept that. Started converting old-style middleware classes to new-style middleware functions (incomplete). Tweaked a nomcom decorator to preserve function names and attributes, like a good decorator should. Replaced the removed django templatetag 'removetags' with our own version which uses bleach, and does sanitizing in addition to removing explicitly mentionied html tags. Rewrote the filename argument handling in a management command which had broken with the upgrade. - Legacy-Id: 12818 --- ietf/community/models.py | 2 +- ietf/community/urls.py | 2 +- ietf/cookies/urls.py | 2 +- ietf/dbtemplate/urls.py | 2 +- ietf/doc/redirect_drafts_urls.py | 2 +- ietf/doc/redirect_idtracker_urls.py | 3 +- ietf/doc/tests_charter.py | 2 +- ietf/doc/tests_status_change.py | 4 +- ietf/doc/urls.py | 11 +++-- ietf/doc/urls_charter.py | 2 +- ietf/doc/urls_conflict_review.py | 2 +- ietf/doc/urls_material.py | 2 +- ietf/doc/urls_review.py | 2 +- ietf/doc/urls_status_change.py | 4 +- ietf/doc/views_ballot.py | 6 +-- ietf/doc/views_doc.py | 8 ++-- ietf/group/admin.py | 2 +- ietf/group/features.py | 8 ++-- ietf/group/tests_info.py | 12 ++--- ietf/group/urls.py | 7 +-- ietf/group/urls_info.py | 5 +- ietf/group/urls_info_details.py | 14 +++--- ietf/group/urls_stream.py | 4 +- ietf/group/utils.py | 6 +-- ietf/help/urls.py | 2 +- ietf/iesg/urls.py | 2 +- ietf/ietfauth/urls.py | 2 +- ietf/ipr/feeds.py | 2 +- ietf/ipr/models.py | 2 +- ietf/ipr/tests.py | 14 +++--- ietf/ipr/urls.py | 14 +++--- ietf/ipr/views.py | 16 ++++--- ietf/liaisons/urls.py | 2 +- ietf/mailinglists/urls.py | 2 +- ietf/mailtrigger/urls.py | 6 +-- ietf/meeting/tests_js.py | 3 +- ietf/meeting/urls.py | 10 ++-- ietf/meeting/views.py | 24 +++++----- ietf/message/tests.py | 2 +- ietf/middleware.py | 15 ++++++ ietf/nomcom/decorators.py | 4 +- ietf/nomcom/redirect_ann_urls.py | 3 +- ietf/nomcom/tests.py | 10 ++-- ietf/nomcom/urls.py | 8 ++-- ietf/nomcom/views.py | 8 ++-- ietf/person/fields.py | 2 +- ietf/person/urls.py | 4 +- ietf/redirects/urls.py | 2 +- ietf/release/urls.py | 2 +- ietf/secr/announcement/urls.py | 2 +- ietf/secr/areas/urls.py | 2 +- ietf/secr/console/urls.py | 2 +- ietf/secr/drafts/urls.py | 2 +- ietf/secr/groups/urls.py | 2 +- ietf/secr/meetings/urls.py | 4 +- ietf/secr/proceedings/urls.py | 2 +- ietf/secr/roles/urls.py | 2 +- ietf/secr/rolodex/urls.py | 2 +- ietf/secr/sreq/tests.py | 6 +-- ietf/secr/sreq/urls.py | 4 +- ietf/secr/sreq/views.py | 8 ++-- ietf/secr/telechat/urls.py | 2 +- ietf/secr/templates/meetings/times.html | 2 +- ietf/secr/templates/sreq/main.html | 2 +- ietf/secr/templates/sreq/new.html | 2 +- ietf/submit/urls.py | 2 +- ietf/sync/urls.py | 2 +- ietf/templates/base/menu.html | 2 +- ietf/templates/doc/charter/submit.html | 2 +- .../doc/document_ballot_content.html | 2 +- ietf/templates/doc/document_draft.html | 2 +- .../templates/doc/document_status_change.html | 2 +- .../templates/doc/material/edit_material.html | 6 +-- .../doc/search/search_result_row.html | 2 +- .../status_change/last_call_announcement.txt | 2 +- ietf/templates/group/bofs.html | 2 +- ietf/templates/group/chartering_groups.html | 2 +- ietf/templates/ipr/state.html | 2 +- ietf/templates/meeting/agenda.html | 3 +- ietf/templates/nomcom/announcements.html | 2 +- ietf/templates/nomcom/edit_nominee.html | 2 +- .../templates/nomcom/nomcom_private_base.html | 2 +- ietf/templates/nomcom/private_index.html | 2 +- ietf/templates/nomcom/view_feedback.html | 2 +- ietf/utils/html.py | 47 ++++++++++++------- .../management/commands/coverage_changes.py | 6 ++- ietf/utils/test_runner.py | 33 ++++++++----- ietf/utils/tests.py | 3 +- ietf/utils/urls.py | 20 ++++---- requirements.txt | 1 + 90 files changed, 267 insertions(+), 207 deletions(-) diff --git a/ietf/community/models.py b/ietf/community/models.py index 6839801ce..b2df5c663 100644 --- a/ietf/community/models.py +++ b/ietf/community/models.py @@ -28,7 +28,7 @@ class CommunityList(models.Model): if self.user: return urlreverse(ietf.community.views.view_list, kwargs={ 'username': self.user.username }) elif self.group: - return urlreverse("group_docs", kwargs={ 'acronym': self.group.acronym }) + return urlreverse("ietf.group.views.group_documents", kwargs={ 'acronym': self.group.acronym }) return "" diff --git a/ietf/community/urls.py b/ietf/community/urls.py index d07c37475..f80547ffa 100644 --- a/ietf/community/urls.py +++ b/ietf/community/urls.py @@ -1,7 +1,7 @@ -from django.conf.urls import url from ietf.community import views +from ietf.utils.urls import url urlpatterns = [ url(r'^personal/(?P[^/]+)/$', views.view_list), diff --git a/ietf/cookies/urls.py b/ietf/cookies/urls.py index 1e8c4518e..1d4fa8be9 100644 --- a/ietf/cookies/urls.py +++ b/ietf/cookies/urls.py @@ -1,7 +1,7 @@ # Copyright The IETF Trust 2010, All Rights Reserved -from django.conf.urls import url from ietf.cookies import views +from ietf.utils.urls import url urlpatterns = [ url(r'^$', views.preferences), diff --git a/ietf/dbtemplate/urls.py b/ietf/dbtemplate/urls.py index 3d878422a..86bba648e 100644 --- a/ietf/dbtemplate/urls.py +++ b/ietf/dbtemplate/urls.py @@ -1,7 +1,7 @@ -from django.conf.urls import url from ietf.dbtemplate import views +from ietf.utils.urls import url urlpatterns = [ url(r'^(?P[-a-z0-9]+)/$', views.template_list, name='template_list'), diff --git a/ietf/doc/redirect_drafts_urls.py b/ietf/doc/redirect_drafts_urls.py index 8e3d415bd..42e4c6c27 100644 --- a/ietf/doc/redirect_drafts_urls.py +++ b/ietf/doc/redirect_drafts_urls.py @@ -1,11 +1,11 @@ # Copyright The IETF Trust 2007, All Rights Reserved -from django.conf.urls import url from django.views.generic import RedirectView from django.http import HttpResponsePermanentRedirect from django.shortcuts import get_object_or_404 from ietf.group.models import Group +from ietf.utils.urls import url urlpatterns = [ url(r'^$', RedirectView.as_view(url='/doc/', permanent=True)), diff --git a/ietf/doc/redirect_idtracker_urls.py b/ietf/doc/redirect_idtracker_urls.py index e9214c525..8feefbc64 100644 --- a/ietf/doc/redirect_idtracker_urls.py +++ b/ietf/doc/redirect_idtracker_urls.py @@ -1,6 +1,7 @@ -from django.conf.urls import url from django.views.generic import RedirectView +from ietf.utils.urls import url + urlpatterns = [ url(r'^help/(?:sub)?state/(?:\d+/)?$', RedirectView.as_view(url='/doc/help/state/draft-iesg/', permanent=True)), url(r'^help/evaluation/$', RedirectView.as_view(url='https://www.ietf.org/iesg/voting-procedures.html', permanent=True)), diff --git a/ietf/doc/tests_charter.py b/ietf/doc/tests_charter.py index 5efaf27a8..62e03dfe3 100644 --- a/ietf/doc/tests_charter.py +++ b/ietf/doc/tests_charter.py @@ -559,7 +559,7 @@ class EditCharterTests(TestCase): self.assertTrue("approved" in outbox[0]['Subject'].lower()) self.assertTrue("iesg-secretary" in outbox[0]['To']) body = outbox[0].get_payload() - for word in ["WG", "/wg/ames/charter/", + for word in ["WG", "/wg/ames/about/", "Charter", "/doc/charter-ietf-ames/", ]: self.assertIn(word, body) # diff --git a/ietf/doc/tests_status_change.py b/ietf/doc/tests_status_change.py index 6ae7b2285..b296683bd 100644 --- a/ietf/doc/tests_status_change.py +++ b/ietf/doc/tests_status_change.py @@ -77,7 +77,7 @@ class StatusChangeTests(TestCase): def test_change_state(self): doc = Document.objects.get(name='status-change-imaginary-mid-review') - url = urlreverse('status_change_change_state',kwargs=dict(name=doc.name)) + url = urlreverse('ietf.doc.views_status_change.change_state',kwargs=dict(name=doc.name)) login_testing_unauthorized(self, "ad", url) @@ -432,7 +432,7 @@ class StatusChangeSubmitTests(TestCase): f.write('This is the old proposal.') f.close() # Put the old proposal into IESG review (exercises ballot tab when looking at an older revision below) - state_change_url = urlreverse('status_change_change_state',kwargs=dict(name=doc.name)) + state_change_url = urlreverse('ietf.doc.views_status_change.change_state',kwargs=dict(name=doc.name)) iesgeval_pk = str(State.objects.get(slug='iesgeval',type__slug='statchg').pk) r = self.client.post(state_change_url,dict(new_state=iesgeval_pk)) self.assertEqual(r.status_code, 302) diff --git a/ietf/doc/urls.py b/ietf/doc/urls.py index cacb9c44d..4ebd4bbbe 100644 --- a/ietf/doc/urls.py +++ b/ietf/doc/urls.py @@ -30,11 +30,12 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -from django.conf.urls import url, include +from django.conf.urls import include from django.views.generic import RedirectView from django.conf import settings from ietf.doc import views_search, views_draft, views_ballot, views_status_change, views_doc, views_stats, views_help +from ietf.utils.urls import url session_patterns = [ url(r'^add$', views_doc.add_sessionpresentation), @@ -67,19 +68,19 @@ urlpatterns = [ url(r'^%(name)s/(?:%(rev)s/)?bibtex/$' % settings.URL_REGEXPS, views_doc.document_bibtex), url(r'^%(name)s/history/$' % settings.URL_REGEXPS, views_doc.document_history, name="doc_history"), url(r'^%(name)s/writeup/$' % settings.URL_REGEXPS, views_doc.document_writeup, name="doc_writeup"), - url(r'^%(name)s/email/$' % settings.URL_REGEXPS, views_doc.document_email, name="doc_email"), + url(r'^%(name)s/email/$' % settings.URL_REGEXPS, views_doc.document_email, name="ietf.doc.views_doc.document_email"), url(r'^%(name)s/shepherdwriteup/$' % settings.URL_REGEXPS, views_doc.document_shepherd_writeup, name="doc_shepherd_writeup"), url(r'^%(name)s/references/$' % settings.URL_REGEXPS, views_doc.document_references, name="doc_references"), url(r'^%(name)s/referencedby/$' % settings.URL_REGEXPS, views_doc.document_referenced_by, name="doc_referenced_by"), - url(r'^%(name)s/ballot/$' % settings.URL_REGEXPS, views_doc.document_ballot, name="doc_ballot"), - url(r'^%(name)s/ballot/(?P[0-9]+)/$' % settings.URL_REGEXPS, views_doc.document_ballot, name="doc_ballot"), + url(r'^%(name)s/ballot/$' % settings.URL_REGEXPS, views_doc.document_ballot), + url(r'^%(name)s/ballot/(?P[0-9]+)/$' % settings.URL_REGEXPS, views_doc.document_ballot), url(r'^%(name)s/ballot/(?P[0-9]+)/position/$' % settings.URL_REGEXPS, views_ballot.edit_position), url(r'^%(name)s/ballot/(?P[0-9]+)/emailposition/$' % settings.URL_REGEXPS, views_ballot.send_ballot_comment, name='doc_send_ballot_comment'), url(r'^%(name)s/(?:%(rev)s/)?doc.json$' % settings.URL_REGEXPS, views_doc.document_json), url(r'^%(name)s/ballotpopup/(?P[0-9]+)/$' % settings.URL_REGEXPS, views_doc.ballot_popup), url(r'^(?P[A-Za-z0-9._+-]+)/reviewrequest/', include("ietf.doc.urls_review")), - url(r'^%(name)s/email-aliases/$' % settings.URL_REGEXPS, RedirectView.as_view(pattern_name='doc_email', permanent=False),name='doc_specific_email_aliases'), + url(r'^%(name)s/email-aliases/$' % settings.URL_REGEXPS, RedirectView.as_view(pattern_name='ietf.doc.views_doc.document_email', permanent=False),name='doc_specific_email_aliases'), url(r'^%(name)s/edit/state/$' % settings.URL_REGEXPS, views_draft.change_state, name='doc_change_state'), # IESG state url(r'^%(name)s/edit/state/(?Piana-action|iana-review)/$' % settings.URL_REGEXPS, views_draft.change_iana_state, name='doc_change_iana_state'), diff --git a/ietf/doc/urls_charter.py b/ietf/doc/urls_charter.py index ce3448d85..51e95718a 100644 --- a/ietf/doc/urls_charter.py +++ b/ietf/doc/urls_charter.py @@ -1,9 +1,9 @@ # Copyright The IETF Trust 2011, All Rights Reserved -from django.conf.urls import url from django.conf import settings from ietf.doc import views_charter, views_doc +from ietf.utils.urls import url urlpatterns = [ url(r'^state/$', views_charter.change_state, name='charter_change_state'), diff --git a/ietf/doc/urls_conflict_review.py b/ietf/doc/urls_conflict_review.py index 4125b3dd8..5c008a87e 100644 --- a/ietf/doc/urls_conflict_review.py +++ b/ietf/doc/urls_conflict_review.py @@ -1,6 +1,6 @@ -from django.conf.urls import url from ietf.doc import views_conflict_review, views_doc +from ietf.utils.urls import url urlpatterns = [ url(r'^state/$', views_conflict_review.change_state, name='conflict_review_change_state'), diff --git a/ietf/doc/urls_material.py b/ietf/doc/urls_material.py index 97942bc31..a637ae7e0 100644 --- a/ietf/doc/urls_material.py +++ b/ietf/doc/urls_material.py @@ -1,6 +1,6 @@ -from django.conf.urls import url from ietf.doc import views_material +from ietf.utils.urls import url urlpatterns = [ url(r'^(?Pstate|title|abstract|revise)/$', views_material.edit_material, name="material_edit"), diff --git a/ietf/doc/urls_review.py b/ietf/doc/urls_review.py index e8ec5c6a8..3feb8c419 100644 --- a/ietf/doc/urls_review.py +++ b/ietf/doc/urls_review.py @@ -1,5 +1,5 @@ -from django.conf.urls import url from ietf.doc import views_review +from ietf.utils.urls import url urlpatterns = [ url(r'^$', views_review.request_review), diff --git a/ietf/doc/urls_status_change.py b/ietf/doc/urls_status_change.py index 278adb101..00b59035b 100644 --- a/ietf/doc/urls_status_change.py +++ b/ietf/doc/urls_status_change.py @@ -1,9 +1,9 @@ -from django.conf.urls import url from ietf.doc import views_status_change, views_doc +from ietf.utils.urls import url urlpatterns = [ - url(r'^state/$', views_status_change.change_state, name='status_change_change_state'), + url(r'^state/$', views_status_change.change_state), url(r'^submit/$', views_status_change.submit, name='status_change_submit'), url(r'^ad/$', views_status_change.edit_ad, name='status_change_ad'), url(r'^title/$', views_status_change.edit_title, name='status_change_title'), diff --git a/ietf/doc/views_ballot.py b/ietf/doc/views_ballot.py index ad5d4213e..cbaea134f 100644 --- a/ietf/doc/views_ballot.py +++ b/ietf/doc/views_ballot.py @@ -116,7 +116,7 @@ def edit_position(request, name, ballot_id): if 'ballot_edit_return_point' in request.session: return_to_url = request.session['ballot_edit_return_point'] else: - return_to_url = urlreverse("doc_ballot", kwargs=dict(name=doc.name, ballot_id=ballot_id)) + return_to_url = urlreverse("ietf.doc.views_doc.document_ballot", kwargs=dict(name=doc.name, ballot_id=ballot_id)) # if we're in the Secretariat, we can select an AD to act as stand-in for if has_role(request.user, "Secretariat"): @@ -245,12 +245,12 @@ def send_ballot_comment(request, name, ballot_id): if 'ballot_edit_return_point' in request.session: return_to_url = request.session['ballot_edit_return_point'] else: - return_to_url = urlreverse("doc_ballot", kwargs=dict(name=doc.name, ballot_id=ballot_id)) + return_to_url = urlreverse("ietf.doc.views_doc.document_ballot", kwargs=dict(name=doc.name, ballot_id=ballot_id)) if 'HTTP_REFERER' in request.META: back_url = request.META['HTTP_REFERER'] else: - back_url = urlreverse("doc_ballot", kwargs=dict(name=doc.name, ballot_id=ballot_id)) + back_url = urlreverse("ietf.doc.views_doc.document_ballot", kwargs=dict(name=doc.name, ballot_id=ballot_id)) # if we're in the Secretariat, we can select an AD to act as stand-in for if not has_role(request.user, "Area Director"): diff --git a/ietf/doc/views_doc.py b/ietf/doc/views_doc.py index f3738181a..9d64e9c0d 100644 --- a/ietf/doc/views_doc.py +++ b/ietf/doc/views_doc.py @@ -73,14 +73,14 @@ def render_document_top(request, doc, tab, name): ballot = doc.latest_event(BallotDocEvent, type="created_ballot") if doc.type_id in ("draft","conflrev", "statchg"): - tabs.append(("IESG Evaluation Record", "ballot", urlreverse("doc_ballot", kwargs=dict(name=name)), ballot, None if ballot else "IESG Evaluation Ballot has not been created yet")) + tabs.append(("IESG Evaluation Record", "ballot", urlreverse("ietf.doc.views_doc.document_ballot", kwargs=dict(name=name)), ballot, None if ballot else "IESG Evaluation Ballot has not been created yet")) elif doc.type_id == "charter" and doc.group.type_id == "wg": - tabs.append(("IESG Review", "ballot", urlreverse("doc_ballot", kwargs=dict(name=name)), ballot, None if ballot else "IESG Review Ballot has not been created yet")) + tabs.append(("IESG Review", "ballot", urlreverse("ietf.doc.views_doc.document_ballot", kwargs=dict(name=name)), ballot, None if ballot else "IESG Review Ballot has not been created yet")) if doc.type_id == "draft" or (doc.type_id == "charter" and doc.group.type_id == "wg"): tabs.append(("IESG Writeups", "writeup", urlreverse("doc_writeup", kwargs=dict(name=name)), True, None)) - tabs.append(("Email expansions","email",urlreverse("doc_email", kwargs=dict(name=name)), True, None)) + tabs.append(("Email expansions","email",urlreverse("ietf.doc.views_doc.document_email", kwargs=dict(name=name)), True, None)) tabs.append(("History", "history", urlreverse("doc_history", kwargs=dict(name=name)), True, None)) if name.startswith("rfc"): @@ -260,7 +260,7 @@ def document_main(request, name, rev=None): elif group.type_id in ("rg", "wg"): submission = "%s %s" % (group.acronym, group.type) if group.type_id == "wg": - submission = "%s" % (urlreverse("group_home", kwargs=dict(group_type=group.type_id, acronym=group.acronym)), submission) + submission = "%s" % (urlreverse("ietf.group.views.group_home", kwargs=dict(group_type=group.type_id, acronym=group.acronym)), submission) if doc.stream_id and doc.get_state_slug("draft-stream-%s" % doc.stream_id) == "c-adopt": submission = "candidate for %s" % submission diff --git a/ietf/group/admin.py b/ietf/group/admin.py index 6ebe70143..3d0a18dfa 100644 --- a/ietf/group/admin.py +++ b/ietf/group/admin.py @@ -41,7 +41,7 @@ class GroupAdmin(admin.ModelAdmin): # SDO reminder def get_urls(self): - from django.conf.urls import url + from ietf.utils.urls import url def wrap(view): def wrapper(*args, **kwargs): diff --git a/ietf/group/features.py b/ietf/group/features.py index d853c14bc..4c536374f 100644 --- a/ietf/group/features.py +++ b/ietf/group/features.py @@ -10,7 +10,7 @@ class GroupFeatures(object): has_reviews = False has_default_jabber = False customize_workflow = False - about_page = "group_about" + about_page = "ietf.group.views.group_about" default_tab = about_page material_types = ["slides"] admin_roles = ["chair"] @@ -23,10 +23,10 @@ class GroupFeatures(object): self.customize_workflow = True self.has_default_jabber = True self.has_dependencies = True - self.default_tab = "group_docs" + self.default_tab = "ietf.group.views.group_documents" elif group.type_id in ("team",): self.has_materials = True - self.default_tab = "group_about" + self.default_tab = "ietf.group.views.group_about" elif group.type_id in ("program",): self.has_documents = True self.has_milestones = True @@ -35,7 +35,7 @@ class GroupFeatures(object): self.admin_roles = ["chair", "secr"] if self.has_chartering_process: - self.about_page = "group_charter" + self.about_page = "ietf.group.views.group_about" from ietf.review.utils import active_review_teams if group in active_review_teams(): diff --git a/ietf/group/tests_info.py b/ietf/group/tests_info.py index a7481d12a..79e28a7ae 100644 --- a/ietf/group/tests_info.py +++ b/ietf/group/tests_info.py @@ -342,7 +342,7 @@ class GroupPagesTests(TestCase): self.assertTrue(doc.title in unicontent(r)) self.assertTrue(doc.name in unicontent(r)) - url = urlreverse("group_materials", kwargs={ 'acronym': group.acronym }) + url = urlreverse("ietf.group.views.materials", kwargs={ 'acronym': group.acronym }) # try deleting the document and check it's gone doc.set_state(State.objects.get(type="slides", slug="deleted")) @@ -429,7 +429,7 @@ class GroupEditTests(TestCase): def test_create(self): make_test_data() - url = urlreverse('group_create', kwargs=dict(group_type="wg")) + url = urlreverse('ietf.group.views_edit.edit', kwargs=dict(group_type="wg", action="charter")) login_testing_unauthorized(self, "secretary", url) num_wgs = len(Group.objects.filter(type="wg")) @@ -488,7 +488,7 @@ class GroupEditTests(TestCase): make_test_data() - url = urlreverse('group_create', kwargs=dict(group_type="rg")) + url = urlreverse('ietf.group.views_edit.edit', kwargs=dict(group_type="rg", action="charter")) login_testing_unauthorized(self, "secretary", url) irtf = Group.objects.get(acronym='irtf') @@ -513,7 +513,7 @@ class GroupEditTests(TestCase): def test_create_based_on_existing_bof(self): make_test_data() - url = urlreverse('group_create', kwargs=dict(group_type="wg")) + url = urlreverse('ietf.group.views_edit.edit', kwargs=dict(group_type="wg", action="charter")) login_testing_unauthorized(self, "secretary", url) group = Group.objects.get(acronym="mars") @@ -548,7 +548,7 @@ class GroupEditTests(TestCase): make_test_data() group = Group.objects.get(acronym="mars") - url = urlreverse('group_edit', kwargs=dict(group_type=group.type_id, acronym=group.acronym)) + url = urlreverse('ietf.group.views_edit.edit', kwargs=dict(group_type=group.type_id, acronym=group.acronym, action="edit")) login_testing_unauthorized(self, "secretary", url) # normal get @@ -625,7 +625,7 @@ class GroupEditTests(TestCase): review_req = make_review_data(doc) group = review_req.team - url = urlreverse('group_edit', kwargs=dict(group_type=group.type_id, acronym=group.acronym)) + url = urlreverse('ietf.group.views_edit.edit', kwargs=dict(group_type=group.type_id, acronym=group.acronym, action="edit")) login_testing_unauthorized(self, "secretary", url) # normal get diff --git a/ietf/group/urls.py b/ietf/group/urls.py index 3ccf275bf..e217098ef 100644 --- a/ietf/group/urls.py +++ b/ietf/group/urls.py @@ -1,20 +1,21 @@ # Copyright The IETF Trust 2007, All Rights Reserved -from django.conf.urls import url, include +from django.conf.urls import include from django.conf import settings from ietf.group import views, views_ajax, views_edit +from ietf.utils.urls import url urlpatterns = [ url(r'^$', views.active_groups), url(r'^groupmenu.json', views_ajax.group_menu_data, None, "group_menu_data"), url(r'^%(acronym)s.json$' % settings.URL_REGEXPS, views_ajax.group_json), url(r'^chartering/$', views.chartering_groups), - url(r'^chartering/create/(?P(wg|rg))/$', views_edit.edit, {'action': "charter"}, "group_create"), + url(r'^chartering/create/(?P(wg|rg))/$', views_edit.edit, {'action': "charter"}), url(r'^concluded/$', views.concluded_groups), url(r'^email-aliases/$', views.email_aliases), url(r'^all-status/$', views.all_status), - url(r'^%(acronym)s/$' % settings.URL_REGEXPS, views.group_home, None, "group_home"), + url(r'^%(acronym)s/$' % settings.URL_REGEXPS, views.group_home), url(r'^%(acronym)s/' % settings.URL_REGEXPS, include('ietf.group.urls_info_details')), ] diff --git a/ietf/group/urls_info.py b/ietf/group/urls_info.py index 7b5ce3f76..770268faa 100644 --- a/ietf/group/urls_info.py +++ b/ietf/group/urls_info.py @@ -1,10 +1,11 @@ # Copyright The IETF Trust 2008, All Rights Reserved -from django.conf.urls import url, include +from django.conf.urls import include from django.views.generic import RedirectView from django.conf import settings from ietf.group import views, views_edit +from ietf.utils.urls import url urlpatterns = [ url(r'^$', views.active_groups), @@ -19,7 +20,7 @@ urlpatterns = [ url(r'^chartering/create/$', RedirectView.as_view(url='/group/chartering/create/%(group_type)s/', permanent=True)), url(r'^bofs/$', views.bofs), url(r'^email-aliases/$', views.email_aliases), - url(r'^bofs/create/$', views_edit.edit, {'action': "create", }, "bof_create"), + url(r'^bofs/create/$', views_edit.edit, {'action': "create", }), url(r'^photos/$', views.chair_photos), url(r'^%(acronym)s/' % settings.URL_REGEXPS, include('ietf.group.urls_info_details')), ] diff --git a/ietf/group/urls_info_details.py b/ietf/group/urls_info_details.py index d2ef10e76..8bb4284b0 100644 --- a/ietf/group/urls_info_details.py +++ b/ietf/group/urls_info_details.py @@ -1,20 +1,20 @@ -from django.conf.urls import url from django.views.generic import RedirectView from ietf.community import views as community_views from ietf.doc import views_material as material_views from ietf.group import views, views_edit, views_review, milestones as milestone_views +from ietf.utils.urls import url urlpatterns = [ - url(r'^$', views.group_home, None, "group_home"), + url(r'^$', views.group_home), url(r'^documents/txt/$', views.group_documents_txt), - url(r'^documents/$', views.group_documents, None, "group_docs"), + url(r'^documents/$', views.group_documents), url(r'^documents/manage/$', community_views.manage_list), url(r'^documents/csv/$', community_views.export_to_csv), url(r'^documents/feed/$', community_views.feed), url(r'^documents/subscription/$', community_views.subscription), - url(r'^charter/$', views.group_about, None, 'group_charter'), - url(r'^about/$', views.group_about, None, 'group_about'), + url(r'^charter/$', views.group_about), + url(r'^about/$', views.group_about), url(r'^about/status/$', views.group_about_status), url(r'^about/status/edit/$', views.group_about_status_edit), url(r'^about/status/meeting/(?P\d+)/$', views.group_about_status_meeting), @@ -22,13 +22,13 @@ urlpatterns = [ url(r'^email/$', views.email), url(r'^deps/(?P[\w-]+)/$', views.dependencies), url(r'^meetings/$', views.meetings), - url(r'^edit/$', views_edit.edit, {'action': "edit"}, "group_edit"), + url(r'^edit/$', views_edit.edit, {'action': "edit"}), url(r'^conclude/$', views_edit.conclude), url(r'^milestones/$', milestone_views.edit_milestones, {'milestone_set': "current"}, "group_edit_milestones"), url(r'^milestones/charter/$', milestone_views.edit_milestones, {'milestone_set': "charter"}, "group_edit_charter_milestones"), url(r'^milestones/charter/reset/$', milestone_views.reset_charter_milestones, None, "group_reset_charter_milestones"), url(r'^workflow/$', views_edit.customize_workflow), - url(r'^materials/$', views.materials, None, "group_materials"), + url(r'^materials/$', views.materials), url(r'^materials/new/$', material_views.choose_material_type), url(r'^materials/new/(?P[\w-]+)/$', material_views.edit_material, { 'action': "new" }, "group_new_material"), url(r'^archives/$', views.derived_archives), diff --git a/ietf/group/urls_stream.py b/ietf/group/urls_stream.py index f19efbff8..a4c59d149 100644 --- a/ietf/group/urls_stream.py +++ b/ietf/group/urls_stream.py @@ -1,9 +1,9 @@ # Copyright The IETF Trust 2008, All Rights Reserved -from django.conf.urls import url from django.conf import settings -import views_stream +from ietf.group import views_stream +from ietf.utils.urls import url urlpatterns = [ url(r'^$', views_stream.streams), diff --git a/ietf/group/utils.py b/ietf/group/utils.py index af131ceeb..7e9c068a6 100644 --- a/ietf/group/utils.py +++ b/ietf/group/utils.py @@ -169,9 +169,9 @@ def construct_group_menu_context(request, group, selected, group_type, others): if group.features.has_documents: entries.append(("Documents", urlreverse("ietf.group.views.group_documents", kwargs=kwargs))) if group.features.has_chartering_process: - entries.append(("Charter", urlreverse("group_charter", kwargs=kwargs))) + entries.append(("Charter", urlreverse("ietf.group.views.group_about", kwargs=kwargs))) else: - entries.append(("About", urlreverse("group_about", kwargs=kwargs))) + entries.append(("About", urlreverse("ietf.group.views.group_about", kwargs=kwargs))) if group.features.has_materials and get_group_materials(group).exists(): entries.append(("Materials", urlreverse("ietf.group.views.materials", kwargs=kwargs))) if group.features.has_reviews: @@ -220,7 +220,7 @@ def construct_group_menu_context(request, group, selected, group_type, others): if group.state_id != "conclude" and (is_admin or can_manage): - actions.append((u"Edit group", urlreverse("group_edit", kwargs=kwargs))) + actions.append((u"Edit group", urlreverse("ietf.group.views_edit.edit", dict(kwargs, action="edit")))) if group.features.customize_workflow and (is_admin or can_manage): actions.append((u"Customize workflow", urlreverse("ietf.group.views_edit.customize_workflow", kwargs=kwargs))) diff --git a/ietf/help/urls.py b/ietf/help/urls.py index 48f92576e..26b65528d 100644 --- a/ietf/help/urls.py +++ b/ietf/help/urls.py @@ -1,6 +1,6 @@ -from django.conf.urls import url from ietf.help import views +from ietf.utils.urls import url urlpatterns = [ url(r'^state/(?P[-\w]+)/(?P[-\w]+)/?$', views.state), diff --git a/ietf/iesg/urls.py b/ietf/iesg/urls.py index fdcb2b8b3..e01b829ce 100644 --- a/ietf/iesg/urls.py +++ b/ietf/iesg/urls.py @@ -32,11 +32,11 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -from django.conf.urls import url from django.views.generic import RedirectView from django.conf import settings from ietf.iesg import views +from ietf.utils.urls import url urlpatterns = [ url(r'^telechat/.*$', RedirectView.as_view(url='https://www.ietf.org/iesg/minutes.html', permanent=True)), diff --git a/ietf/ietfauth/urls.py b/ietf/ietfauth/urls.py index ee278a4d4..deb11f8b2 100644 --- a/ietf/ietfauth/urls.py +++ b/ietf/ietfauth/urls.py @@ -1,9 +1,9 @@ # Copyright The IETF Trust 2007, 2009, All Rights Reserved -from django.conf.urls import url from django.contrib.auth.views import login, logout from ietf.ietfauth import views +from ietf.utils.urls import url urlpatterns = [ url(r'^$', views.index), diff --git a/ietf/ipr/feeds.py b/ietf/ipr/feeds.py index 13cd2425a..2e9a6f01f 100644 --- a/ietf/ipr/feeds.py +++ b/ietf/ipr/feeds.py @@ -10,7 +10,7 @@ from ietf.ipr.models import IprDisclosureBase class LatestIprDisclosuresFeed(Feed): feed_type = Atom1Feed title = "IPR Disclosures to the IETF" - link = reverse_lazy('ipr_showlist') + link = reverse_lazy('ietf.ipr.views.showlist') description = "Updates on new IPR Disclosures made to the IETF." language = "en" feed_url = "/feed/ipr/" diff --git a/ietf/ipr/models.py b/ietf/ipr/models.py index 564a5124b..9822cb2a0 100644 --- a/ietf/ipr/models.py +++ b/ietf/ipr/models.py @@ -29,7 +29,7 @@ class IprDisclosureBase(models.Model): return self.title def get_absolute_url(self): - return settings.IDTRACKER_BASE_URL + reverse('ipr_show',kwargs={'id':self.id}) + return settings.IDTRACKER_BASE_URL + reverse('ietf.ipr.views.show',kwargs={'id':self.id}) def get_child(self): """Returns the child instance""" diff --git a/ietf/ipr/tests.py b/ietf/ipr/tests.py index c22338aa8..7034ba954 100644 --- a/ietf/ipr/tests.py +++ b/ietf/ipr/tests.py @@ -108,14 +108,14 @@ class IprTests(TestCase): def test_showlist(self): make_test_data() ipr = IprDisclosureBase.objects.get(title='Statement regarding rights') - r = self.client.get(urlreverse("ipr_showlist")) + r = self.client.get(urlreverse("ietf.ipr.views.showlist")) self.assertEqual(r.status_code, 200) self.assertTrue(ipr.title in unicontent(r)) def test_show_posted(self): make_test_data() ipr = IprDisclosureBase.objects.get(title='Statement regarding rights') - r = self.client.get(urlreverse("ipr_show", kwargs=dict(id=ipr.pk))) + r = self.client.get(urlreverse("ietf.ipr.views.show", kwargs=dict(id=ipr.pk))) self.assertEqual(r.status_code, 200) self.assertTrue(ipr.title in unicontent(r)) @@ -123,28 +123,28 @@ class IprTests(TestCase): make_test_data() ipr = IprDisclosureBase.objects.get(title='Statement regarding rights') ipr.set_state('parked') - r = self.client.get(urlreverse("ipr_show", kwargs=dict(id=ipr.pk))) + r = self.client.get(urlreverse("ietf.ipr.views.show", kwargs=dict(id=ipr.pk))) self.assertEqual(r.status_code, 404) def test_show_pending(self): make_test_data() ipr = IprDisclosureBase.objects.get(title='Statement regarding rights') ipr.set_state('pending') - r = self.client.get(urlreverse("ipr_show", kwargs=dict(id=ipr.pk))) + r = self.client.get(urlreverse("ietf.ipr.views.show", kwargs=dict(id=ipr.pk))) self.assertEqual(r.status_code, 404) def test_show_rejected(self): make_test_data() ipr = IprDisclosureBase.objects.get(title='Statement regarding rights') ipr.set_state('rejected') - r = self.client.get(urlreverse("ipr_show", kwargs=dict(id=ipr.pk))) + r = self.client.get(urlreverse("ietf.ipr.views.show", kwargs=dict(id=ipr.pk))) self.assertEqual(r.status_code, 404) def test_show_removed(self): make_test_data() ipr = IprDisclosureBase.objects.get(title='Statement regarding rights') ipr.set_state('removed') - r = self.client.get(urlreverse("ipr_show", kwargs=dict(id=ipr.pk))) + r = self.client.get(urlreverse("ietf.ipr.views.show", kwargs=dict(id=ipr.pk))) self.assertEqual(r.status_code, 200) self.assertTrue('This IPR disclosure was removed' in unicontent(r)) @@ -176,7 +176,7 @@ class IprTests(TestCase): draft = make_test_data() ipr = IprDisclosureBase.objects.get(title="Statement regarding rights").get_child() - url = urlreverse("ipr_search") + url = urlreverse("ietf.ipr.views.search") r = self.client.get(url) self.assertEqual(r.status_code, 200) diff --git a/ietf/ipr/urls.py b/ietf/ipr/urls.py index 856170159..4ddf31860 100644 --- a/ietf/ipr/urls.py +++ b/ietf/ipr/urls.py @@ -1,20 +1,20 @@ # Copyright The IETF Trust 2007, All Rights Reserved -from django.conf.urls import url from django.views.generic import RedirectView from django.core.urlresolvers import reverse_lazy from ietf.ipr import views +from ietf.utils.urls import url urlpatterns = [ - url(r'^$', views.showlist, name='ipr_showlist'), + url(r'^$', views.showlist), url(r'^about/$', views.about), url(r'^admin/$', RedirectView.as_view(url=reverse_lazy('ipr_admin',kwargs={'state':'pending'}), permanent=True),name="ipr_admin_main"), url(r'^admin/(?Ppending|removed|parked)/$', views.admin, name='ipr_admin'), url(r'^ajax/search/$', views.ajax_search, name='ipr_ajax_search'), url(r'^by-draft/$', views.by_draft_txt), url(r'^by-draft-recursive/$', views.by_draft_recursive_txt), - url(r'^(?P\d+)/$', views.show, name='ipr_show'), + url(r'^(?P\d+)/$', views.show), url(r'^(?P\d+)/addcomment/$', views.add_comment, name='ipr_add_comment'), url(r'^(?P\d+)/addemail/$', views.add_email, name='ipr_add_email'), url(r'^(?P\d+)/edit/$', views.edit, name='ipr_edit'), @@ -23,8 +23,8 @@ urlpatterns = [ url(r'^(?P\d+)/notify/(?Pupdate|posted)/$', views.notify, name='ipr_notify'), url(r'^(?P\d+)/post/$', views.post, name='ipr_post'), url(r'^(?P\d+)/state/$', views.state, name='ipr_state'), - url(r'^update/$', RedirectView.as_view(url=reverse_lazy('ipr_showlist'), permanent=True)), - url(r'^update/(?P\d+)/$', views.update, name='ipr_update'), - url(r'^new-(?P(specific|generic|third-party))/$', views.new, name='ipr_new'), - url(r'^search/$', views.search, name="ipr_search"), + url(r'^update/$', RedirectView.as_view(url=reverse_lazy('ietf.ipr.views.showlist'), permanent=True)), + url(r'^update/(?P\d+)/$', views.update), + url(r'^new-(?P(specific|generic|third-party))/$', views.new), + url(r'^search/$', views.search), ] diff --git a/ietf/ipr/views.py b/ietf/ipr/views.py index c32a49d05..e6fc47d7b 100644 --- a/ietf/ipr/views.py +++ b/ietf/ipr/views.py @@ -296,7 +296,7 @@ def edit(request, id, updates=None): desc="Changed disclosure metadata") messages.success(request,'Disclosure modified') - return redirect("ipr_show", id=ipr.id) + return redirect("ietf.ipr.views.show", id=ipr.id) else: if ipr.updates: @@ -320,7 +320,7 @@ def email(request, id): if request.method == 'POST': button_text = request.POST.get('submit', '') if button_text == 'Cancel': - return redirect("ipr_show", id=ipr.id) + return redirect("ietf.ipr.views.show", id=ipr.id) form = MessageModelForm(request.POST) if form.is_valid(): @@ -349,7 +349,7 @@ def email(request, id): send_mail_message(None,msg) messages.success(request, 'Email sent.') - return redirect('ipr_show', id=ipr.id) + return redirect('ietf.ipr.views.show', id=ipr.id) else: reply_to = get_reply_to() @@ -455,7 +455,9 @@ def new(request, type, updates=None): valid_formsets = True if form.is_valid() and valid_formsets: - updates = form.cleaned_data.get('updates') + if 'updates' in form.cleaned_data: + updates = form.cleaned_data['updates'] + del form.cleaned_data['updates'] disclosure = form.save(commit=False) disclosure.by = person disclosure.state = IprDisclosureStateName.objects.get(slug='pending') @@ -528,7 +530,7 @@ def notify(request, id, type): message = message, ) messages.success(request,'Notifications sent') - return redirect("ipr_show", id=ipr.id) + return redirect("ietf.ipr.views.show", id=ipr.id) else: if type == 'update': @@ -700,7 +702,7 @@ def get_details_tabs(ipr, selected): return [ t + (t[0].lower() == selected.lower(),) for t in [ - ('Disclosure', urlreverse('ipr_show', kwargs={ 'id': ipr.pk })), + ('Disclosure', urlreverse('ietf.ipr.views.show', kwargs={ 'id': ipr.pk })), ('History', urlreverse('ipr_history', kwargs={ 'id': ipr.pk })) ]] @@ -770,7 +772,7 @@ def state(request, id): desc=form.cleaned_data['comment'] ) messages.success(request, 'State Changed') - return redirect("ipr_show", id=ipr.id) + return redirect("ietf.ipr.views.show", id=ipr.id) else: form = StateForm(initial={'state':ipr.state.pk,'private':True}) diff --git a/ietf/liaisons/urls.py b/ietf/liaisons/urls.py index 33dabbb9e..c3ae5422a 100644 --- a/ietf/liaisons/urls.py +++ b/ietf/liaisons/urls.py @@ -1,9 +1,9 @@ # Copyright The IETF Trust 2007, All Rights Reserved -from django.conf.urls import url from django.views.generic import RedirectView, TemplateView from ietf.liaisons import views +from ietf.utils.urls import url urlpatterns = [ url(r'^help/$', TemplateView.as_view(template_name='liaisons/help.html')), diff --git a/ietf/mailinglists/urls.py b/ietf/mailinglists/urls.py index 3671d7ebc..d7b635b1f 100644 --- a/ietf/mailinglists/urls.py +++ b/ietf/mailinglists/urls.py @@ -1,9 +1,9 @@ # Copyright The IETF Trust 2007, All Rights Reserved -from django.conf.urls import url from django.views.generic import RedirectView from ietf.mailinglists import views +from ietf.utils.urls import url urlpatterns = [ url(r'^wg/$', views.groups), diff --git a/ietf/mailtrigger/urls.py b/ietf/mailtrigger/urls.py index 037ce3355..918c90f34 100644 --- a/ietf/mailtrigger/urls.py +++ b/ietf/mailtrigger/urls.py @@ -1,12 +1,12 @@ -from django.conf.urls import url from django.views.generic import RedirectView from django.core.urlresolvers import reverse_lazy from ietf.mailtrigger import views +from ietf.utils.urls import url urlpatterns = [ - url(r'^$', RedirectView.as_view(url=reverse_lazy('mailtrigger_show_triggers'), permanent=True)), - url(r'^name/$', views.show_triggers, name='mailtrigger_show_triggers' ), + url(r'^$', RedirectView.as_view(url=reverse_lazy('ietf.mailtrigger.views.show_triggers'), permanent=True)), + url(r'^name/$', views.show_triggers), url(r'^name/(?P[-\w]+)/$', views.show_triggers ), url(r'^recipient/$', views.show_recipients ), url(r'^recipient/(?P[-\w]+)/$', views.show_recipients ), diff --git a/ietf/meeting/tests_js.py b/ietf/meeting/tests_js.py index 9e142e9ff..97e0af95d 100644 --- a/ietf/meeting/tests_js.py +++ b/ietf/meeting/tests_js.py @@ -5,6 +5,7 @@ import time from pyquery import PyQuery from unittest import skipIf +import django.contrib.auth.views from django.contrib.staticfiles.testing import StaticLiveServerTestCase from django.core.urlresolvers import reverse as urlreverse #from django.test.utils import override_settings @@ -126,7 +127,7 @@ class SlideReorderTests(StaticLiveServerTestCase): return '%s%s'%(self.live_server_url,urlreverse(*args,**kwargs)) def secr_login(self): - url = '%s%s'%(self.live_server_url, urlreverse('django.contrib.auth.views.login')) + url = '%s%s'%(self.live_server_url, urlreverse(django.contrib.auth.views.login)) self.driver.get(url) self.driver.find_element_by_name('username').send_keys('secretary') self.driver.find_element_by_name('password').send_keys('secretary+password') diff --git a/ietf/meeting/urls.py b/ietf/meeting/urls.py index 40a05ccf2..d50c94ab7 100644 --- a/ietf/meeting/urls.py +++ b/ietf/meeting/urls.py @@ -1,11 +1,11 @@ # Copyright The IETF Trust 2007, All Rights Reserved -from django.conf.urls import url, include +from django.conf.urls import include from django.views.generic import RedirectView from django.conf import settings -from ietf.meeting import views -from ietf.meeting import ajax +from ietf.meeting import views, ajax +from ietf.utils.urls import url safe_for_all_meeting_types = [ url(r'^session/(?P[-a-z0-9]+)/?$', views.session_details), @@ -38,8 +38,8 @@ type_ietf_only_patterns = [ url(r'^agenda/by-type$', views.agenda_by_type), url(r'^agenda/by-type/(?P[a-z]+)$', views.agenda_by_type), url(r'^agenda/by-type/(?P[a-z]+)/ics$', views.agenda_by_type_ics), - url(r'^agendas/list$', views.list_agendas, name='meeting_list_agendas'), - url(r'^agendas/edit$', RedirectView.as_view(pattern_name='meeting_list_agendas', permanent=True)), + url(r'^agendas/list$', views.list_agendas), + url(r'^agendas/edit$', RedirectView.as_view(pattern_name='ietf.meeting.views.list_agendas', permanent=True)), url(r'^timeslots/edit$', views.edit_timeslots), url(r'^rooms$', ajax.timeslot_roomsurl), url(r'^room/(?P\d+).json$', ajax.timeslot_roomurl), diff --git a/ietf/meeting/views.py b/ietf/meeting/views.py index 0d3c9a08f..cb195e738 100644 --- a/ietf/meeting/views.py +++ b/ietf/meeting/views.py @@ -1757,11 +1757,11 @@ def interim_request(request): meeting = form.save(date=get_earliest_session_date(formset)) # need to use curry here to pass custom variable to form init - SessionFormset.form = staticmethod(curry( - InterimSessionModelForm, + SessionFormset.form.__init__ = curry( + InterimSessionModelForm.__init__, user=request.user, group=group, - is_approved_or_virtual=(is_approved or is_virtual))) + is_approved_or_virtual=(is_approved or is_virtual)) formset = SessionFormset(instance=meeting, data=request.POST) formset.is_valid() formset.save() @@ -1777,11 +1777,11 @@ def interim_request(request): # subsequently dealt with individually elif meeting_type == 'series': series = [] - SessionFormset.form = staticmethod(curry( - InterimSessionModelForm, + SessionFormset.form.__init__ = curry( + InterimSessionModelForm.__init__, user=request.user, group=group, - is_approved_or_virtual=(is_approved or is_virtual))) + is_approved_or_virtual=(is_approved or is_virtual)) formset = SessionFormset(instance=Meeting(), data=request.POST) formset.is_valid() # re-validate for session_form in formset.forms: @@ -1896,13 +1896,15 @@ def interim_request_edit(request, number): data=request.POST) group = Group.objects.get(pk=form.data['group']) is_approved = is_meeting_approved(meeting) - SessionFormset.form = staticmethod(curry( - InterimSessionModelForm, + + SessionFormset.form.__init__ = curry( + InterimSessionModelForm.__init__, user=request.user, group=group, - is_approved_or_virtual=is_approved)) - formset = SessionFormset(instance=meeting, - data=request.POST) + is_approved_or_virtual=is_approved) + + formset = SessionFormset(instance=meeting, data=request.POST) + if form.is_valid() and formset.is_valid(): meeting = form.save(date=get_earliest_session_date(formset)) formset.save() diff --git a/ietf/message/tests.py b/ietf/message/tests.py index fc3d8f33c..eeece0ee8 100644 --- a/ietf/message/tests.py +++ b/ietf/message/tests.py @@ -26,7 +26,7 @@ class MessageTests(TestCase): ) msg.related_groups.add(nomcom) - r = self.client.get(urlreverse("nomcom_announcement", kwargs=dict(message_id=msg.id))) + r = self.client.get(urlreverse("ietf.message.views.message", kwargs=dict(message_id=msg.id))) self.assertEqual(r.status_code, 200) self.assertTrue(msg.subject in unicontent(r)) self.assertTrue(msg.to in unicontent(r)) diff --git a/ietf/middleware.py b/ietf/middleware.py index 5865958aa..7e58d855b 100644 --- a/ietf/middleware.py +++ b/ietf/middleware.py @@ -9,6 +9,7 @@ import re import smtplib import unicodedata +# old-style middleware class SQLLogMiddleware(object): def process_response(self, request, response): for q in connection.queries: @@ -16,6 +17,15 @@ class SQLLogMiddleware(object): log(q['sql']) return response +# new-style middleware +def sql_log_middleware_factory(get_response): + def sql_log_middleware(request): + response = get_response(request) + for q in connection.queries: + if re.match('(update|insert)', q['sql'], re.IGNORECASE): + log(q['sql']) + return response + class SMTPExceptionMiddleware(object): def process_exception(self, request, exception): if isinstance(exception, smtplib.SMTPException): @@ -24,6 +34,11 @@ class SMTPExceptionMiddleware(object): {'exception': extype, 'args': value, 'traceback': "".join(tb)} ) return None +def smtp_exception_middleware_factory(get_response): + def smtp_exception_middleware(request): + response = get_response(request) + return response + class RedirectTrailingPeriod(object): def process_response(self, request, response): if response.status_code == 404 and request.path.endswith("."): diff --git a/ietf/nomcom/decorators.py b/ietf/nomcom/decorators.py index a0b5499b9..0762c7094 100644 --- a/ietf/nomcom/decorators.py +++ b/ietf/nomcom/decorators.py @@ -1,3 +1,5 @@ +import functools + from django.core.urlresolvers import reverse from django.http import HttpResponseRedirect from django.utils.http import urlquote @@ -12,4 +14,4 @@ def nomcom_private_key_required(view_func): return HttpResponseRedirect('%s?back_to=%s' % (reverse('nomcom_private_key', None, args=(year, )), urlquote(request.get_full_path()))) else: return view_func(request, *args, **kwargs) - return inner + return functools.update_wrapper(inner, view_func) diff --git a/ietf/nomcom/redirect_ann_urls.py b/ietf/nomcom/redirect_ann_urls.py index 624684d81..0131ae631 100644 --- a/ietf/nomcom/redirect_ann_urls.py +++ b/ietf/nomcom/redirect_ann_urls.py @@ -1,6 +1,7 @@ -from django.conf.urls import url from django.views.generic import RedirectView +from ietf.utils.urls import url + urlpatterns = [ url(r'^nomcom/$', RedirectView.as_view(url="/nomcom/ann/", permanent=True)), url(r'^nomcom/(?P\d+)/$', RedirectView.as_view(url="/nomcom/ann/%(message_id)s/", permanent=True)), diff --git a/ietf/nomcom/tests.py b/ietf/nomcom/tests.py index 6c9dab942..6fbc7b34f 100644 --- a/ietf/nomcom/tests.py +++ b/ietf/nomcom/tests.py @@ -76,7 +76,7 @@ class NomcomViewsTest(TestCase): self.year = NOMCOM_YEAR # private urls - self.private_index_url = reverse('nomcom_private_index', kwargs={'year': self.year}) + self.private_index_url = reverse('ietf.nomcom.views.private_index', kwargs={'year': self.year}) self.private_merge_person_url = reverse('ietf.nomcom.views.private_merge_person', kwargs={'year': self.year}) self.private_merge_nominee_url = reverse('ietf.nomcom.views.private_merge_nominee', kwargs={'year': self.year}) self.edit_members_url = reverse('nomcom_edit_members', kwargs={'year': self.year}) @@ -1131,7 +1131,7 @@ class InactiveNomcomTests(TestCase): self.assertEqual(response.status_code, 403) def test_cannot_modify_nominees(self): - url = reverse('nomcom_private_index', kwargs={'year':self.nc.year()}) + url = reverse('ietf.nomcom.views.private_index', kwargs={'year':self.nc.year()}) login_testing_unauthorized(self, self.chair.user.username, url) response = self.client.get(url) self.assertEqual(response.status_code, 200) @@ -1287,7 +1287,7 @@ class FeedbackLastSeenTests(TestCase): self.assertEqual( len(q('.label-success')), 0 ) def test_feedback_nominee_badges(self): - url = reverse('nomcom_view_feedback_nominee',kwargs={'year':self.nc.year(),'nominee_id':self.nominee.id}) + url = reverse('ietf.nomcom.views.view_feedback_nominee', kwargs={'year':self.nc.year(), 'nominee_id':self.nominee.id}) login_testing_unauthorized(self, self.member.user.username, url) provide_private_key_to_test_client(self) response = self.client.get(url) @@ -1679,7 +1679,7 @@ Junk body for testing self.assertEqual(response.status_code, 404) def test_edit_nominee(self): - nominee = self.nc.nominee_set.first() + nominee = self.nc.nominee_set.order_by('pk').first() new_email = EmailFactory(person=nominee.person) url = reverse('nomcom_edit_nominee',kwargs={'year':self.nc.year(),'nominee_id':nominee.id}) login_testing_unauthorized(self,self.chair.user.username,url) @@ -1687,7 +1687,7 @@ Junk body for testing self.assertEqual(response.status_code, 200) response = self.client.post(url,{'nominee_email':new_email.address}) self.assertEqual(response.status_code, 302) - nominee = self.nc.nominee_set.first() + nominee = self.nc.nominee_set.order_by('pk').first() self.assertEqual(nominee.email,new_email) def test_request_merge(self): diff --git a/ietf/nomcom/urls.py b/ietf/nomcom/urls.py index 6bbed45ae..5acd825ee 100644 --- a/ietf/nomcom/urls.py +++ b/ietf/nomcom/urls.py @@ -1,13 +1,13 @@ -from django.conf.urls import url from ietf.nomcom.forms import EditMembersForm, EditMembersFormPreview from ietf.nomcom import views from ietf.message import views as message_views +from ietf.utils.urls import url urlpatterns = [ url(r'^$', views.index), url(r'^ann/$', views.announcements), - url(r'^(?P\d{4})/private/$', views.private_index, name='nomcom_private_index'), + url(r'^(?P\d{4})/private/$', views.private_index), url(r'^(?P\d{4})/private/key/$', views.private_key, name='nomcom_private_key'), url(r'^(?P\d{4})/private/help/$', views.configuration_help, name='nomcom_chair_help'), url(r'^(?P\d{4})/private/nominate/$', views.private_nominate, name='nomcom_private_nominate'), @@ -18,7 +18,7 @@ urlpatterns = [ url(r'^(?P\d{4})/private/view-feedback/$', views.view_feedback, name='nomcom_view_feedback'), url(r'^(?P\d{4})/private/view-feedback/unrelated/$', views.view_feedback_unrelated, name='nomcom_view_feedback_unrelated'), url(r'^(?P\d{4})/private/view-feedback/pending/$', views.view_feedback_pending, name='nomcom_view_feedback_pending'), - url(r'^(?P\d{4})/private/view-feedback/nominee/(?P\d+)$', views.view_feedback_nominee, name='nomcom_view_feedback_nominee'), + url(r'^(?P\d{4})/private/view-feedback/nominee/(?P\d+)$', views.view_feedback_nominee), url(r'^(?P\d{4})/private/edit/nominee/(?P\d+)$', views.edit_nominee, name='nomcom_edit_nominee'), url(r'^(?P\d{4})/private/merge-nominee/?$', views.private_merge_nominee), url(r'^(?P\d{4})/private/merge-person/?$', views.private_merge_person), @@ -42,5 +42,5 @@ urlpatterns = [ url(r'^(?P\d{4})/nominate/newperson$', views.public_nominate_newperson, name='nomcom_public_nominate_newperson'), url(r'^(?P\d{4})/process-nomination-status/(?P\d+)/(?P[\w]+)/(?P[\d]+)/(?P[a-f0-9]+)/$', views.process_nomination_status, name='nomcom_process_nomination_status'), # use the generic view from message - url(r'^ann/(?P\d+)/$', message_views.message, {'group_type': "nomcom" }, "nomcom_announcement"), + url(r'^ann/(?P\d+)/$', message_views.message, {'group_type': "nomcom" }), ] diff --git a/ietf/nomcom/views.py b/ietf/nomcom/views.py index b6d05e508..58f2bb940 100644 --- a/ietf/nomcom/views.py +++ b/ietf/nomcom/views.py @@ -113,7 +113,7 @@ def private_key(request, year): else: messages.warning(request, "You don't have a private decryption key set for this session yet") - back_url = request.GET.get('back_to', reverse('nomcom_private_index', None, args=(year, ))) + back_url = request.GET.get('back_to', reverse('ietf.nomcom.views.private_index', None, args=(year, ))) if request.method == 'POST': form = PrivateKeyForm(data=request.POST) if form.is_valid(): @@ -276,7 +276,7 @@ def private_merge_person(request, year): if form.is_valid(): form.save() messages.success(request, 'A merge request has been sent to the secretariat.') - return redirect('nomcom_private_index',year=year) + return redirect('ietf.nomcom.views.private_index',year=year) else: form = MergePersonForm(nomcom=nomcom) @@ -301,7 +301,7 @@ def private_merge_nominee(request, year): if form.is_valid(): form.save() messages.success(request, 'The Nominee records have been joined.') - return redirect('nomcom_private_index',year=year) + return redirect('ietf.nomcom.views.private_index',year=year) else: form = MergeNomineeForm(nomcom=nomcom) @@ -811,7 +811,7 @@ def edit_nominee(request, year, nominee_id): if form.is_valid(): form.save() messages.success(request, 'The nomination address for %s has been changed to %s'%(nominee.name(),nominee.email.address)) - return redirect('nomcom_private_index', year=year) + return redirect('ietf.nomcom.views.private_index', year=year) else: form = EditNomineeForm(instance=nominee) diff --git a/ietf/person/fields.py b/ietf/person/fields.py index d7ba971b3..45e4bb263 100644 --- a/ietf/person/fields.py +++ b/ietf/person/fields.py @@ -85,7 +85,7 @@ class SearchablePersonsField(forms.CharField): # doing this in the constructor is difficult because the URL # patterns may not have been fully constructed there yet - self.widget.attrs["data-ajax-url"] = urlreverse("ajax_select2_search_person_email", kwargs={ "model_name": self.model.__name__.lower() }) + self.widget.attrs["data-ajax-url"] = urlreverse("ietf.person.views.ajax_select2_search", kwargs={ "model_name": self.model.__name__.lower() }) query_args = {} if self.only_users: query_args["user"] = "1" diff --git a/ietf/person/urls.py b/ietf/person/urls.py index 0c8a7da91..63d85da87 100644 --- a/ietf/person/urls.py +++ b/ietf/person/urls.py @@ -1,8 +1,8 @@ -from django.conf.urls import url from ietf.person import views, ajax +from ietf.utils.urls import url urlpatterns = [ - url(r'^search/(?P(person|email))/$', views.ajax_select2_search, None, 'ajax_select2_search_person_email'), + url(r'^search/(?P(person|email))/$', views.ajax_select2_search), url(r'^(?P[a-z0-9]+).json$', ajax.person_json), url(ur'^(?P[-\w\s\']+)', views.profile), ] diff --git a/ietf/redirects/urls.py b/ietf/redirects/urls.py index fa78dd600..43d2b4abc 100644 --- a/ietf/redirects/urls.py +++ b/ietf/redirects/urls.py @@ -1,8 +1,8 @@ # Copyright The IETF Trust 2007, All Rights Reserved -from django.conf.urls import url from ietf.redirects import views +from ietf.utils.urls import url urlpatterns = [ url(r'^(?P