collapsing all of dr_botzo one directory
This commit is contained in:
0
dispatch/__init__.py
Normal file
0
dispatch/__init__.py
Normal file
9
dispatch/admin.py
Normal file
9
dispatch/admin.py
Normal file
@@ -0,0 +1,9 @@
|
||||
"""Manage dispatch models in the admin interface."""
|
||||
|
||||
from django.contrib import admin
|
||||
|
||||
from dispatch.models import Dispatcher, DispatcherAction
|
||||
|
||||
|
||||
admin.site.register(Dispatcher)
|
||||
admin.site.register(DispatcherAction)
|
||||
21
dispatch/migrations/0001_initial.py
Normal file
21
dispatch/migrations/0001_initial.py
Normal file
@@ -0,0 +1,21 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from django.db import models, migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Dispatcher',
|
||||
fields=[
|
||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
||||
('key', models.CharField(unique=True, max_length=16)),
|
||||
('type', models.CharField(max_length=16, choices=[(b'privmsg', b'IRC privmsg'), (b'file', b'Write to file')])),
|
||||
('destination', models.CharField(max_length=200)),
|
||||
],
|
||||
),
|
||||
]
|
||||
34
dispatch/migrations/0002_auto_20150619_1124.py
Normal file
34
dispatch/migrations/0002_auto_20150619_1124.py
Normal file
@@ -0,0 +1,34 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from django.db import models, migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('dispatch', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='DispatcherAction',
|
||||
fields=[
|
||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
||||
('type', models.CharField(max_length=16, choices=[(b'privmsg', b'IRC privmsg'), (b'file', b'Write to file')])),
|
||||
('destination', models.CharField(max_length=200)),
|
||||
],
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='dispatcher',
|
||||
name='destination',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='dispatcher',
|
||||
name='type',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='dispatcheraction',
|
||||
name='dispatcher',
|
||||
field=models.ForeignKey(to='dispatch.Dispatcher'),
|
||||
),
|
||||
]
|
||||
22
dispatch/migrations/0003_auto_20150619_1637.py
Normal file
22
dispatch/migrations/0003_auto_20150619_1637.py
Normal file
@@ -0,0 +1,22 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from django.db import models, migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('dispatch', '0002_auto_20150619_1124'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='dispatcher',
|
||||
options={'permissions': (('send_message', 'Can send messages to dispatchers'),)},
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='dispatcheraction',
|
||||
name='dispatcher',
|
||||
field=models.ForeignKey(related_name='actions', to='dispatch.Dispatcher'),
|
||||
),
|
||||
]
|
||||
18
dispatch/migrations/0004_dispatcheraction_include_key.py
Normal file
18
dispatch/migrations/0004_dispatcheraction_include_key.py
Normal file
@@ -0,0 +1,18 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from django.db import models, migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('dispatch', '0003_auto_20150619_1637'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='dispatcheraction',
|
||||
name='include_key',
|
||||
field=models.BooleanField(default=False),
|
||||
),
|
||||
]
|
||||
19
dispatch/migrations/0005_auto_20160116_1955.py
Normal file
19
dispatch/migrations/0005_auto_20160116_1955.py
Normal file
@@ -0,0 +1,19 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('dispatch', '0004_dispatcheraction_include_key'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='dispatcheraction',
|
||||
name='type',
|
||||
field=models.CharField(choices=[('privmsg', 'IRC privmsg'), ('file', 'Write to file')], max_length=16),
|
||||
),
|
||||
]
|
||||
0
dispatch/migrations/__init__.py
Normal file
0
dispatch/migrations/__init__.py
Normal file
48
dispatch/models.py
Normal file
48
dispatch/models.py
Normal file
@@ -0,0 +1,48 @@
|
||||
"""Track dispatcher configurations."""
|
||||
|
||||
import logging
|
||||
|
||||
from django.db import models
|
||||
|
||||
|
||||
log = logging.getLogger('dispatch.models')
|
||||
|
||||
|
||||
class Dispatcher(models.Model):
|
||||
|
||||
"""Organize dispatchers by key."""
|
||||
|
||||
key = models.CharField(max_length=16, unique=True)
|
||||
|
||||
class Meta:
|
||||
permissions = (
|
||||
('send_message', "Can send messages to dispatchers"),
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
"""String representation."""
|
||||
|
||||
return "{0:s}".format(self.key)
|
||||
|
||||
|
||||
class DispatcherAction(models.Model):
|
||||
|
||||
"""Handle requests to dispatchers and do something with them."""
|
||||
|
||||
PRIVMSG_TYPE = 'privmsg'
|
||||
FILE_TYPE = 'file'
|
||||
|
||||
TYPE_CHOICES = (
|
||||
(PRIVMSG_TYPE, "IRC privmsg"),
|
||||
(FILE_TYPE, "Write to file"),
|
||||
)
|
||||
|
||||
dispatcher = models.ForeignKey('Dispatcher', related_name='actions')
|
||||
type = models.CharField(max_length=16, choices=TYPE_CHOICES)
|
||||
destination = models.CharField(max_length=200)
|
||||
include_key = models.BooleanField(default=False)
|
||||
|
||||
def __str__(self):
|
||||
"""String representation."""
|
||||
|
||||
return "{0:s} -> {1:s} {2:s}".format(self.dispatcher.key, self.type, self.destination)
|
||||
27
dispatch/serializers.py
Normal file
27
dispatch/serializers.py
Normal file
@@ -0,0 +1,27 @@
|
||||
"""Serializers for the dispatcher API objects."""
|
||||
|
||||
from rest_framework import serializers
|
||||
|
||||
from dispatch.models import Dispatcher, DispatcherAction
|
||||
|
||||
|
||||
class DispatcherActionSerializer(serializers.ModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = DispatcherAction
|
||||
fields = ('id', 'dispatcher', 'type', 'destination')
|
||||
|
||||
|
||||
class DispatcherSerializer(serializers.ModelSerializer):
|
||||
|
||||
actions = DispatcherActionSerializer(many=True, read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = Dispatcher
|
||||
fields = ('id', 'key', 'actions')
|
||||
|
||||
|
||||
class DispatchMessageSerializer(serializers.Serializer):
|
||||
|
||||
message = serializers.CharField()
|
||||
status = serializers.CharField(read_only=True)
|
||||
20
dispatch/urls.py
Normal file
20
dispatch/urls.py
Normal file
@@ -0,0 +1,20 @@
|
||||
"""URL patterns for the dispatcher API."""
|
||||
|
||||
from django.conf.urls import patterns, url
|
||||
|
||||
from dispatch.views import (DispatchMessage, DispatchMessageByKey, DispatcherList, DispatcherDetail,
|
||||
DispatcherDetailByKey, DispatcherActionList, DispatcherActionDetail)
|
||||
|
||||
|
||||
urlpatterns = patterns('dispatch.views',
|
||||
url(r'^api/dispatchers/$', DispatcherList.as_view(), name='dispatch_api_dispatchers'),
|
||||
url(r'^api/dispatchers/(?P<pk>[0-9]+)/$', DispatcherDetail.as_view(), name='dispatch_api_dispatcher_detail'),
|
||||
url(r'^api/dispatchers/(?P<pk>[0-9]+)/message$', DispatchMessage.as_view(), name='dispatch_api_dispatch_message'),
|
||||
url(r'^api/dispatchers/(?P<key>[A-Za-z-]+)/$', DispatcherDetailByKey.as_view(),
|
||||
name='dispatch_api_dispatcher_detail'),
|
||||
url(r'^api/dispatchers/(?P<key>[A-Za-z-]+)/message$', DispatchMessageByKey.as_view(),
|
||||
name='dispatch_api_dispatch_message'),
|
||||
|
||||
url(r'^api/actions/$', DispatcherActionList.as_view(), name='dispatch_api_actions'),
|
||||
url(r'^api/actions/(?P<pk>[0-9]+)/$', DispatcherActionDetail.as_view(), name='dispatch_api_action_detail'),
|
||||
)
|
||||
121
dispatch/views.py
Normal file
121
dispatch/views.py
Normal file
@@ -0,0 +1,121 @@
|
||||
"""Handle dispatcher API requests."""
|
||||
|
||||
import copy
|
||||
import logging
|
||||
import os
|
||||
import xmlrpc.client
|
||||
|
||||
from django.conf import settings
|
||||
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 DispatchMessageSerializer, DispatcherSerializer, DispatcherActionSerializer
|
||||
|
||||
|
||||
log = logging.getLogger('dispatch.views')
|
||||
|
||||
|
||||
class HasSendMessagePermission(IsAuthenticated):
|
||||
|
||||
def has_permission(self, request, view):
|
||||
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):
|
||||
|
||||
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):
|
||||
dispatcher = self.get_object()
|
||||
data = {'message': "", 'status': "READY"}
|
||||
message = self.serializer_class(data=data)
|
||||
return Response(message.initial_data)
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
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(settings.IRCBOT_XMLRPC_HOST, settings.IRCBOT_XMLRPC_PORT)
|
||||
bot = xmlrpc.client.ServerProxy(bot_url)
|
||||
log.debug("sending '%s' to channel %s", text, action.destination)
|
||||
bot.privmsg(action.destination, text)
|
||||
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):
|
||||
|
||||
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
|
||||
Reference in New Issue
Block a user