Added Django 4 support.

This commit is contained in:
Nick McCullum 2022-03-16 22:29:09 -04:00
parent e7fd06da53
commit 358080926c
17 changed files with 87 additions and 87 deletions

View File

@ -13,7 +13,7 @@ Including another URLconf
1. Import the include() function: from django.conf.urls import url, include 1. Import the include() function: from django.conf.urls import url, include
2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) 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.contrib import admin
from django.conf import settings from django.conf import settings
from django.conf.urls.static import static 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/ # https://docs.djangoproject.com/en/1.10/howto/static-files/
urlpatterns = [ urlpatterns = [
url(r'^admin/', admin.site.urls), path('admin/', admin.site.urls),
url(r'^', include('helpdesk.urls', namespace='helpdesk')), path('', include('helpdesk.urls', namespace='helpdesk')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

View File

@ -1,5 +1,5 @@
from django.contrib import admin 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 Queue, Ticket, FollowUp, PreSetReply, KBCategory
from helpdesk.models import EscalationExclusion, EmailTemplate, KBItem from helpdesk.models import EscalationExclusion, EmailTemplate, KBItem
from helpdesk.models import TicketChange, KBIAttachment, FollowUpAttachment, IgnoreEmail from helpdesk.models import TicketChange, KBIAttachment, FollowUpAttachment, IgnoreEmail

View File

@ -27,7 +27,7 @@ from django.core.exceptions import ValidationError
from django.core.files.uploadedfile import SimpleUploadedFile from django.core.files.uploadedfile import SimpleUploadedFile
from django.db.models import Q from django.db.models import Q
from django.utils import encoding, timezone 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 email_reply_parser import EmailReplyParser
from helpdesk import settings from helpdesk import settings
@ -129,7 +129,7 @@ def pop3_sync(q, logger, server):
if type(raw_content[0]) is bytes: if type(raw_content[0]) is bytes:
full_message = "\n".join([elm.decode('utf-8') for elm in raw_content]) full_message = "\n".join([elm.decode('utf-8') for elm in raw_content])
else: 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) ticket = object_from_message(message=full_message, queue=q, logger=logger)
if ticket: if ticket:
@ -175,7 +175,7 @@ def imap_sync(q, logger, server):
for num in msgnums: for num in msgnums:
logger.info("Processing message %s" % num) logger.info("Processing message %s" % num)
status, data = server.fetch(num, '(RFC822)') 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: try:
ticket = object_from_message(message=full_message, queue=q, logger=logger) ticket = object_from_message(message=full_message, queue=q, logger=logger)
except TypeError: except TypeError:
@ -268,7 +268,7 @@ def process_queue(q, logger):
for i, m in enumerate(mail, 1): for i, m in enumerate(mail, 1):
logger.info("Processing message %d" % i) logger.info("Processing message %d" % i)
with open(m, 'r') as f: 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) ticket = object_from_message(message=full_message, queue=q, logger=logger)
if ticket: if ticket:
logger.info("Successfully processed message %d, ticket/comment created.", i) 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") logger.debug("Discovered plain text MIME part")
else: else:
try: try:
email_body = encoding.smart_text(part.get_payload(decode=True)) email_body = encoding.smart_str(part.get_payload(decode=True))
except UnicodeDecodeError: 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: if not body and not full_body:
# no text has been parsed so far - try such deep parsing for some messages # no text has been parsed so far - try such deep parsing for some messages

View File

@ -12,7 +12,7 @@ from datetime import datetime, date, time
from django.core.exceptions import ObjectDoesNotExist, ValidationError from django.core.exceptions import ObjectDoesNotExist, ValidationError
from django import forms from django import forms
from django.conf import settings 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.contrib.auth import get_user_model
from django.utils import timezone from django.utils import timezone

View File

@ -10,7 +10,7 @@ import logging
import mimetypes import mimetypes
from django.conf import settings from django.conf import settings
from django.utils.encoding import smart_text from django.utils.encoding import smart_str
from helpdesk.models import FollowUpAttachment from helpdesk.models import FollowUpAttachment
@ -117,13 +117,13 @@ def text_is_spam(text, request):
if ak.verify_key(): if ak.verify_key():
ak_data = { ak_data = {
'user_ip': request.META.get('REMOTE_ADDR', '127.0.0.1'), 'user_ip': request.META.get('REMOTE_ADDR', '127.0.0.1'),
'user_agent': request.META.get('HTTP_USER_AGENT', ''), 'user_agent': request.headers.get('User-Agent', ''),
'referrer': request.META.get('HTTP_REFERER', ''), 'referrer': request.headers.get('Referer', ''),
'comment_type': 'comment', 'comment_type': 'comment',
'comment_author': '', 'comment_author': '',
} }
return ak.comment_check(smart_text(text), data=ak_data) return ak.comment_check(smart_str(text), data=ak_data)
return False return False
@ -135,7 +135,7 @@ def process_attachments(followup, attached_files):
for attached in attached_files: for attached in attached_files:
if attached.size: if attached.size:
filename = smart_text(attached.name) filename = smart_str(attached.name)
att = FollowUpAttachment( att = FollowUpAttachment(
followup=followup, followup=followup,
file=attached, file=attached,

View File

@ -19,7 +19,7 @@ from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.core.management.base import BaseCommand, CommandError from django.core.management.base import BaseCommand, CommandError
from django.db.utils import IntegrityError 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 from helpdesk.models import Queue

View File

@ -8,7 +8,7 @@ create_usersettings.py - Easy way to create helpdesk-specific settings for
users who don't yet have them. 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.core.management.base import BaseCommand
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model

View File

@ -15,7 +15,7 @@ import sys
from django.core.management.base import BaseCommand, CommandError from django.core.management.base import BaseCommand, CommandError
from django.db.models import Q 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 django.utils import timezone
from helpdesk.models import Queue, Ticket, FollowUp, EscalationExclusion, TicketChange from helpdesk.models import Queue, Ticket, FollowUp, EscalationExclusion, TicketChange

View File

@ -2,7 +2,7 @@
from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ObjectDoesNotExist
from django.db import migrations from django.db import migrations
from django.db.utils import IntegrityError 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): def create_and_assign_permissions(apps, schema_editor):

View File

@ -14,7 +14,7 @@ from django.core.exceptions import ObjectDoesNotExist, ValidationError
from django.db import models from django.db import models
from django.conf import settings from django.conf import settings
from django.utils import timezone 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 from io import StringIO
import re import re
import os import os
@ -1007,11 +1007,11 @@ class TicketChange(models.Model):
def __str__(self): def __str__(self):
out = '%s ' % self.field out = '%s ' % self.field
if not self.new_value: if not self.new_value:
out += ugettext('removed') out += gettext('removed')
elif not self.old_value: elif not self.old_value:
out += ugettext('set to %s') % self.new_value out += gettext('set to %s') % self.new_value
else: 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, 'old_value': self.old_value,
'new_value': self.new_value 'new_value': self.new_value
} }

View File

@ -1,7 +1,7 @@
from django.db.models import Q from django.db.models import Q
from django.urls import reverse from django.urls import reverse
from django.utils.html import escape 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 b64encode
from base64 import b64decode from base64 import b64decode

View File

@ -2,7 +2,7 @@
from django.core.files.uploadedfile import SimpleUploadedFile from django.core.files.uploadedfile import SimpleUploadedFile
from django.urls import reverse from django.urls import reverse
from django.test import override_settings, TestCase 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 from helpdesk import lib, models
@ -78,7 +78,7 @@ class AttachmentIntegrationTests(TestCase):
# Ensure attachment is available with correct content # Ensure attachment is available with correct content
att = models.FollowUpAttachment.objects.get(followup__ticket=response.context['ticket']) att = models.FollowUpAttachment.objects.get(followup__ticket=response.context['ticket'])
with open(os.path.join(MEDIA_DIR, att.file.name)) as file_on_disk: 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, 'โจ') self.assertEqual(disk_content, 'โจ')

View File

@ -1,7 +1,7 @@
from django.conf.urls import include, url from django.urls import include, path
from django.contrib import admin from django.contrib import admin
urlpatterns = [ urlpatterns = [
url(r'^helpdesk/', include('helpdesk.urls', namespace='helpdesk')), path('helpdesk/', include('helpdesk.urls', namespace='helpdesk')),
url(r'^admin/', admin.site.urls), path('admin/', admin.site.urls),
] ]

View File

@ -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. 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.decorators import login_required
from django.contrib.auth import views as auth_views from django.contrib.auth import views as auth_views
from django.views.generic import TemplateView 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}=)?$' base64_pattern = r'(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$'
urlpatterns = [ urlpatterns = [
url(r'^dashboard/$', path('dashboard/',
staff.dashboard, staff.dashboard,
name='dashboard'), name='dashboard'),
url(r'^tickets/$', path('tickets/',
staff.ticket_list, staff.ticket_list,
name='list'), name='list'),
url(r'^tickets/update/$', path('tickets/update/',
staff.mass_update, staff.mass_update,
name='mass_update'), name='mass_update'),
url(r'^tickets/merge$', path('tickets/merge',
staff.merge_tickets, staff.merge_tickets,
name='merge_tickets'), name='merge_tickets'),
url(r'^tickets/(?P<ticket_id>[0-9]+)/$', path('tickets/<int:ticket_id>/',
staff.view_ticket, staff.view_ticket,
name='view'), name='view'),
url(r'^tickets/(?P<ticket_id>[0-9]+)/followup_edit/(?P<followup_id>[0-9]+)/$', path('tickets/<int:ticket_id>/followup_edit/<int:followup_id>/',
staff.followup_edit, staff.followup_edit,
name='followup_edit'), name='followup_edit'),
url(r'^tickets/(?P<ticket_id>[0-9]+)/followup_delete/(?P<followup_id>[0-9]+)/$', path('tickets/<int:ticket_id>/followup_delete/<int:followup_id>/',
staff.followup_delete, staff.followup_delete,
name='followup_delete'), name='followup_delete'),
url(r'^tickets/(?P<ticket_id>[0-9]+)/edit/$', path('tickets/<int:ticket_id>/edit/',
staff.edit_ticket, staff.edit_ticket,
name='edit'), name='edit'),
url(r'^tickets/(?P<ticket_id>[0-9]+)/update/$', path('tickets/<int:ticket_id>/update/',
staff.update_ticket, staff.update_ticket,
name='update'), name='update'),
url(r'^tickets/(?P<ticket_id>[0-9]+)/delete/$', path('tickets/<int:ticket_id>/delete/',
staff.delete_ticket, staff.delete_ticket,
name='delete'), name='delete'),
url(r'^tickets/(?P<ticket_id>[0-9]+)/hold/$', path('tickets/<int:ticket_id>/hold/',
staff.hold_ticket, staff.hold_ticket,
name='hold'), name='hold'),
url(r'^tickets/(?P<ticket_id>[0-9]+)/unhold/$', path('tickets/<int:ticket_id>/unhold/',
staff.unhold_ticket, staff.unhold_ticket,
name='unhold'), name='unhold'),
url(r'^tickets/(?P<ticket_id>[0-9]+)/cc/$', path('tickets/<int:ticket_id>/cc/',
staff.ticket_cc, staff.ticket_cc,
name='ticket_cc'), name='ticket_cc'),
url(r'^tickets/(?P<ticket_id>[0-9]+)/cc/add/$', path('tickets/<int:ticket_id>/cc/add/',
staff.ticket_cc_add, staff.ticket_cc_add,
name='ticket_cc_add'), name='ticket_cc_add'),
url(r'^tickets/(?P<ticket_id>[0-9]+)/cc/delete/(?P<cc_id>[0-9]+)/$', path('tickets/<int:ticket_id>/cc/delete/<int:cc_id>/',
staff.ticket_cc_del, staff.ticket_cc_del,
name='ticket_cc_del'), name='ticket_cc_del'),
url(r'^tickets/(?P<ticket_id>[0-9]+)/dependency/add/$', path('tickets/<int:ticket_id>/dependency/add/',
staff.ticket_dependency_add, staff.ticket_dependency_add,
name='ticket_dependency_add'), name='ticket_dependency_add'),
url(r'^tickets/(?P<ticket_id>[0-9]+)/dependency/delete/(?P<dependency_id>[0-9]+)/$', path('tickets/<int:ticket_id>/dependency/delete/<int:dependency_id>/',
staff.ticket_dependency_del, staff.ticket_dependency_del,
name='ticket_dependency_del'), name='ticket_dependency_del'),
url(r'^tickets/(?P<ticket_id>[0-9]+)/attachment_delete/(?P<attachment_id>[0-9]+)/$', path('tickets/<int:ticket_id>/attachment_delete/<int:attachment_id>/',
staff.attachment_del, staff.attachment_del,
name='attachment_del'), name='attachment_del'),
url(r'^raw/(?P<type>\w+)/$', re_path(r'^raw/(?P<type>\w+)/$',
staff.raw_details, staff.raw_details,
name='raw'), name='raw'),
url(r'^rss/$', path('rss/',
staff.rss_list, staff.rss_list,
name='rss_index'), name='rss_index'),
url(r'^reports/$', path('reports/',
staff.report_index, staff.report_index,
name='report_index'), name='report_index'),
url(r'^reports/(?P<report>\w+)/$', re_path(r'^reports/(?P<report>\w+)/$',
staff.run_report, staff.run_report,
name='run_report'), name='run_report'),
url(r'^save_query/$', path('save_query/',
staff.save_query, staff.save_query,
name='savequery'), name='savequery'),
url(r'^delete_query/(?P<id>[0-9]+)/$', path('delete_query/<int:id>/',
staff.delete_saved_query, staff.delete_saved_query,
name='delete_query'), name='delete_query'),
url(r'^settings/$', path('settings/',
staff.EditUserSettingsView.as_view(), staff.EditUserSettingsView.as_view(),
name='user_settings'), name='user_settings'),
url(r'^ignore/$', path('ignore/',
staff.email_ignore, staff.email_ignore,
name='email_ignore'), name='email_ignore'),
url(r'^ignore/add/$', path('ignore/add/',
staff.email_ignore_add, staff.email_ignore_add,
name='email_ignore_add'), name='email_ignore_add'),
url(r'^ignore/delete/(?P<id>[0-9]+)/$', path('ignore/delete/<int:id>/',
staff.email_ignore_del, staff.email_ignore_del,
name='email_ignore_del'), name='email_ignore_del'),
url(r'^datatables_ticket_list/(?P<query>{})$'.format(base64_pattern), re_path(r'^datatables_ticket_list/(?P<query>{})$'.format(base64_pattern),
staff.datatables_ticket_list, staff.datatables_ticket_list,
name="datatables_ticket_list"), name="datatables_ticket_list"),
url(r'^timeline_ticket_list/(?P<query>{})$'.format(base64_pattern), re_path(r'^timeline_ticket_list/(?P<query>{})$'.format(base64_pattern),
staff.timeline_ticket_list, staff.timeline_ticket_list,
name="timeline_ticket_list"), name="timeline_ticket_list"),
] ]
urlpatterns += [ urlpatterns += [
url(r'^$', path('',
protect_view(public.Homepage.as_view()), protect_view(public.Homepage.as_view()),
name='home'), name='home'),
url(r'^tickets/submit/$', path('tickets/submit/',
public.create_ticket, public.create_ticket,
name='submit'), name='submit'),
url(r'^tickets/submit_iframe/$', path('tickets/submit_iframe/',
public.CreateTicketIframeView.as_view(), public.CreateTicketIframeView.as_view(),
name='submit_iframe'), name='submit_iframe'),
url(r'^tickets/success_iframe/$', # Ticket was submitted successfully path('tickets/success_iframe/', # Ticket was submitted successfully
public.SuccessIframeView.as_view(), public.SuccessIframeView.as_view(),
name='success_iframe'), name='success_iframe'),
url(r'^view/$', path('view/',
public.view_ticket, public.view_ticket,
name='public_view'), name='public_view'),
url(r'^change_language/$', path('change_language/',
public.change_language, public.change_language,
name='public_change_language'), name='public_change_language'),
] ]
urlpatterns += [ urlpatterns += [
url(r'^rss/user/(?P<user_name>[^/]+)/$', path('rss/user/<str:user_name>/',
helpdesk_staff_member_required(feeds.OpenTicketsByUser()), helpdesk_staff_member_required(feeds.OpenTicketsByUser()),
name='rss_user'), name='rss_user'),
url(r'^rss/user/(?P<user_name>[^/]+)/(?P<queue_slug>[A-Za-z0-9_-]+)/$', re_path(r'^rss/user/(?P<user_name>[^/]+)/(?P<queue_slug>[A-Za-z0-9_-]+)/$',
helpdesk_staff_member_required(feeds.OpenTicketsByUser()), helpdesk_staff_member_required(feeds.OpenTicketsByUser()),
name='rss_user_queue'), name='rss_user_queue'),
url(r'^rss/queue/(?P<queue_slug>[A-Za-z0-9_-]+)/$', re_path(r'^rss/queue/(?P<queue_slug>[A-Za-z0-9_-]+)/$',
helpdesk_staff_member_required(feeds.OpenTicketsByQueue()), helpdesk_staff_member_required(feeds.OpenTicketsByQueue()),
name='rss_queue'), name='rss_queue'),
url(r'^rss/unassigned/$', path('rss/unassigned/',
helpdesk_staff_member_required(feeds.UnassignedTickets()), helpdesk_staff_member_required(feeds.UnassignedTickets()),
name='rss_unassigned'), name='rss_unassigned'),
url(r'^rss/recent_activity/$', path('rss/recent_activity/',
helpdesk_staff_member_required(feeds.RecentFollowUps()), helpdesk_staff_member_required(feeds.RecentFollowUps()),
name='rss_activity'), name='rss_activity'),
] ]
urlpatterns += [ urlpatterns += [
url(r'^login/$', path('login/',
login.login, login.login,
name='login'), name='login'),
url(r'^logout/$', path('logout/',
auth_views.LogoutView.as_view( auth_views.LogoutView.as_view(
template_name='helpdesk/registration/login.html', template_name='helpdesk/registration/login.html',
next_page='../'), next_page='../'),
name='logout'), name='logout'),
url(r'^password_change/$', path('password_change/',
auth_views.PasswordChangeView.as_view( auth_views.PasswordChangeView.as_view(
template_name='helpdesk/registration/change_password.html', template_name='helpdesk/registration/change_password.html',
success_url='./done'), success_url='./done'),
name='password_change'), name='password_change'),
url(r'^password_change/done$', path('password_change/done',
auth_views.PasswordChangeDoneView.as_view( auth_views.PasswordChangeDoneView.as_view(
template_name='helpdesk/registration/change_password_done.html',), template_name='helpdesk/registration/change_password_done.html',),
name='password_change_done'), name='password_change_done'),
@ -237,29 +237,29 @@ urlpatterns += [
if helpdesk_settings.HELPDESK_KB_ENABLED: if helpdesk_settings.HELPDESK_KB_ENABLED:
urlpatterns += [ urlpatterns += [
url(r'^kb/$', path('kb/',
kb.index, kb.index,
name='kb_index'), name='kb_index'),
url(r'^kb/(?P<slug>[A-Za-z0-9_-]+)/$', re_path(r'^kb/(?P<slug>[A-Za-z0-9_-]+)/$',
kb.category, kb.category,
name='kb_category'), name='kb_category'),
url(r'^kb/(?P<item>[0-9]+)/vote/$', path('kb/<int:item>/vote/',
kb.vote, kb.vote,
name='kb_vote'), name='kb_vote'),
url(r'^kb_iframe/(?P<slug>[A-Za-z0-9_-]+)/$', re_path(r'^kb_iframe/(?P<slug>[A-Za-z0-9_-]+)/$',
kb.category_iframe, kb.category_iframe,
name='kb_category_iframe'), name='kb_category_iframe'),
] ]
urlpatterns += [ urlpatterns += [
url(r'^help/context/$', path('help/context/',
TemplateView.as_view(template_name='helpdesk/help_context.html'), TemplateView.as_view(template_name='helpdesk/help_context.html'),
name='help_context'), name='help_context'),
url(r'^system_settings/$', path('system_settings/',
login_required(DirectTemplateView.as_view(template_name='helpdesk/system_settings.html')), login_required(DirectTemplateView.as_view(template_name='helpdesk/system_settings.html')),
name='system_settings'), name='system_settings'),
] ]

View File

@ -11,7 +11,7 @@ from django.contrib.auth import get_user_model
from django.contrib.syndication.views import Feed from django.contrib.syndication.views import Feed
from django.urls import reverse from django.urls import reverse
from django.db.models import Q 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 django.shortcuts import get_object_or_404
from helpdesk.models import Ticket, FollowUp, Queue from helpdesk.models import Ticket, FollowUp, Queue

View File

@ -15,8 +15,8 @@ from django.core.exceptions import (
from django.urls import reverse from django.urls import reverse
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect
from django.shortcuts import render from django.shortcuts import render
from django.utils.http import urlquote from urllib.parse import quote
from django.utils.translation import ugettext as _ from django.utils.translation import gettext as _
from django.conf import settings from django.conf import settings
from django.views.decorators.clickjacking import xframe_options_exempt from django.views.decorators.clickjacking import xframe_options_exempt
from django.views.decorators.csrf import csrf_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' % ( return HttpResponseRedirect('%s?ticket=%s&email=%s&key=%s' % (
reverse('helpdesk:public_view'), reverse('helpdesk:public_view'),
ticket.ticket_for_url, ticket.ticket_for_url,
urlquote(ticket.submitter_email), quote(ticket.submitter_email),
ticket.secret_key) ticket.secret_key)
) )
except ValueError: except ValueError:

View File

@ -19,7 +19,7 @@ from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.db.models import Q from django.db.models import Q
from django.http import HttpResponseRedirect, Http404, HttpResponse, JsonResponse from django.http import HttpResponseRedirect, Http404, HttpResponse, JsonResponse
from django.shortcuts import render, get_object_or_404, redirect 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.html import escape
from django.utils import timezone from django.utils import timezone
from django.views.decorators.csrf import requires_csrf_token from django.views.decorators.csrf import requires_csrf_token