From 358080926c1353a44bddb45bcf934a453132d8af Mon Sep 17 00:00:00 2001 From: Nick McCullum Date: Wed, 16 Mar 2022 22:29:09 -0400 Subject: [PATCH] Added Django 4 support. --- demo/demodesk/config/urls.py | 6 +- helpdesk/admin.py | 2 +- helpdesk/email.py | 12 +- helpdesk/forms.py | 2 +- helpdesk/lib.py | 10 +- .../commands/create_queue_permissions.py | 2 +- .../commands/create_usersettings.py | 2 +- .../management/commands/escalate_tickets.py | 2 +- .../0009_migrate_queuemembership.py | 2 +- helpdesk/models.py | 8 +- helpdesk/query.py | 2 +- helpdesk/tests/test_attachments.py | 4 +- helpdesk/tests/urls.py | 6 +- helpdesk/urls.py | 104 +++++++++--------- helpdesk/views/feeds.py | 2 +- helpdesk/views/public.py | 6 +- helpdesk/views/staff.py | 2 +- 17 files changed, 87 insertions(+), 87 deletions(-) diff --git a/demo/demodesk/config/urls.py b/demo/demodesk/config/urls.py index 0c37aac6..e4c9b48e 100644 --- a/demo/demodesk/config/urls.py +++ b/demo/demodesk/config/urls.py @@ -13,7 +13,7 @@ Including another URLconf 1. Import the include() function: from django.conf.urls import url, include 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) """ -from django.conf.urls import url, include +from django.urls import include, path from django.contrib import admin from django.conf import settings from django.conf.urls.static import static @@ -26,6 +26,6 @@ from django.conf.urls.static import static # https://docs.djangoproject.com/en/1.10/howto/static-files/ urlpatterns = [ - url(r'^admin/', admin.site.urls), - url(r'^', include('helpdesk.urls', namespace='helpdesk')), + path('admin/', admin.site.urls), + path('', include('helpdesk.urls', namespace='helpdesk')), ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) diff --git a/helpdesk/admin.py b/helpdesk/admin.py index 9d18007e..339e02fb 100644 --- a/helpdesk/admin.py +++ b/helpdesk/admin.py @@ -1,5 +1,5 @@ from django.contrib import admin -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from helpdesk.models import Queue, Ticket, FollowUp, PreSetReply, KBCategory from helpdesk.models import EscalationExclusion, EmailTemplate, KBItem from helpdesk.models import TicketChange, KBIAttachment, FollowUpAttachment, IgnoreEmail diff --git a/helpdesk/email.py b/helpdesk/email.py index 998ebb96..537f9af4 100644 --- a/helpdesk/email.py +++ b/helpdesk/email.py @@ -27,7 +27,7 @@ from django.core.exceptions import ValidationError from django.core.files.uploadedfile import SimpleUploadedFile from django.db.models import Q from django.utils import encoding, timezone -from django.utils.translation import ugettext as _ +from django.utils.translation import gettext as _ from email_reply_parser import EmailReplyParser from helpdesk import settings @@ -129,7 +129,7 @@ def pop3_sync(q, logger, server): if type(raw_content[0]) is bytes: full_message = "\n".join([elm.decode('utf-8') for elm in raw_content]) else: - full_message = encoding.force_text("\n".join(raw_content), errors='replace') + full_message = encoding.force_str("\n".join(raw_content), errors='replace') ticket = object_from_message(message=full_message, queue=q, logger=logger) if ticket: @@ -175,7 +175,7 @@ def imap_sync(q, logger, server): for num in msgnums: logger.info("Processing message %s" % num) status, data = server.fetch(num, '(RFC822)') - full_message = encoding.force_text(data[0][1], errors='replace') + full_message = encoding.force_str(data[0][1], errors='replace') try: ticket = object_from_message(message=full_message, queue=q, logger=logger) except TypeError: @@ -268,7 +268,7 @@ def process_queue(q, logger): for i, m in enumerate(mail, 1): logger.info("Processing message %d" % i) with open(m, 'r') as f: - full_message = encoding.force_text(f.read(), errors='replace') + full_message = encoding.force_str(f.read(), errors='replace') ticket = object_from_message(message=full_message, queue=q, logger=logger) if ticket: logger.info("Successfully processed message %d, ticket/comment created.", i) @@ -579,9 +579,9 @@ def object_from_message(message, queue, logger): logger.debug("Discovered plain text MIME part") else: try: - email_body = encoding.smart_text(part.get_payload(decode=True)) + email_body = encoding.smart_str(part.get_payload(decode=True)) except UnicodeDecodeError: - email_body = encoding.smart_text(part.get_payload(decode=False)) + email_body = encoding.smart_str(part.get_payload(decode=False)) if not body and not full_body: # no text has been parsed so far - try such deep parsing for some messages diff --git a/helpdesk/forms.py b/helpdesk/forms.py index 377ad387..99a927f9 100644 --- a/helpdesk/forms.py +++ b/helpdesk/forms.py @@ -12,7 +12,7 @@ from datetime import datetime, date, time from django.core.exceptions import ObjectDoesNotExist, ValidationError from django import forms from django.conf import settings -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from django.contrib.auth import get_user_model from django.utils import timezone diff --git a/helpdesk/lib.py b/helpdesk/lib.py index da853990..9dd22bce 100644 --- a/helpdesk/lib.py +++ b/helpdesk/lib.py @@ -10,7 +10,7 @@ import logging import mimetypes from django.conf import settings -from django.utils.encoding import smart_text +from django.utils.encoding import smart_str from helpdesk.models import FollowUpAttachment @@ -117,13 +117,13 @@ def text_is_spam(text, request): if ak.verify_key(): ak_data = { 'user_ip': request.META.get('REMOTE_ADDR', '127.0.0.1'), - 'user_agent': request.META.get('HTTP_USER_AGENT', ''), - 'referrer': request.META.get('HTTP_REFERER', ''), + 'user_agent': request.headers.get('User-Agent', ''), + 'referrer': request.headers.get('Referer', ''), 'comment_type': 'comment', 'comment_author': '', } - return ak.comment_check(smart_text(text), data=ak_data) + return ak.comment_check(smart_str(text), data=ak_data) return False @@ -135,7 +135,7 @@ def process_attachments(followup, attached_files): for attached in attached_files: if attached.size: - filename = smart_text(attached.name) + filename = smart_str(attached.name) att = FollowUpAttachment( followup=followup, file=attached, diff --git a/helpdesk/management/commands/create_queue_permissions.py b/helpdesk/management/commands/create_queue_permissions.py index 50e980c3..fb72f3fe 100644 --- a/helpdesk/management/commands/create_queue_permissions.py +++ b/helpdesk/management/commands/create_queue_permissions.py @@ -19,7 +19,7 @@ from django.contrib.auth.models import Permission from django.contrib.contenttypes.models import ContentType from django.core.management.base import BaseCommand, CommandError from django.db.utils import IntegrityError -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from helpdesk.models import Queue diff --git a/helpdesk/management/commands/create_usersettings.py b/helpdesk/management/commands/create_usersettings.py index e27cea16..2ed628a1 100644 --- a/helpdesk/management/commands/create_usersettings.py +++ b/helpdesk/management/commands/create_usersettings.py @@ -8,7 +8,7 @@ create_usersettings.py - Easy way to create helpdesk-specific settings for users who don't yet have them. """ -from django.utils.translation import ugettext as _ +from django.utils.translation import gettext as _ from django.core.management.base import BaseCommand from django.contrib.auth import get_user_model diff --git a/helpdesk/management/commands/escalate_tickets.py b/helpdesk/management/commands/escalate_tickets.py index edbf7307..07c9a1c4 100644 --- a/helpdesk/management/commands/escalate_tickets.py +++ b/helpdesk/management/commands/escalate_tickets.py @@ -15,7 +15,7 @@ import sys from django.core.management.base import BaseCommand, CommandError from django.db.models import Q -from django.utils.translation import ugettext as _ +from django.utils.translation import gettext as _ from django.utils import timezone from helpdesk.models import Queue, Ticket, FollowUp, EscalationExclusion, TicketChange diff --git a/helpdesk/migrations/0009_migrate_queuemembership.py b/helpdesk/migrations/0009_migrate_queuemembership.py index 09e2a60f..318b24ab 100644 --- a/helpdesk/migrations/0009_migrate_queuemembership.py +++ b/helpdesk/migrations/0009_migrate_queuemembership.py @@ -2,7 +2,7 @@ from django.core.exceptions import ObjectDoesNotExist from django.db import migrations from django.db.utils import IntegrityError -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ def create_and_assign_permissions(apps, schema_editor): diff --git a/helpdesk/models.py b/helpdesk/models.py index f8ffb8b1..67a792d4 100644 --- a/helpdesk/models.py +++ b/helpdesk/models.py @@ -14,7 +14,7 @@ from django.core.exceptions import ObjectDoesNotExist, ValidationError from django.db import models from django.conf import settings from django.utils import timezone -from django.utils.translation import ugettext_lazy as _, ugettext +from django.utils.translation import gettext_lazy as _, gettext from io import StringIO import re import os @@ -1007,11 +1007,11 @@ class TicketChange(models.Model): def __str__(self): out = '%s ' % self.field if not self.new_value: - out += ugettext('removed') + out += gettext('removed') elif not self.old_value: - out += ugettext('set to %s') % self.new_value + out += gettext('set to %s') % self.new_value else: - out += ugettext('changed from "%(old_value)s" to "%(new_value)s"') % { + out += gettext('changed from "%(old_value)s" to "%(new_value)s"') % { 'old_value': self.old_value, 'new_value': self.new_value } diff --git a/helpdesk/query.py b/helpdesk/query.py index 36d7eca2..c347c406 100644 --- a/helpdesk/query.py +++ b/helpdesk/query.py @@ -1,7 +1,7 @@ from django.db.models import Q from django.urls import reverse from django.utils.html import escape -from django.utils.translation import ugettext as _ +from django.utils.translation import gettext as _ from base64 import b64encode from base64 import b64decode diff --git a/helpdesk/tests/test_attachments.py b/helpdesk/tests/test_attachments.py index 942a2353..3f65dc0a 100644 --- a/helpdesk/tests/test_attachments.py +++ b/helpdesk/tests/test_attachments.py @@ -2,7 +2,7 @@ from django.core.files.uploadedfile import SimpleUploadedFile from django.urls import reverse from django.test import override_settings, TestCase -from django.utils.encoding import smart_text +from django.utils.encoding import smart_str from helpdesk import lib, models @@ -78,7 +78,7 @@ class AttachmentIntegrationTests(TestCase): # Ensure attachment is available with correct content att = models.FollowUpAttachment.objects.get(followup__ticket=response.context['ticket']) with open(os.path.join(MEDIA_DIR, att.file.name)) as file_on_disk: - disk_content = smart_text(file_on_disk.read(), 'utf-8') + disk_content = smart_str(file_on_disk.read(), 'utf-8') self.assertEqual(disk_content, 'โจ') diff --git a/helpdesk/tests/urls.py b/helpdesk/tests/urls.py index 640937c2..252441f3 100644 --- a/helpdesk/tests/urls.py +++ b/helpdesk/tests/urls.py @@ -1,7 +1,7 @@ -from django.conf.urls import include, url +from django.urls import include, path from django.contrib import admin urlpatterns = [ - url(r'^helpdesk/', include('helpdesk.urls', namespace='helpdesk')), - url(r'^admin/', admin.site.urls), + path('helpdesk/', include('helpdesk.urls', namespace='helpdesk')), + path('admin/', admin.site.urls), ] diff --git a/helpdesk/urls.py b/helpdesk/urls.py index 6959a99b..7e55f280 100644 --- a/helpdesk/urls.py +++ b/helpdesk/urls.py @@ -7,7 +7,7 @@ urls.py - Mapping of URL's to our various views. Note we always used NAMED views for simplicity in linking later on. """ -from django.conf.urls import url +from django.urls import path, re_path from django.contrib.auth.decorators import login_required from django.contrib.auth import views as auth_views from django.views.generic import TemplateView @@ -41,195 +41,195 @@ app_name = 'helpdesk' base64_pattern = r'(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$' urlpatterns = [ - url(r'^dashboard/$', + path('dashboard/', staff.dashboard, name='dashboard'), - url(r'^tickets/$', + path('tickets/', staff.ticket_list, name='list'), - url(r'^tickets/update/$', + path('tickets/update/', staff.mass_update, name='mass_update'), - url(r'^tickets/merge$', + path('tickets/merge', staff.merge_tickets, name='merge_tickets'), - url(r'^tickets/(?P[0-9]+)/$', + path('tickets//', staff.view_ticket, name='view'), - url(r'^tickets/(?P[0-9]+)/followup_edit/(?P[0-9]+)/$', + path('tickets//followup_edit//', staff.followup_edit, name='followup_edit'), - url(r'^tickets/(?P[0-9]+)/followup_delete/(?P[0-9]+)/$', + path('tickets//followup_delete//', staff.followup_delete, name='followup_delete'), - url(r'^tickets/(?P[0-9]+)/edit/$', + path('tickets//edit/', staff.edit_ticket, name='edit'), - url(r'^tickets/(?P[0-9]+)/update/$', + path('tickets//update/', staff.update_ticket, name='update'), - url(r'^tickets/(?P[0-9]+)/delete/$', + path('tickets//delete/', staff.delete_ticket, name='delete'), - url(r'^tickets/(?P[0-9]+)/hold/$', + path('tickets//hold/', staff.hold_ticket, name='hold'), - url(r'^tickets/(?P[0-9]+)/unhold/$', + path('tickets//unhold/', staff.unhold_ticket, name='unhold'), - url(r'^tickets/(?P[0-9]+)/cc/$', + path('tickets//cc/', staff.ticket_cc, name='ticket_cc'), - url(r'^tickets/(?P[0-9]+)/cc/add/$', + path('tickets//cc/add/', staff.ticket_cc_add, name='ticket_cc_add'), - url(r'^tickets/(?P[0-9]+)/cc/delete/(?P[0-9]+)/$', + path('tickets//cc/delete//', staff.ticket_cc_del, name='ticket_cc_del'), - url(r'^tickets/(?P[0-9]+)/dependency/add/$', + path('tickets//dependency/add/', staff.ticket_dependency_add, name='ticket_dependency_add'), - url(r'^tickets/(?P[0-9]+)/dependency/delete/(?P[0-9]+)/$', + path('tickets//dependency/delete//', staff.ticket_dependency_del, name='ticket_dependency_del'), - url(r'^tickets/(?P[0-9]+)/attachment_delete/(?P[0-9]+)/$', + path('tickets//attachment_delete//', staff.attachment_del, name='attachment_del'), - url(r'^raw/(?P\w+)/$', + re_path(r'^raw/(?P\w+)/$', staff.raw_details, name='raw'), - url(r'^rss/$', + path('rss/', staff.rss_list, name='rss_index'), - url(r'^reports/$', + path('reports/', staff.report_index, name='report_index'), - url(r'^reports/(?P\w+)/$', + re_path(r'^reports/(?P\w+)/$', staff.run_report, name='run_report'), - url(r'^save_query/$', + path('save_query/', staff.save_query, name='savequery'), - url(r'^delete_query/(?P[0-9]+)/$', + path('delete_query//', staff.delete_saved_query, name='delete_query'), - url(r'^settings/$', + path('settings/', staff.EditUserSettingsView.as_view(), name='user_settings'), - url(r'^ignore/$', + path('ignore/', staff.email_ignore, name='email_ignore'), - url(r'^ignore/add/$', + path('ignore/add/', staff.email_ignore_add, name='email_ignore_add'), - url(r'^ignore/delete/(?P[0-9]+)/$', + path('ignore/delete//', staff.email_ignore_del, name='email_ignore_del'), - url(r'^datatables_ticket_list/(?P{})$'.format(base64_pattern), + re_path(r'^datatables_ticket_list/(?P{})$'.format(base64_pattern), staff.datatables_ticket_list, name="datatables_ticket_list"), - url(r'^timeline_ticket_list/(?P{})$'.format(base64_pattern), + re_path(r'^timeline_ticket_list/(?P{})$'.format(base64_pattern), staff.timeline_ticket_list, name="timeline_ticket_list"), ] urlpatterns += [ - url(r'^$', + path('', protect_view(public.Homepage.as_view()), name='home'), - url(r'^tickets/submit/$', + path('tickets/submit/', public.create_ticket, name='submit'), - url(r'^tickets/submit_iframe/$', + path('tickets/submit_iframe/', public.CreateTicketIframeView.as_view(), name='submit_iframe'), - url(r'^tickets/success_iframe/$', # Ticket was submitted successfully + path('tickets/success_iframe/', # Ticket was submitted successfully public.SuccessIframeView.as_view(), name='success_iframe'), - url(r'^view/$', + path('view/', public.view_ticket, name='public_view'), - url(r'^change_language/$', + path('change_language/', public.change_language, name='public_change_language'), ] urlpatterns += [ - url(r'^rss/user/(?P[^/]+)/$', + path('rss/user//', helpdesk_staff_member_required(feeds.OpenTicketsByUser()), name='rss_user'), - url(r'^rss/user/(?P[^/]+)/(?P[A-Za-z0-9_-]+)/$', + re_path(r'^rss/user/(?P[^/]+)/(?P[A-Za-z0-9_-]+)/$', helpdesk_staff_member_required(feeds.OpenTicketsByUser()), name='rss_user_queue'), - url(r'^rss/queue/(?P[A-Za-z0-9_-]+)/$', + re_path(r'^rss/queue/(?P[A-Za-z0-9_-]+)/$', helpdesk_staff_member_required(feeds.OpenTicketsByQueue()), name='rss_queue'), - url(r'^rss/unassigned/$', + path('rss/unassigned/', helpdesk_staff_member_required(feeds.UnassignedTickets()), name='rss_unassigned'), - url(r'^rss/recent_activity/$', + path('rss/recent_activity/', helpdesk_staff_member_required(feeds.RecentFollowUps()), name='rss_activity'), ] urlpatterns += [ - url(r'^login/$', + path('login/', login.login, name='login'), - url(r'^logout/$', + path('logout/', auth_views.LogoutView.as_view( template_name='helpdesk/registration/login.html', next_page='../'), name='logout'), - url(r'^password_change/$', + path('password_change/', auth_views.PasswordChangeView.as_view( template_name='helpdesk/registration/change_password.html', success_url='./done'), name='password_change'), - url(r'^password_change/done$', + path('password_change/done', auth_views.PasswordChangeDoneView.as_view( template_name='helpdesk/registration/change_password_done.html',), name='password_change_done'), @@ -237,29 +237,29 @@ urlpatterns += [ if helpdesk_settings.HELPDESK_KB_ENABLED: urlpatterns += [ - url(r'^kb/$', + path('kb/', kb.index, name='kb_index'), - url(r'^kb/(?P[A-Za-z0-9_-]+)/$', + re_path(r'^kb/(?P[A-Za-z0-9_-]+)/$', kb.category, name='kb_category'), - url(r'^kb/(?P[0-9]+)/vote/$', + path('kb//vote/', kb.vote, name='kb_vote'), - url(r'^kb_iframe/(?P[A-Za-z0-9_-]+)/$', + re_path(r'^kb_iframe/(?P[A-Za-z0-9_-]+)/$', kb.category_iframe, name='kb_category_iframe'), ] urlpatterns += [ - url(r'^help/context/$', + path('help/context/', TemplateView.as_view(template_name='helpdesk/help_context.html'), name='help_context'), - url(r'^system_settings/$', + path('system_settings/', login_required(DirectTemplateView.as_view(template_name='helpdesk/system_settings.html')), name='system_settings'), ] diff --git a/helpdesk/views/feeds.py b/helpdesk/views/feeds.py index aca10630..7ae8ebcb 100644 --- a/helpdesk/views/feeds.py +++ b/helpdesk/views/feeds.py @@ -11,7 +11,7 @@ from django.contrib.auth import get_user_model from django.contrib.syndication.views import Feed from django.urls import reverse from django.db.models import Q -from django.utils.translation import ugettext as _ +from django.utils.translation import gettext as _ from django.shortcuts import get_object_or_404 from helpdesk.models import Ticket, FollowUp, Queue diff --git a/helpdesk/views/public.py b/helpdesk/views/public.py index 779e8d6d..b0c97c24 100644 --- a/helpdesk/views/public.py +++ b/helpdesk/views/public.py @@ -15,8 +15,8 @@ from django.core.exceptions import ( from django.urls import reverse from django.http import HttpResponseRedirect from django.shortcuts import render -from django.utils.http import urlquote -from django.utils.translation import ugettext as _ +from urllib.parse import quote +from django.utils.translation import gettext as _ from django.conf import settings from django.views.decorators.clickjacking import xframe_options_exempt from django.views.decorators.csrf import csrf_exempt @@ -112,7 +112,7 @@ class BaseCreateTicketView(abstract_views.AbstractCreateTicketMixin, FormView): return HttpResponseRedirect('%s?ticket=%s&email=%s&key=%s' % ( reverse('helpdesk:public_view'), ticket.ticket_for_url, - urlquote(ticket.submitter_email), + quote(ticket.submitter_email), ticket.secret_key) ) except ValueError: diff --git a/helpdesk/views/staff.py b/helpdesk/views/staff.py index 462b3540..bba76f32 100644 --- a/helpdesk/views/staff.py +++ b/helpdesk/views/staff.py @@ -19,7 +19,7 @@ from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger from django.db.models import Q from django.http import HttpResponseRedirect, Http404, HttpResponse, JsonResponse from django.shortcuts import render, get_object_or_404, redirect -from django.utils.translation import ugettext as _ +from django.utils.translation import gettext as _ from django.utils.html import escape from django.utils import timezone from django.views.decorators.csrf import requires_csrf_token