* Enlarged Chart sizes to allow more data to be displayed

* Added superuser 'System settings' page with links to admin
* Added ability to ignore e-mail addresses (using wildcards) from the e-mail parser
* Added link to ignore email address from ticket details page (for superusers only)
* Cleaned up report output by styling text & labels in the same way as tables in other views
* Cleaned up dashboard lists to show text in place of tickets if no tickets are found
* Added ability to sort in reverse order

NOTE: REQUIRES A 'syncdb' TO CREATE THE EMAIL-IGNORE TABLES. No other DB changes were made.
This commit is contained in:
Ross Poulton 2008-10-24 22:52:34 +00:00
parent 5914e98d43
commit c97a255155
15 changed files with 273 additions and 24 deletions

View File

@ -14,7 +14,7 @@ from django.contrib.auth.models import User
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from helpdesk.lib import send_templated_mail from helpdesk.lib import send_templated_mail
from helpdesk.models import Ticket, Queue, FollowUp from helpdesk.models import Ticket, Queue, FollowUp, IgnoreEmail
class TicketForm(forms.Form): class TicketForm(forms.Form):
queue = forms.ChoiceField( queue = forms.ChoiceField(
@ -265,3 +265,7 @@ class UserSettingsForm(forms.Form):
help_text=_('If a ticket is altered by the API, do you want to receive an e-mail?'), help_text=_('If a ticket is altered by the API, do you want to receive an e-mail?'),
required=False, required=False,
) )
class EmailIgnoreForm(forms.ModelForm):
class Meta:
model = IgnoreEmail

10
lib.py
View File

@ -165,8 +165,8 @@ def line_chart(data):
max = field max = field
# Set width to '65px * number of months'. # Set width to '65px * number of months + 100 for headings.'.
chart_url = 'http://chart.apis.google.com/chart?cht=lc&chs=%sx90&chd=t:' % (len(column_headings)*65) chart_url = 'http://chart.apis.google.com/chart?cht=lc&chs=%sx150&chd=t:' % (len(column_headings)*65+100)
first_row = True first_row = True
row_headings = [] row_headings = []
for row in data[1:]: for row in data[1:]:
@ -210,8 +210,8 @@ def bar_chart(data):
max = field max = field
# Set width to '150px * number of months'. # Set width to '220px * number of months'.
chart_url = 'http://chart.apis.google.com/chart?cht=bvg&chs=%sx90&chd=t:' % (len(column_headings) * 150) chart_url = 'http://chart.apis.google.com/chart?cht=bvg&chs=%sx150&chd=t:' % (len(column_headings) * 220)
first_row = True first_row = True
row_headings = [] row_headings = []
for row in data[1:]: for row in data[1:]:
@ -276,6 +276,8 @@ def apply_query(queryset, params):
queryset = queryset.filter(params['other_filter']) queryset = queryset.filter(params['other_filter'])
if params.get('sorting', None): if params.get('sorting', None):
if params.get('sortreverse', None):
params['sorting'] = "-%s" % params['sorting']
queryset = queryset.order_by(params['sorting']) queryset = queryset.order_by(params['sorting'])
return queryset return queryset

View File

@ -20,10 +20,11 @@ from email.Utils import parseaddr
from django.core.files.base import ContentFile from django.core.files.base import ContentFile
from django.core.management.base import BaseCommand from django.core.management.base import BaseCommand
from django.db.models import Q
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from helpdesk.lib import send_templated_mail from helpdesk.lib import send_templated_mail
from helpdesk.models import Queue, Ticket, FollowUp, Attachment from helpdesk.models import Queue, Ticket, FollowUp, Attachment, IgnoreEmail
class Command(BaseCommand): class Command(BaseCommand):
@ -76,9 +77,11 @@ def process_queue(q):
msgSize = msg.split(" ")[1] msgSize = msg.split(" ")[1]
full_message = "\n".join(server.retr(msgNum)[1]) full_message = "\n".join(server.retr(msgNum)[1])
ticket_from_message(message=full_message, queue=q) ticket = ticket_from_message(message=full_message, queue=q)
if ticket:
server.dele(msgNum) server.dele(msgNum)
server.quit() server.quit()
elif q.email_box_type == 'imap': elif q.email_box_type == 'imap':
@ -94,8 +97,10 @@ def process_queue(q):
status, data = server.search(None, 'ALL') status, data = server.search(None, 'ALL')
for num in data[0].split(): for num in data[0].split():
status, data = server.fetch(num, '(RFC822)') status, data = server.fetch(num, '(RFC822)')
ticket_from_message(message=data[0][1], queue=q) ticket = ticket_from_message(message=data[0][1], queue=q)
if ticket:
server.store(num, '+FLAGS', '\\Deleted') server.store(num, '+FLAGS', '\\Deleted')
server.expunge() server.expunge()
server.close() server.close()
server.logout() server.logout()
@ -111,8 +116,10 @@ def ticket_from_message(message, queue):
sender = message.get('from', _('Unknown Sender')) sender = message.get('from', _('Unknown Sender'))
sender_email = parseaddr(sender)[1] sender_email = parseaddr(sender)[1]
if sender_email.startswith('postmaster'):
sender_email = '' for ignore in IgnoreEmail.objects.filter(Q(queues=queue) | Q(queues__isnull=True)):
if ignore.test(sender_email):
return False
regex = re.compile("^\[[A-Za-z0-9]+-\d+\]") regex = re.compile("^\[[A-Za-z0-9]+-\d+\]")
if regex.match(subject): if regex.match(subject):
@ -256,6 +263,8 @@ def ticket_from_message(message, queue):
a.save() a.save()
print " - %s" % file['filename'] print " - %s" % file['filename']
return ticket
if __name__ == '__main__': if __name__ == '__main__':
process_email() process_email()

View File

@ -926,3 +926,68 @@ def create_usersettings(sender, created_models=[], instance=None, created=False,
models.signals.post_syncdb.connect(create_usersettings) models.signals.post_syncdb.connect(create_usersettings)
models.signals.post_save.connect(create_usersettings, sender=User) models.signals.post_save.connect(create_usersettings, sender=User)
class IgnoreEmail(models.Model):
"""
This model lets us easily ignore e-mails from certain senders when
processing IMAP and POP3 mailboxes, eg mails from postmaster or from
known trouble-makers.
"""
queues = models.ManyToManyField(
Queue,
blank=True,
null=True,
help_text=_('Leave blank for this e-mail to be ignored on all '
'queues, or select those queues you wish to ignore this e-mail '
'for.'),
)
name = models.CharField(
_('Name'),
max_length=100,
)
date = models.DateField(
_('Date'),
help_text=_('Date on which this e-mail address was added'),
blank=True,
editable=False
)
email_address = models.CharField(
_('E-Mail Address'),
max_length=150,
help_text=_('Enter a full e-mail address, or portions with '
'wildcards, eg *@domain.com or postmaster@*.'),
)
def __unicode__(self):
return u'%s' % self.name
def save(self):
if not self.date:
self.date = datetime.now()
return super(IgnoreEmail, self).save()
def test(self, email):
"""
Possible situations:
1. Username & Domain both match
2. Username is wildcard, domain matches
3. Username matches, domain is wildcard
4. username & domain are both wildcards
5. Other (no match)
1-4 return True, 5 returns False.
"""
own_parts = self.email_address.split("@")
email_parts = email.split("@")
if self.email_address == email \
or own_parts[0] == "*" and own_parts[1] == email_parts[1] \
or own_parts[1] == "*" and own_parts[0] == email_parts[0] \
or own_parts[0] == "*" and own_parts[1] == "*":
return True
else:
return False

View File

@ -28,7 +28,7 @@
{% block helpdesk_body %}{% endblock %} {% block helpdesk_body %}{% endblock %}
</div> </div>
<div id='footer'> <div id='footer'>
<p>{% trans "Powered by <a href='http://www.jutda.com.au/'>Jutda Helpdesk</a>." %} <a href='{% url helpdesk_rss_index %}'><img src='{{ MEDIA_URL }}/helpdesk/rss_icon.png' width='14' height='14' alt='{% trans "RSS Icon" %}' title='{% trans "RSS Feeds" %}' border='0' />{% trans "RSS Feeds" %}</a> <a href='{% url helpdesk_api_help %}'>{% trans "API" %}</a> <a href='{% url helpdesk_user_settings %}'>{% trans "User Settings" %}</a></p> <p>{% trans "Powered by <a href='http://www.jutda.com.au/'>Jutda Helpdesk</a>." %} <a href='{% url helpdesk_rss_index %}'><img src='{{ MEDIA_URL }}/helpdesk/rss_icon.png' width='14' height='14' alt='{% trans "RSS Icon" %}' title='{% trans "RSS Feeds" %}' border='0' />{% trans "RSS Feeds" %}</a> <a href='{% url helpdesk_api_help %}'>{% trans "API" %}</a> <a href='{% url helpdesk_user_settings %}'>{% trans "User Settings" %}</a> {% if user.is_superuser %}<a href='{% url helpdesk_system_settings %}'>{% trans "System Settings" %}</a>{% endif %}</p>
</div> </div>
</div> </div>
{% include "helpdesk/debug.html" %} {% include "helpdesk/debug.html" %}

View File

@ -5,7 +5,7 @@
{% endblock %} {% endblock %}
{% block helpdesk_body %} {% block helpdesk_body %}
<table width='30%' align='left'> <table width='40%' align='left'>
<tr class='row_tablehead'><td colspan='4'>{% trans "Helpdesk Summary" %}</td></tr> <tr class='row_tablehead'><td colspan='4'>{% trans "Helpdesk Summary" %}</td></tr>
<tr class='row_columnheads'><th>{% trans "Queue" %}</th><th>{% trans "Open" %}</th><th>{% trans "Resolved" %}</th></tr> <tr class='row_columnheads'><th>{% trans "Queue" %}</th><th>{% trans "Open" %}</th><th>{% trans "Resolved" %}</th></tr>
{% for queue in dash_tickets %} {% for queue in dash_tickets %}
@ -17,7 +17,7 @@
{% endfor %} {% endfor %}
</table> </table>
<p style='padding-left: 5px;'>Welcome to your Helpdesk Dashboard! From here you can quickly see your own tickets, and those tickets that have no owner. Why not pick up an orphan ticket and sort it out for a customer?</p> <p style='margin-left: 42%;'>Welcome to your Helpdesk Dashboard! From here you can quickly see your own tickets, and those tickets that have no owner. Why not pick up an orphan ticket and sort it out for a customer?</p>
<br style='clear: both;' /> <br style='clear: both;' />
@ -34,6 +34,9 @@
<td><span title='{{ ticket.modified|date:"r" }}'>{{ ticket.modified|timesince }}</span></td> <td><span title='{{ ticket.modified|date:"r" }}'>{{ ticket.modified|timesince }}</span></td>
</tr> </tr>
{% endfor %} {% endfor %}
{% if not unassigned_tickets %}
<tr class='row_odd'><td colspan='5'>{% trans "You have no tickets assigned to you." %}</td></tr>
{% endif %}
</table> </table>
<table width='100%'> <table width='100%'>
@ -49,6 +52,9 @@
<th><a href='{{ ticket.get_absolute_url }}?take'><span class='button button_take'>{% trans "Take" %}</span></a></th> <th><a href='{{ ticket.get_absolute_url }}?take'><span class='button button_take'>{% trans "Take" %}</span></a></th>
</tr> </tr>
{% endfor %} {% endfor %}
{% if not unassigned_tickets %}
<tr class='row_odd'><td colspan='6'>{% trans "There are no unassigned tickets." %}</td></tr>
{% endif %}
</table> </table>
{% endblock %} {% endblock %}

View File

@ -0,0 +1,27 @@
{% extends "helpdesk/base.html" %}{% load i18n %}
{% block helpdesk_title %}{% trans "Ignore E-Mail Address" %}{% endblock %}
{% block helpdesk_body %}{% blocktrans %}
<h2>Ignore E-Mail Address</h2>
<p>To ignore an e-mail address and prevent any emails from that address creating tickets automatically, enter the e-mail address below.</p>
<p>You can either enter a whole e-mail address such as <em>email@domain.com</em> or a portion of an e-mail address with a wildcard, such as <em>*@domain.com</em> or <em>user@*</em>.</p>{% endblocktrans %}
<form method='post' action='./'>
<fieldset>
<dl>{% for field in form %}
<dt><label for='id_{{ field.name }}'>{{ field.label }}</label></dt>
<dd>{{ field }}</dd>
{% if field.errors %}<dd class='error'>{{ field.errors }}</dd>{% endif %}
{% if field.help_text %}<dd class='form_help_text'>{{ field.help_text }}</dd>{% endif %}
{% endfor %}</dl>
</fieldset>
<input type='submit' value='{% trans "Ignore E-Mail Address" %}' />
</form>
{% endblock %}

View File

@ -0,0 +1,14 @@
{% extends "helpdesk/base.html" %}{% load i18n %}
{% block helpdesk_title %}{% trans "Delete Ignored E-Mail Address" %}{% endblock %}
{% block helpdesk_body %}{% blocktrans with ignore.email_address as email_address %}
<h2>Un-Ignore E-Mail Address</h2>
<p>Are you sure you wish to stop removing this email address (<em>{{ email_address }}</em>) and allow their e-mails to automatically create tickets in your system? You can re-add this e-mail address at any time.<?p>
{% endblocktrans %}
{% blocktrans %}<p><a href='../../'>Keep Ignoring It</a></p>
<form method='post' action='./'><input type='submit' value='Stop Ignoring It' /></form>
{% endblocktrans %}{% endblock %}

View File

@ -0,0 +1,28 @@
{% extends "helpdesk/base.html" %}{% load i18n %}
{% block helpdesk_title %}{% trans "Ignored E-Mail Addresses" %}{% endblock %}
{% block helpdesk_body %}{% blocktrans %}
<h2>Ignored E-Mail Addresses</h2>
<p>The following e-mail addresses are currently being ignored by the incoming e-mail processor. You can <a href='add/'>add a new e-mail address to the list</a> or delete any of the items below as required.</p>{% endblocktrans %}
<table width='100%'>
<thead>
<tr class='row_tablehead'><td colspan='5'>{% trans "Ignored E-Mail Addresses" %}</td></tr>
<tr class='row_columnheads'><th>{% trans "Name" %}</th><th>{% trans "E-Mail Address" %}</th><th>{% trans "Date Added" %}</th><th>{% trans "Queues" %}</th><th>{% trans "Delete" %}</th></tr>
</thead>
<tbody>
{% for ignore in ignore_list %}
<tr class='row_{% cycle odd,even %}'>
<td>{{ ignore.name }}</td>
<td>{{ ignore.email_address }}</td>
<td>{{ ignore.date }}</td>
<td>{% for queue in ignore.queues.all %}{{ queue.slug }}{% if not forloop.last %}, {% endif %}{% endfor %}{% if not ignore.queues.all %}All{% endif %}</td>
<td><a href='{% url helpdesk_email_ignore_del ignore.id %}'>Delete</a></td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}

View File

@ -6,8 +6,10 @@
<h2>{% trans "Reports &amp; Statistics" %}</h2> <h2>{% trans "Reports &amp; Statistics" %}</h2>
<table> <table>
<tr>{% for h in headings %}<th>{{ h }}</th>{% endfor %}</tr> <tr class='row_tablehead'><td colspan='{{ headings|length }}'>{{ title }}</td></tr>
{% for d in data %}<tr>{% for f in d %}<td>{{ f }}</td>{% endfor %}</tr>{% endfor %} <tr class='row_columnheads'>{% for h in headings %}<th>{% if forloop.first %}{{ h|title }}{% else %}{{ h }}{% endif %}</th>{% endfor %}</tr>
{% for d in data %}
<tr class='row_{% cycle odd,even %}'>{% for f in d %}<td>{{ f }}</td>{% endfor %}</tr>{% endfor %}
</table> </table>
{% if chart %}<img src='{{ chart }}' />{% endif %} {% if chart %}<img src='{{ chart }}' />{% endif %}

View File

@ -0,0 +1,19 @@
{% extends "helpdesk/base.html" %}{% load i18n %}
{% block helpdesk_title %}{% trans "Change System Settings" %}{% endblock %}
{% block helpdesk_body %}{% blocktrans %}
<h2>System Settings</h2>
<p>The following items can be maintained by you or other superusers:</p>{% endblocktrans %}
<ul>
<li><a href='../ignore/'>{% trans "E-Mail Ignore list" %}</a></li>
<li><a href='/admin/helpdesk/queue/'>{% trans "Maintain Queues" %}</a></li>
<li><a href='/admin/helpdesk/presetreply/'>{% trans "Maintain Pre-Set Replies" %}</a></li>
<li><a href='/admin/helpdesk/kbcategory/'>{% trans "Maintain Knowledgebase Categories" %}</a></li>
<li><a href='/admin/helpdesk/kbitem/'>{% trans "Maintain Knowledgebase Items" %}</a></li>
<li><a href='/admin/helpdesk/emailtemplate/'>{% trans "Maintain E-Mail Templates" %}</a></li>
<li><a href='/admin/auth/user/'>{% trans "Maintain Users" %}</a></li>
</ul>
{% endblock %}

View File

@ -60,7 +60,7 @@
<tr class='row_odd'> <tr class='row_odd'>
<th>{% trans "Submitter E-Mail" %}</th> <th>{% trans "Submitter E-Mail" %}</th>
<td>{{ ticket.submitter_email }}</td> <td>{{ ticket.submitter_email }}{% if user.is_superuser %} <strong><a href='{% url helpdesk_email_ignore_add %}?email={{ ticket.submitter_email }}'>{% trans "Ignore" %}</a></strong>{% endif %}</td>
</tr> </tr>
<tr class='row_even'> <tr class='row_even'>

View File

@ -43,6 +43,7 @@ $(document).ready(function() {
<option value='priority'{% ifequal query_params.sorting "priority"%} selected='selected'{% endifequal %}>{% trans "Priority" %}</option> <option value='priority'{% ifequal query_params.sorting "priority"%} selected='selected'{% endifequal %}>{% trans "Priority" %}</option>
<option value='assigned_to'{% ifequal query_params.sorting "assigned_to"%} selected='selected'{% endifequal %}>{% trans "Owner" %}</option> <option value='assigned_to'{% ifequal query_params.sorting "assigned_to"%} selected='selected'{% endifequal %}>{% trans "Owner" %}</option>
</select> </select>
<label for='id_sortreverse'>Reverse</label><input type='checkbox' name='sortreverse' id='id_sortreverse'{% if query_params.sortreverse %} checked='checked'{% endif %} />
<p class='filterHelp'>Ordering applied to tickets</p> <p class='filterHelp'>Ordering applied to tickets</p>
<input type='button' class='filterBuilderRemove' value='-' /> <input type='button' class='filterBuilderRemove' value='-' />
</div> </div>

17
urls.py
View File

@ -73,6 +73,18 @@ urlpatterns = patterns('helpdesk.views.staff',
url(r'^settings/$', url(r'^settings/$',
'user_settings', 'user_settings',
name='helpdesk_user_settings'), name='helpdesk_user_settings'),
url(r'^ignore/$',
'email_ignore',
name='helpdesk_email_ignore'),
url(r'^ignore/add/$',
'email_ignore_add',
name='helpdesk_email_ignore_add'),
url(r'^ignore/delete/(?P<id>[0-9]+)/$',
'email_ignore_del',
name='helpdesk_email_ignore_del'),
) )
urlpatterns += patterns('helpdesk.views.public', urlpatterns += patterns('helpdesk.views.public',
@ -129,4 +141,9 @@ urlpatterns += patterns('',
'django.views.generic.simple.direct_to_template', 'django.views.generic.simple.direct_to_template',
{'template': 'helpdesk/help_context.html',}, {'template': 'helpdesk/help_context.html',},
name='helpdesk_help_context'), name='helpdesk_help_context'),
url(r'^system_settings/$',
'django.views.generic.simple.direct_to_template',
{'template': 'helpdesk/system_settings.html',},
name='helpdesk_system_settings'),
) )

View File

@ -10,7 +10,7 @@ views/staff.py - The bulk of the application - provides most business logic and
from datetime import datetime from datetime import datetime
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required, user_passes_test
from django.core.files.base import ContentFile from django.core.files.base import ContentFile
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.db import connection from django.db import connection
@ -20,9 +20,14 @@ from django.shortcuts import render_to_response, get_object_or_404
from django.template import loader, Context, RequestContext from django.template import loader, Context, RequestContext
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from helpdesk.forms import TicketForm, UserSettingsForm from helpdesk.forms import TicketForm, UserSettingsForm, EmailIgnoreForm
from helpdesk.lib import send_templated_mail, line_chart, bar_chart, query_to_dict, apply_query, safe_template_context from helpdesk.lib import send_templated_mail, line_chart, bar_chart, query_to_dict, apply_query, safe_template_context
from helpdesk.models import Ticket, Queue, FollowUp, TicketChange, PreSetReply, Attachment, SavedSearch from helpdesk.models import Ticket, Queue, FollowUp, TicketChange, PreSetReply, Attachment, SavedSearch, IgnoreEmail
staff_member_required = user_passes_test(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)
def dashboard(request): def dashboard(request):
@ -199,7 +204,7 @@ def update_ticket(request, ticket_id):
if f.new_status == Ticket.RESOLVED_STATUS: if f.new_status == Ticket.RESOLVED_STATUS:
ticket.resolution = comment ticket.resolution = comment
if ticket.submitter_email and ((f.comment != '' and public) or (f.new_status in (Ticket.RESOLVED_STATUS, Ticket.CLOSED_STATUS))): if ticket.submitter_email and public and (f.comment or (f.new_status in (Ticket.RESOLVED_STATUS, Ticket.CLOSED_STATUS))):
context = { context = {
'ticket': ticket, 'ticket': ticket,
'queue': ticket.queue, 'queue': ticket.queue,
@ -287,6 +292,7 @@ def ticket_list(request):
query_params = { query_params = {
'filtering': {}, 'filtering': {},
'sorting': None, 'sorting': None,
'sortreverse': False,
'keyword': None, 'keyword': None,
'other_filter': None, 'other_filter': None,
} }
@ -308,7 +314,8 @@ def ticket_list(request):
or request.GET.has_key('assigned_to') or request.GET.has_key('assigned_to')
or request.GET.has_key('status') or request.GET.has_key('status')
or request.GET.has_key('q') or request.GET.has_key('q')
or request.GET.has_key('sort') ): or request.GET.has_key('sort')
or request.GET.has_key('sortreverse') ):
# Fall-back if no querying is being done, force the list to only # Fall-back if no querying is being done, force the list to only
# show open/reopened/resolved (not closed) cases sorted by creation # show open/reopened/resolved (not closed) cases sorted by creation
@ -354,6 +361,9 @@ def ticket_list(request):
sort = 'created' sort = 'created'
query_params['sorting'] = sort query_params['sorting'] = sort
sortreverse = request.GET.get('sortreverse', None)
query_params['sortreverse'] = sortreverse
tickets = apply_query(Ticket.objects.select_related(), query_params) tickets = apply_query(Ticket.objects.select_related(), query_params)
import cPickle, base64 import cPickle, base64
@ -555,30 +565,37 @@ def run_report(request, report):
if report == 'userpriority': if report == 'userpriority':
sql = user_base_sql % priority_sql sql = user_base_sql % priority_sql
columns = ['username'] + priority_columns columns = ['username'] + priority_columns
title = 'User by Priority'
elif report == 'userqueue': elif report == 'userqueue':
sql = user_base_sql % queue_sql sql = user_base_sql % queue_sql
columns = ['username'] + queue_columns columns = ['username'] + queue_columns
title = 'User by Queue'
elif report == 'userstatus': elif report == 'userstatus':
sql = user_base_sql % status_sql sql = user_base_sql % status_sql
columns = ['username'] + status_columns columns = ['username'] + status_columns
title = 'User by Status'
elif report == 'usermonth': elif report == 'usermonth':
sql = user_base_sql % month_sql sql = user_base_sql % month_sql
columns = ['username'] + month_columns columns = ['username'] + month_columns
title = 'User by Month'
elif report == 'queuepriority': elif report == 'queuepriority':
sql = queue_base_sql % priority_sql sql = queue_base_sql % priority_sql
columns = ['queue'] + priority_columns columns = ['queue'] + priority_columns
title = 'Queue by Priority'
elif report == 'queuestatus': elif report == 'queuestatus':
sql = queue_base_sql % status_sql sql = queue_base_sql % status_sql
columns = ['queue'] + status_columns columns = ['queue'] + status_columns
title = 'Queue by Status'
elif report == 'queuemonth': elif report == 'queuemonth':
sql = queue_base_sql % month_sql sql = queue_base_sql % month_sql
columns = ['queue'] + month_columns columns = ['queue'] + month_columns
title = 'Queue by Month'
cursor = connection.cursor() cursor = connection.cursor()
@ -604,8 +621,8 @@ def run_report(request, report):
RequestContext(request, { RequestContext(request, {
'headings': columns, 'headings': columns,
'data': data, 'data': data,
'sql': sql,
'chart': chart_url, 'chart': chart_url,
'title': title,
})) }))
run_report = login_required(run_report) run_report = login_required(run_report)
@ -638,6 +655,7 @@ def delete_saved_query(request, id):
})) }))
delete_saved_query = login_required(delete_saved_query) delete_saved_query = login_required(delete_saved_query)
def user_settings(request): def user_settings(request):
s = request.user.usersettings s = request.user.usersettings
if request.POST: if request.POST:
@ -653,3 +671,40 @@ def user_settings(request):
'form': form, 'form': form,
})) }))
user_settings = login_required(user_settings) user_settings = login_required(user_settings)
def email_ignore(request):
return render_to_response('helpdesk/email_ignore_list.html',
RequestContext(request, {
'ignore_list': IgnoreEmail.objects.all(),
}))
email_ignore = superuser_required(email_ignore)
def email_ignore_add(request):
if request.method == 'POST':
form = EmailIgnoreForm(request.POST)
if form.is_valid():
ignore = form.save()
return HttpResponseRedirect(reverse('helpdesk_email_ignore'))
else:
form = EmailIgnoreForm(request.GET)
return render_to_response('helpdesk/email_ignore_add.html',
RequestContext(request, {
'form': form,
}))
email_ignore_add = superuser_required(email_ignore_add)
def email_ignore_del(request, id):
ignore = get_object_or_404(IgnoreEmail, id=id)
if request.method == 'POST':
ignore.delete()
return HttpResponseRedirect(reverse('helpdesk_email_ignore'))
else:
return render_to_response('helpdesk/email_ignore_del.html',
RequestContext(request, {
'ignore': ignore,
}))
email_ignore_del = superuser_required(email_ignore_del)