2015-06-18 23:57:43 -05:00
|
|
|
"""Handle dispatcher API requests."""
|
2015-06-19 10:51:11 -05:00
|
|
|
import copy
|
2015-06-18 23:57:43 -05:00
|
|
|
import logging
|
|
|
|
import os
|
2016-01-16 17:58:11 -06:00
|
|
|
import xmlrpc.client
|
2015-06-18 23:57:43 -05:00
|
|
|
|
|
|
|
from rest_framework import generics, status
|
2015-06-19 16:45:10 -05:00
|
|
|
from rest_framework.permissions import IsAuthenticated
|
|
|
|
from rest_framework.response import Response
|
2015-06-18 23:57:43 -05:00
|
|
|
|
2015-06-19 11:29:00 -05:00
|
|
|
from dispatch.models import Dispatcher, DispatcherAction
|
2021-04-25 08:59:01 -05:00
|
|
|
from dispatch.serializers import DispatcherActionSerializer, DispatcherSerializer, DispatchMessageSerializer
|
2015-06-18 23:57:43 -05:00
|
|
|
|
|
|
|
log = logging.getLogger('dispatch.views')
|
|
|
|
|
|
|
|
|
2015-06-19 16:45:10 -05:00
|
|
|
class HasSendMessagePermission(IsAuthenticated):
|
2017-02-12 11:58:20 -06:00
|
|
|
"""Class to check if the authenticated user can send messages via dispatch."""
|
2015-06-19 16:45:10 -05:00
|
|
|
|
|
|
|
def has_permission(self, request, view):
|
2017-02-12 11:58:20 -06:00
|
|
|
"""Check user permission for dispatch.send_message."""
|
2015-06-19 16:45:10 -05:00
|
|
|
if request.user.has_perm('dispatch.send_message'):
|
|
|
|
return True
|
|
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
2015-06-18 23:57:43 -05:00
|
|
|
class DispatcherList(generics.ListAPIView):
|
|
|
|
"""List all dispatchers."""
|
|
|
|
|
2023-02-28 18:37:05 -06:00
|
|
|
permission_classes = (IsAuthenticated,)
|
|
|
|
|
2015-06-18 23:57:43 -05:00
|
|
|
queryset = Dispatcher.objects.all()
|
|
|
|
serializer_class = DispatcherSerializer
|
|
|
|
|
|
|
|
|
|
|
|
class DispatcherDetail(generics.RetrieveAPIView):
|
|
|
|
"""Detail the given dispatcher."""
|
|
|
|
|
2023-02-28 18:37:05 -06:00
|
|
|
permission_classes = (IsAuthenticated,)
|
|
|
|
|
2015-06-18 23:57:43 -05:00
|
|
|
queryset = Dispatcher.objects.all()
|
|
|
|
serializer_class = DispatcherSerializer
|
|
|
|
|
|
|
|
|
2015-06-20 11:22:17 -05:00
|
|
|
class DispatcherDetailByKey(DispatcherDetail):
|
2017-02-12 11:58:20 -06:00
|
|
|
"""Detail a specific dispatcher."""
|
2015-06-20 11:22:17 -05:00
|
|
|
|
|
|
|
lookup_field = 'key'
|
|
|
|
|
|
|
|
|
2015-06-19 10:51:11 -05:00
|
|
|
class DispatchMessage(generics.GenericAPIView):
|
2015-06-18 23:57:43 -05:00
|
|
|
"""Send a message to the given dispatcher."""
|
|
|
|
|
2015-06-19 16:45:10 -05:00
|
|
|
permission_classes = (HasSendMessagePermission,)
|
|
|
|
|
2015-06-19 10:51:11 -05:00
|
|
|
queryset = Dispatcher.objects.all()
|
|
|
|
serializer_class = DispatchMessageSerializer
|
|
|
|
|
|
|
|
def get(self, request, *args, **kwargs):
|
2017-02-12 11:58:20 -06:00
|
|
|
"""Return a default message, since this needs POST."""
|
2015-06-19 15:10:21 -05:00
|
|
|
data = {'message': "", 'status': "READY"}
|
2015-06-19 10:51:11 -05:00
|
|
|
message = self.serializer_class(data=data)
|
|
|
|
return Response(message.initial_data)
|
|
|
|
|
|
|
|
def post(self, request, *args, **kwargs):
|
2017-02-12 11:58:20 -06:00
|
|
|
"""Accept and dispatch a provided message."""
|
2015-06-19 10:51:11 -05:00
|
|
|
dispatcher = self.get_object()
|
|
|
|
message = self.serializer_class(data=request.data)
|
|
|
|
if message.is_valid():
|
2015-06-19 15:08:57 -05:00
|
|
|
for action in dispatcher.actions.all():
|
2015-06-20 11:22:56 -05:00
|
|
|
# manipulate the message if desired
|
|
|
|
if action.include_key:
|
|
|
|
text = "[{0:s}] {1:s}".format(action.dispatcher.key, message.data['message'])
|
|
|
|
else:
|
|
|
|
text = message.data['message']
|
|
|
|
|
2023-02-28 18:25:02 -06:00
|
|
|
if action.action_type == DispatcherAction.PRIVMSG_TYPE:
|
2015-06-20 11:22:56 -05:00
|
|
|
# connect over XML-RPC and send
|
|
|
|
try:
|
2021-04-25 08:59:01 -05:00
|
|
|
bot_url = 'http://{0:s}:{1:d}/'.format(dispatcher.bot_xmlrpc_host, dispatcher.bot_xmlrpc_port)
|
2017-02-12 11:39:40 -06:00
|
|
|
bot = xmlrpc.client.ServerProxy(bot_url, allow_none=True)
|
2015-06-20 11:22:56 -05:00
|
|
|
log.debug("sending '%s' to channel %s", text, action.destination)
|
2017-02-12 11:39:40 -06:00
|
|
|
bot.reply(None, text, False, action.destination)
|
2023-02-28 18:25:02 -06:00
|
|
|
except xmlrpc.client.Fault as xmlex:
|
2015-06-20 11:22:56 -05:00
|
|
|
new_data = copy.deepcopy(message.data)
|
2023-02-28 18:25:02 -06:00
|
|
|
new_data['status'] = "FAILED - {0:s}".format(str(xmlex))
|
2015-06-20 11:22:56 -05:00
|
|
|
new_message = self.serializer_class(data=new_data)
|
|
|
|
return Response(new_message.initial_data)
|
2023-02-28 18:25:02 -06:00
|
|
|
elif action.action_type == DispatcherAction.FILE_TYPE:
|
2015-06-20 11:22:56 -05:00
|
|
|
# write to file
|
2015-06-19 11:29:00 -05:00
|
|
|
filename = os.path.abspath(action.destination)
|
2015-06-20 11:22:56 -05:00
|
|
|
log.debug("sending '%s' to file %s", text, filename)
|
2015-06-19 11:29:00 -05:00
|
|
|
with open(filename, 'w') as f:
|
2016-01-17 11:39:43 -06:00
|
|
|
f.write(text + '\n')
|
2015-06-18 23:57:43 -05:00
|
|
|
|
2015-06-19 10:51:11 -05:00
|
|
|
new_data = copy.deepcopy(message.data)
|
|
|
|
new_data['status'] = "OK"
|
|
|
|
new_message = self.serializer_class(data=new_data)
|
|
|
|
return Response(new_message.initial_data)
|
|
|
|
|
|
|
|
return Response(message.errors, status=status.HTTP_400_BAD_REQUEST)
|
2015-06-19 11:29:00 -05:00
|
|
|
|
|
|
|
|
2015-06-20 11:22:17 -05:00
|
|
|
class DispatchMessageByKey(DispatchMessage):
|
2017-02-12 11:58:20 -06:00
|
|
|
"""Dispatch a message for a specific key."""
|
2015-06-20 11:22:17 -05:00
|
|
|
|
|
|
|
lookup_field = 'key'
|
|
|
|
|
|
|
|
|
2015-06-19 11:29:00 -05:00
|
|
|
class DispatcherActionList(generics.ListAPIView):
|
|
|
|
"""List all dispatchers."""
|
|
|
|
|
2023-02-28 18:37:05 -06:00
|
|
|
permission_classes = (IsAuthenticated,)
|
|
|
|
|
2015-06-19 11:29:00 -05:00
|
|
|
queryset = DispatcherAction.objects.all()
|
|
|
|
serializer_class = DispatcherActionSerializer
|
|
|
|
|
|
|
|
|
|
|
|
class DispatcherActionDetail(generics.RetrieveAPIView):
|
|
|
|
"""Detail the given dispatcher."""
|
|
|
|
|
2023-02-28 18:37:05 -06:00
|
|
|
permission_classes = (IsAuthenticated,)
|
|
|
|
|
2015-06-19 11:29:00 -05:00
|
|
|
queryset = DispatcherAction.objects.all()
|
|
|
|
serializer_class = DispatcherActionSerializer
|