2008-08-19 10:50:38 +02:00
""" ..
2011-01-26 00:08:41 +01:00
django - helpdesk - A Django powered ticket tracker for small enterprise .
2008-02-06 05:36:07 +01:00
( c ) Copyright 2008 Jutda . All Rights Reserved . See LICENSE for details .
api . py - Wrapper around API calls , and core functions to provide complete
API to third party applications .
2008-08-19 10:50:38 +02:00
The API documentation can be accessed by visiting http : / / helpdesk / api / help /
2011-01-26 00:08:41 +01:00
( obviously , substitute helpdesk for your django - helpdesk URI ) , or by reading
2008-08-29 11:11:02 +02:00
through templates / helpdesk / help_api . html .
2008-02-06 05:36:07 +01:00
"""
2008-08-19 10:50:38 +02:00
from django import forms
2008-02-06 05:36:07 +01:00
from django . contrib . auth import authenticate
2014-06-18 16:21:37 +02:00
try :
from django . contrib . auth import get_user_model
User = get_user_model ( )
except ImportError :
from django . contrib . auth . models import User
2008-02-06 05:36:07 +01:00
from django . http import HttpResponse
2016-06-21 07:18:06 +02:00
from django . shortcuts import render
2008-02-06 05:36:07 +01:00
from django . template import loader , Context
2014-09-10 01:06:50 +02:00
import simplejson
2012-01-15 11:38:28 +01:00
from django . views . decorators . csrf import csrf_exempt
2008-02-06 05:36:07 +01:00
2013-01-23 02:21:54 +01:00
try :
from django . utils import timezone
except ImportError :
from datetime import datetime as timezone
2008-08-19 10:50:38 +02:00
from helpdesk . forms import TicketForm
2011-11-09 16:37:37 +01:00
from helpdesk . lib import send_templated_mail , safe_template_context
2008-02-06 05:36:07 +01:00
from helpdesk . models import Ticket , Queue , FollowUp
2015-12-22 01:28:00 +01:00
import warnings
2008-02-06 05:36:07 +01:00
STATUS_OK = 200
STATUS_ERROR = 400
STATUS_ERROR_NOT_FOUND = 404
STATUS_ERROR_PERMISSIONS = 403
STATUS_ERROR_BADMETHOD = 405
2012-01-15 11:38:28 +01:00
@csrf_exempt
2008-08-19 10:50:38 +02:00
def api ( request , method ) :
2008-02-06 05:36:07 +01:00
"""
2008-08-19 10:50:38 +02:00
Regardless of any other paramaters , we provide a help screen
to the user if they requested one .
2008-02-06 05:36:07 +01:00
If the user isn ' t looking for help, then we enforce a few conditions:
* The request must be sent via HTTP POST
* The request must contain a ' user ' and ' password ' which
must be valid users
* The method must match one of the public methods of the API class .
2008-08-19 10:50:38 +02:00
2015-12-22 01:28:00 +01:00
THIS IS DEPRECATED AS OF DECEMBER 2015 AND WILL BE REMOVED IN JANUARY 2016.
SEE https : / / github . com / rossp / django - helpdesk / issues / 198 FOR DETAILS
2008-02-06 05:36:07 +01:00
"""
2008-08-19 10:50:38 +02:00
2015-12-22 01:28:00 +01:00
warnings . warn ( " django-helpdesk API will be removed in January 2016. See https://github.com/rossp/django-helpdesk/issues/198 for details. " , category = DeprecationWarning )
2008-08-19 10:50:38 +02:00
if method == ' help ' :
2016-06-21 07:18:06 +02:00
return render ( request , template_name = ' helpdesk/help_api.html ' )
2008-08-19 10:50:38 +02:00
2008-02-06 05:36:07 +01:00
if request . method != ' POST ' :
return api_return ( STATUS_ERROR_BADMETHOD )
2008-08-19 10:50:38 +02:00
# TODO: Move away from having the username & password in every request.
request . user = authenticate (
username = request . POST . get ( ' user ' , False ) ,
2008-08-20 03:57:41 +02:00
password = request . POST . get ( ' password ' ) ,
)
2008-08-19 10:50:38 +02:00
2008-02-06 05:36:07 +01:00
if request . user is None :
return api_return ( STATUS_ERROR_PERMISSIONS )
2008-08-19 10:50:38 +02:00
2008-02-06 05:36:07 +01:00
api = API ( request )
if hasattr ( api , ' api_public_ %s ' % method ) :
return getattr ( api , ' api_public_ %s ' % method ) ( )
return api_return ( STATUS_ERROR )
def api_return ( status , text = ' ' , json = False ) :
content_type = ' text/plain '
if status == STATUS_OK and json :
content_type = ' text/json '
2008-08-19 10:50:38 +02:00
2008-02-06 05:36:07 +01:00
if text is None :
if status == STATUS_ERROR :
text = ' Error '
elif status == STATUS_ERROR_NOT_FOUND :
text = ' Resource Not Found '
elif status == STATUS_ERROR_PERMISSIONS :
text = ' Invalid username or password '
elif status == STATUS_ERROR_BADMETHOD :
text = ' Invalid request method '
elif status == STATUS_OK :
text = ' OK '
2008-08-19 10:50:38 +02:00
2008-02-06 05:36:07 +01:00
r = HttpResponse ( status = status , content = text , content_type = content_type )
2008-08-19 10:50:38 +02:00
2008-02-06 05:36:07 +01:00
if status == STATUS_ERROR_BADMETHOD :
r . Allow = ' POST '
2008-08-19 10:50:38 +02:00
2008-02-06 05:36:07 +01:00
return r
class API :
def __init__ ( self , request ) :
self . request = request
2008-08-19 10:50:38 +02:00
def api_public_create_ticket ( self ) :
2008-02-06 23:47:46 +01:00
form = TicketForm ( self . request . POST )
2008-02-06 05:36:07 +01:00
form . fields [ ' queue ' ] . choices = [ [ q . id , q . title ] for q in Queue . objects . all ( ) ]
2014-10-22 07:18:04 +02:00
form . fields [ ' assigned_to ' ] . choices = [ [ u . id , u . get_username ( ) ] for u in User . objects . filter ( is_active = True ) ]
2008-08-19 10:50:38 +02:00
2008-02-06 05:36:07 +01:00
if form . is_valid ( ) :
ticket = form . save ( user = self . request . user )
return api_return ( STATUS_OK , " %s " % ticket . id )
else :
2008-02-06 23:47:46 +01:00
return api_return ( STATUS_ERROR , text = form . errors . as_text ( ) )
2008-02-06 05:36:07 +01:00
2008-08-19 10:50:38 +02:00
2008-02-06 05:36:07 +01:00
def api_public_list_queues ( self ) :
2014-10-23 16:44:59 +02:00
return api_return ( STATUS_OK , simplejson . dumps ( [ { " id " : " %s " % q . id , " title " : " %s " % q . title } for q in Queue . objects . all ( ) ] ) , json = True )
2008-08-19 10:50:38 +02:00
2008-02-06 05:36:07 +01:00
def api_public_find_user ( self ) :
username = self . request . POST . get ( ' username ' , False )
2008-08-19 10:50:38 +02:00
2008-02-06 05:36:07 +01:00
try :
u = User . objects . get ( username = username )
return api_return ( STATUS_OK , " %s " % u . id )
2008-08-19 10:50:38 +02:00
2008-08-18 23:29:31 +02:00
except User . DoesNotExist :
2008-02-06 05:36:07 +01:00
return api_return ( STATUS_ERROR , " Invalid username provided " )
def api_public_delete_ticket ( self ) :
if not self . request . POST . get ( ' confirm ' , False ) :
return api_return ( STATUS_ERROR , " No confirmation provided " )
try :
ticket = Ticket . objects . get ( id = self . request . POST . get ( ' ticket ' , False ) )
2008-08-18 23:29:31 +02:00
except Ticket . DoesNotExist :
2008-02-06 05:36:07 +01:00
return api_return ( STATUS_ERROR , " Invalid ticket ID " )
ticket . delete ( )
2008-08-19 10:50:38 +02:00
2008-02-06 05:36:07 +01:00
return api_return ( STATUS_OK )
2008-08-19 10:50:38 +02:00
2008-02-06 05:36:07 +01:00
def api_public_hold_ticket ( self ) :
try :
ticket = Ticket . objects . get ( id = self . request . POST . get ( ' ticket ' , False ) )
2008-08-18 23:29:31 +02:00
except Ticket . DoesNotExist :
2008-02-06 05:36:07 +01:00
return api_return ( STATUS_ERROR , " Invalid ticket ID " )
ticket . on_hold = True
ticket . save ( )
return api_return ( STATUS_OK )
2008-08-19 10:50:38 +02:00
2008-02-06 05:36:07 +01:00
def api_public_unhold_ticket ( self ) :
try :
ticket = Ticket . objects . get ( id = self . request . POST . get ( ' ticket ' , False ) )
2008-08-18 23:29:31 +02:00
except Ticket . DoesNotExist :
2008-02-06 05:36:07 +01:00
return api_return ( STATUS_ERROR , " Invalid ticket ID " )
ticket . on_hold = False
ticket . save ( )
return api_return ( STATUS_OK )
def api_public_add_followup ( self ) :
try :
ticket = Ticket . objects . get ( id = self . request . POST . get ( ' ticket ' , False ) )
2008-08-18 23:29:31 +02:00
except Ticket . DoesNotExist :
2008-02-06 05:36:07 +01:00
return api_return ( STATUS_ERROR , " Invalid ticket ID " )
message = self . request . POST . get ( ' message ' , None )
public = self . request . POST . get ( ' public ' , ' n ' )
if public not in [ ' y ' , ' n ' ] :
return api_return ( STATUS_ERROR , " Invalid ' public ' flag " )
if not message :
return api_return ( STATUS_ERROR , " Blank message " )
2008-08-19 10:50:38 +02:00
f = FollowUp (
ticket = ticket ,
2013-01-23 00:59:12 +01:00
date = timezone . now ( ) ,
2008-08-19 10:50:38 +02:00
comment = message ,
user = self . request . user ,
title = ' Comment Added ' ,
)
2008-02-06 05:36:07 +01:00
if public :
f . public = True
2008-08-19 10:50:38 +02:00
2008-02-06 05:36:07 +01:00
f . save ( )
2008-08-19 10:50:38 +02:00
2011-11-09 16:37:37 +01:00
context = safe_template_context ( ticket )
context [ ' comment ' ] = f . comment
2015-11-12 15:31:14 +01:00
2009-08-11 11:02:48 +02:00
messages_sent_to = [ ]
2008-02-06 05:36:07 +01:00
if public and ticket . submitter_email :
2008-08-19 10:50:38 +02:00
send_templated_mail (
' updated_submitter ' ,
context ,
recipients = ticket . submitter_email ,
sender = ticket . queue . from_address ,
fail_silently = True ,
)
2009-08-11 11:02:48 +02:00
messages_sent_to . append ( ticket . submitter_email )
2008-08-19 10:50:38 +02:00
2009-09-09 10:47:48 +02:00
if public :
for cc in ticket . ticketcc_set . all ( ) :
if cc . email_address not in messages_sent_to :
send_templated_mail (
' updated_submitter ' ,
context ,
recipients = cc . email_address ,
sender = ticket . queue . from_address ,
fail_silently = True ,
)
messages_sent_to . append ( cc . email_address )
2009-08-11 11:02:48 +02:00
if ticket . queue . updated_ticket_cc and ticket . queue . updated_ticket_cc not in messages_sent_to :
2008-08-19 10:50:38 +02:00
send_templated_mail (
' updated_cc ' ,
context ,
recipients = ticket . queue . updated_ticket_cc ,
sender = ticket . queue . from_address ,
fail_silently = True ,
)
2009-08-11 11:02:48 +02:00
messages_sent_to . append ( ticket . queue . updated_ticket_cc )
2008-08-19 10:50:38 +02:00
2015-11-12 15:31:14 +01:00
if (
ticket . assigned_to and
self . request . user != ticket . assigned_to and
ticket . assigned_to . usersettings . settings . get ( ' email_on_ticket_apichange ' , False ) and
ticket . assigned_to . email and
ticket . assigned_to . email not in messages_sent_to
) :
2008-08-19 10:50:38 +02:00
send_templated_mail (
' updated_owner ' ,
context ,
recipients = ticket . assigned_to . email ,
sender = ticket . queue . from_address ,
fail_silently = True ,
2015-11-12 15:31:14 +01:00
)
2008-02-06 05:36:07 +01:00
ticket . save ( )
return api_return ( STATUS_OK )
def api_public_resolve ( self ) :
try :
ticket = Ticket . objects . get ( id = self . request . POST . get ( ' ticket ' , False ) )
2008-08-18 23:29:31 +02:00
except Ticket . DoesNotExist :
2008-02-06 05:36:07 +01:00
return api_return ( STATUS_ERROR , " Invalid ticket ID " )
resolution = self . request . POST . get ( ' resolution ' , None )
if not resolution :
return api_return ( STATUS_ERROR , " Blank resolution " )
2008-08-19 10:50:38 +02:00
f = FollowUp (
ticket = ticket ,
2013-01-23 00:59:12 +01:00
date = timezone . now ( ) ,
2008-08-19 10:50:38 +02:00
comment = resolution ,
user = self . request . user ,
title = ' Resolved ' ,
public = True ,
)
2008-02-06 05:36:07 +01:00
f . save ( )
2008-08-19 10:50:38 +02:00
2011-11-09 16:37:37 +01:00
context = safe_template_context ( ticket )
context [ ' resolution ' ] = f . comment
2008-08-19 10:50:38 +02:00
2008-02-06 05:36:07 +01:00
subject = ' %s %s (Resolved) ' % ( ticket . ticket , ticket . title )
2015-11-12 15:31:14 +01:00
2009-08-11 11:02:48 +02:00
messages_sent_to = [ ]
2008-02-06 05:36:07 +01:00
2008-02-06 23:47:46 +01:00
if ticket . submitter_email :
2008-08-19 10:50:38 +02:00
send_templated_mail (
' resolved_submitter ' ,
context ,
recipients = ticket . submitter_email ,
sender = ticket . queue . from_address ,
fail_silently = True ,
)
2009-08-11 11:02:48 +02:00
messages_sent_to . append ( ticket . submitter_email )
2008-08-19 10:50:38 +02:00
2009-09-09 10:47:48 +02:00
for cc in ticket . ticketcc_set . all ( ) :
if cc . email_address not in messages_sent_to :
send_templated_mail (
' resolved_submitter ' ,
context ,
recipients = cc . email_address ,
sender = ticket . queue . from_address ,
fail_silently = True ,
)
messages_sent_to . append ( cc . email_address )
2009-08-11 11:02:48 +02:00
if ticket . queue . updated_ticket_cc and ticket . queue . updated_ticket_cc not in messages_sent_to :
2008-08-19 10:50:38 +02:00
send_templated_mail (
' resolved_cc ' ,
context ,
recipients = ticket . queue . updated_ticket_cc ,
sender = ticket . queue . from_address ,
fail_silently = True ,
)
2009-08-11 11:02:48 +02:00
messages_sent_to . append ( ticket . queue . updated_ticket_cc )
2008-08-19 10:50:38 +02:00
2009-08-11 11:02:48 +02:00
if ticket . assigned_to and self . request . user != ticket . assigned_to and getattr ( ticket . assigned_to . usersettings . settings , ' email_on_ticket_apichange ' , False ) and ticket . assigned_to . email and ticket . assigned_to . email not in messages_sent_to :
2008-08-19 10:50:38 +02:00
send_templated_mail (
' resolved_resolved ' ,
context ,
recipients = ticket . assigned_to . email ,
sender = ticket . queue . from_address ,
fail_silently = True ,
)
2008-02-06 05:36:07 +01:00
ticket . resoltuion = f . comment
2008-02-06 23:47:46 +01:00
ticket . status = Ticket . RESOLVED_STATUS
2008-02-06 05:36:07 +01:00
ticket . save ( )
2015-12-22 01:28:00 +01:00
return api_return ( STATUS_OK )