this is the first step in trying to get the bot to support multiple servers with different channels, countdown triggers, and so on this also ends up affecting some configuration around: * dispatch * markov * admin privmsg form
119 lines
4.1 KiB
Python
119 lines
4.1 KiB
Python
"""Handle dispatcher API requests."""
|
|
import copy
|
|
import logging
|
|
import os
|
|
import xmlrpc.client
|
|
|
|
from rest_framework import generics, status
|
|
from rest_framework.permissions import IsAuthenticated
|
|
from rest_framework.response import Response
|
|
|
|
from dispatch.models import Dispatcher, DispatcherAction
|
|
from dispatch.serializers import DispatcherActionSerializer, DispatcherSerializer, DispatchMessageSerializer
|
|
|
|
log = logging.getLogger('dispatch.views')
|
|
|
|
|
|
class HasSendMessagePermission(IsAuthenticated):
|
|
"""Class to check if the authenticated user can send messages via dispatch."""
|
|
|
|
def has_permission(self, request, view):
|
|
"""Check user permission for dispatch.send_message."""
|
|
if request.user.has_perm('dispatch.send_message'):
|
|
return True
|
|
|
|
return False
|
|
|
|
|
|
class DispatcherList(generics.ListAPIView):
|
|
"""List all dispatchers."""
|
|
|
|
queryset = Dispatcher.objects.all()
|
|
serializer_class = DispatcherSerializer
|
|
|
|
|
|
class DispatcherDetail(generics.RetrieveAPIView):
|
|
"""Detail the given dispatcher."""
|
|
|
|
queryset = Dispatcher.objects.all()
|
|
serializer_class = DispatcherSerializer
|
|
|
|
|
|
class DispatcherDetailByKey(DispatcherDetail):
|
|
"""Detail a specific dispatcher."""
|
|
|
|
lookup_field = 'key'
|
|
|
|
|
|
class DispatchMessage(generics.GenericAPIView):
|
|
"""Send a message to the given dispatcher."""
|
|
|
|
permission_classes = (HasSendMessagePermission,)
|
|
|
|
queryset = Dispatcher.objects.all()
|
|
serializer_class = DispatchMessageSerializer
|
|
|
|
def get(self, request, *args, **kwargs):
|
|
"""Return a default message, since this needs POST."""
|
|
data = {'message': "", 'status': "READY"}
|
|
message = self.serializer_class(data=data)
|
|
return Response(message.initial_data)
|
|
|
|
def post(self, request, *args, **kwargs):
|
|
"""Accept and dispatch a provided message."""
|
|
dispatcher = self.get_object()
|
|
message = self.serializer_class(data=request.data)
|
|
if message.is_valid():
|
|
for action in dispatcher.actions.all():
|
|
# 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']
|
|
|
|
if action.type == DispatcherAction.PRIVMSG_TYPE:
|
|
# connect over XML-RPC and send
|
|
try:
|
|
bot_url = 'http://{0:s}:{1:d}/'.format(dispatcher.bot_xmlrpc_host, dispatcher.bot_xmlrpc_port)
|
|
bot = xmlrpc.client.ServerProxy(bot_url, allow_none=True)
|
|
log.debug("sending '%s' to channel %s", text, action.destination)
|
|
bot.reply(None, text, False, action.destination)
|
|
except Exception as e:
|
|
new_data = copy.deepcopy(message.data)
|
|
new_data['status'] = "FAILED - {0:s}".format(str(e))
|
|
new_message = self.serializer_class(data=new_data)
|
|
return Response(new_message.initial_data)
|
|
elif action.type == DispatcherAction.FILE_TYPE:
|
|
# write to file
|
|
filename = os.path.abspath(action.destination)
|
|
log.debug("sending '%s' to file %s", text, filename)
|
|
with open(filename, 'w') as f:
|
|
f.write(text + '\n')
|
|
|
|
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)
|
|
|
|
|
|
class DispatchMessageByKey(DispatchMessage):
|
|
"""Dispatch a message for a specific key."""
|
|
|
|
lookup_field = 'key'
|
|
|
|
|
|
class DispatcherActionList(generics.ListAPIView):
|
|
"""List all dispatchers."""
|
|
|
|
queryset = DispatcherAction.objects.all()
|
|
serializer_class = DispatcherActionSerializer
|
|
|
|
|
|
class DispatcherActionDetail(generics.RetrieveAPIView):
|
|
"""Detail the given dispatcher."""
|
|
|
|
queryset = DispatcherAction.objects.all()
|
|
serializer_class = DispatcherActionSerializer
|