From 0d2df19835056e5d3b9c2d599e489af4fb021b1e Mon Sep 17 00:00:00 2001 From: Garret Wassermann Date: Thu, 28 Dec 2017 06:04:05 -0500 Subject: [PATCH 1/7] Fix collectstatic errors, as reported in #479 --- helpdesk/static/helpdesk/vendor/jquery-ui/jquery-ui.css | 1 - 1 file changed, 1 deletion(-) diff --git a/helpdesk/static/helpdesk/vendor/jquery-ui/jquery-ui.css b/helpdesk/static/helpdesk/vendor/jquery-ui/jquery-ui.css index 93707f4c..d1da601d 100644 --- a/helpdesk/static/helpdesk/vendor/jquery-ui/jquery-ui.css +++ b/helpdesk/static/helpdesk/vendor/jquery-ui/jquery-ui.css @@ -1,7 +1,6 @@ /*! jQuery UI - v1.12.1 - 2016-09-14 * http://jqueryui.com * Includes: core.css, accordion.css, autocomplete.css, menu.css, button.css, controlgroup.css, checkboxradio.css, datepicker.css, dialog.css, draggable.css, resizable.css, progressbar.css, selectable.css, selectmenu.css, slider.css, sortable.css, spinner.css, tabs.css, tooltip.css, theme.css -* To view and modify this theme, visit http://jqueryui.com/themeroller/?bgShadowXPos=&bgOverlayXPos=&bgErrorXPos=&bgHighlightXPos=&bgContentXPos=&bgHeaderXPos=&bgActiveXPos=&bgHoverXPos=&bgDefaultXPos=&bgShadowYPos=&bgOverlayYPos=&bgErrorYPos=&bgHighlightYPos=&bgContentYPos=&bgHeaderYPos=&bgActiveYPos=&bgHoverYPos=&bgDefaultYPos=&bgShadowRepeat=&bgOverlayRepeat=&bgErrorRepeat=&bgHighlightRepeat=&bgContentRepeat=&bgHeaderRepeat=&bgActiveRepeat=&bgHoverRepeat=&bgDefaultRepeat=&iconsHover=url(%22images%2Fui-icons_555555_256x240.png%22)&iconsHighlight=url(%22images%2Fui-icons_777620_256x240.png%22)&iconsHeader=url(%22images%2Fui-icons_444444_256x240.png%22)&iconsError=url(%22images%2Fui-icons_cc0000_256x240.png%22)&iconsDefault=url(%22images%2Fui-icons_777777_256x240.png%22)&iconsContent=url(%22images%2Fui-icons_444444_256x240.png%22)&iconsActive=url(%22images%2Fui-icons_ffffff_256x240.png%22)&bgImgUrlShadow=&bgImgUrlOverlay=&bgImgUrlHover=&bgImgUrlHighlight=&bgImgUrlHeader=&bgImgUrlError=&bgImgUrlDefault=&bgImgUrlContent=&bgImgUrlActive=&opacityFilterShadow=Alpha(Opacity%3D30)&opacityFilterOverlay=Alpha(Opacity%3D30)&opacityShadowPerc=30&opacityOverlayPerc=30&iconColorHover=%23555555&iconColorHighlight=%23777620&iconColorHeader=%23444444&iconColorError=%23cc0000&iconColorDefault=%23777777&iconColorContent=%23444444&iconColorActive=%23ffffff&bgImgOpacityShadow=0&bgImgOpacityOverlay=0&bgImgOpacityError=95&bgImgOpacityHighlight=55&bgImgOpacityContent=75&bgImgOpacityHeader=75&bgImgOpacityActive=65&bgImgOpacityHover=75&bgImgOpacityDefault=75&bgTextureShadow=flat&bgTextureOverlay=flat&bgTextureError=flat&bgTextureHighlight=flat&bgTextureContent=flat&bgTextureHeader=flat&bgTextureActive=flat&bgTextureHover=flat&bgTextureDefault=flat&cornerRadius=3px&fwDefault=normal&ffDefault=Arial%2CHelvetica%2Csans-serif&fsDefault=1em&cornerRadiusShadow=8px&thicknessShadow=5px&offsetLeftShadow=0px&offsetTopShadow=0px&opacityShadow=.3&bgColorShadow=%23666666&opacityOverlay=.3&bgColorOverlay=%23aaaaaa&fcError=%235f3f3f&borderColorError=%23f1a899&bgColorError=%23fddfdf&fcHighlight=%23777620&borderColorHighlight=%23dad55e&bgColorHighlight=%23fffa90&fcContent=%23333333&borderColorContent=%23dddddd&bgColorContent=%23ffffff&fcHeader=%23333333&borderColorHeader=%23dddddd&bgColorHeader=%23e9e9e9&fcActive=%23ffffff&borderColorActive=%23003eff&bgColorActive=%23007fff&fcHover=%232b2b2b&borderColorHover=%23cccccc&bgColorHover=%23ededed&fcDefault=%23454545&borderColorDefault=%23c5c5c5&bgColorDefault=%23f6f6f6 * Copyright jQuery Foundation and other contributors; Licensed MIT */ /* Layout helpers From f91762d4cd344e7a6c6122f31e7044e280980c90 Mon Sep 17 00:00:00 2001 From: Garret Wassermann Date: Thu, 28 Dec 2017 06:32:42 -0500 Subject: [PATCH 2/7] Bump version to 0.2.5, add STATIC_ROOT to demo config to test collectstatic --- demo/demodesk/config/settings.py | 2 ++ demo/setup.py | 2 +- setup.py | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/demo/demodesk/config/settings.py b/demo/demodesk/config/settings.py index 19425f0a..256f1f15 100644 --- a/demo/demodesk/config/settings.py +++ b/demo/demodesk/config/settings.py @@ -194,6 +194,8 @@ USE_TZ = True # https://docs.djangoproject.com/en/1.11/howto/static-files/ STATIC_URL = '/static/' +# static root needs to be defined in order to use collectstatic +STATIC_ROOT = os.path.join(BASE_DIR, 'static') # MEDIA_ROOT is where media uploads are stored. # We set this to a directory to host file attachments created diff --git a/demo/setup.py b/demo/setup.py index 998c5e69..2cfdd613 100644 --- a/demo/setup.py +++ b/demo/setup.py @@ -13,7 +13,7 @@ project_root = os.path.dirname(here) NAME = 'django-helpdesk-demodesk' DESCRIPTION = 'A demo Django project using django-helpdesk' README = open(os.path.join(here, 'README.rst')).read() -VERSION = '0.2.3' +VERSION = '0.2.5' #VERSION = open(os.path.join(project_root, 'VERSION')).read().strip() AUTHOR = 'django-helpdesk team' URL = 'https://github.com/django-helpdesk/django-helpdesk' diff --git a/setup.py b/setup.py index afb7cacb..7a8923c4 100644 --- a/setup.py +++ b/setup.py @@ -6,7 +6,7 @@ from distutils.util import convert_path from fnmatch import fnmatchcase from setuptools import setup, find_packages -version = '0.2.4' +version = '0.2.5' # Provided as an attribute, so you can append to these instead # of replicating them: From 5112f0dfd07527157157b73a8c20efffd92687fc Mon Sep 17 00:00:00 2001 From: Garret Wassermann Date: Thu, 28 Dec 2017 07:23:51 -0500 Subject: [PATCH 3/7] Address deprecation warnings to be compatible with Django 2.0 --- helpdesk/decorators.py | 4 +-- helpdesk/management/commands/get_email.py | 5 +++- helpdesk/migrations/0001_initial.py | 30 +++++++++---------- .../0004_add_per_queue_staff_membership.py | 2 +- .../0014_usersettings_related_name.py | 4 ++- helpdesk/models.py | 17 ++++++++++- helpdesk/tests/test_get_email.py | 8 ++--- helpdesk/views/public.py | 4 +-- helpdesk/views/staff.py | 10 +++---- quicktest.py | 5 ++-- 10 files changed, 55 insertions(+), 34 deletions(-) diff --git a/helpdesk/decorators.py b/helpdesk/decorators.py index 341c65e0..cb0adeac 100644 --- a/helpdesk/decorators.py +++ b/helpdesk/decorators.py @@ -14,9 +14,9 @@ def protect_view(view_func): """ @wraps(view_func, assigned=available_attrs(view_func)) def _wrapped_view(request, *args, **kwargs): - if not request.user.is_authenticated() and helpdesk_settings.HELPDESK_REDIRECT_TO_LOGIN_BY_DEFAULT: + if not request.user.is_authenticated and helpdesk_settings.HELPDESK_REDIRECT_TO_LOGIN_BY_DEFAULT: return HttpResponseRedirect(reverse('helpdesk:login')) - elif not request.user.is_authenticated() and helpdesk_settings.HELPDESK_ANON_ACCESS_RAISES_404: + elif not request.user.is_authenticated and helpdesk_settings.HELPDESK_ANON_ACCESS_RAISES_404: raise Http404 return view_func(request, *args, **kwargs) diff --git a/helpdesk/management/commands/get_email.py b/helpdesk/management/commands/get_email.py index 0a32f1f7..520ab3d5 100755 --- a/helpdesk/management/commands/get_email.py +++ b/helpdesk/management/commands/get_email.py @@ -374,7 +374,10 @@ def ticket_from_message(message, queue, logger): non_b64_err = TypeError try: logger.debug("Try to base64 decode the attachment payload") - payloadToWrite = base64.decodestring(payload) + if six.PY2: + payloadToWrite = base64.decodestring(payload) + else: + payloadToWrite = base64.decodebytes(payload) except non_b64_err: logger.debug("Payload was not base64 encoded, using raw bytes") payloadToWrite = payload diff --git a/helpdesk/migrations/0001_initial.py b/helpdesk/migrations/0001_initial.py index 2c157c6e..3bd49746 100644 --- a/helpdesk/migrations/0001_initial.py +++ b/helpdesk/migrations/0001_initial.py @@ -140,7 +140,7 @@ class Migration(migrations.Migration): ('votes', models.IntegerField(verbose_name='Votes', default=0, help_text='Total number of votes cast for this item')), ('recommendations', models.IntegerField(verbose_name='Positive Votes', default=0, help_text='Number of votes for this item which were POSITIVE.')), ('last_updated', models.DateTimeField(verbose_name='Last Updated', blank=True, help_text='The date on which this question was most recently changed.')), - ('category', models.ForeignKey(verbose_name='Category', to='helpdesk.KBCategory')), + ('category', models.ForeignKey(verbose_name='Category', to='helpdesk.KBCategory', on_delete=models.CASCADE)), ], options={ 'verbose_name_plural': 'Knowledge base items', @@ -203,7 +203,7 @@ class Migration(migrations.Migration): ('title', models.CharField(verbose_name='Query Name', help_text='User-provided name for this query', max_length=100)), ('shared', models.BooleanField(verbose_name='Shared With Other Users?', default=False, help_text='Should other users see this query?')), ('query', models.TextField(verbose_name='Search Query', help_text='Pickled query object. Be wary changing this.')), - ('user', models.ForeignKey(verbose_name='User', to=settings.AUTH_USER_MODEL)), + ('user', models.ForeignKey(verbose_name='User', to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), ], options={ 'verbose_name_plural': 'Saved searches', @@ -226,8 +226,8 @@ class Migration(migrations.Migration): ('priority', models.IntegerField(verbose_name='Priority', help_text='1 = Highest Priority, 5 = Low Priority', blank=3, default=3, choices=[(1, '1. Critical'), (2, '2. High'), (3, '3. Normal'), (4, '4. Low'), (5, '5. Very Low')])), ('due_date', models.DateTimeField(null=True, verbose_name='Due on', blank=True)), ('last_escalation', models.DateTimeField(editable=False, null=True, blank=True, help_text='The date this ticket was last escalated - updated automatically by management/commands/escalate_tickets.py.')), - ('assigned_to', models.ForeignKey(null=True, verbose_name='Assigned to', blank=True, related_name='assigned_to', to=settings.AUTH_USER_MODEL)), - ('queue', models.ForeignKey(verbose_name='Queue', to='helpdesk.Queue')), + ('assigned_to', models.ForeignKey(null=True, verbose_name='Assigned to', blank=True, related_name='assigned_to', to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), + ('queue', models.ForeignKey(verbose_name='Queue', to='helpdesk.Queue', on_delete=models.CASCADE)), ], options={ 'verbose_name_plural': 'Tickets', @@ -244,8 +244,8 @@ class Migration(migrations.Migration): ('email', models.EmailField(null=True, verbose_name='E-Mail Address', help_text='For non-user followers, enter their e-mail address', blank=True, max_length=75)), ('can_view', models.BooleanField(verbose_name='Can View Ticket?', default=False, help_text='Can this CC login to view the ticket details?')), ('can_update', models.BooleanField(verbose_name='Can Update Ticket?', default=False, help_text='Can this CC login and update the ticket?')), - ('ticket', models.ForeignKey(verbose_name='Ticket', to='helpdesk.Ticket')), - ('user', models.ForeignKey(null=True, verbose_name='User', blank=True, to=settings.AUTH_USER_MODEL, help_text='User who wishes to receive updates for this ticket.')), + ('ticket', models.ForeignKey(verbose_name='Ticket', to='helpdesk.Ticket', on_delete=models.CASCADE)), + ('user', models.ForeignKey(null=True, verbose_name='User', blank=True, to=settings.AUTH_USER_MODEL, help_text='User who wishes to receive updates for this ticket.', on_delete=models.CASCADE)), ], options={ }, @@ -258,7 +258,7 @@ class Migration(migrations.Migration): ('field', models.CharField(verbose_name='Field', max_length=100)), ('old_value', models.TextField(null=True, verbose_name='Old Value', blank=True)), ('new_value', models.TextField(null=True, verbose_name='New Value', blank=True)), - ('followup', models.ForeignKey(verbose_name='Follow-up', to='helpdesk.FollowUp')), + ('followup', models.ForeignKey(verbose_name='Follow-up', to='helpdesk.FollowUp', on_delete=models.CASCADE)), ], options={ 'verbose_name_plural': 'Ticket changes', @@ -271,8 +271,8 @@ class Migration(migrations.Migration): fields=[ ('id', models.AutoField(auto_created=True, verbose_name='ID', primary_key=True, serialize=False)), ('value', models.TextField(null=True, blank=True)), - ('field', models.ForeignKey(verbose_name='Field', to='helpdesk.CustomField')), - ('ticket', models.ForeignKey(verbose_name='Ticket', to='helpdesk.Ticket')), + ('field', models.ForeignKey(verbose_name='Field', to='helpdesk.CustomField', on_delete=models.CASCADE)), + ('ticket', models.ForeignKey(verbose_name='Ticket', to='helpdesk.Ticket', on_delete=models.CASCADE)), ], options={ 'verbose_name_plural': 'Ticket custom field values', @@ -284,8 +284,8 @@ class Migration(migrations.Migration): name='TicketDependency', fields=[ ('id', models.AutoField(auto_created=True, verbose_name='ID', primary_key=True, serialize=False)), - ('depends_on', models.ForeignKey(related_name='depends_on', verbose_name='Depends On Ticket', to='helpdesk.Ticket')), - ('ticket', models.ForeignKey(related_name='ticketdependency', verbose_name='Ticket', to='helpdesk.Ticket')), + ('depends_on', models.ForeignKey(related_name='depends_on', verbose_name='Depends On Ticket', to='helpdesk.Ticket', on_delete=models.CASCADE)), + ('ticket', models.ForeignKey(related_name='ticketdependency', verbose_name='Ticket', to='helpdesk.Ticket', on_delete=models.CASCADE)), ], options={ 'verbose_name_plural': 'Ticket dependencies', @@ -298,7 +298,7 @@ class Migration(migrations.Migration): fields=[ ('id', models.AutoField(auto_created=True, verbose_name='ID', primary_key=True, serialize=False)), ('settings_pickled', models.TextField(null=True, verbose_name='Settings Dictionary', blank=True, help_text='This is a base64-encoded representation of a pickled Python dictionary. Do not change this field via the admin.')), - ('user', models.OneToOneField(to=settings.AUTH_USER_MODEL)), + ('user', models.OneToOneField(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), ], options={ 'verbose_name_plural': 'User Settings', @@ -325,13 +325,13 @@ class Migration(migrations.Migration): migrations.AddField( model_name='followup', name='ticket', - field=models.ForeignKey(verbose_name='Ticket', to='helpdesk.Ticket'), + field=models.ForeignKey(verbose_name='Ticket', to='helpdesk.Ticket', on_delete=models.CASCADE), preserve_default=True, ), migrations.AddField( model_name='followup', name='user', - field=models.ForeignKey(null=True, verbose_name='User', blank=True, to=settings.AUTH_USER_MODEL), + field=models.ForeignKey(null=True, verbose_name='User', blank=True, to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE), preserve_default=True, ), migrations.AddField( @@ -343,7 +343,7 @@ class Migration(migrations.Migration): migrations.AddField( model_name='attachment', name='followup', - field=models.ForeignKey(verbose_name='Follow-up', to='helpdesk.FollowUp'), + field=models.ForeignKey(verbose_name='Follow-up', to='helpdesk.FollowUp', on_delete=models.CASCADE), preserve_default=True, ), ] diff --git a/helpdesk/migrations/0004_add_per_queue_staff_membership.py b/helpdesk/migrations/0004_add_per_queue_staff_membership.py index b2644039..1b96b3bc 100644 --- a/helpdesk/migrations/0004_add_per_queue_staff_membership.py +++ b/helpdesk/migrations/0004_add_per_queue_staff_membership.py @@ -18,7 +18,7 @@ class Migration(migrations.Migration): fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('queues', models.ManyToManyField(to='helpdesk.Queue', verbose_name='Authorized Queues')), - ('user', models.OneToOneField(verbose_name='User', to=settings.AUTH_USER_MODEL)), + ('user', models.OneToOneField(verbose_name='User', to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), ], options={ 'verbose_name': 'Queue Membership', diff --git a/helpdesk/migrations/0014_usersettings_related_name.py b/helpdesk/migrations/0014_usersettings_related_name.py index 133f90bc..ab58ee01 100644 --- a/helpdesk/migrations/0014_usersettings_related_name.py +++ b/helpdesk/migrations/0014_usersettings_related_name.py @@ -15,6 +15,8 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='usersettings', name='user', - field=models.OneToOneField(to=settings.AUTH_USER_MODEL, related_name='usersettings_helpdesk'), + field=models.OneToOneField(to=settings.AUTH_USER_MODEL, + related_name='usersettings_helpdesk', + on_delete=models.CASCADE), ), ] diff --git a/helpdesk/models.py b/helpdesk/models.py index 2ffc9c61..a45da370 100644 --- a/helpdesk/models.py +++ b/helpdesk/models.py @@ -255,11 +255,11 @@ class Queue(models.Model): default_owner = models.ForeignKey( settings.AUTH_USER_MODEL, + on_delete=models.SET_NULL, related_name='default_owner', blank=True, null=True, verbose_name=_('Default owner'), - on_delete=models.SET_NULL, ) def __str__(self): @@ -387,6 +387,7 @@ class Ticket(models.Model): queue = models.ForeignKey( Queue, + on_delete=models.CASCADE, verbose_name=_('Queue'), ) @@ -412,6 +413,7 @@ class Ticket(models.Model): assigned_to = models.ForeignKey( settings.AUTH_USER_MODEL, + on_delete=models.CASCADE, related_name='assigned_to', blank=True, null=True, @@ -628,6 +630,7 @@ class FollowUp(models.Model): ticket = models.ForeignKey( Ticket, + on_delete=models.CASCADE, verbose_name=_('Ticket'), ) @@ -659,6 +662,7 @@ class FollowUp(models.Model): user = models.ForeignKey( settings.AUTH_USER_MODEL, + on_delete=models.CASCADE, blank=True, null=True, verbose_name=_('User'), @@ -701,6 +705,7 @@ class TicketChange(models.Model): followup = models.ForeignKey( FollowUp, + on_delete=models.CASCADE, verbose_name=_('Follow-up'), ) @@ -763,6 +768,7 @@ class Attachment(models.Model): followup = models.ForeignKey( FollowUp, + on_delete=models.CASCADE, verbose_name=_('Follow-up'), ) @@ -976,6 +982,7 @@ class KBItem(models.Model): """ category = models.ForeignKey( KBCategory, + on_delete=models.CASCADE, verbose_name=_('Category'), ) @@ -1049,6 +1056,7 @@ class SavedSearch(models.Model): """ user = models.ForeignKey( settings.AUTH_USER_MODEL, + on_delete=models.CASCADE, verbose_name=_('User'), ) @@ -1093,6 +1101,7 @@ class UserSettings(models.Model): user = models.OneToOneField( settings.AUTH_USER_MODEL, + on_delete=models.CASCADE, related_name="usersettings_helpdesk") settings_pickled = models.TextField( @@ -1251,11 +1260,13 @@ class TicketCC(models.Model): ticket = models.ForeignKey( Ticket, + on_delete=models.CASCADE, verbose_name=_('Ticket'), ) user = models.ForeignKey( settings.AUTH_USER_MODEL, + on_delete=models.CASCADE, blank=True, null=True, help_text=_('User who wishes to receive updates for this ticket.'), @@ -1425,11 +1436,13 @@ class CustomField(models.Model): class TicketCustomFieldValue(models.Model): ticket = models.ForeignKey( Ticket, + on_delete=models.CASCADE, verbose_name=_('Ticket'), ) field = models.ForeignKey( CustomField, + on_delete=models.CASCADE, verbose_name=_('Field'), ) @@ -1458,12 +1471,14 @@ class TicketDependency(models.Model): ticket = models.ForeignKey( Ticket, + on_delete=models.CASCADE, verbose_name=_('Ticket'), related_name='ticketdependency', ) depends_on = models.ForeignKey( Ticket, + on_delete=models.CASCADE, verbose_name=_('Depends On Ticket'), related_name='depends_on', ) diff --git a/helpdesk/tests/test_get_email.py b/helpdesk/tests/test_get_email.py index e2c23e35..583eaddd 100644 --- a/helpdesk/tests/test_get_email.py +++ b/helpdesk/tests/test_get_email.py @@ -92,7 +92,7 @@ class GetEmailParametricTemplate(object): if self.socks: from socks import ProxyConnectionError - with self.assertRaisesRegexp(ProxyConnectionError, '%s:%s' % (unrouted_socks_server, unused_port)): + with self.assertRaisesRegex(ProxyConnectionError, '%s:%s' % (unrouted_socks_server, unused_port)): call_command('get_email') else: @@ -165,7 +165,7 @@ class GetEmailParametricTemplate(object): if self.socks: from socks import ProxyConnectionError - with self.assertRaisesRegexp(ProxyConnectionError, '%s:%s' % (unrouted_socks_server, unused_port)): + with self.assertRaisesRegex(ProxyConnectionError, '%s:%s' % (unrouted_socks_server, unused_port)): call_command('get_email') else: @@ -278,7 +278,7 @@ class GetEmailParametricTemplate(object): if self.socks: from socks import ProxyConnectionError - with self.assertRaisesRegexp(ProxyConnectionError, '%s:%s' % (unrouted_socks_server, unused_port)): + with self.assertRaisesRegex(ProxyConnectionError, '%s:%s' % (unrouted_socks_server, unused_port)): call_command('get_email') else: @@ -525,7 +525,7 @@ a9eiiQ+3V1v+7wWHXCzq if self.socks: from socks import ProxyConnectionError - with self.assertRaisesRegexp(ProxyConnectionError, '%s:%s' % (unrouted_socks_server, unused_port)): + with self.assertRaisesRegex(ProxyConnectionError, '%s:%s' % (unrouted_socks_server, unused_port)): call_command('get_email') else: diff --git a/helpdesk/views/public.py b/helpdesk/views/public.py index 9227e83d..f3f377e1 100644 --- a/helpdesk/views/public.py +++ b/helpdesk/views/public.py @@ -23,7 +23,7 @@ from helpdesk.models import Ticket, Queue, UserSettings, KBCategory @protect_view def homepage(request): if request.user.is_staff or \ - (request.user.is_authenticated() and + (request.user.is_authenticated and helpdesk_settings.HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE): try: if request.user.usersettings_helpdesk.settings.get('login_view_ticketlist', False): @@ -61,7 +61,7 @@ def homepage(request): if queue: initial_data['queue'] = queue.id - if request.user.is_authenticated() and request.user.email: + if request.user.is_authenticated and request.user.email: initial_data['submitter_email'] = request.user.email form = PublicTicketForm(initial=initial_data) diff --git a/helpdesk/views/staff.py b/helpdesk/views/staff.py index 34e766ad..f3c00175 100644 --- a/helpdesk/views/staff.py +++ b/helpdesk/views/staff.py @@ -46,14 +46,14 @@ User = get_user_model() if helpdesk_settings.HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE: # treat 'normal' users like 'staff' staff_member_required = user_passes_test( - lambda u: u.is_authenticated() and u.is_active) + lambda u: u.is_authenticated and u.is_active) else: staff_member_required = user_passes_test( - lambda u: u.is_authenticated() and u.is_active and u.is_staff) + lambda u: u.is_authenticated and u.is_active and u.is_staff) superuser_required = user_passes_test( - lambda u: u.is_authenticated() and u.is_active and u.is_superuser) + lambda u: u.is_authenticated and u.is_active and u.is_superuser) def _get_user_queues(user): @@ -387,7 +387,7 @@ def subscribe_staff_member_to_ticket(ticket, user): def update_ticket(request, ticket_id, public=False): if not (public or ( - request.user.is_authenticated() and + request.user.is_authenticated and request.user.is_active and ( request.user.is_staff or helpdesk_settings.HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE))): @@ -644,7 +644,7 @@ def update_ticket(request, ticket_id, public=False): ticket.save() # auto subscribe user if enabled - if helpdesk_settings.HELPDESK_AUTO_SUBSCRIBE_ON_TICKET_RESPONSE and request.user.is_authenticated(): + if helpdesk_settings.HELPDESK_AUTO_SUBSCRIBE_ON_TICKET_RESPONSE and request.user.is_authenticated: ticketcc_string, SHOW_SUBSCRIBE = return_ticketccstring_and_show_subscribe(request.user, ticket) if SHOW_SUBSCRIBE: subscribe_staff_member_to_ticket(ticket, request.user) diff --git a/quicktest.py b/quicktest.py index e72d56ff..371696fb 100644 --- a/quicktest.py +++ b/quicktest.py @@ -29,7 +29,8 @@ class QuickDjangoTest(object): 'django.contrib.staticfiles', 'bootstrapform', ) - MIDDLEWARE_CLASSES = [ + MIDDLEWARE = [ + 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', @@ -78,7 +79,7 @@ class QuickDjangoTest(object): } }, INSTALLED_APPS=self.INSTALLED_APPS + self.apps, - MIDDLEWARE_CLASSES=self.MIDDLEWARE_CLASSES, + MIDDLEWARE=self.MIDDLEWARE, ROOT_URLCONF='helpdesk.tests.urls', STATIC_URL='/static/', TEMPLATES=self.TEMPLATES From d18ce1f1d54a4d8c0b4e0d9770fce5236de9a917 Mon Sep 17 00:00:00 2001 From: Garret Wassermann Date: Thu, 28 Dec 2017 09:11:34 -0500 Subject: [PATCH 4/7] Bump version to 0.2.6 to fix remaining Django 2.0 warnings --- demo/setup.py | 2 +- helpdesk/decorators.py | 2 +- helpdesk/forms.py | 2 +- helpdesk/models.py | 16 ++++++++-------- helpdesk/templatetags/ticket_to_link.py | 2 +- helpdesk/tests/helpers.py | 4 ++-- helpdesk/tests/test_attachments.py | 2 +- helpdesk/tests/test_navigation.py | 4 ++-- .../tests/test_per_queue_staff_permission.py | 2 +- helpdesk/tests/test_public_actions.py | 2 +- helpdesk/tests/test_savequery.py | 2 +- helpdesk/tests/test_ticket_actions.py | 2 +- helpdesk/tests/test_ticket_lookup.py | 2 +- helpdesk/tests/test_ticket_submission.py | 2 +- helpdesk/tests/test_usersettings.py | 2 +- helpdesk/views/feeds.py | 2 +- helpdesk/views/public.py | 2 +- helpdesk/views/staff.py | 2 +- setup.py | 2 +- 19 files changed, 28 insertions(+), 28 deletions(-) diff --git a/demo/setup.py b/demo/setup.py index 2cfdd613..fbcebce1 100644 --- a/demo/setup.py +++ b/demo/setup.py @@ -13,7 +13,7 @@ project_root = os.path.dirname(here) NAME = 'django-helpdesk-demodesk' DESCRIPTION = 'A demo Django project using django-helpdesk' README = open(os.path.join(here, 'README.rst')).read() -VERSION = '0.2.5' +VERSION = '0.2.6' #VERSION = open(os.path.join(project_root, 'VERSION')).read().strip() AUTHOR = 'django-helpdesk team' URL = 'https://github.com/django-helpdesk/django-helpdesk' diff --git a/helpdesk/decorators.py b/helpdesk/decorators.py index cb0adeac..47dc5911 100644 --- a/helpdesk/decorators.py +++ b/helpdesk/decorators.py @@ -1,6 +1,6 @@ from functools import wraps -from django.core.urlresolvers import reverse +from django.urls import reverse from django.http import HttpResponseRedirect, Http404 from django.utils.decorators import available_attrs diff --git a/helpdesk/forms.py b/helpdesk/forms.py index 7ab2024f..1195e5d0 100644 --- a/helpdesk/forms.py +++ b/helpdesk/forms.py @@ -11,7 +11,7 @@ forms.py - Definitions of newforms-based forms for creating and maintaining from django.core.exceptions import ObjectDoesNotExist from django.utils.six import StringIO from django import forms -from django.forms import extras +from django.forms import widgets from django.conf import settings from django.utils.translation import ugettext_lazy as _ from django.contrib.auth import get_user_model diff --git a/helpdesk/models.py b/helpdesk/models.py index a45da370..a1978346 100644 --- a/helpdesk/models.py +++ b/helpdesk/models.py @@ -528,7 +528,7 @@ class Ticket(models.Model): """ from django.contrib.sites.models import Site from django.core.exceptions import ImproperlyConfigured - from django.core.urlresolvers import reverse + from django.urls import reverse try: site = Site.objects.get_current() except ImproperlyConfigured: @@ -548,7 +548,7 @@ class Ticket(models.Model): """ from django.contrib.sites.models import Site from django.core.exceptions import ImproperlyConfigured - from django.core.urlresolvers import reverse + from django.urls import reverse try: site = Site.objects.get_current() except ImproperlyConfigured: @@ -581,8 +581,8 @@ class Ticket(models.Model): return '%s %s' % (self.id, self.title) def get_absolute_url(self): - return 'helpdesk:view', (self.id,) - get_absolute_url = models.permalink(get_absolute_url) + from django.urls import reverse + return reverse('helpdesk:view', args=(self.id,)) def save(self, *args, **kwargs): if not self.id: @@ -970,8 +970,8 @@ class KBCategory(models.Model): verbose_name_plural = _('Knowledge base categories') def get_absolute_url(self): - return 'helpdesk:kb_category', (), {'slug': self.slug} - get_absolute_url = models.permalink(get_absolute_url) + from django.urls import reverse + return reverse('helpdesk:kb_category', kwargs={'slug': self.slug}) @python_2_unicode_compatible @@ -1038,8 +1038,8 @@ class KBItem(models.Model): verbose_name_plural = _('Knowledge base items') def get_absolute_url(self): - return 'helpdesk:kb_item', (self.id,) - get_absolute_url = models.permalink(get_absolute_url) + from django.urls import reverse + return reverse('helpdesk:kb_item', args=(self.id,)) @python_2_unicode_compatible diff --git a/helpdesk/templatetags/ticket_to_link.py b/helpdesk/templatetags/ticket_to_link.py index 772a3984..f62f590b 100644 --- a/helpdesk/templatetags/ticket_to_link.py +++ b/helpdesk/templatetags/ticket_to_link.py @@ -14,7 +14,7 @@ templatetags/ticket_to_link.py - Used in ticket comments to allow wiki-style import re from django import template -from django.core.urlresolvers import reverse +from django.urls import reverse from django.utils.safestring import mark_safe from helpdesk.models import Ticket diff --git a/helpdesk/tests/helpers.py b/helpdesk/tests/helpers.py index 09055adc..efebe389 100644 --- a/helpdesk/tests/helpers.py +++ b/helpdesk/tests/helpers.py @@ -20,7 +20,7 @@ def get_staff_user(username='helpdesk.staff', password='password'): def reload_urlconf(urlconf=None): - from imp import reload # python 3 needs this import. + from importlib import reload # python 3 needs this import. if urlconf is None: from django.conf import settings @@ -33,7 +33,7 @@ def reload_urlconf(urlconf=None): if urlconf in sys.modules: reload(sys.modules[urlconf]) - from django.core.urlresolvers import clear_url_caches + from django.urls import clear_url_caches clear_url_caches() diff --git a/helpdesk/tests/test_attachments.py b/helpdesk/tests/test_attachments.py index dbc53d51..ebc6a8d9 100644 --- a/helpdesk/tests/test_attachments.py +++ b/helpdesk/tests/test_attachments.py @@ -6,7 +6,7 @@ import shutil from tempfile import gettempdir from django.core.files.uploadedfile import SimpleUploadedFile -from django.core.urlresolvers import reverse +from django.urls import reverse from django.test import override_settings, TestCase from django.utils.encoding import smart_text diff --git a/helpdesk/tests/test_navigation.py b/helpdesk/tests/test_navigation.py index 4ea6567f..1bde969a 100644 --- a/helpdesk/tests/test_navigation.py +++ b/helpdesk/tests/test_navigation.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from django.core.urlresolvers import reverse +from django.urls import reverse from django.test import TestCase from helpdesk.tests.helpers import get_staff_user, reload_urlconf @@ -23,7 +23,7 @@ class TestKBDisabled(TestCase): def test_navigation(self): """Test proper rendering of navigation.html by accessing the dashboard""" - from django.core.urlresolvers import NoReverseMatch + from django.urls import NoReverseMatch self.client.login(username=get_staff_user().get_username(), password='password') self.assertRaises(NoReverseMatch, reverse, 'helpdesk:kb_index') diff --git a/helpdesk/tests/test_per_queue_staff_permission.py b/helpdesk/tests/test_per_queue_staff_permission.py index 5e93ad9c..f1bd8be7 100644 --- a/helpdesk/tests/test_per_queue_staff_permission.py +++ b/helpdesk/tests/test_per_queue_staff_permission.py @@ -1,6 +1,6 @@ from django.contrib.auth import get_user_model from django.contrib.auth.models import Permission -from django.core.urlresolvers import reverse +from django.urls import reverse from django.test import TestCase from django.test.client import Client diff --git a/helpdesk/tests/test_public_actions.py b/helpdesk/tests/test_public_actions.py index 38adc422..a88a1c8e 100644 --- a/helpdesk/tests/test_public_actions.py +++ b/helpdesk/tests/test_public_actions.py @@ -1,7 +1,7 @@ from helpdesk.models import Queue, Ticket from django.test import TestCase from django.test.client import Client -from django.core.urlresolvers import reverse +from django.urls import reverse class PublicActionsTestCase(TestCase): diff --git a/helpdesk/tests/test_savequery.py b/helpdesk/tests/test_savequery.py index 5aaa7086..8838b597 100644 --- a/helpdesk/tests/test_savequery.py +++ b/helpdesk/tests/test_savequery.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from django.core.urlresolvers import reverse +from django.urls import reverse from django.test import TestCase from helpdesk.models import Queue from helpdesk.tests.helpers import get_staff_user diff --git a/helpdesk/tests/test_ticket_actions.py b/helpdesk/tests/test_ticket_actions.py index 7058ca03..a5c82bf3 100644 --- a/helpdesk/tests/test_ticket_actions.py +++ b/helpdesk/tests/test_ticket_actions.py @@ -1,6 +1,6 @@ from django.contrib.auth import get_user_model from django.core import mail -from django.core.urlresolvers import reverse +from django.urls import reverse from django.test import TestCase from django.test.client import Client from helpdesk.models import CustomField, Queue, Ticket diff --git a/helpdesk/tests/test_ticket_lookup.py b/helpdesk/tests/test_ticket_lookup.py index d98406a1..fa2b516a 100644 --- a/helpdesk/tests/test_ticket_lookup.py +++ b/helpdesk/tests/test_ticket_lookup.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from django.core.urlresolvers import reverse +from django.urls import reverse from django.test import TestCase from helpdesk.models import Ticket, Queue diff --git a/helpdesk/tests/test_ticket_submission.py b/helpdesk/tests/test_ticket_submission.py index a88c7121..e21cd4fb 100644 --- a/helpdesk/tests/test_ticket_submission.py +++ b/helpdesk/tests/test_ticket_submission.py @@ -2,7 +2,7 @@ from helpdesk.models import Queue, CustomField, Ticket from django.test import TestCase from django.core import mail from django.test.client import Client -from django.core.urlresolvers import reverse +from django.urls import reverse try: # python 3 from urllib.parse import urlparse diff --git a/helpdesk/tests/test_usersettings.py b/helpdesk/tests/test_usersettings.py index 25776ce9..67ed23f8 100644 --- a/helpdesk/tests/test_usersettings.py +++ b/helpdesk/tests/test_usersettings.py @@ -1,6 +1,6 @@ from django.contrib.auth import get_user_model from django.core import mail -from django.core.urlresolvers import reverse +from django.urls import reverse from django.test import TestCase from django.test.client import Client from helpdesk.models import CustomField, Queue, Ticket diff --git a/helpdesk/views/feeds.py b/helpdesk/views/feeds.py index 08fc74ef..aca10630 100644 --- a/helpdesk/views/feeds.py +++ b/helpdesk/views/feeds.py @@ -9,7 +9,7 @@ views/feeds.py - A handful of staff-only RSS feeds to provide ticket details from django.contrib.auth import get_user_model from django.contrib.syndication.views import Feed -from django.core.urlresolvers import reverse +from django.urls import reverse from django.db.models import Q from django.utils.translation import ugettext as _ from django.shortcuts import get_object_or_404 diff --git a/helpdesk/views/public.py b/helpdesk/views/public.py index f3f377e1..bde6a8ea 100644 --- a/helpdesk/views/public.py +++ b/helpdesk/views/public.py @@ -7,7 +7,7 @@ views/public.py - All public facing views, eg non-staff (no authentication required) views. """ from django.core.exceptions import ObjectDoesNotExist -from django.core.urlresolvers import reverse +from django.urls import reverse from django.http import HttpResponseRedirect from django.shortcuts import render from django.utils.http import urlquote diff --git a/helpdesk/views/staff.py b/helpdesk/views/staff.py index f3c00175..4bca4841 100644 --- a/helpdesk/views/staff.py +++ b/helpdesk/views/staff.py @@ -12,7 +12,7 @@ from datetime import datetime, timedelta from django.conf import settings from django.contrib.auth import get_user_model from django.contrib.auth.decorators import user_passes_test -from django.core.urlresolvers import reverse +from django.urls import reverse from django.core.exceptions import ValidationError, PermissionDenied from django.db import connection from django.db.models import Q diff --git a/setup.py b/setup.py index 7a8923c4..a33e8fed 100644 --- a/setup.py +++ b/setup.py @@ -6,7 +6,7 @@ from distutils.util import convert_path from fnmatch import fnmatchcase from setuptools import setup, find_packages -version = '0.2.5' +version = '0.2.6' # Provided as an attribute, so you can append to these instead # of replicating them: From 4b78704180e1873ff57fa3c61a87593eddf8b185 Mon Sep 17 00:00:00 2001 From: Garret Wassermann Date: Thu, 28 Dec 2017 09:22:57 -0500 Subject: [PATCH 5/7] Fix error on python 2 --- helpdesk/tests/helpers.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/helpdesk/tests/helpers.py b/helpdesk/tests/helpers.py index efebe389..02147bb1 100644 --- a/helpdesk/tests/helpers.py +++ b/helpdesk/tests/helpers.py @@ -20,7 +20,9 @@ def get_staff_user(username='helpdesk.staff', password='password'): def reload_urlconf(urlconf=None): - from importlib import reload # python 3 needs this import. + from django.utils import six + if six.PY3: + from importlib import reload if urlconf is None: from django.conf import settings From aa63e8f2999959d0d7ae192da2d980898869f50f Mon Sep 17 00:00:00 2001 From: Garret Wassermann Date: Thu, 28 Dec 2017 09:26:14 -0500 Subject: [PATCH 6/7] Really fix py 2 imp/importlib --- helpdesk/tests/helpers.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/helpdesk/tests/helpers.py b/helpdesk/tests/helpers.py index 02147bb1..5d6c6bfc 100644 --- a/helpdesk/tests/helpers.py +++ b/helpdesk/tests/helpers.py @@ -21,7 +21,9 @@ def get_staff_user(username='helpdesk.staff', password='password'): def reload_urlconf(urlconf=None): from django.utils import six - if six.PY3: + if six.PY2: + from imp import reload + else: from importlib import reload if urlconf is None: From bad1ece1c5db6735f5dd97e0b52470e7845d47e7 Mon Sep 17 00:00:00 2001 From: Garret Wassermann Date: Fri, 29 Dec 2017 01:03:16 -0500 Subject: [PATCH 7/7] Remove offending CSS comment again to address #479 --- helpdesk/static/helpdesk/vendor/jquery-ui/jquery-ui.theme.css | 1 - 1 file changed, 1 deletion(-) diff --git a/helpdesk/static/helpdesk/vendor/jquery-ui/jquery-ui.theme.css b/helpdesk/static/helpdesk/vendor/jquery-ui/jquery-ui.theme.css index 6089438c..50ecb9bf 100644 --- a/helpdesk/static/helpdesk/vendor/jquery-ui/jquery-ui.theme.css +++ b/helpdesk/static/helpdesk/vendor/jquery-ui/jquery-ui.theme.css @@ -8,7 +8,6 @@ * * http://api.jqueryui.com/category/theming/ * - * To view and modify this theme, visit http://jqueryui.com/themeroller/?bgShadowXPos=&bgOverlayXPos=&bgErrorXPos=&bgHighlightXPos=&bgContentXPos=&bgHeaderXPos=&bgActiveXPos=&bgHoverXPos=&bgDefaultXPos=&bgShadowYPos=&bgOverlayYPos=&bgErrorYPos=&bgHighlightYPos=&bgContentYPos=&bgHeaderYPos=&bgActiveYPos=&bgHoverYPos=&bgDefaultYPos=&bgShadowRepeat=&bgOverlayRepeat=&bgErrorRepeat=&bgHighlightRepeat=&bgContentRepeat=&bgHeaderRepeat=&bgActiveRepeat=&bgHoverRepeat=&bgDefaultRepeat=&iconsHover=url(%22images%2Fui-icons_555555_256x240.png%22)&iconsHighlight=url(%22images%2Fui-icons_777620_256x240.png%22)&iconsHeader=url(%22images%2Fui-icons_444444_256x240.png%22)&iconsError=url(%22images%2Fui-icons_cc0000_256x240.png%22)&iconsDefault=url(%22images%2Fui-icons_777777_256x240.png%22)&iconsContent=url(%22images%2Fui-icons_444444_256x240.png%22)&iconsActive=url(%22images%2Fui-icons_ffffff_256x240.png%22)&bgImgUrlShadow=&bgImgUrlOverlay=&bgImgUrlHover=&bgImgUrlHighlight=&bgImgUrlHeader=&bgImgUrlError=&bgImgUrlDefault=&bgImgUrlContent=&bgImgUrlActive=&opacityFilterShadow=Alpha(Opacity%3D30)&opacityFilterOverlay=Alpha(Opacity%3D30)&opacityShadowPerc=30&opacityOverlayPerc=30&iconColorHover=%23555555&iconColorHighlight=%23777620&iconColorHeader=%23444444&iconColorError=%23cc0000&iconColorDefault=%23777777&iconColorContent=%23444444&iconColorActive=%23ffffff&bgImgOpacityShadow=0&bgImgOpacityOverlay=0&bgImgOpacityError=95&bgImgOpacityHighlight=55&bgImgOpacityContent=75&bgImgOpacityHeader=75&bgImgOpacityActive=65&bgImgOpacityHover=75&bgImgOpacityDefault=75&bgTextureShadow=flat&bgTextureOverlay=flat&bgTextureError=flat&bgTextureHighlight=flat&bgTextureContent=flat&bgTextureHeader=flat&bgTextureActive=flat&bgTextureHover=flat&bgTextureDefault=flat&cornerRadius=3px&fwDefault=normal&ffDefault=Arial%2CHelvetica%2Csans-serif&fsDefault=1em&cornerRadiusShadow=8px&thicknessShadow=5px&offsetLeftShadow=0px&offsetTopShadow=0px&opacityShadow=.3&bgColorShadow=%23666666&opacityOverlay=.3&bgColorOverlay=%23aaaaaa&fcError=%235f3f3f&borderColorError=%23f1a899&bgColorError=%23fddfdf&fcHighlight=%23777620&borderColorHighlight=%23dad55e&bgColorHighlight=%23fffa90&fcContent=%23333333&borderColorContent=%23dddddd&bgColorContent=%23ffffff&fcHeader=%23333333&borderColorHeader=%23dddddd&bgColorHeader=%23e9e9e9&fcActive=%23ffffff&borderColorActive=%23003eff&bgColorActive=%23007fff&fcHover=%232b2b2b&borderColorHover=%23cccccc&bgColorHover=%23ededed&fcDefault=%23454545&borderColorDefault=%23c5c5c5&bgColorDefault=%23f6f6f6 */