import threading from types import GeneratorType from Util import call from time import sleep,time from Logging import LogFile pdLog = LogFile("PluginDispatcher") pdwtLog = LogFile("PluginDispatcherWorkerThread") pddtLog = LogFile("PluginDispatcherDedicatedThread") class PluginDispatcherDedicatedThread(threading.Thread): callback = None recover = True active = True connectorInfo = (None, None) def __init__(self,callback, responseObject= None, consumer= lambda x:None ): super(PluginDispatcherDedicatedThread,self).__init__() self.connectorInfo=responseObject,consumer self.callback = callback pddtLog.note("New PDDT",callback,responseObject,consumer) def run(self): args = {} crashProtection=[0]*30 while self.active: try: crashProtection=crashProtection[1:]+[time()] if crashProtection[-1]-crashProtection[0]<5: pdLog.error("A static thread has returned 30 times in 5 seconds. Killing process.") return args.update({"response":self.connectorInfo[0]})
from PluginManager import PluginManager from PluginDispatcher import PluginDispatcher from Configuration import ConfigFile from re import match from sys import path from os import getcwd from Util import dictJoin from Logging import LogFile path.append(getcwd()) log = LogFile("Core") class Core: _PluginManager = None _PluginDispatcher = None _ResponseObject = None _Connector = None _Config = None def _LoadConnector(self): log.debug("Loading connector") if not self._Config: log.critical("No Config file") return None ConName = self._Config["Core","Connector"] con = __import__("Connectors.%s"%ConName, globals(), locals(), ConName) cls = getattr(con,ConName,None) if cls: c = cls() log.debug("Connector constructed") return c
from Hook import * parser = None from Logging import LogFile log = LogFile("Seen") import datetime storeFile = "SeenStore.pkl" try: import cPickle as pickle log.debug("Using cPickle") except: import pickle log.debug("Using pickle.") def now(): return datetime.datetime.now().strftime("%H:%M:%S") def saveState(state): try: pickle.dump(state, file(storeFile, "w")) except: log.exception("Failed to store pickle.") def loadState(): try: return pickle.load(file(storeFile)) except: log.exception("Failed to load pickle")
"""Useful tools for opening and reading pages.""" from urllib2 import Request, build_opener, urlopen, URLError, HTTPError import sys from Logging import LogFile log = LogFile("URLUtils") class URLUtils(object): USER_AGENT = ('User-agent', 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT') def open_url(self, url): """Simply open and return page contents mimicking a browser.""" request = Request(url, None) opener = build_opener() opener.add_headers = [self.USER_AGENT] try: response = opener.open(request) except HTTPError, e: log.exception("There server couldn't fulfill the request.", "Error: %s" % e.code, "URL: %s" % url) except URLError, e: log.exception("Failed to reach a server.", "Error: %s" % e.code, "URL: %s" % url)
import time import random import re import urllib from Hook import * from Logging import LogFile from collections import Counter log = LogFile("Numbers") def solve(game): url = "http://djce.org.uk/countdown?n=" + "&n=".join(map( str, game[0])) + "&t=" + str(game[1]) return urllib.urlopen(url).read().split("\n</pre>")[0].split("\n")[-1] def chooseNumbers(numLarge): log.debug("Choose numbers called, {}".format(numLarge)) if 0 > numLarge or numLarge > 4: return None large = [25, 50, 75, 100] small = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10] random.shuffle(large) random.shuffle(small) numbers = large[:numLarge] + small[:6 - numLarge] return numbers, random.randint(100, 900) def factor(n): if n == 1: return [1] if n & 1 == 0:
import sys from inspect import isclass, getmembers from re import match from Logging import LogFile from Configuration import ConfigFile log = LogFile("PluginManager") class PluginManager: __services__={} __plugins__={} __hooks__=[] # list of (function, pluginname, functionname) AutoLoadDeps = False def hasPlugin(self,plug): log.debug("hasPlugin %s"%plug) return self.__plugins__.has_key(plug) def checkRequirements(self,cls): log.debug("Check requirements",cls) req = getattr(cls,"sbreq",None) if not req:#no requirements, no problem! log.debug("No requirements.") return True for r in req: for s in r: if self.__services__.has_key(s):
from Hook import * from Logging import LogFile try: import cPickle as pickle except ImportError: import pickle def save(obj, filename): pickle.dump(obj, open(filename, "w")) return obj def load(filename): if not os.path.exists(filename): save(dict(), filename) return pickle.load(open(filename, "r")) log = LogFile("Gifts") gifts_file = "GiftsStore.pkl" gifts = load(gifts_file) pluralized_file = "PluralizedStore.pkl" pluralized = load(pluralized_file) def map_plural(singular, plural): global pluralized global gifts if plural in pluralized.keys(): if plural in pluralized.values(): if singular != plural: pluralized[singular] = plural
from Hook import * parser = None from Logging import LogFile log = LogFile("Alarm") import time import datetime storeFile = "AlarmStore.pkl" parseStrings = [ "%m/%d", "%m/%d/%y", "%m/%d/%y %H:%M:%S", "%m/%d/%y %h:%M:%S %p" ] def backupParse(s): global parseStrings for fmt in parseStrings: try: return datetime.datetime.strptime(s,fmt) except:pass return None try: import parsedatetime.parsedatetime as pdt import parsedatetime.parsedatetime_consts as pdc c = pdc.Constants() p = pdt.Calendar(c) parser = lambda s:datetime.datetime(*p.parse(s)[0][:6]) log.debug("Using parsedatetime") except:
from Hook import * parser = None from Logging import LogFile log = LogFile("Alarm") import time import datetime storeFile = "AlarmStore.pkl" parseStrings = [ "%m/%d", "%m/%d/%y", "%m/%d/%y %H:%M:%S", "%m/%d/%y %h:%M:%S %p" ] def backupParse(s): global parseStrings for fmt in parseStrings: try: return datetime.datetime.strptime(s, fmt) except: pass return None try: import parsedatetime.parsedatetime as pdt import parsedatetime.parsedatetime_consts as pdc c = pdc.Constants() p = pdt.Calendar(c) parser = lambda s: datetime.datetime(*p.parse(s)[0][:6]) log.debug("Using parsedatetime") except:
from Hook import * import time import urllib from Logging import LogFile log = LogFile("Mtgox") keys = ["low", "buy", "avg", "sell", "high"] class Mtgox: streamSize = [0] * 5 lastData = [0] * 5 @dedicated(delay=10) def ded(self, response): d = dict( eval( urllib.urlopen("https://mtgox.com/api/0/data/ticker.php").read( )))["ticker"] d = {k: round(d[k], 3) for k in keys} vals = map(d.get, keys) log.dict(d, "Ticker data") diffs = map(lambda (x, y): x - y, zip(vals, self.lastData)) self.lastData = vals change = filter(lambda x: x, diffs) != [] log.debug(diffs, self.lastData, change, self.streamSize) if not change: log.debug("No change in ticker. Waiting 10 seconds") return
from Hook import bindFunction, requires, prefers from Logging import LogFile log = LogFile("GD") log.debug("Log start") import sys @requires("Google") @prefers("Colors") class Google_Define: @bindFunction(message="!gd (?P<term>[a-zA-Z ]+) ?(?P<definition>\d*)") def g_define(self, term, response, target, colorize, gdefine, definition): log.debug("g_define", term, response, target, colorize, gdefine, definition) d = gdefine(term.strip().replace(' ', '+'), definition) if colorize: return response.msg( target, colorize("<{C3}Google Define{}: %s [{B}%s{} of %s]>" % d)) else: return response.msg(target, "<Google Define: %s [%s of %s]>" % d)
from Hook import * parser = None from Logging import LogFile log = LogFile("Seen") import datetime storeFile = "SeenStore.pkl" try: import cPickle as pickle log.debug("Using cPickle") except: import pickle log.debug("Using pickle.") def now(): return datetime.datetime.now().strftime("%H:%M:%S") def saveState(state): try: pickle.dump(state,file(storeFile,"w")) except: log.exception("Failed to store pickle.") def loadState(): try: return pickle.load(file(storeFile)) except: log.exception("Failed to load pickle") return None
from Hook import bindFunction from Logging import LogFile log = LogFile("Security_Service") class Security: sessions = {} def __init__(self): log.debug("Security service created.") def onEvent(self, event): # a plugin wants access to our stuff! log.debug("onEvent") event["loggedIn"] = self.isLoggedIn #only give the the ability to check if a nick is logged in. def logIn(self, nick, pswd): # plugin will make call back to here log.debug("logIn", nick, self.sessions) ses = self.sessions.get(nick, {"pswd": pswd}) if pswd == ses["pswd"]: ses["LoggedIn"] = True else: return False self.sessions[nick] = ses return True def logOut(self, nick): log.debug("logOut", nick, self.sessions) ses = self.sessions.get(nick, {}) ses["LoggedIn"] = False
import sys import traceback from Configuration import ConfigFile from Logging import LogFile from twisted.words.protocols import irc from twisted.internet import protocol, reactor #these events get given to plugins to give back to the the ircconnector log = LogFile("IRCConnector") log.debug("Connector imported") class IRCConnectorEvents: def __init__(self): pass def join(self, channel, key=None): return "join", channel, key def part(self, channel, message=None): return "part", channel, messages def kick(self, channel, user, message=None): return "kick", channel, user, message def topic(self, channel, message=None): return "topic", channel, message def say(self, channel, message, length=None): return "say", channel, message, 1024 def msg(self, user, message, length=None):
from Hook import * from Logging import LogFile try: import cPickle as pickle log.debug("Using cPickle") except: import pickle log.debug("Using pickle") log = LogFile("Alias") storeFile = "AliasStore.pkl" aliases = {} def saveAliases(): global aliases log.debug("Saving aliases.") try: pickle.dump(aliases,file(storeFile,"w")) except: log.exception("Failed to save aliases.") def loadAliases(): global aliases log.debug("Loading aliases.") try: aliases = pickle.load(file(storeFile)) print "Aliases 1:",aliases return True
except ImportError: import pickle def save(obj, filename): pickle.dump(obj, open(filename, "w")) return obj def load(filename): if not os.path.exists(filename): save(dict(), filename) return pickle.load(open(filename, "r")) log = LogFile("Gifts") gifts_file = "GiftsStore.pkl" gifts = load(gifts_file) pluralized_file = "PluralizedStore.pkl" pluralized = load(pluralized_file) def map_plural(singular, plural): global pluralized global gifts if plural in pluralized.keys(): if plural in pluralized.values(): if singular != plural:
from Hook import bindFunction, requires, prefers from Logging import LogFile log = LogFile("GD") log.debug("Log start") import sys @requires("Google") @prefers("Colors") class Google_Define: @bindFunction(message="!gd (?P<term>[a-zA-Z ]+) ?(?P<definition>\d*)") def g_define(self, term, response, target, colorize, gdefine, definition): log.debug("g_define",term, response, target, colorize, gdefine, definition) d = gdefine(term.strip().replace(' ', '+'), definition) if colorize: return response.msg(target, colorize( "<{C3}Google Define{}: %s [{B}%s{} of %s]>" % d)) else: return response.msg(target, "<Google Define: %s [%s of %s]>" % d)
import threading from types import GeneratorType from Util import call from time import sleep from Logging import LogFile pdLog = LogFile("PluginDispatcher") pdwtLog = LogFile("PluginDispatcherWorkerThread") class PluginDispatcherWorkerThread(threading.Thread): running = True produce = None consume = None def run(self): pdwtLog.debug("Worker thread started.") while True: while self.produce == None or self.consume == None: pdwtLog.debug("Waiting on producer and consumer", "P:" + str(self.produce), "C:" + str(self.consume)) sleep(1) if self.produce and self.consume: pdwtLog.debug("Producer and consumer set.", "P:" + str(self.produce), "C:" + str(self.consume)) func, args = self.produce() pdwtLog.debug("Produced", func, args)
from PluginManager import PluginManager from PluginDispatcher import PluginDispatcher from Configuration import ConfigFile from Util import call from re import match from sys import path from os import getcwd from Util import dictJoin from Logging import LogFile path.append(getcwd()) log = LogFile("Core") class Core: _PluginManager = None _PluginDispatcher = None _ResponseObject = None _Connector = None _Config = None def _LoadConnector(self, ConName): try: con = __import__("%s.Connector" % ConName, globals(), locals(), "Connector") log.debug("Got connector:", con) cls = getattr(con, "Connector", None) except : log.exception("Exception while loading connector") cls = None
from Configuration import ConfigFile from Logging import LogFile from twisted.words.protocols import irc from twisted.internet import protocol,reactor import sys,traceback #these events get given to plugins to give back to the the ircconnector log = LogFile("IRCConnector") log.debug("Connector imported") class IRCConnectorEvents: def __init__(self): pass def join(self,channel, key=None): return "join",channel,key def part(self,channel, message=None): return "part",channel,messages def kick(self,channel, user, message=None): return "kick",channel,user,message def topic(self,channel, message=None): return "topic",channel,message def say(self, channel, message, length=None): return "say",channel,message,1024 def msg(self, user, message, length=None): return "msg",user,message,1024 def notice(self,user, message): return "notice",user, message def away(self,message=""): return "away",message def back(self): return "back" def setNick(self,nickname):
from Hook import * from Logging import LogFile import shelve import urllib2 import json log = LogFile("Weather") KEY = "90911f1ab7b29950" def getResponse(command): url = "http://api.wunderground.com/api/%s/%s.json"%(KEY,urllib2.quote(command)) log.debug("getResponse",url) f = urllib2.urlopen(url) json_string = f.read() response = json.loads(json_string) return response class Weather: @bindFunction(message="^!w (?P<location>.*)$") def currentWeather(self,response,target,location): weather = getResponse("conditions/q/%s"%location) log.debug(weather.keys()) if weather["response"].has_key("results"): yield response.say(target,"I found multiple results for "\ +location+". Please specify the state (or use zip instead)") states = [str(entry["state"]) for entry in weather["response"]["results"]] yield response.say(target,"Stats found: (%s)"%", ".join(states))
import urllib import urllib2 import lxml.html try: import simplejson is_json = True except: is_json = False from Hook import bindFunction from Logging import LogFile log = LogFile("GoogleService") GOOGLE_SEARCH_URL = "http://www.google.com/dictionary/json?callback=dict_api.callbacks.id100&sl=en&tl=en&restrict=pr%2Cde&client=te&" HEADERS = {'User-Agent': "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.5)"} class Google: def _buildResponse(self, url, is_json=False): log.debug("Build request", url, is_json) request = urllib2.Request(url, None, HEADERS) response = urllib2.urlopen(request) if is_json: response = response.read() # FIXME: simplejson doesn't like the callback, I think response = simplejson.load(response) if not 'responseData' in response: log.warning("Json response was empty") return # no data, pointless return response['responseData'] return response
from Hook import bindFunction, prefers from Logging import LogFile import re log = LogFile("Sed") msgHistory = [""] * 20 sedRegex = "(?P<delim>[^a-zA-Z])(?P<search>.*?)\\1(?P<replace>.*?)\\1(?P<flags>.*?)(?P<extras>(?:\\1.*)|)$" replacementColors = [4, 7, 3, 10, 6] def applySed(searchRE, replace, flags, message, colorNum=0): log.debug("applySed:", searchRE.pattern, replace, flags, message, colorNum) if "c" in flags: colorNum %= len(replacementColors) replace = "{C%i}%s{}" % (replacementColors[colorNum], replace) if "g" in flags: out = searchRE.sub(replace, message, 0) #all else: out = searchRE.sub(replace, message, 1) #once return out def findMatch(searchRE): global msgHistory for msg in msgHistory: if searchRE.search(msg): log.debug("Found match", msg) return msg