dispatch: port to django REST framework
this moves the dispatcher functionality that used to be in the old ircbot directly to django REST framework, which is more robust and allows for cooler stuff down the road. this still retains the ability to have the bot privmsg, that still happens over the XML-RPC interface, this is just a more convenient frontend to that
This commit is contained in:
parent
fccb5f3fb3
commit
0641e1c062
|
@ -0,0 +1,8 @@
|
|||
"""Manage dispatch models in the admin interface."""
|
||||
|
||||
from django.contrib import admin
|
||||
|
||||
from dispatch.models import Dispatcher
|
||||
|
||||
|
||||
admin.site.register(Dispatcher)
|
|
@ -0,0 +1,22 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
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)),
|
||||
],
|
||||
),
|
||||
]
|
|
@ -0,0 +1,30 @@
|
|||
"""Track dispatcher configurations."""
|
||||
|
||||
import logging
|
||||
|
||||
from django.db import models
|
||||
|
||||
|
||||
log = logging.getLogger('dispatch.models')
|
||||
|
||||
|
||||
class Dispatcher(models.Model):
|
||||
|
||||
"""Handle incoming API requests and do something with them."""
|
||||
|
||||
PRIVMSG_TYPE = 'privmsg'
|
||||
FILE_TYPE = 'file'
|
||||
|
||||
TYPE_CHOICES = (
|
||||
(PRIVMSG_TYPE, "IRC privmsg"),
|
||||
(FILE_TYPE, "Write to file"),
|
||||
)
|
||||
|
||||
key = models.CharField(max_length=16, unique=True)
|
||||
type = models.CharField(max_length=16, choices=TYPE_CHOICES)
|
||||
destination = models.CharField(max_length=200)
|
||||
|
||||
def __unicode__(self):
|
||||
"""String representation."""
|
||||
|
||||
return u"{0:s} -> {1:s}".format(self.key, self.destination)
|
|
@ -0,0 +1,17 @@
|
|||
"""Serializers for the dispatcher API objects."""
|
||||
|
||||
from rest_framework import serializers
|
||||
|
||||
from dispatch.models import Dispatcher
|
||||
|
||||
|
||||
class DispatcherSerializer(serializers.ModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = Dispatcher
|
||||
fields = ('id', 'key', 'type', 'destination')
|
||||
|
||||
|
||||
class DispatchMessageSerializer(serializers.Serializer):
|
||||
|
||||
message = serializers.CharField()
|
|
@ -0,0 +1,12 @@
|
|||
"""URL patterns for the dispatcher API."""
|
||||
|
||||
from django.conf.urls import patterns, url
|
||||
|
||||
from dispatch.views import DispatchMessage, DispatcherList, DispatcherDetail
|
||||
|
||||
|
||||
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'),
|
||||
)
|
|
@ -0,0 +1,72 @@
|
|||
"""Handle dispatcher API requests."""
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import logging
|
||||
import os
|
||||
import xmlrpclib
|
||||
|
||||
from django.conf import settings
|
||||
from django.http import Http404
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework.response import Response
|
||||
from rest_framework import generics, status
|
||||
|
||||
from dispatch.models import Dispatcher
|
||||
from dispatch.serializers import DispatchMessageSerializer, DispatcherSerializer
|
||||
|
||||
|
||||
log = logging.getLogger('dispatch.views')
|
||||
|
||||
|
||||
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 DispatchMessage(APIView):
|
||||
|
||||
"""Send a message to the given dispatcher."""
|
||||
|
||||
queryset = Dispatcher.objects.none()
|
||||
|
||||
def get_object(self, pk):
|
||||
try:
|
||||
return Dispatcher.objects.get(pk=pk)
|
||||
except Dispatcher.DoesNotExist:
|
||||
raise Http404
|
||||
|
||||
def get(self, request, pk, format=None):
|
||||
dispatcher = self.get_object(pk)
|
||||
return Response({'message': ""})
|
||||
|
||||
def post(self, request, pk, format=None):
|
||||
dispatcher = self.get_object(pk)
|
||||
serializer = DispatchMessageSerializer(data=request.data)
|
||||
if serializer.is_valid():
|
||||
if dispatcher.type == Dispatcher.PRIVMSG_TYPE:
|
||||
bot_url = 'http://{0:s}:{1:d}/'.format(settings.IRCBOT_XMLRPC_HOST, settings.IRCBOT_XMLRPC_PORT)
|
||||
bot = xmlrpclib.ServerProxy(bot_url)
|
||||
log.debug("sending '%s' to channel %s", serializer.data['message'], dispatcher.destination)
|
||||
bot.privmsg(dispatcher.destination, serializer.data['message'])
|
||||
return Response({'status': "OK"})
|
||||
elif dispatcher.type == Dispatcher.FILE_TYPE:
|
||||
filename = os.path.abspath(dispatcher.destination)
|
||||
log.debug("sending '%s' to file %s", serializer.data['message'], filename)
|
||||
with open(filename, 'w') as f:
|
||||
f.write(serializer.data['message'])
|
||||
f.write('\n')
|
||||
return Response({'status': "OK"})
|
||||
|
||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
|
@ -37,7 +37,9 @@ INSTALLED_APPS = (
|
|||
'django.contrib.staticfiles',
|
||||
'django_extensions',
|
||||
'adminplus',
|
||||
'rest_framework',
|
||||
'countdown',
|
||||
'dispatch',
|
||||
'facts',
|
||||
'ircbot',
|
||||
'karma',
|
||||
|
@ -121,6 +123,15 @@ STATICFILES_DIRS = (
|
|||
)
|
||||
|
||||
|
||||
REST_FRAMEWORK = {
|
||||
# Use Django's standard `django.contrib.auth` permissions,
|
||||
# or allow read-only access for unauthenticated users.
|
||||
'DEFAULT_PERMISSION_CLASSES': [
|
||||
'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly'
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
# IRC bot stuff
|
||||
|
||||
# tuple of hostname, port number, and password (or None)
|
||||
|
|
|
@ -9,6 +9,7 @@ admin.autodiscover()
|
|||
urlpatterns = patterns('',
|
||||
url(r'^$', 'dr_botzo.views.home', name='home'),
|
||||
|
||||
url(r'^dispatch/', include('dispatch.urls')),
|
||||
url(r'^markov/', include('markov.urls')),
|
||||
url(r'^races/', include('races.urls')),
|
||||
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
Django==1.8.1
|
||||
django-adminplus==0.3
|
||||
django-extensions==1.5.3
|
||||
django-filter==0.10.0
|
||||
djangorestframework==3.1.3
|
||||
httplib2==0.7.4
|
||||
inflect==0.2.5
|
||||
irc==12.1.4
|
||||
|
@ -13,6 +16,7 @@ jaraco.logging==1.2
|
|||
jaraco.text==1.3
|
||||
logilab-astng==0.24.0
|
||||
logilab-common==0.58.1
|
||||
Markdown==2.6.2
|
||||
more-itertools==2.2
|
||||
MySQL-python==1.2.3
|
||||
oauth2==1.5.211
|
||||
|
@ -29,4 +33,3 @@ tempora==1.3
|
|||
twython==3.0.0
|
||||
yg.lockfile==2.0
|
||||
zc.lockfile==1.1.0
|
||||
django-adminplus==0.3
|
||||
|
|
Loading…
Reference in New Issue