def handle_twitterfriends(bot, ievent): """ no arguments - show friends timeline (your normal twitter feed). """ if not go: ievent.reply( "the twitter plugin needs the credentials.py file in the .jsb/data/config dir. see .jsb/data/examples" ) return try: token = get_token(ievent.user.data.name) if not token: ievent.reply( "you are not logged in yet .. run the twitter-auth command.") return key, secret = getcreds(getdatadir()) token = tweepy.oauth.OAuthToken(key, secret).from_string(token) twitter = twitterapi(key, secret, token) method = getattr(twitter, "friends_timeline") result = method() res = [] for item in result: try: res.append("%s - %s" % (item.author.screen_name, item.text)) except Exception, ex: handle_exception() ievent.reply("results: ", res)
def handle_adminreloadconfig(bot, event): """ no arguments - reload bot config and mainconfig files. """ try: bot.cfg.reload() getmainconfig().reload() except Exception, ex: handle_exception()
def stopall(self): """ call stop() on all fleet bots. """ for i in self.bots: try: i.stop() except: handle_exception()
def reloadcheck(self, event): """ check if plugin need to be reloaded for callback, """ plugloaded = [] target = event.cbtype or event.cmnd try: from boot import getcallbacktable p = getcallbacktable()[target] except KeyError: logging.debug("botbase - can't find plugin to reload for %s" % event.cmnd) return logging.debug("%s - checking %s" % (self.name, unicode(p))) for name in p: if name in self.plugs: continue if name in default_plugins: pass elif self.cfg.blacklist and name in self.cfg.blacklist: continue elif self.cfg.loadlist and name not in self.cfg.loadlist: continue logging.warn("%s - on demand reloading of %s" % (self.name, name)) try: mod = self.plugs.reload(name, force=True, showerror=False) if mod: plugloaded.append(mod) continue except Exception, ex: handle_exception(event)
def loadall(self, paths=[], force=True): """ load all plugins from given paths, if force is true .. otherwise load all plugins for default_plugins list. """ if not paths: paths = plugin_packages imp = None old = self.keys() new = [] logging.warn("loading all from paths %s" % paths) for module in paths: try: imp = _import(module) except ImportError, ex: #handle_exception() logging.warn("no %s plugin package found - %s" % (module, str(ex))) continue except Exception, ex: handle_exception() logging.debug("got plugin package %s" % module) try: for plug in imp.__plugs__: if "gae" in plug: continue mod = "%s.%s" % (module, plug) if not isenabled(mod): logging.warn("%s is not enabled. not loading" % mod) ; continue try: self.reload(mod, force=force, showerror=True) except RequireError, ex: logging.info(str(ex)) ; continue except KeyError: logging.debug("failed to load plugin package %s" % module) ; continue except Exception, ex: handle_exception() ; continue new.append(mod)
def _listen(self): """ listen for udp messages .. /msg via bot""" if not cfg['udp']: return fleet = getfleet() for botname in cfg['udpbots']: if not fleet.byname(botname): logging.info("udp - can't find %s bot" % botname) try: fleet.startok.wait(5) logging.warn('udp listening on %s %s' % (cfg['udphost'], cfg['udpport'])) self.sock.bind((cfg['udphost'], cfg['udpport'])) self.stop = 0 except IOError: handle_exception() self.sock = None self.stop = 1 return # loop on listening udp socket while not self.stop: try: input, addr = self.sock.recvfrom(64000) except socket.timeout: continue except Exception, ex: try: (errno, errstr) = ex except ValueError: errno = 0 ; errstr = str(ex) if errno == 4: logging.warn("udp - %s - %s" % (self.name, str(ex))) ; break if errno == 35: continue else: handle_exception() ; break if self.stop: break self.queue.put((input, addr))
def forwardoutcb(bot, event): """ forward callback. """ e = cpy(event) logging.debug("forward - cbtype is %s - %s" % (event.cbtype, event.how)) e.forwarded = True e.source = bot.jid e.botname = bot.server or bot.name if not event.chan: event.bind(bot) if event.chan: e.allowwatch = event.chan.data.allowwatch fleet = getfleet() for jid in forward.data.channels[event.channel.lower()]: logging.info("forward - sending to %s" % jid) if jid == "twitter": try: postmsg(forward.data.outs[jid], e.txt) except Exception, ex: handle_exception() continue outbot = fleet.getfirstjabber(bot.isgae) if not outbot and bot.isgae: outbot = fleet.makebot('xmpp', 'forwardbot') if outbot: e.source = outbot.jid txt = outbot.normalize(e.tojson()) txt = stripcolor(txt) #txt = e.tojson() container = Container(outbot.jid, txt) outbot.outnocb(jid, container.tojson()) else: logging.info("forward - no xmpp bot found in fleet".upper())
def startshell(self, connect=True): """ start the console bot. """ self.start(False) while not self.stopped: try: input = console.raw_input("\n> ") if self.stopped: return event = ConsoleEvent() event.parse(self, input, console) event.nooutput = True event.nodispatch = False e = self.put(event) res = e.wait() if res: for r in res: txt = self.makeresponse(r, dot="<br>") self.out(e.userhost, txt, plugorigin=e.plugorigin) mainhandler.handle_one() except IOError: break except NoInput: continue except (KeyboardInterrupt, EOFError): break except Exception, ex: handle_exception()
def plusscan(skip=False): global teller teller += 1 if teller % 5 != 0: return logging.warn("running plus scan") fleet = getfleet() for id, channels in state.data.ids.iteritems(): if not id in state.data.seen: state.data.seen[id] = [] for botname, chan in channels: try: res = getplus(id) if not res: logging.warn("no result from %s" % id) continue bot = fleet.byname(botname) if bot: todo = [] for r in res: stamp = uuid.uuid3(uuid.NAMESPACE_URL, str(r)).hex if stamp not in state.data.seen[id]: state.data.seen[id].append(stamp) todo.append(r) if todo: bot.say(chan, "new plus update: ", todo) else: logging.warn("no %s bot in fleet" % botname) except AttributeError, ex: logging.error(str(ex)) except Exception, ex: handle_exception()
def startshell(self, connect=True): """ start the console bot. """ self.start(False) time.sleep(0.1) self.dostart() while not self.stopped: try: input = console.raw_input("> ") event = ConsoleEvent() event.parse(self, input, console) if False and input.startswith('#'): try: env = {"bot": self, "event": event} env.update(locals()) env.update(globals()) console.locals.update(env) console.runsource(input[1:]) continue except Exception, ex: handle_exception() continue #event.direct = True self.put(event) waitevents([event, ]) #if not result: continue #logging.debug("console - waiting for %s to finish" % event.usercmnd) #res = waitforqueue(event.outqueue) time.sleep(0.2) #logging.debug("console - %s" % res) except NoInput: continue except (KeyboardInterrupt, EOFError): break except Exception, ex: handle_exception()
def handle_twitterfriends(bot, ievent): """ do a twitter API cmommand. """ if not go: ievent.reply( "the twitter plugin needs the credentials.py file in the .jsb/data/config dir. see .jsb/data/examples" ) return try: twitteruser = TwitterUsers("users") token = twitteruser.data.get(ievent.user.data.name) if not token: ievent.reply( "you are not logged in yet .. run the twitter-auth command.") return key, secret = getcreds(getdatadir()) token = oauth.OAuthToken(key, secret).from_string(token) twitter = twitterapi(key, secret, token) method = getattr(twitter, "friends_timeline") # do the thing result = method() res = [] for item in result: try: res.append("%s - %s" % (item.author.screen_name, item.text)) #logging.warn("twitter - %s" % dir(item.author)) #res.append(unicode(item.__getstate__())) except Exception, ex: handle_exception() ievent.reply("results: ", res)
def unload(self, modname): """ unload plugin .. remove related commands from cmnds object. """ logging.debug("plugins - unloading %s" % modname) try: self[modname].shutdown() logging.debug('plugins - called %s shutdown' % modname) except KeyError: logging.debug("plugins - no %s module found" % modname) return False except AttributeError: pass try: cmnds.unload(modname) except KeyError: pass try: first_callbacks.unload(modname) except KeyError: pass try: callbacks.unload(modname) except KeyError: pass try: last_callbacks.unload(modname) except KeyError: pass try: remote_callbacks.unload(modname) except KeyError: pass try: outputmorphs.unload(modname) except: handle_exception() try: inputmorphs.unload(modname) except: handle_exception() return True
def dump(self, withtypes=False): """ just dunp the lazydict object. DON'T convert to json. """ #logging.warn("lazydict - dumping - %s" % type(self)) try: return dumpelement(cpy(self), withtypes) except RuntimeError, ex: handle_exception()
def startshell(self, connect=True): """ start the console bot. """ self.start(False) time.sleep(0.1) self.dostart() while not self.stopped: try: input = console.raw_input("> ") event = ConsoleEvent() event.parse(self, input, console) event.showall = True if False and input.startswith('#'): try: env = {"bot": self, "event": event} env.update(locals()) env.update(globals()) console.locals.update(env) console.runsource(input[1:]) continue except Exception, ex: handle_exception() continue self.put(event) if self.shouldwait: waitforqueue(event.resqueue) time.sleep(0.2) except NoInput: continue except (KeyboardInterrupt, EOFError): break except Exception, ex: handle_exception()
def resume(self, sessionfile): """ resume bot from session file. """ try: session = json.load(open(sessionfile, 'r')) self._resume(session) except: handle_exception()
def __init__(self, filename, verbose=False, input={}, ddir=None, *args, **kw): assert filename LazyDict.__init__(self, input, *args, **kw) self.filename = filename or 'mainconfig' self.datadir = ddir or getdatadir() self.dir = self.datadir + os.sep + 'config' self.cfile = self.dir + os.sep + self.filename logging.debug("filename is %s" % self.cfile) self.jsondb = None try: import waveapi ; self.isdb = True except ImportError: self.isdb = False if not self.comments: self.comments = {} try: try: self.fromfile(self.cfile) except IOError: logging.warn("can't read config from %s" % self.cfile) import waveapi from persist import Persist self.jsondb = Persist(self.cfile) self.update(self.jsondb.data) self.isdb = True logging.debug("fromdb - %s - %s" % (self.cfile, str(self))) except ImportError: handle_exception() self.isdb = False self.init() self.datadir = ddir or getdatadir() self.dir = self.datadir + os.sep + 'config' self.cfile = self.dir + os.sep + self.filename if not self.owner: self.owner = [] dosave = False if not self.uuid: self.uuid = str(uuid.uuid4()) ; dosave = True if not self.cfile: self.cfile = self.dir + os.sep + self.filename ; dosave = True if dosave: self.save() assert self.cfile
def _raw(self, stanza): """ output a xml stanza to the socket. """ if not self.connection: return time.sleep(0.01) try: stanza = stanza.strip() if not stanza: logging.debug("%s - no stanze provided. called from: %s" % (self.name, whichmodule())) return what = jabberstrip(stanza) what = toenc(stanza) logging.debug("%s - out - %s" % (self.name, what)) if not what.endswith('>') or not what.startswith('<'): logging.error('%s - invalid stanza: %s' % (self.name, what)) return if what.startswith('<stream') or what.startswith( '<message') or what.startswith( '<presence') or what.startswith('<iq'): logging.debug(u"%s - sxmpp - out - %s" % (self.name, what)) try: self.connection.send(what + u"\r\n") except AttributeError: self.connection.write(what) else: logging.error('%s - invalid stanza: %s' % (self.name, what)) except socket.error, ex: if 'Broken pipe' in str(ex): logging.debug('%s - core - broken pipe .. ignoring' % self.name) return self.error = str(ex) handle_exception()
def handle(self, speed, args): """ schedule a bot command. """ try: descr, func, bot, ievent = args self.nowrunning = getname(func) + " - " + descr self.starttime = time.time() if not ievent.nolog: logging.info("event handler is %s" % str(func)) if self.nowrunning in self.longrunning and not self.nowrunning in self.shortrunning: logging.warn("putting %s on longrunner" % self.nowrunning) longrunner.put(ievent.speed or speed, descr, func, bot, ievent) return self.working = True try: result = func(bot, ievent) except URLNotEnabled, ex: logging.warn("urls fetching is disabled (%s)" % ievent.usercmnd) ; return str(ex) self.finished = time.time() self.elapsed = self.finished - self.starttime if self.elapsed > 5: if self.nowrunning not in self.longrunning: self.longrunning.append(self.nowrunning) try: self.shortrunning.remove(self.nowrunning) except ValueError: pass if not ievent.nolog: logging.debug('ALERT %s %s job taking too long: %s seconds' % (descr, str(func), self.elapsed)) stats.upitem(self.nowrunning) stats.upitem(self.name) time.sleep(0.005) logstr = "finished %s - %s - %s (%s)" % (self.nowrunning, result or "no result", ievent.cbtype, self.elapsed) if ievent.cbtype not in ['TICK', 'PING', 'NOTICE', 'TICK60']: logging.info(logstr) except Exception, ex: handle_exception() result = str(ex)
def __init__(self, filename=None, verbose=False, input={}, ddir=None, *args, **kw): LazyDict.__init__(self, input, *args, **kw) filename = filename or 'mainconfig' datadir = ddir or getdatadir() dir = datadir + os.sep + 'config' if datadir not in filename: cfile = dir + os.sep + filename else: cfile = filename logging.debug("config - filename is %s" % cfile) self.jsondb = None try: import waveapi ; self.isdb = True except ImportError: self.isdb = False if not self.comments: self.comments = {} try: try: self.fromfile(cfile) except IOError: logging.warn("can't read config from %s" % self.cfile) import waveapi from persist import Persist self.jsondb = Persist(cfile) self.update(self.jsondb.data) self.isdb = True logging.debug("config - fromdb - %s - %s" % (self.cfile, str(self))) except ImportError: handle_exception() self.isdb = False self.cfile = cfile self.dir = dir self.filename = filename self.init() if not self.owner: self.owner = [] if not self.uuid: self.uuid = str(uuid.uuid4())
def _readloop(self): logging.debug("%s - starting readloop" % self.cfg.name) self.connectok.wait(15) self.auth = requests.AuthObject(self.cfg.username, self.cfg.password) while not self.stopped and not self.stopreadloop: try: time.sleep(1) if self.cursor: result = self.get("live.json", {"cursor": self.cursor}) else: result = self.get("live.json") if self.stopped or self.stopreadloop: break if not result: time.sleep(20) ; continue if result.has_key("_id"): self.cursor = result["_id"] if not result: continue if not result.messages: continue logging.info("%s - incoming - %s" % (self.cfg.name, str(result))) for message in result.messages: try: event = ConvoreEvent() event.parse(self, message, result) if event.username.lower() == self.cfg.username.lower(): continue event.bind(self) method = getattr(self, "handle_%s" % event.type) method(event) except (TypeError, AttributeError): logging.error("%s - no handler for %s kind" % (self.cfg.name, message['kind'])) except: handle_exception() except urllib2.URLError, ex: logging.error("%s - url error - %s" % (self.cfg.name, str(ex))) except Exception, ex: handle_exception() logging.debug("%s - stopping readloop" % self.cfg.name)
def handle_twitterfriends(bot, ievent): """ do a twitter API cmommand. """ if not go: ievent.reply("the twitter plugin needs the credentials.py file in the .jsb/data/config dir. see .jsb/data/examples") return try: twitteruser = TwitterUsers("users") token = twitteruser.data.get(ievent.user.data.name) if not token: ievent.reply("you are not logged in yet .. run the twitter-auth command.") return key , secret = getcreds(getdatadir()) token = oauth.OAuthToken(key, secret).from_string(token) twitter = twitterapi(key, secret, token) method = getattr(twitter, "friends_timeline") # do the thing result = method() res = [] for item in result: try: res.append("%s - %s" % (item.author.screen_name, item.text)) #logging.warn("twitter - %s" % dir(item.author)) #res.append(unicode(item.__getstate__())) except Exception, ex: handle_exception() ievent.reply("results: ", res)
def loadall(self, paths=[], force=True): """ load all plugins from given paths, if force is true .. otherwise load all plugins for default_plugins list. """ from boot import plugblacklist if not paths: paths = plugin_packages imp = None for module in paths: try: imp = _import(module) except ImportError, ex: #handle_exception() logging.warn("no %s plugin package found - %s" % (module, str(ex))) continue except Exception, ex: handle_exception() logging.debug("got plugin package %s" % module) try: for plug in imp.__plugs__: mod = "%s.%s" % (module, plug) if mod in plugblacklist.data: logging.warn("%s is in blacklist .. not loading." % mod) ; continue try: self.reload(mod, force=force, showerror=True) except KeyError: logging.debug("failed to load plugin package %s" % module) except Exception, ex: handle_exception() except AttributeError: logging.error("no plugins in %s .. define __plugs__ in __init__.py" % module)
def remotecb(bot, event): """ dispatch an event. """ try: container = Container().load(event.txt) except TypeError: handle_exception() logging.warn("remotecallbacks - not a remote event - %s " % event.userhost) return logging.debug('doing REMOTE callback') try: digest = hmac.new(str(container.hashkey), XMLunescape(container.payload), hashlib.sha512).hexdigest() logging.debug("remotecallbacks - digest is %s" % digest) except TypeError: handle_exception() logging.error("remotecallbacks - can't load payload - %s" % container.payload) return if container.digest == digest: e = EventBase().load(XMLunescape(container.payload)) else: raise NoProperDigest() e.txt = XMLunescape(e.txt) e.nodispatch = True e.forwarded = True bot.doevent(e) event.status = "done" return
def makeresponse(self, name, res, channel, sep=" .. "): """ loop over result to make a response. """ item = self.byname(name) result = u"[%s] - " % name try: itemslist = item.itemslists.data[jsonstring([name, channel])] except KeyError: item = self.byname(name) if item == None: return "no %s rss item" % name else: item.itemslists.data[jsonstring([name, channel])] = ['title', 'link'] item.itemslists.save() for j in res: if item.markup.get(jsonstring([name, channel]), 'skipmerge') and 'Merge branch' in j['title']: continue resultstr = u"" for i in item.itemslists.data[jsonstring([name, channel])]: try: ii = getattr(j, i) if not ii: continue ii = unicode(ii) if ii.startswith('http://'): if item.markup.get(jsonstring([name, channel]), 'tinyurl'): try: tinyurl = get_tinyurl(ii) logging.debug('rss - tinyurl is: %s' % str(tinyurl)) if not tinyurl: resultstr += u"%s - " % ii else: resultstr += u"%s - " % tinyurl[0] except Exception, ex: handle_exception() resultstr += u"%s - " % item else: resultstr += u"%s - " % ii else: resultstr += u"%s - " % ii.strip() except (KeyError, AttributeError), ex: logging.info('hubbub - %s - %s' % (name, str(ex))) continue
def handle_rc(bot, event): """ arguments: <file>|<url> - execute a .jsb resource file with bot commands. """ if not event.rest: event.missing("<file>|<url>") ; return if not getmainconfig().allowrc: event.reply("rc mode is not enabled") ; return teller = 0 t = event.rest waiting = [] try: try: if getmainconfig().allowremoterc and t.startswith("http"): data = geturl2(t) else: data = open(t, 'r').read() except IOError, ex: event.reply("I/O error: %s" % str(ex)) ; return if not data: event.reply("can't get data from %s" % event.rest) ; return for d in data.split("\n"): i = d.strip() if not i: continue if i.startswith("#"): continue e = cpy(event) e.txt = "%s" % i.strip() e.direct = True bot.put(e) waiting.append(e) teller += 1 event.reply("%s commands executed" % teller) except Exception, ex: event.reply("an error occured: %s" % str(ex)) ; handle_exception()
def send(self, what): """ send stanza to the server. """ if not what: logging.debug("%s - can't send empty message" % self.name) return try: to = what['to'] except (KeyError, TypeError): logging.error("%s - can't determine where to send %s to" % (self.name, what)) return try: jid = JID(to) except (InvalidJID, AttributeError): logging.error("%s - invalid jid - %s - %s" % (self.name, str(to), str(what))) return try: del what['from'] except KeyError: pass try: xml = what.tojabber() if not xml: raise Exception("can't convert %s to xml .. bot.send()" % what) except (AttributeError, TypeError): handle_exception() return if not self.checkifvalid(xml): logging.error("%s - NOT PROPER XML - %s" % (self.name, xml)) else: self._raw(xml)
def ratelimit(bot, ievent): """ karma rate limiter """ waittime = 30 limit = 2 try: name = ievent.userhost if not bot.state.has_key(name): bot.state[name] = {} if not bot.state[name].has_key('karma'): bot.state[name]['karma'] = {'count': 0, 'time': time.time()} if time.time() > (bot.state[name]['karma']['time'] + waittime): bot.state[name]['karma']['count'] = 0 bot.state[name]['karma']['count'] += 1 if bot.state[name]['karma']['count'] > limit: if name in ratelimited: return 0 ievent.reply( "karma limit reached, you'll have to wait %s seconds" % int((bot.state[name]['karma']['time'] + waittime) - time.time())) ratelimited.append(name) return 0 bot.state[name]['karma']['time'] = time.time() try: ratelimited.remove(name) except ValueError: pass return 1 except Exception, ex: handle_exception(ievent)
def handle_message(self, data): """ message handler. """ m = Message(data) m.parse(self) if data.type == 'groupchat' and data.subject: logging.debug("%s - checking topic" % self.name) self.topiccheck(m) nm = Message(m) callbacks.check(self, nm) return if data.get('x').xmlns == 'jabber:x:delay': logging.warn("%s - ignoring delayed message" % self.name) return self.privwait.check(m) if m.isresponse: logging.debug("%s - message is a response" % self.name) return jid = None m.origjid = m.jid for node in m.subelements: try: m.jid = node.x.item.jid except (AttributeError, TypeError): continue if self.me in m.fromm: logging.debug("%s - message to self .. ignoring" % self.name) return 0 try: if m.type == 'error': if m.code: logging.error('%s - error - %s' % (self.name, str(m))) self.errorwait.check(m) self.errorHandler(m) except Exception, ex: handle_exception()
def loadall(self, paths=[], force=True): """ load all plugins from given paths, if force is true .. otherwise load all plugins for default_plugins list. """ if not paths: paths = plugin_packages imp = None old = self.keys() new = [] logging.warn("loading all from paths %s" % paths) for module in paths: try: imp = _import(module) except ImportError, ex: logging.warn("no %s plugin package found - %s" % (module, str(ex))) continue except Exception, ex: handle_exception() logging.debug("got plugin package %s" % module) try: for plug in imp.__plugs__: if "gae" in plug: continue mod = "%s.%s" % (module, plug) if not isenabled(mod): logging.warn("%s is not enabled. not loading" % mod) ; continue try: self.reload(mod, force=force, showerror=True) except RequireError, ex: logging.info(str(ex)) ; continue except KeyError: logging.debug("failed to load plugin package %s" % module) ; continue except Exception, ex: handle_exception() ; continue new.append(mod)
def handle_error(self): """ take care of errors. """ exctype, excvalue, tb = sys.exc_info() if exctype == socket.error: try: errno, errtxt = excvalue if errno in [11, 35, 9]: logging.error("res.client - %s - %s %s" % (self.url, errno, errtxt)) return except ValueError: pass self.error = str(excvalue) else: logging.error("%s - %s" % (self.name, exceptionmsg())) self.error = exceptionmsg() self.buffer = '' result = RestResult(self.url, self.name) result.error = self.error result.data = None for cb in self.callbacks: try: cb(self, result) logging.info('rest.client - %s - called callback %s' % (url, str(cb))) except Exception, ex: handle_exception()
def callback(self, cb, bot, event): """ do the actual callback with provided bot and event as arguments. """ if event.stop: logging.info("callbacks - event is stopped.") ; return event.calledfrom = cb.modname try: if event.status == "done": logging.debug("callback - event is done .. ignoring") return if event.chan and cb.plugname in event.chan.data.denyplug: logging.warn("%s denied in %s - %s" % (cb.modname, event.channel, event.auth)) return if cb.prereq: logging.debug('callbacks - executing in loop %s' % str(cb.prereq)) if not cb.prereq(bot, event): return if not cb.func: return if event.isremote(): logging.info('%s - executing REMOTE %s - %s' % (bot.name, getname(cb.func), event.cbtype)) elif event.cbtype == "TICK": logging.debug('LOCAL - %s - executing %s - %s' % (bot.name, getname(cb.func), event.cbtype)) else: logging.info('%s - executing %s - %s' % (bot.name, getname(cb.func), event.cbtype)) event.iscallback = True logging.debug("callback - %s - trail - %s" % (getname(cb.func), callstack(sys._getframe())[::-1])) #if not event.direct and cb.threaded and not bot.isgae: start_new_thread(cb.func, (bot, event)) if cb.threaded and not bot.isgae: start_new_thread(cb.func, (bot, event)) else: if bot.isgae or event.direct: cb.func(bot, event) else: from runner import callbackrunner callbackrunner.put(cb.modname, cb.func, bot, event) return True except Exception, ex: handle_exception()
def handle_rc(bot, event): """ import aliases by url. assumes a .RC file. 1 alias per line """ if not event.rest: event.missing("<file>|<url>") ; return teller = 0 t = event.rest waiting = [] try: try: if t.startswith("http"): data = geturl2(t) else: data = open(t, 'r').read() except IOError, ex: event.reply("I/O error: %s" % str(ex)) ; return if not data: event.reply("can't get data from %s" % event.rest) ; return for d in data.split("\n"): i = d.strip() if not i: continue if i.startswith("#"): continue e = cpy(event) e.txt = "%s" % i.strip() e.direct = True bot.put(e) waiting.append(e) #result = bot.docmnd(event.userhost, event.channel, i, wait=1, event=event) #if result: result.waitall() teller += 1 #waitevents(waiting) event.reply("%s commands executed" % teller) except Exception, ex: event.reply("an error occured: %s" % str(ex)) ; handle_exception()
def startshell(self, connect=True): """ start the console bot. """ self.start(False) time.sleep(0.1) self.dostart() while not self.stopped: try: input = console.raw_input("> ") event = ConsoleEvent() event.parse(self, input, console) if False and input.startswith('#'): try: env = {"bot": self, "event": event} env.update(locals()) env.update(globals()) console.locals.update(env) console.runsource(input[1:]) continue except Exception, ex: handle_exception() continue #event.direct = True self.put(event) waitevents([ event, ]) #if not result: continue #logging.debug("console - waiting for %s to finish" % event.usercmnd) #res = waitforqueue(event.outqueue) time.sleep(0.2) #logging.debug("console - %s" % res) except NoInput: continue
def work(self, botname, type, channel, entries, url, *args, **kwargs): try: item = self.byurl(url) name = item.data.name try: fleet = getfleet() bot = fleet.byname(botname) if not bot and type: bot = fleet.makebot(type, botname) if not bot: bot = fleet.makebot('xmpp', botname) except NoSuchBotType, ex: logging.warn("hubbub - %s" % str(ex)) ; return if not bot: logging.error("hubbub - can't find %s bot in fleet" % type) ; return res2 = entries if not res2: logging.info("no updates for %s (%s) feed available" % (item.data.name, channel)) ; return if item.markup.get(jsonstring([name, channel]), 'reverse-order'): res2 = res2[::-1] if item.markup.get(jsonstring([name, channel]), 'all-lines'): for i in res2: response = self.makeresponse(name, [i, ], channel) try: bot.say(channel, response) except Exception, ex: handle_exception() else: sep = item.markup.get(jsonstring([name, channel]), 'separator') if sep: response = self.makeresponse(name, res2, channel, sep=sep) else: response = self.makeresponse(name, res2, channel) bot.say(channel, response) except Exception, ex: handle_exception()
def _raw(self, stanza): """ output a xml stanza to the socket. """ if not self.connection: return time.sleep(0.01) try: stanza = stanza.strip() if not stanza: logging.debug("%s - no stanze provided. called from: %s" % (self.name, whichmodule())) return what = jabberstrip(stanza) what = toenc(stanza) logging.debug("%s - out - %s" % (self.name, what)) if not what.endswith('>') or not what.startswith('<'): logging.error('%s - invalid stanza: %s' % (self.name, what)) return if what.startswith('<stream') or what.startswith('<message') or what.startswith('<presence') or what.startswith('<iq'): logging.debug(u"%s - sxmpp - out - %s" % (self.name, what)) try: self.connection.send(what + u"\r\n") except AttributeError: self.connection.write(what) else: logging.error('%s - invalid stanza: %s' % (self.name, what)) except socket.error, ex: if 'Broken pipe' in str(ex): logging.debug('%s - core - broken pipe .. ignoring' % self.name) return self.error = str(ex) handle_exception()
def _raw(self, txt, event=None, *args, **kwargs): """ output some txt to the wave. """ assert event.chan if not event.chan: logging.error("%s - event.chan is not set" % self.name) ; return if event.chan.data.json_data: wavelet = self.blind_wavelet(event.chan.data.json_data) else: logging.warn("did not join channel %s" % event.chan.data.id) ; return if not wavelet: logging.error("cant get wavelet") ; return txt = self.normalize(txt) txt = unicode(txt.strip()) logging.warn("%s - wave - out - %s" % (self.name, txt)) try: annotations = [] for url in txt.split(): got = url.find("http://") if got != -1: logging.debug("wave - found url - %s" % str(url)) start = txt.find(url.strip()) if url.endswith(">"): annotations.append((start+2, start+len(url)-1, "link/manual", url[1:-1])) else: annotations.append((start, start+len(url), "link/manual", url)) except Exception, ex: handle_exception() logging.debug("annotations used: %s", annotations) reply = wavelet.reply(txt) if annotations: for ann in annotations: if ann[0]: try: reply.range(ann[0], ann[1]).annotate(ann[2], ann[3]) except Exception, ex: handle_exception() logging.info("submitting to server: %s" % wavelet.serialize()) try: import google self.submit(wavelet) except google.appengine.api.urlfetch_errors.DownloadError: handle_exception()
def handle_lists(bot, ievent): """ list <listname> [',' <item>] """ if not ievent.rest: ievent.missing("<listname> [',' <item>]") return username = getusers().getname(ievent.userhost) try: listname, item = ievent.rest.split(',', 1) except ValueError: l = getlist(username, ievent.rest) if not l: ievent.reply('no %s list available' % ievent.rest) return result = [] for i in l: result.append("%s) %s" % (i[0], i[3])) ievent.reply("results: ", result) return listname = listname.strip().lower() item = item.strip() if not listname or not item: ievent.missing("<listname> [',' <item>]") return ok = 0 try: ok = addtolist(username, listname, item) except Exception, ex: handle_exception() ievent.reply('ERROR: %s' % str(ex)) return
def handle_tododone(bot, ievent): """ todo-done <listofnrs> .. remove todo items """ if len(ievent.args) == 0: ievent.missing('<list of nrs>') return try: nrs = [] for i in ievent.args: nrs.append(int(i)) nrs.sort() except ValueError: ievent.reply('%s is not an integer' % i) return name = ievent.channel nrdone = 0 failed = [] todo = TodoList(name) for i in nrs[::-1]: try: del todo.data.list[i-1] nrdone += 1 except IndexError: continue except Exception, ex: failed.append(str(i)) handle_exception()
def _dccloop(self, sock, nick, userhost, channel=None): """ loop for dcc commands. """ sockfile = sock.makefile('r') sock.setblocking(True) res = "" partyline.add_party(self, sock, nick, userhost, channel) while 1: time.sleep(0.001) try: res = sockfile.readline() logging.debug("%s - dcc - %s got %s" % (self.name, userhost, res)) if self.stopped or not res: logging.warn('%s - closing dcc with %s' % (self.name, nick)) partyline.del_party(nick) return except socket.timeout: continue except socket.error, ex: try: (errno, errstr) = ex except: errno = 0 errstr = str(ex) if errno == 35 or errno == 11: continue else: raise except Exception, ex: handle_exception() logging.warn('%s - closing dcc with %s' % (self.name, nick)) partyline.del_party(nick) return
def handle(self, speed, argslist): """ schedule a job. """ self.working = True try: try: descr, func, args, kwargs = argslist except ValueError: try: descr, func, args = argslist kwargs = {} except ValueError: descr, func = argslist args = () kwargs = {} self.nowrunning = getname(func) + " - " + descr logging.info('running %s - %s- %s' % (descr, str(func), args)) self.starttime = time.time() result = func(*args, **kwargs) self.finished = time.time() self.elapsed = self.finished - self.starttime if self.elapsed > 5: logging.debug('ALERT %s %s job taking too long: %s seconds' % (descr, str(func), self.elapsed)) stats.upitem(self.nowrunning) stats.upitem(self.name) logstr = "finished %s - %s (%s)" % (self.nowrunning, result or "no result", self.elapsed) logging.warn(logstr) time.sleep(0.005) except Exception, ex: handle_exception() result = str(ex)
def remotecb(bot, event): """ dispatch an event. """ try: container = Container().load(event.txt) except TypeError: handle_exception() logging.warn("remotecallbacks - not a remote event - %s " % event.userhost) return logging.debug("doing REMOTE callback") try: digest = hmac.new(str(container.hashkey), xmlstream.XMLunescape(container.payload), hashlib.sha512).hexdigest() logging.debug("remotecallbacks - digest is %s" % digest) except TypeError: handle_exception() logging.error("remotecallbacks - can't load payload - %s" % container.payload) return if container.digest == digest: e = EventBase().load(xmlstream.XMLunescape(container.payload)) else: raise NoProperDigest() e.txt = xmlstream.XMLunescape(e.txt) e.nodispatch = True e.forwarded = True e.dontbind = True bot.doevent(e) event.status = "done" return
def _raw(self, txt, event=None, *args, **kwargs): """ output some txt to the wave. """ assert event.chan if not event.chan: logging.error("%s - event.chan is not set" % self.name) return if event.chan.data.json_data: wavelet = self.blind_wavelet(event.chan.data.json_data) else: logging.warn("did not join channel %s" % event.chan.data.id) return if not wavelet: logging.error("cant get wavelet") return txt = self.normalize(txt) txt = unicode(txt.strip()) logging.warn("%s - wave - out - %s" % (self.name, txt)) try: annotations = [] for url in txt.split(): got = url.find("http://") if got != -1: logging.debug("wave - found url - %s" % str(url)) start = txt.find(url.strip()) if url.endswith(">"): annotations.append((start + 2, start + len(url) - 1, "link/manual", url[1:-1])) else: annotations.append( (start, start + len(url), "link/manual", url)) except Exception, ex: handle_exception()
def _raw(self, stanza): """ output a xml stanza to the socket. """ if self.stopped or self.failure: logging.info("%s - bot is stopped .. not sending" % self.cfg.name) ; return try: stanza = stanza.strip() if not stanza: logging.debug("%s - no stanze provided. called from: %s" % (self.cfg.name, whichmodule())) return what = jabberstrip(stanza, allowed=["\n", ]) what = toenc(what) if not what.endswith('>') or not what.startswith('<'): logging.error('%s - invalid stanza: %s' % (self.cfg.name, what)) return start = what[:3] if start in ['<st', '<me', '<pr', '<iq', "<au", "<re", "<fa", "<ab"]: if start == "<pr": logging.info(u"> %s" % what) else: logging.info(u"> %s" % what) if not self.connection: self.sock.send(what) else: try: self.connection.send(what + u"\r\n") except AttributeError: try: self.connection.write(what) except AttributeError: self.sock.send(what) else: logging.error('%s - invalid stanza: %s' % (self.cfg.name, what)) if self.cfg.sleeptime: time.sleep(self.cfg.sleeptime) else: time.sleep(0.01) except socket.error, ex: if 'Broken pipe' in str(ex): logging.debug('%s - core - broken pipe .. ignoring' % self.cfg.name) return self.error = str(ex) handle_exception()
def finish(self, data): """ finish processing of an xml stanza. """ methods = [] self.final['subelements'] = self.subelements for subelement in self.subelements: logging.debug("%s - %s" % (self.cfg.name, str(subelement))) for elem in subelement: logging.debug("%s - setting %s handler" % (self.cfg.name, elem)) methods.append(self.getHandler(elem)) for method in methods: if not method: continue try: result = GozerEvent(subelement) result.bot = self result.orig = data result.jabber = True method(result) except Exception, ex: handle_exception() if self.tags: element = self.tags[0] logging.debug("%s - setting element: %s" % (self.cfg.name, element)) else: element = 'stream' self.final['element'] = element method = self.getHandler(element) if method: try: result = GozerEvent(self.final) result.bot = self result.orig = data result.jabber = True method(result) except Exception, ex: handle_exception() result = {}
def handle_listsdel(bot, ievent): """ list-del <listname> ',' <listofnrs> .. remove items with indexnr from list """ if not ievent.rest: ievent.missing('<listofnrs>') return try: nrs = [] for i in ievent.rest.split(): nrs.append(int(i)) except ValueError: ievent.reply('%s is not an integer' % i) return username = getusers().getname(ievent.userhost) nrs.sort() failed = [] itemsdeleted = 0 try: for i in nrs: result = delfromlist(username, i) if not result: failed.append(str(i)) else: itemsdeleted += 1 except Exception, ex: handle_exception() ievent.reply('ERROR: %s' % str(ex)) return
def send(self, what): """ send stanza to the server. """ if not what: logging.debug("%s - can't send empty message" % self.cfg.name) return try: to = what['to'] except (KeyError, TypeError): logging.error("%s - can't determine where to send %s to" % (self.cfg.name, str(what))) return try: jid = JID(to) except (InvalidJID, AttributeError): logging.error("%s - invalid jid - %s - %s" % (self.cfg.name, str(to), whichmodule(2))) return try: del what['from'] except KeyError: pass try: xml = what.tojabber() if not xml: raise Exception("can't convert %s to xml .. bot.send()" % what) except (AttributeError, TypeError): handle_exception() return if not self.checkifvalid(xml): logging.error("%s - NOT PROPER XML - %s" % (self.cfg.name, xml)) else: self._raw(xml)
def handle(self, event, url, depth, speed=5): if depth < 0: return if not self.url.base in url: logging.warn("skipping %s (%s)" % (url, self.url.base)) return if url in self.errors: logging.warn("skipping %s" % url) return urls = [] linknr = 0 follownr = 0 n = 0 try: if url not in self.urls: self.urls.append(url) page = Url(url) time.sleep(10 - speed) content = page.fetch() event.reply("fetched %s - %s - %s" % (url, len(content), content.status)) try: urldata = UrlData(url, striphtml(content)) if urldata.data.txt: urldata.save() except Exception, ex: handle_exception() for p in page.geturls(): if not p in self.errors: self.put(6, event, p, depth - 1, speed - 1) if not self.queue.qsize(): self.stop()
def handle_geoJOIN(bot, event): event.reply("geo - doing query on %s" % event.hostname) try: result = querygeoipserver(host2ip(event.hostname)) if result: event.reply("%s lives in %s, %s (%s)" % (event.nick, result['city'], result['country_name'], result['country_code'])) else: event.reply("no result") except: handle_exception()
def handle(self, event, url, depth, speed=5): if depth < 0: return if not self.url.base in url: logging.warn("skipping %s (%s)" % (url, self.url.base)) ; return if url in self.errors: logging.warn("skipping %s" % url) ; return urls = [] linknr = 0 follownr = 0 n = 0 try: if url not in self.urls: self.urls.append(url) page = Url(url) time.sleep(10-speed) content = page.fetch() event.reply("fetched %s - %s - %s" % (url, len(content), content.status)) try: urldata = UrlData(url, striphtml(content)) if urldata.data.txt: urldata.save() except Exception, ex: handle_exception() for p in page.geturls(): if not p in self.errors: self.put(6, event, p, depth-1, speed-1) if not self.queue.qsize(): self.stop() except Exception, e: logging.warn("ERROR: Can't process url '%s' (%s)" % (url, e)) self.errors.append(url) handle_exception() if len(self.errors) > 10: self.stop()
def run(self): """ run the thread. """ try: logging.debug('threads - running thread %s' % self.name) threading.Thread.run(self) except Exception, ex: handle_exception() time.sleep(1)
def part(self, channel): logging.warn("%s - leaving %s" % (self.cfg.name, channel)) try: id = self.state["idcache"][channel] res = self.post("groups/%s/leave.json" % id, {"group_id": id}) except: handle_exception() ; return if channel in self.state['joinedchannels']: self.state['joinedchannels'].remove(channel) ; self.state.save() return res
def geturl_validate(url): """ validate url """ url = urlvalidate % urllib.urlencode({'uri': url}) try: result = geturl(url) except IOError, ex: try: errno = ex[0] except IndexError: handle_exception() ; return return False