diff --git a/README b/README
index 17e2bf1f..7b98cfe8 100644
--- a/README
+++ b/README
@@ -11,6 +11,7 @@ Jutda Helpdesk - A Django powered ticket tracker for small enterprise.
3. Installation
4. Initial Configuration
5. API Usage
+6. Thank You
#########################
1. Licensing
@@ -104,7 +105,7 @@ LICENSE.JQUERY and LICENSE.NICEDIT for their respective license terms.
Don't forget to set the relevant Django environment variables in your
crontab:
- */5 * * * * DJANGO_SETTINGS_MODULE='myproject.settings' python /path/to/helpdesk/scripts/get_email.py
+ */5 * * * * /path/to/helpdesksite/manage.py get_email
This will run the e-mail import every 5 minutes
@@ -114,7 +115,7 @@ LICENSE.JQUERY and LICENSE.NICEDIT for their respective license terms.
4. If you wish to automatically escalate tickets based on their age, set up
a cronjob to run scripts/escalate_tickets.py on a regular basis:
- 0 * * * * DJANGO_SETTINGS_MODULE='myproject.settings' python /path/to/helpdesk/scripts/escalate_tickets.py
+ 0 * * * * /path/to/helpdesksite/manage.py escalate_tickets.py
This will run the escalation process hourly, using the 'Escalation Hours'
setting for each queue to determine which tickets to escalate.
@@ -123,7 +124,7 @@ LICENSE.JQUERY and LICENSE.NICEDIT for their respective license terms.
the dates manually via the Admin, or setup a cronjob to run
scripts/create_escalation_exclusions.py on a regular basis:
- 0 0 * * 0 DJANGO_SETTINGS_MODULE='myproject.settings' python /path/to/helpdesk/scripts/create_escalation_exclusions.py --days saturday,sunday --verbose
+ 0 0 * * 0 /path/to/helpdesksite/manage.py create_escalation_exclusions.py --days saturday,sunday --verbose
This will, on a weekly basis, create exclusions for the coming weekend.
@@ -138,3 +139,18 @@ you to create and alter tickets from 3rd party software and systems.
For usage instructions and command syntax, see the file
templates/helpdesk/api_help.html, or visit http://helpdesk/api/help/.
+
+#########################
+6. Thank You
+#########################
+
+While this started as a project to suit my own needs, since publishing the
+code a number of people have made some fantastic improvements and provided
+bug fixes and updates as the Django codebase has moved on and caused small
+portions of this application to break.
+
+To these people, my sincere thanks:
+
+David Clymer
+Chris Etcp
+Nikolay Panov
diff --git a/forms.py b/forms.py
index d87e5539..73f40a4f 100644
--- a/forms.py
+++ b/forms.py
@@ -57,7 +57,7 @@ class TicketForm(forms.Form):
try:
u = User.objects.get(id=self.cleaned_data['assigned_to'])
t.assigned_to = u
- except:
+ except User.DoesNotExist:
t.assigned_to = None
t.save()
diff --git a/scripts/__init__.py b/management/__init__.py
similarity index 100%
rename from scripts/__init__.py
rename to management/__init__.py
diff --git a/management/commands/__init__.py b/management/commands/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/scripts/create_escalation_exclusions.py b/management/commands/create_escalation_exclusions.py
similarity index 61%
rename from scripts/create_escalation_exclusions.py
rename to management/commands/create_escalation_exclusions.py
index 27e16bda..e497e15a 100644
--- a/scripts/create_escalation_exclusions.py
+++ b/management/commands/create_escalation_exclusions.py
@@ -13,6 +13,58 @@ from django.db.models import Q
from helpdesk.models import EscalationExclusion, Queue
import sys, getopt
+from django.core.management.base import BaseCommand, CommandError
+from optparse import make_option
+
+class Command(BaseCommand):
+ def __init__(self):
+ BaseCommand.__init__(self)
+
+ self.option_list += (
+ make_option(
+ '--days', '-d',
+ help='Days of week (monday, tuesday, etc)'),
+ make_option(
+ '--occurrences', '-o',
+ type='int',
+ default=1,
+ help='Occurrences: How many weeks ahead to exclude this day'),
+ make_option(
+ '--queues', '-q',
+ help='Queues to include (default: all). Use queue slugs'),
+ make_option(
+ '--verbose', '-v',
+ action='store_true',
+ default=False,
+ help='Display a list of dates excluded'),
+ )
+
+ def handle(self, *args, **options):
+ days = options['days']
+ occurrences = options['occurrences']
+ verbose = False
+ queue_slugs = options['queues']
+ queues = []
+
+ if options['verbose']:
+ verbose = True
+
+ # this should already be handled by optparse
+ if not occurrences: occurrences = 1
+ if not (days and occurrences):
+ raise CommandError('One or more occurrences must be specified.')
+
+ if queue_slugs is not None:
+ queue_set = queue_slugs.split(',')
+ for queue in queue_set:
+ try:
+ q = Queue.objects.get(slug__exact=queue)
+ except Queue.DoesNotExist:
+ raise CommandError("Queue %s does not exist." % queue)
+ queues.append(q)
+
+ create_exclusions(days=days, occurrences=occurrences, verbose=verbose, queues=queues)
+
day_names = {
'monday': 0,
'tuesday': 1,
@@ -88,7 +140,7 @@ if __name__ == '__main__':
for queue in queue_set:
try:
q = Queue.objects.get(slug__exact=queue)
- except:
+ except Queue.DoesNotExist:
print "Queue %s does not exist." % queue
sys.exit(2)
queues.append(q)
diff --git a/scripts/escalate_tickets.py b/management/commands/escalate_tickets.py
similarity index 75%
rename from scripts/escalate_tickets.py
rename to management/commands/escalate_tickets.py
index e4970f7f..885926c6 100644
--- a/scripts/escalate_tickets.py
+++ b/management/commands/escalate_tickets.py
@@ -15,6 +15,45 @@ from django.utils.translation import ugettext as _
from helpdesk.models import Queue, Ticket, FollowUp, EscalationExclusion, TicketChange
from helpdesk.lib import send_templated_mail
+
+from django.core.management.base import BaseCommand
+from optparse import make_option
+
+class Command(BaseCommand):
+ def __init__(self):
+ BaseCommand.__init__(self)
+
+ self.option_list += (
+ make_option(
+ '--queues', '-q',
+ help='Queues to include (default: all). Use queue slugs'),
+ make_option(
+ '--verbose', '-v',
+ action='store_true',
+ default=False,
+ help='Display a list of dates excluded'),
+ )
+
+ def handle(self, *args, **options):
+ verbose = False
+ queue_slugs = None
+ queues = []
+
+ if options['verbose']:
+ verbose = True
+ if options['queues']:
+ queue_slugs = options['queues']
+
+ if queue_slugs is not None:
+ queue_set = queue_slugs.split(',')
+ for queue in queue_set:
+ try:
+ q = Queue.objects.get(slug__exact=queue)
+ except Queue.DoesNotExist:
+ raise CommandError("Queue %s does not exist." % queue)
+ queues.append(queue)
+
+ escalate_tickets(queues=queues, verbose=verbose)
def escalate_tickets(queues, verbose):
""" Only include queues with escalation configured """
@@ -47,7 +86,7 @@ def escalate_tickets(queues, verbose):
context = {
'ticket': t,
- 'queue': queue,
+ 'queue': q,
}
if t.submitter_email:
@@ -106,7 +145,7 @@ if __name__ == '__main__':
for queue in queue_set:
try:
q = Queue.objects.get(slug__exact=queue)
- except:
+ except Queue.DoesNotExist:
print "Queue %s does not exist." % queue
sys.exit(2)
queues.append(queue)
diff --git a/scripts/get_email.py b/management/commands/get_email.py
similarity index 95%
rename from scripts/get_email.py
rename to management/commands/get_email.py
index 94147dc0..a457d3e8 100644
--- a/scripts/get_email.py
+++ b/management/commands/get_email.py
@@ -19,6 +19,12 @@ from helpdesk.lib import send_templated_mail
from django.core.files.base import ContentFile
+from django.core.management.base import BaseCommand
+
+class Command(BaseCommand):
+ def handle(self, *args, **options):
+ process_email()
+
def process_email():
for q in Queue.objects.filter(email_box_type__isnull=False, allow_email_submission=True):
if not q.email_box_last_check: q.email_box_last_check = datetime.now()-timedelta(minutes=30)
@@ -89,7 +95,7 @@ def ticket_from_message(message, queue):
counter = 0
files = []
for part in message.walk():
- if part.get_main_type() == 'multipart':
+ if part.get_content_maintype() == 'multipart':
continue
name = part.get_param("name")
@@ -97,7 +103,7 @@ def ticket_from_message(message, queue):
if part.get_content_maintype() == 'text' and name == None:
body = part.get_payload()
else:
- if name == None:
+ if not name:
ext = mimetypes.guess_extension(part.get_content_type())
name = "part-%i%s" % (counter, ext)
files.append({'filename': name, 'content': part.get_payload(decode=True), 'type': part.get_content_type()})
@@ -110,7 +116,7 @@ def ticket_from_message(message, queue):
try:
t = Ticket.objects.get(id=ticket)
new = False
- except:
+ except Ticket.DoesNotExist:
ticket = None
priority = 3
diff --git a/templates/helpdesk/public_view_ticket.html b/templates/helpdesk/public_view_ticket.html
index b5f91457..b9fea7c6 100644
--- a/templates/helpdesk/public_view_ticket.html
+++ b/templates/helpdesk/public_view_ticket.html
@@ -13,7 +13,7 @@
{{ ticket.id }}. {{ ticket.title }} [{{ ticket.get_status }}] |
-{% blocktrans %}Queue: {{ ticket.queue }}{% endblocktrans %} |
+{% blocktrans with ticket.queue as queue_name %}Queue: {{ queue_name }}{% endblocktrans %} |
{% trans "Submitted On" %} |
diff --git a/templatetags/ticket_to_link.py b/templatetags/ticket_to_link.py
index 0211e74d..403118a2 100644
--- a/templatetags/ticket_to_link.py
+++ b/templatetags/ticket_to_link.py
@@ -41,7 +41,7 @@ def num_to_link(text):
url = reverse('helpdesk_view', args=[number])
try:
ticket = Ticket.objects.get(id=number)
- except:
+ except Ticket.DoesNotExist:
ticket = None
if ticket:
diff --git a/views/api.py b/views/api.py
index 243fcc85..34e7d602 100644
--- a/views/api.py
+++ b/views/api.py
@@ -107,7 +107,7 @@ class API:
try:
u = User.objects.get(username=username)
return api_return(STATUS_OK, "%s" % u.id)
- except:
+ except User.DoesNotExist:
return api_return(STATUS_ERROR, "Invalid username provided")
@@ -117,7 +117,7 @@ class API:
try:
ticket = Ticket.objects.get(id=self.request.POST.get('ticket', False))
- except:
+ except Ticket.DoesNotExist:
return api_return(STATUS_ERROR, "Invalid ticket ID")
ticket.delete()
@@ -127,7 +127,7 @@ class API:
def api_public_hold_ticket(self):
try:
ticket = Ticket.objects.get(id=self.request.POST.get('ticket', False))
- except:
+ except Ticket.DoesNotExist:
return api_return(STATUS_ERROR, "Invalid ticket ID")
ticket.on_hold = True
@@ -139,7 +139,7 @@ class API:
def api_public_unhold_ticket(self):
try:
ticket = Ticket.objects.get(id=self.request.POST.get('ticket', False))
- except:
+ except Ticket.DoesNotExist:
return api_return(STATUS_ERROR, "Invalid ticket ID")
ticket.on_hold = False
@@ -151,7 +151,7 @@ class API:
def api_public_add_followup(self):
try:
ticket = Ticket.objects.get(id=self.request.POST.get('ticket', False))
- except:
+ except Ticket.DoesNotExist:
return api_return(STATUS_ERROR, "Invalid ticket ID")
message = self.request.POST.get('message', None)
@@ -191,7 +191,7 @@ class API:
def api_public_resolve(self):
try:
ticket = Ticket.objects.get(id=self.request.POST.get('ticket', False))
- except:
+ except Ticket.DoesNotExist:
return api_return(STATUS_ERROR, "Invalid ticket ID")
resolution = self.request.POST.get('resolution', None)
diff --git a/views/public.py b/views/public.py
index 66312da9..6f6462ba 100644
--- a/views/public.py
+++ b/views/public.py
@@ -48,7 +48,7 @@ def view_ticket(request):
t = Ticket.objects.get(id=ticket_id, queue__slug__iexact=queue, submitter_email__iexact=email)
return render_to_response('helpdesk/public_view_ticket.html',
RequestContext(request, {'ticket': t,}))
- except:
+ except Ticket.DoesNotExist:
t = False;
error_message = _('Invalid ticket ID or e-mail address. Please try again.')