start work switch to py3 and ircbot
This commit is contained in:
parent
12e6c0374e
commit
6eefcdda74
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -6,3 +6,4 @@ db.sqlite3
|
|||
.env
|
||||
*.pyc
|
||||
venv/
|
||||
venv3/
|
||||
|
|
|
@ -44,6 +44,7 @@ INSTALLED_APPS = [
|
|||
'program',
|
||||
'info',
|
||||
'sponsors',
|
||||
'ircbot',
|
||||
|
||||
'allauth',
|
||||
'allauth.account',
|
||||
|
|
0
ircbot/__init__.py
Normal file
0
ircbot/__init__.py
Normal file
3
ircbot/admin.py
Normal file
3
ircbot/admin.py
Normal file
|
@ -0,0 +1,3 @@
|
|||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
7
ircbot/apps.py
Normal file
7
ircbot/apps.py
Normal file
|
@ -0,0 +1,7 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class IrcbotConfig(AppConfig):
|
||||
name = 'ircbot'
|
91
ircbot/irc3module.py
Normal file
91
ircbot/irc3module.py
Normal file
|
@ -0,0 +1,91 @@
|
|||
import irc3
|
||||
from ircbot.models import OutgoingIrcMessage
|
||||
from django.conf import settings
|
||||
|
||||
|
||||
@irc3.plugin
|
||||
class Plugin(object):
|
||||
"""BornHack IRC3 class"""
|
||||
|
||||
requires = [
|
||||
'irc3.plugins.core', # makes the bot able to connect to an irc server and do basic irc stuff
|
||||
'irc3.plugins.userlist', # maintains a convenient list of the channels the bot is in and their users
|
||||
'irc3.plugins.command', # what does this do?
|
||||
]
|
||||
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
self.log = self.bot.log
|
||||
|
||||
|
||||
###############################################################################################
|
||||
### builtin irc3 event methods
|
||||
|
||||
def server_ready(self, **kwargs):
|
||||
"""triggered after the server sent the MOTD (require core plugin)"""
|
||||
if settings.DEBUG:
|
||||
print("inside server_ready(), kwargs: %s" % kwargs)
|
||||
|
||||
|
||||
def connection_lost(self, **kwargs):
|
||||
"""triggered when connection is lost"""
|
||||
if settings.DEBUG:
|
||||
print("inside connection_lost(), kwargs: %s" % kwargs)
|
||||
|
||||
|
||||
def connection_made(self, **kwargs):
|
||||
"""triggered when connection is up"""
|
||||
if settings.DEBUG:
|
||||
print("inside connection_made(), kwargs: %s" % kwargs)
|
||||
|
||||
|
||||
###############################################################################################
|
||||
### decorated irc3 event methods
|
||||
|
||||
@irc3.event(irc3.rfc.JOIN_PART_QUIT)
|
||||
def on_join_part_quit(self, **kwargs):
|
||||
"""triggered when there is a join part or quit on a channel the bot is in"""
|
||||
if settings.DEBUG:
|
||||
print("inside on_join_part_quit(), kwargs: %s" % kwargs)
|
||||
if self.bot.nick == kwargs['mask'].split("!")[0] and kwargs['channel'] == "#tirsdagsfilm":
|
||||
self.bot.loop.call_later(1, self.bot.get_outgoing_messages)
|
||||
|
||||
|
||||
@irc3.event(irc3.rfc.PRIVMSG)
|
||||
def on_privmsg(self, **kwargs):
|
||||
"""triggered when a privmsg is sent to the bot or to a channel the bot is in"""
|
||||
if settings.DEBUG:
|
||||
print("inside on_privmsg(), kwargs: %s" % kwargs)
|
||||
|
||||
|
||||
@irc3.event(irc3.rfc.KICK)
|
||||
def on_kick(self, **kwargs):
|
||||
if settings.DEBUG:
|
||||
print("inside on_kick(), kwargs: %s" % kwargs)
|
||||
|
||||
|
||||
###############################################################################################
|
||||
### custom irc3 methods
|
||||
@irc3.extend
|
||||
def get_outgoing_messages(self):
|
||||
"""
|
||||
This method gets unprocessed OutgoingIrcMessage objects and attempts to send them to
|
||||
the target channel. Messages are skipped if the bot is not in the channel.
|
||||
"""
|
||||
# TODO: handle privmsg to users
|
||||
# TODO: set a timeout for messages.. a few minutes maybe?
|
||||
# TODO: make sleep time configurable
|
||||
print("inside get_outgoing_messages()")
|
||||
for msg in OutgoingIrcMessage.objects.filter(processed=False).order_by('created_date'):
|
||||
if msg.target[0] == "#" and msg.target in self.bot.channels:
|
||||
print("sending privmsg to %s: %s" % (msg.target, msg.message))
|
||||
self.bot.privmsg(msg.target, msg.message)
|
||||
msg.processed=True
|
||||
msg.save()
|
||||
else:
|
||||
print("skipping message to channel %s because the bot is not in the channel" % msg.target)
|
||||
|
||||
# call this function again in 60 seconds
|
||||
self.bot.loop.call_later(60, self.bot.get_outgoing_messages)
|
||||
|
||||
|
0
ircbot/management/__init__.py
Normal file
0
ircbot/management/__init__.py
Normal file
0
ircbot/management/commands/__init__.py
Normal file
0
ircbot/management/commands/__init__.py
Normal file
30
ircbot/management/commands/ircbot.py
Normal file
30
ircbot/management/commands/ircbot.py
Normal file
|
@ -0,0 +1,30 @@
|
|||
from django.core.management.base import BaseCommand
|
||||
from django.conf import settings
|
||||
from django.utils import timezone
|
||||
from time import sleep
|
||||
import irc3, sys, asyncio
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
args = 'none'
|
||||
help = 'Runs the BornHack IRC bot to announce talks and manage team channel permissions'
|
||||
|
||||
def output(self, message):
|
||||
self.stdout.write('%s: %s' % (timezone.now().strftime("%Y-%m-%d %H:%M:%S"), message))
|
||||
|
||||
def handle(self, *args, **options):
|
||||
self.output('IRC bot worker running...')
|
||||
# connect to IRC
|
||||
config = {
|
||||
'nick': 'BornHack',
|
||||
'autojoins': ['#tirsdagsfilm'],
|
||||
'host': 'ircd.tyknet.dk',
|
||||
'port': 6697,
|
||||
'ssl': True,
|
||||
'timeout': 30,
|
||||
'includes': [
|
||||
'ircbot.irc3module',
|
||||
],
|
||||
}
|
||||
irc3.IrcBot(**config).run(forever=True)
|
||||
|
30
ircbot/migrations/0001_initial.py
Normal file
30
ircbot/migrations/0001_initial.py
Normal file
|
@ -0,0 +1,30 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.5 on 2017-01-29 20:29
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='OutgoingIrcMessage',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('created', models.DateTimeField(auto_now_add=True)),
|
||||
('updated', models.DateTimeField(auto_now=True)),
|
||||
('target', models.CharField(max_length=100)),
|
||||
('message', models.CharField(max_length=200)),
|
||||
('processed', models.BooleanField(default=False)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
]
|
0
ircbot/migrations/__init__.py
Normal file
0
ircbot/migrations/__init__.py
Normal file
10
ircbot/models.py
Normal file
10
ircbot/models.py
Normal file
|
@ -0,0 +1,10 @@
|
|||
from __future__ import unicode_literals
|
||||
from utils.models import UUIDModel, CreatedUpdatedModel
|
||||
from django.db import models
|
||||
|
||||
|
||||
class OutgoingIrcMessage(CreatedUpdatedModel):
|
||||
target = models.CharField(max_length=100)
|
||||
message = models.CharField(max_length=200)
|
||||
processed = models.BooleanField(default=False)
|
||||
|
3
ircbot/views.py
Normal file
3
ircbot/views.py
Normal file
|
@ -0,0 +1,3 @@
|
|||
from django.shortcuts import render
|
||||
|
||||
# Create your views here.
|
|
@ -4,6 +4,7 @@ Pillow==4.0.0
|
|||
PyPDF2==1.26.0
|
||||
Unidecode==0.04.20
|
||||
argparse==1.2.1
|
||||
asyncio==3.4.3
|
||||
bleach==1.5.0
|
||||
django-allauth==0.30.0
|
||||
django-bleach==0.3.0
|
||||
|
@ -11,8 +12,10 @@ django-bootstrap3==8.1.0
|
|||
django-debug-toolbar==1.6
|
||||
django-environ==0.4.1
|
||||
django-wkhtmltopdf==3.1.0
|
||||
docopt==0.6.2
|
||||
future==0.16.0
|
||||
html5lib==0.9999999
|
||||
irc3==0.9.8
|
||||
oauthlib==2.0.1
|
||||
olefile==0.44
|
||||
psycopg2==2.6.2
|
||||
|
@ -23,5 +26,6 @@ requests==2.12.5
|
|||
requests-oauthlib==0.7.0
|
||||
six==1.10.0
|
||||
sqlparse==0.2.2
|
||||
venusian==1.0
|
||||
webencodings==0.5
|
||||
wsgiref==0.1.2
|
||||
|
|
30
requirements3.txt
Normal file
30
requirements3.txt
Normal file
|
@ -0,0 +1,30 @@
|
|||
CommonMark==0.7.3
|
||||
Django==1.10.5
|
||||
Pillow==4.0.0
|
||||
PyPDF2==1.26.0
|
||||
Unidecode==0.04.20
|
||||
argparse==1.2.1
|
||||
asyncio==3.4.3
|
||||
bleach==1.5.0
|
||||
django-allauth==0.30.0
|
||||
django-bleach==0.3.0
|
||||
django-bootstrap3==8.1.0
|
||||
django-debug-toolbar==1.6
|
||||
django-environ==0.4.1
|
||||
django-wkhtmltopdf==3.1.0
|
||||
docopt==0.6.2
|
||||
future==0.16.0
|
||||
html5lib==0.9999999
|
||||
irc3==0.9.8
|
||||
oauthlib==2.0.1
|
||||
olefile==0.44
|
||||
psycopg2==2.6.2
|
||||
python-openid==2.2.5
|
||||
pytz==2016.10
|
||||
qrcode==5.3
|
||||
requests==2.12.5
|
||||
requests-oauthlib==0.7.0
|
||||
six==1.10.0
|
||||
sqlparse==0.2.2
|
||||
venusian==1.0
|
||||
webencodings==0.5
|
|
@ -1,5 +1,5 @@
|
|||
from django.conf.urls import url
|
||||
from views import *
|
||||
from .views import *
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^$', ShopIndexView.as_view(), name='index'),
|
||||
|
|
|
@ -447,21 +447,18 @@ class EpayCallbackView(SingleObjectMixin, View):
|
|||
|
||||
if 'orderid' in request.GET:
|
||||
query = OrderedDict(
|
||||
map(
|
||||
lambda x: tuple(x.split('=')),
|
||||
request.META['QUERY_STRING'].split('&')
|
||||
)
|
||||
[tuple(x.split('=')) for x in request.META['QUERY_STRING'].split('&')]
|
||||
)
|
||||
order = get_object_or_404(Order, pk=query.get('orderid'))
|
||||
if order.pk != self.get_object().pk:
|
||||
print "bad epay callback, orders do not match!"
|
||||
print("bad epay callback, orders do not match!")
|
||||
return HttpResponse(status=400)
|
||||
|
||||
if validate_epay_callback(query):
|
||||
callback.md5valid=True
|
||||
callback.save()
|
||||
else:
|
||||
print "bad epay callback!"
|
||||
print("bad epay callback!")
|
||||
return HttpResponse(status=400)
|
||||
|
||||
if order.paid:
|
||||
|
@ -479,7 +476,7 @@ class EpayCallbackView(SingleObjectMixin, View):
|
|||
### and mark order as paid (this will create tickets)
|
||||
order.mark_as_paid()
|
||||
else:
|
||||
print "valid epay callback with wrong amount detected"
|
||||
print("valid epay callback with wrong amount detected")
|
||||
else:
|
||||
return HttpResponse(status=400)
|
||||
|
||||
|
@ -541,7 +538,7 @@ class CoinifyRedirectView(LoginRequiredMixin, EnsureUserOwnsOrderMixin, EnsureUn
|
|||
# check if it expired
|
||||
if parse_datetime(order.coinifyapiinvoice.invoicejson['expire_time']) < timezone.now():
|
||||
# this coinifyinvoice expired, delete it
|
||||
print "deleting expired coinifyinvoice id %s" % order.coinifyapiinvoice.invoicejson['id']
|
||||
print("deleting expired coinifyinvoice id %s" % order.coinifyapiinvoice.invoicejson['id'])
|
||||
order.coinifyapiinvoice.delete()
|
||||
order = self.get_object()
|
||||
|
||||
|
@ -568,10 +565,10 @@ class CoinifyRedirectView(LoginRequiredMixin, EnsureUserOwnsOrderMixin, EnsureUn
|
|||
# Parse response
|
||||
if not response['success']:
|
||||
api_error = response['error']
|
||||
print "API error: %s (%s)" % (
|
||||
print("API error: %s (%s)" % (
|
||||
api_error['message'],
|
||||
api_error['code']
|
||||
)
|
||||
))
|
||||
messages.error(request, "There was a problem with the payment provider. Please try again later")
|
||||
return HttpResponseRedirect(reverse_lazy('shop:order_detail', kwargs={'pk': self.get_object().pk}))
|
||||
else:
|
||||
|
@ -580,7 +577,7 @@ class CoinifyRedirectView(LoginRequiredMixin, EnsureUserOwnsOrderMixin, EnsureUn
|
|||
invoicejson = response['data'],
|
||||
order = order,
|
||||
)
|
||||
print "created new coinifyinvoice id %s" % coinifyinvoice.invoicejson['id']
|
||||
print("created new coinifyinvoice id %s" % coinifyinvoice.invoicejson['id'])
|
||||
return super(CoinifyRedirectView, self).dispatch(
|
||||
request, *args, **kwargs
|
||||
)
|
||||
|
@ -603,7 +600,7 @@ class CoinifyCallbackView(SingleObjectMixin, View):
|
|||
|
||||
# make a dict with all HTTP_ headers
|
||||
headerdict = {}
|
||||
for key, value in request.META.iteritems():
|
||||
for key, value in request.META.items():
|
||||
if key[:5] == 'HTTP_':
|
||||
headerdict[key[5:]] = value
|
||||
|
||||
|
@ -625,7 +622,7 @@ class CoinifyCallbackView(SingleObjectMixin, View):
|
|||
try:
|
||||
coinifyinvoice = CoinifyAPIInvoice.objects.get(invoicejson__id=callbackjson['data']['id'])
|
||||
except CoinifyAPIInvoice.DoesNotExist:
|
||||
print "unable to find CoinifyAPIInvoice with id %s" % callbackjson['data']['id']
|
||||
print("unable to find CoinifyAPIInvoice with id %s" % callbackjson['data']['id'])
|
||||
return HttpResponseBadRequest('bad coinifyinvoice id')
|
||||
|
||||
# save new coinifyinvoice payload
|
||||
|
@ -641,7 +638,7 @@ class CoinifyCallbackView(SingleObjectMixin, View):
|
|||
else:
|
||||
return HttpResponseBadRequest('unsupported event')
|
||||
else:
|
||||
print "invalid coinify callback detected"
|
||||
print("invalid coinify callback detected")
|
||||
return HttpResponseBadRequest('something is fucky')
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue