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
dr_botzo/dispatch/__init__.py
Normal file
0
dr_botzo/dispatch/__init__.py
Normal file
8
dr_botzo/dispatch/admin.py
Normal file
8
dr_botzo/dispatch/admin.py
Normal file
@ -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)
|
22
dr_botzo/dispatch/migrations/0001_initial.py
Normal file
22
dr_botzo/dispatch/migrations/0001_initial.py
Normal file
@ -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
dr_botzo/dispatch/migrations/__init__.py
Normal file
0
dr_botzo/dispatch/migrations/__init__.py
Normal file
30
dr_botzo/dispatch/models.py
Normal file
30
dr_botzo/dispatch/models.py
Normal file
@ -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)
|
17
dr_botzo/dispatch/serializers.py
Normal file
17
dr_botzo/dispatch/serializers.py
Normal file
@ -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()
|
12
dr_botzo/dispatch/urls.py
Normal file
12
dr_botzo/dispatch/urls.py
Normal file
@ -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'),
|
||||
)
|
72
dr_botzo/dispatch/views.py
Normal file
72
dr_botzo/dispatch/views.py
Normal file
@ -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
Block a user