From 1b3557c6b58bf89b45b5640c5172c035fc8dc8de Mon Sep 17 00:00:00 2001 From: Andrew Williams Date: Wed, 27 Aug 2014 17:17:04 +0100 Subject: [PATCH] Add Redis support and ZKB listening. --- .gitignore | 3 +++ .vagrant/init.sh | 8 ++++++++ Vagrantfile | 9 +++++++++ dropbot/bot.py | 36 +++++++++++++++++++++++++++++++++--- dropbot/cli.py | 2 +- dropbot/utils.py | 28 ++++++++++++++++++++++++++++ 6 files changed, 82 insertions(+), 4 deletions(-) create mode 100644 .vagrant/init.sh create mode 100644 Vagrantfile create mode 100644 dropbot/utils.py diff --git a/.gitignore b/.gitignore index b66adaf..78265fe 100644 --- a/.gitignore +++ b/.gitignore @@ -59,3 +59,6 @@ target/ # EVE eve.db + +# Vagrant +.vagrant/ diff --git a/.vagrant/init.sh b/.vagrant/init.sh new file mode 100644 index 0000000..22df611 --- /dev/null +++ b/.vagrant/init.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +# Install Redis +apt-get update +apt-get install -y redis-server + +# Show versions +dpkg -la | grep redis-server \ No newline at end of file diff --git a/Vagrantfile b/Vagrantfile new file mode 100644 index 0000000..9015479 --- /dev/null +++ b/Vagrantfile @@ -0,0 +1,9 @@ +Vagrant.configure("2") do |config| + config.vm.box = "ubuntu" + config.vm.network :forwarded_port, guest: 6379, host: 6379 + # Set virtual machine memory size + config.vm.provider :virtualbox do |vbox| + vbox.customize ["modifyvm", :id, "--memory", 1024] + end + config.vm.provision :shell, :path => ".vagrant/init.sh" +end \ No newline at end of file diff --git a/dropbot/bot.py b/dropbot/bot.py index a57172b..2c989c0 100644 --- a/dropbot/bot.py +++ b/dropbot/bot.py @@ -1,19 +1,23 @@ +from datetime import datetime from xml.etree import ElementTree import pkgutil from json import loads as base_loads from random import choice import logging import re +import urlparse from sleekxmpp import ClientXMPP -from redis import Redis +from redis import Redis, ConnectionPool import requests from humanize import intcomma from pyzkb import ZKillboard from eveapi import EVEAPIConnection from dropbot.map import Map, base_range, ship_class_to_range +from dropbot.utils import EVEAPIRedisCache +urlparse.uses_netloc.append("redis") market_systems = [ ('Jita', 30000142), @@ -38,8 +42,12 @@ class DropBot(ClientXMPP): self.cmd_prefix = kwargs.pop('cmd_prefix', '!') self.kos_url = kwargs.pop('kos_url', 'http://kos.cva-eve.org/api/') self.hidden_commands = ['cmd_prefix'] + self.last_killdate = datetime.utcnow() + self.kill_corps = kwargs.pop('kill_corps', []) + self.kill_check_timeout = kwargs.pop('kill_check_timeout', 300) - self.redis_conn = Redis() + self.redis_pool = ConnectionPool.from_url(kwargs.pop('redis_url', 'redis://localhost:6379/0')) + self.redis = Redis(connection_pool=self.redis_pool) self.map = Map.from_json(pkgutil.get_data('dropbot', 'data/map.json')) super(DropBot, self).__init__(*args, **kwargs) @@ -74,6 +82,9 @@ class DropBot(ClientXMPP): for room in self.rooms: self.plugin['xep_0045'].joinMUC(room, self.nickname, wait=True) + # Start the killchecker + self._get_kills() + def call_command(self, command, *args, **kwargs): if hasattr(self, 'cmd_%s' % command): try: @@ -185,6 +196,25 @@ class DropBot(ClientXMPP): intcomma(float(root.findall("./marketstat/type[@id='{}']/buy/max".format(type_id))[0].text)), ) + def _get_kills(self): + secs = (datetime.utcnow() - self.last_killdate).total_seconds() + if secs >= self.kill_check_timeout: + for corp_id in self.kill_corps: + headers, kills = ZKillboard().corporationID(corp_id).pastSeconds(int(secs)).kills().get() + res = [] + for kill in kills: + body, html = self.call_command('kill', [kill['killID']], None, no_url=False) + res.append(body) + if len(res): + text = 'New Kills:\n{}'.format('\n'.join(res)) + for room in self.rooms: + self.send_message(room, text, mtype='groupchat') + self.last_killdate = datetime.utcnow() + self.schedule('zkb_check', self.kill_check_timeout, self._get_kills) + + def get_eveapi(self): + return EVEAPIConnection(cacheHandler=EVEAPIRedisCache(self.redis)) + # Commands def cmd_help(self, args, msg): @@ -514,7 +544,7 @@ class DropBot(ClientXMPP): return '!id ' char_name = ' '.join(args) - result = EVEAPIConnection().eve.CharacterID(names=char_name.strip()) + result = self.get_eveapi().eve.CharacterID(names=char_name.strip()) char_name = result.characters[0].name char_id = result.characters[0].characterID diff --git a/dropbot/cli.py b/dropbot/cli.py index 2cf5b68..d0a5a6d 100644 --- a/dropbot/cli.py +++ b/dropbot/cli.py @@ -33,7 +33,7 @@ def main(): # Parse the environment for config config = dict([(k[8:].lower(), v) for k, v in os.environ.items() if 'DROPBOT_' in k]) # Split out array type configs - for key in ['rooms', 'admins']: + for key in ['rooms', 'admins', 'kill_corps']: if key in config: config[key] = [x.strip() for x in config[key].split(',')] elif opts.config.lower().startswith('http'): diff --git a/dropbot/utils.py b/dropbot/utils.py new file mode 100644 index 0000000..07e5a8e --- /dev/null +++ b/dropbot/utils.py @@ -0,0 +1,28 @@ +from hashlib import sha1 +import zlib + + +class EVEAPIRedisCache(object): + + def __init__(self, redis): + self.redis = redis + + @staticmethod + def gen_key(host, path, params): + params = ''.join(['{}={}'.format(x, y) for x, y in params.items()]) + key_hash = ''.join((host, path, params)) + return 'eveapi_cache_{}'.format(sha1(key_hash).hexdigest()) + + def retrieve(self, host, path, params): + key = self.gen_key(host, path, params) + val = self.redis.get(key) + if val: + return zlib.decompress(val) + + def store(self, host, path, params, doc, obj): + key = self.gen_key(host, path, params) + cache_time = obj.cachedUntil - obj.currentTime + if cache_time > 0: + val = zlib.compress(doc, 9) + self.redis.set(key, val) + self.redis.expire(key, cache_time)