def writeout(botname, type, channel, txt, eventjson): """ output the watched event to the channel. """ event = EventBase().load(eventjson) watchbot = getfleet().byname(botname) if not watchbot: watchbot = getfleet().makebot(type, botname) if watchbot: watchbot.outnocb(channel, txt, event=event)
def handle_adminsave(bot, ievent): """ no arguments - boot the bot .. do some initialisation. """ ievent.reply("saving mainconfig") getmainconfig().save() ievent.reply("saving fleet bots") getfleet().save() ievent.reply("saving all plugins") plugs.save() ievent.done()
def handle_broadcast(bot, ievent): """ arguments: <txt> - broadcast txt to all joined channels. """ if not ievent.rest: ievent.missing('<txt>') return ievent.reply('broadcasting') getfleet().broadcast(ievent.rest) partyline.say_broadcast(ievent.rest) ievent.reply('done')
def alarmsay(self, item): """ say alarm txt """ logging.warn("trying to deliver on %s" % str(item)) bot = getfleet().byname(item.botname) if not bot: bot = getfleet().makebot(None, item.botname) if bot: if item.printto: bot.say(item.printto, "[%s] %s" % (item.nick, item.txt), speed=1) else: bot.say(item.nick, item.txt, speed=1) else: logging.warn("can't find %s bot in fleet" % item.botname) self.delete(item.idnr)
def doreconnect(self): """ reconnect to the server. """ cfg = cpy(self.cfg) botjid = cfg.user newbot = getfleet().makebot('sxmpp', cfg.name, config=cfg, showerror=True) if not newbot: raise Exception("can't make bot %s with config %s" % (self.cfg.name, self.cfg.tojson())) newbot.reconnectcount = self.reconnectcount newbot.start() newbot.joinchannels() getfleet().replace(botjid, newbot) return True
def writeout(botname, type, channel, txt, eventjson): """ output the watched event to the channel. """ event = EventBase().load(eventjson) global bots watchbot = None if botname in bots: watchbot = bots[botname] if not watchbot: watchbot = getfleet().byname(botname) if not watchbot: watchbot = getfleet().makebot(type, botname) if watchbot: if not botname in bots: bots[botname] = watchbot txt = watchbot.normalize(txt) txt = stripcolor(txt) watchbot.outnocb(channel, txt, event=event)
def handle_reboot(bot, ievent): """ no arguments - reboot the bot. """ ievent.reply("rebooting") #time.sleep(3) if ievent.rest == "cold": stateful = False else: stateful = True if stateful: if bot.type == "tornado": callback = functools.partial(reboot_stateful, bot, ievent, getfleet(), partyline) bot.server.io_loop.add_callback(callback) else: mainhandler.put(0, reboot_stateful, bot, ievent, getfleet(), partyline) else: getfleet().exit() mainhandler.put(0, reboot)
def handle_reboot(bot, ievent): """ no arguments - reboot the bot. """ if bot.isgae: ievent.reply("this command doesn't work on the GAE") return ievent.reply("rebooting") time.sleep(3) if ievent.rest == "cold": stateful = False else: stateful = True if stateful: if bot.type == "tornado": bot.ioloop.add_callback(lambda: reboot_stateful(bot, ievent, getfleet(), partyline)) else: mainhandler.put(0, reboot_stateful, bot, ievent, getfleet(), partyline) else: getfleet().exit() mainhandler.put(0, reboot)
def _resume(self, data, reto=None): """ resume a party line connection after reboot. """ fleet = getfleet() for i in data['partyline']: logging.warn("partyline - resuming %s" % i) bot = fleet.byname(i['botname']) if not bot: logging.error("partyline - can't find bot") continue sock = socket.fromfd(i['fileno'], socket.AF_INET, socket.SOCK_STREAM) sock.setblocking(1) nick = i['nick'] userhost = i['userhost'] channel = i['channel'] if not bot: logging.error("partyline - can't find %s bot in fleet" % i['botname']) continue self.socks.append({ 'bot': bot, 'sock': sock, 'nick': nick, 'userhost': userhost, 'channel': channel, 'silent': i['silent'] }) bot._dccresume(sock, nick, userhost, channel) if reto: self.say_nick(nick, 'rebooting done')
def fleet_add(bot, ievent): """ add a fleet bot. """ try: name, type, server, nick = ievent.rest.split() except ValueError: ievent.missing("<name> <type> <server>|<botjid> <nick>|<passwd>") return bots = ievent.rest.split() fleet = getfleet() bot = fleet.byname(name) if bot: event.reply("%s bot already exists" % name) return cfg = Config('fleet' + os.sep + stripname(name) + os.sep + 'config') cfg.disable = 0 if type == "irc": cfg.port = 6667 cfg.server = server cfg.nick = nick elif type in ["xmpp", "sxmpp"]: cfg.port = 4442 cfg.host = server try: n, serv = cfg.host.split("@") except (ValueError, TypeError): pass cfg.server = serv cfg.password = nick cfg.save() bot = fleet.makebot(type, name, cfg) ievent.reply('enabled and started %s bot - %s' % (name, cfg.filename)) start_new_thread(bot.start, ())
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 alarmsay(self, item): """ say alarm txt """ logging.warn("trying to deliver on %s" % str(item)) bot = getfleet().byname(item.botname) if not bot: bot = getfleet().makebot(None, item.botname) if bot: if bot.type == "irc": bot.connectok.wait() if item.printto: bot.say(item.printto, "[%s] %s" % (item.nick, item.txt), speed=1) else: bot.say(item.nick, item.txt, speed=1) else: logging.warn("can't find %s bot in fleet" % item.botname) self.delete(item.idnr)
def handle_relay(bot, event): """ arguments: [<botname>] [<type>] <target> .. open a relay to a user. all input from us will be relayed. """ try: (botname, type, target) = event.args except ValueError: try: botname = bot.cfg.name (type, target) = event.args except ValueError: try: botname = bot.cfg.name type = bot.cfg.bottype target = event.args[0] except IndexError: event.missing('[<botname>] [<bottype>] <target>') return origin = unicode((bot.cfg.name, event.channel)) if not getfleet().byname(botname): event.reply("no %s bot in fleet." % botname) return if not relay.data.has_key(origin): relay.data[origin] = [] try: if not [type, target] in relay.data[origin]: relay.data[origin].append([botname, type, target]) relay.save() except KeyError: relay.data[origin] = [ [botname, type, target], ] relay.save() event.done()
def fleet_cmnd(bot, ievent): """ co cmnd on fleet bot(s). """ try: (name, cmndtxt) = ievent.rest.split(' ', 1) except ValueError: ievent.missing("<name> <cmndstring>") return fleet = getfleet() if name == "all": do = fleet.list() else: do = [ name, ] for botname in do: bot = fleet.byname(botname) if not bot: ievent.reply("%s bot is not in fleet" % botname) return result = bot.docmnd(ievent.userhost, ievent.channel, cmndtxt, wait=1, nooutput=True) if result: res = waitforqueue(result.outqueue, 60000) else: ievent.reply("no result") ievent.reply("[%s] %s" % (botname, ", ".join(res))) ievent.reply("done")
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 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 reboot_stateful(bot, ievent, fleet, partyline): """ reboot the bot, but keep the connections (IRC only). """ logging.warn("reboot - doing statefull reboot") session = {'bots': {}, 'name': bot.cfg.name, 'channel': ievent.channel, 'partyline': []} fleet = getfleet() for i in fleet.bots: logging.warn("reboot - updating %s" % i.cfg.name) data = i._resumedata() if not data: continue session['bots'].update(data) if i.type == "sxmpp": i.exit() ; continue if i.type == "tornado": i.exit() time.sleep(0.1) for socketlist in i.websockets.values(): for sock in socketlist: sock.stream.close() session['partyline'] = partyline._resumedata() sfile, sessionfile = tempfile.mkstemp('-session', 'jsb-', text=True) logging.warn("writing session file %s" % sessionfile) json.dump(session, open(sessionfile, "w")) args = [] skip = False for a in sys.argv[1:]: if skip: skip = False ; continue if a == "-r": skip = True ; continue args.append(a) os.execl(sys.argv[0], sys.argv[0], '-r', sessionfile, *args)
def topicset(state): retval = None fleet = getfleet() for botname in fleet.list(): bot = fleet.byname(botname) if testing: bot.say('#nurdbottest',botname) if bot: if not testing: topicdata = bot.gettopic('#nurds') if testing: topicdata = bot.gettopic('#nurdbottest') # time.sleep(5) # if not testing: topicdata = bot.gettopic('#nurds') # if testing: topicdata = bot.gettopic('#nurdbottest') # if testing: bot.say('#nurdbottest',str(topicdata)) # if not topicdata and not testing: bot.say('#nurds',"can't get topic data, but the status should be toggled to "+statusStr(state)+'!') ; return if not topicdata: bot.say('#nurdbottest',"can't get topic data, but the status should be toggled to "+statusStr(state)+'!') ; return splitted = topicdata[0].split(' | ') statusline = splitted[0] if 'Space is ' in statusline: del splitted[0] if state: splitted.insert(0,'Space is OPEN') retval = True else: splitted.insert(0,'Space is CLOSED') retval = False newtopic = ' | '.join(splitted) for botname in fleet.list(): bot = fleet.byname(botname) if bot and newtopic != topicdata[0]: if not testing: bot.settopic('#nurds', newtopic) if testing: bot.settopic('#nurdbottest', newtopic) return retval
def doorsense_output(msg): '''The listener code for the sensor server.''' pswd = tcppassword.data['password'] if msg[:len(pswd)] == pswd: msg = msg[len(pswd):] rsensor, rvalue = tuple(msg.split(':')) fleet = getfleet() for botname in fleet.list(): bot = fleet.byname(botname) if bot: if not testing: bot.say('#nurds',rsensor+' is '+rvalue) bot.say('#nurdbottest',rsensor+' is '+rvalue) for type in sensorlist.data: for n, sensor in enumerate(sensorlist.data[type]): if rsensor.lower() == sensor['name'].lower(): try: if type == 'door_locked': if rvalue.lower() == 'true': sensor['value']=True elif rvalue.lower() == 'false': sensor['value']=False else: sensor['value']=None else: sensor['value']=float(rvalue) except: pass sensorlist.data[type][n] = sensor sensorlist.save() apiupdate() if type == 'door_locked': statuscheck()
def askcallback(bot, event): """ this is the callbacks that handles the responses to questions. """ sendto = questions.data[event.userhost] jid = [] channels = [] try: (printto, txt) = event.txt.split(':', 1) except ValueError: printto = False txt = event.txt txt = txt.strip() done = [] fleet = getfleet() for botname, type, userhost, channel in sendto: if not printto or userhost != printto: continue askbot = fleet.makebot(type) if not askbot: askbot = fleet.makebot('xmpp', 'askxmppbot') logging.debug("ask - %s %s %s %s" % (botname, type, userhost, channel)) if askbot: for jid in channel: askbot.say(channel, "%s says: %s" % (event.userhost, txt)) else: logging.warn("ask - can't find %s bot in fleet" % type) continue try: questions.data[event.userhost].remove( [botname, type, userhost, channel]) questions.save() except ValueError: pass done.append(channel) break if done: event.reply('answer sent to ', done)
def handle_fleetconnect(bot, ievent): """ arguments: <botname> - connect a fleet bot to it's server. """ try: botname = ievent.args[0] except IndexError: ievent.missing('<botname>') return try: fleet = getfleet() fleetbot = fleet.byname(botname) if fleetbot: start_new_thread(fleetbot.connect, ()) ievent.reply('%s connect thread started' % botname) else: ievent.reply("can't connect %s .. trying enable" % botname) cfg = Config('fleet' + os.sep + stripname(botname) + os.sep + 'config') cfg['disable'] = 0 if not cfg.name: cfg.name = botname cfg.save() bot = fleet.makebot(cfg.type, cfg.name, cfg) if bot: ievent.reply('enabled and started %s bot' % botname) start_new_thread(bot.start, ()) else: ievent.reply("can't make %s bot" % cfg.name) except Exception, ex: ievent.reply(str(ex))
def relaycallback(bot, event): """ this is the callbacks that handles the responses to questions. """ # determine where the event came from e = cpy(event) origin = e.channel e.isrelayed = True e.headlines = True try: # loop over relays for origin for botname, type, target in relay.data[origin]: try: logging.debug('trying relay of %s to (%s,%s)' % (origin, type, target)) #if target == origin: continue # tests to prevent looping if botname == bot.cfg.name and origin == target: continue # check whether relay is blocked if block.data.has_key(origin): if [botname, type, target] in block.data[origin]: continue # retrieve the bot from fleet (based on type) fleet = getfleet() outbot = fleet.byname(botname) if not outbot: outbot = fleet.makebot(type, botname) if outbot: logging.info('relay - outbot found - %s - %s' % (outbot.cfg.name, outbot.type)) # we got bot .. use it to send the relayed message if e.nick == bot.cfg.nick: txt = "[!] %s" % e.txt else: txt = "[%s] %s" % (e.nick, e.txt) if event: t = "[%s]" % outbot.cfg.nick logging.debug("relay - sending to %s (%s)" % (target, outbot.cfg.name)) txt = stripcolor(txt) outbot.outnocb(target, txt, "normal", event=e) else: logging.info("can't find bot for (%s,%s,%s)" % (botname, type, target)) except Exception, ex: handle_exception() except KeyError: pass
def fleet_enable(bot, ievent): """ arguments: <list of botnames> - enable a fleet bot. """ if not ievent.rest: ievent.missing("<list of botnames>") return bots = ievent.rest.split() fleet = getfleet() for name in bots: bot = fleet.byname(name) if bot: bot.cfg.load() bot.cfg['disable'] = 0 if not bot.cfg.name: bot.cfg.name = name bot.cfg.save() ievent.reply('enabled %s' % name) #start_new_thread(bot.connect, ()) elif name in fleet.avail(): cfg = Config('fleet' + os.sep + stripname(name) + os.sep + 'config') cfg['disable'] = 0 if not cfg.name: cfg.name = name cfg.save() bot = fleet.makebot(cfg.type, cfg.name, cfg) if not bot: ievent.reply("can't make %s bot - %s" % (cfg.name, cfg.type)) ; return ievent.reply('enabled %s bot' % name) #start_new_thread(bot.start, ()) else: ievent.reply('no %s bot in fleet' % name)
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() state.save()
def fleet_add(bot, ievent): """ arguments: <name> <type> <server>|<botjid> <nick>|<passwd> - add a newly created bot to the fleet. """ try: name, type, server, nick = ievent.rest.split() except ValueError: ievent.missing("<name> <type> <server>|<botjid> <nick>|<passwd>") ; return type = type.lower() fleet = getfleet() bot = fleet.byname(name) if bot: event.reply("%s bot already exists" % name) ; return cfg = Config('fleet' + os.sep + stripname(name) + os.sep + 'config') cfg.disable = 0 if type == "irc": cfg.port = 6667 cfg.server = server cfg.nick = nick elif type in ["xmpp", "sxmpp"]: cfg.port = 4442 cfg.host = server try: n, serv = cfg.host.split("@") except (ValueError, TypeError): pass cfg.server = serv cfg.password = nick cfg.save() bot = fleet.makebot(type, name, cfg) fleet.addbot(bot) if bot: ievent.reply('enabled and started %s bot - %s' % (name, cfg.filename)) start_new_thread(bot.start, ()) else: ievent.reply("can't make %s bot" % cfg.name)
def scan(skip=False): global teller, dostop if dostop: return teller += 1 try: do = int(cfg.sleep) except ValueError: do = 5 if do < 1: do = 5 if teller % do != 0: return logging.info("running") fleet = getfleet() todo = sync() if not todo: logging.info("nothing todo") ; return for b in todo: uid = str(b.user_id) if not uid in state.data.ids: logging.warn("we don't follow id %s" % uid) ; continue for channel in state.data.ids[uid]: if dostop: return botname, chan = channel bot = fleet.byname(botname) if bot: if b.post_id: url = ("http://stackoverflow.com/questions/%s" % b.post_id) or "no url found" bot.say(chan, "*%s* %s - *%s* - %s - %s - %s (%s)" % (state.data.names[uid].upper(), b.action, b.description, url, time.ctime(b.creation_date), b.detail or "no detail", b.post_type)) if b.action == "answered": aa = getanswers(b.post_id) if aa: a = aa[-1] try: body = a['body'] except KeyError: continue (urls, c) = geturls(body) if c: bot.say(chan, u"> " + c) else: bot.say(chan, "can't find answers") if urls: bot.say(chan, "urls: %s" % " -=- ".join(urls)) else: logging.warn("no %s bot in fleet" % botname)
def topicset(state): retval = None try: fleet = getfleet() for botname in fleet.list(): bot = fleet.byname(botname) if bot: topicdata = bot.gettopic('#nurds') splitted = topicdata[0].split(' | ') statusline = splitted[0] if 'Space is ' in statusline: del splitted[0] if state: splitted.insert(0,'Space is OPEN') retval = True else: splitted.insert(0,'Space is CLOSED') retval = False newtopic = ' | '.join(splitted) for botname in fleet.list(): bot = fleet.byname(botname) if bot and newtopic != topicdata[0]: if not testing: bot.settopic('#nurds', newtopic) # if testing: bot.settopic('#nurdbottest', newtopic) except: pass return retval
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 handle_ask(bot, event): """ arguments: <subject> <question> - this command lets you ask a question that gets dispatched to jabber users that have registered themselves for that particular subject. """ try: subject, question = event.rest.split(' ', 1) except ValueError: event.missing('<subject> <question>') return try: expertslist = experts.data[subject] except KeyError: if '@' in subject: expertslist = [subject, ] else: expertslist = [defaultJID, ] fleet = getfleet() xmppbot = fleet.getfirstjabber() if xmppbot: for expert in expertslist: xmppbot.say(expert, "%s (%s) asks you: %s" % (event.userhost, bot.cfg.name, question)) else: logging.warn("ask - can't find jabber bot in fleet") return asker = event.userhost for expert in expertslist: if not questions.data.has_key(expert): questions.data[expert] = [] questions.data[expert].append([bot.cfg.name, bot.type, event.userhost, event.channel]) questions.save() event.reply('question is sent to %s' % ' .. '.join(expertslist))
def fleet_enable(bot, ievent): """ arguments: <list of botnames> - enable a fleet bot. """ if not ievent.rest: ievent.missing("<list of botnames>") return bots = ievent.rest.split() fleet = getfleet() for name in bots: bot = fleet.byname(name) if bot: bot.cfg.load_config() bot.cfg['disable'] = 0 if not bot.cfg.name: bot.cfg.name = name bot.cfg.save() ievent.reply('enabled %s' % name) #start_new_thread(bot.connect, ()) elif name in fleet.avail(): cfg = Config('fleet' + os.sep + stripname(name) + os.sep + 'config') cfg['disable'] = 0 if not cfg.name: cfg.name = name cfg.save() bot = fleet.makebot(cfg.type, cfg.name, cfg) if not bot: ievent.reply("can't make %s bot - %s" % (cfg.name, cfg.type)) return ievent.reply('enabled %s bot' % name) #start_new_thread(bot.start, ()) else: ievent.reply('no %s bot in fleet' % name)
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.cfg.user e.botname = bot.cfg.server or bot.cfg.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()]: if not "@" in jid: logging.error("forward - %s is not a valid JID" % jid) ; continue 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.cfg.user txt = outbot.normalize(e.tojson()) txt = stripcolor(txt) #txt = e.tojson() container = Container(outbot.cfg.user, txt) outbot.outnocb(jid, container.tojson()) else: logging.info("forward - no xmpp bot found in fleet".upper())
def askcallback(bot, event): """ this is the callbacks that handles the responses to questions. """ sendto = questions.data[event.userhost] jid = [] channels = [] try: (printto, txt) = event.txt.split(':', 1) except ValueError: printto = False ; txt = event.txt txt = txt.strip() done = [] fleet = getfleet() for botname, type, userhost, channel in sendto: if not printto or userhost != printto: continue askbot = fleet.makebot(type) if not askbot: askbot = fleet.makebot('xmpp', 'askxmppbot') logging.debug("ask - %s %s %s %s" % (botname, type, userhost, channel)) if askbot: for jid in channel: askbot.say(channel, "%s says: %s" % (event.userhost, txt)) else: logging.warn("ask - can't find %s bot in fleet" % type) ; continue try: questions.data[event.userhost].remove([botname, type, userhost, channel]) questions.save() except ValueError: pass done.append(channel) break if done: event.reply('answer sent to ', done)
def fleet_cmnd(bot, ievent): """ arguments: <botname> <cmndstring> - do cmnd on fleet bot(s). """ try: (name, cmndtxt) = ievent.rest.split(' ', 1) except ValueError: ievent.missing("<botname> <cmndstring>") ; return fleet = getfleet() if name == "all": fleet.cmndall(ievent, cmndtxt) else: fleet.cmnd(ievent, name, cmndtxt)
def handle_fleetdel(bot, ievent): """ arguments: <botname> - delete bot from fleet. """ try: name = ievent.args[0] except IndexError: ievent.missing('<name>') return try: if getfleet().delete(name): ievent.reply('%s deleted' % name) else: ievent.reply('%s delete failed' % name) except Exception, ex: ievent.reply(str(ex))
def handle_xmppinvite(bot, event): """ arguments: <list of JIDs> - invite (subscribe to) a different user. """ if not event.rest: event.missing("<list of JIDs>") return bot = getfleet().getfirstjabber() if bot: for jid in event.args: bot.invite(jid) event.done() else: event.reply("can't find jabber bot in fleet")
def reboot_stateful(bot, ievent, fleet, partyline): """ reboot the bot, but keep the connections (IRC only). """ logging.warn("reboot - doing statefull reboot") session = {'bots': {}, 'name': bot.name, 'channel': ievent.channel, 'partyline': []} for i in getfleet().bots: logging.warn("reboot - updating %s" % i.name) data = i._resumedata() if not data: continue session['bots'].update(data) if i.bottype == "sxmpp": i.exit() session['partyline'] = partyline._resumedata() sessionfile = tempfile.mkstemp('-session', 'jsb-')[1] json.dump(session, open(sessionfile, 'w')) getfleet().save() args = [] if len(sys.argv) > 1: os.execl(sys.argv[0], sys.argv[0], '-r', sessionfile, *sys.argv[1:]) else: os.execl(sys.argv[0], sys.argv[0], '-r', sessionfile)
def dosay(self, printto, txt): """ send txt to printto .. do some checks. """ if cfg['udpparty'] and partyline.is_on(printto): partyline.say_nick(printto, txt) ; return if not cfg['udpbots']: bots = [cfg['udpbot'], ] else: bots = cfg['udpbots'] for botname in bots: bot = getfleet().byname(botname) if not bot: logging.warn("udp - can't find %s bot in fleet" % botname) ; continue bot.connectok.wait() bot.say(printto, txt) for i in self.loggers: i.log(printto, txt)
def doreconnect(self): """ reconnect to the server. """ botjid = self.jid newbot = getfleet().makebot('sxmpp', self.name, cfg=self.cfg) newbot.reconnectcount = self.reconnectcount self.exit() if newbot.start(): self.jid += '.old' #newbot.joinchannels() if fleet.replace(botjid, newbot): return True return False
def reboot_stateful(bot, ievent, fleet, partyline): """ reboot the bot, but keep the connections (IRC only). """ logging.warn("reboot - doing statefull reboot") session = {'bots': {}, 'name': bot.cfg.name, 'channel': ievent.channel, 'partyline': []} for i in getfleet().bots: logging.warn("reboot - updating %s" % i.cfg.name) data = i._resumedata() if not data: continue session['bots'].update(data) if i.type == "sxmpp": i.exit() ; continue if i.type == "convore": i.exit() ; continue if i.type == "tornado": i.exit() time.sleep(0.1) for socketlist in i.websockets.values(): for sock in socketlist: sock.stream.close() session['partyline'] = partyline._resumedata() sessionfile = tempfile.mkstemp('-session', 'jsb-')[1] json.dump(session, open(sessionfile, 'w')) getfleet().save() os.execl(sys.argv[0], sys.argv[0], '-r', sessionfile, *sys.argv[1:])
def fleet_disable(bot, ievent): """ arguments: <list of botnames> - disable a fleet bot. """ if not ievent.rest: ievent.missing("<list of botnames>") return fleet = getfleet() bots = fleet.loadall(ievent.args) for bot in bots: bot.cfg['disable'] = 1 bot.cfg.save() ievent.reply('disabled %s bot.' % bot.cfg.name) fleet.exit(bot.cfg.name)
def handle_reboot(bot, ievent): """ reboot the bot. """ if bot.isgae: ievent.reply("this command doesn't work on the GAE") return ievent.reply("rebooting") time.sleep(3) if ievent.rest == "cold": stateful = False else: stateful = True if stateful: mainhandler.put(0, reboot_stateful, bot, ievent, getfleet(), partyline) else: bot.exit() mainhandler.put(0, reboot)
def irccat_output(msg): fleet = getfleet() dest, msg = splitMsg(msg) for chan in dest: logging.info("sending to %s" % chan) for botname in fleet.list(): if botname not in cfg.data['botnames']: continue bot = fleet.byname(botname) if bot: if chan[0] == "#" and chan not in bot.state['joinedchannels']: logging.warn("someone tried to make me say something in a channel i'm not in! (%s - %s)" % (bot.cfg.name, chan)) else: bot.say(chan, msg) else: logging.error("can't find %s bot in fleet" % botname)
def handle_fleetdisconnect(bot, ievent): """ arguments: <botname> - disconnect a fleet bot from server. """ try: botname = ievent.args[0] except IndexError: ievent.missing('<botname>') return ievent.reply('exiting %s' % botname) try: fleet = getfleet() if fleet.exit(botname): ievent.reply("%s bot stopped" % botname) else: ievent.reply("can't stop %s bot" % botname) except Exception, ex: ievent.reply("fleet - %s" % str(ex))
def handle_nsauth(bot, ievent): """ perform an auth request. """ if bot.jabber: return if len(ievent.args) != 1: name = bot.name else: name = ievent.args[0] fbot = getfleet().byname(name) if not fbot: ievent.reply('fleet bot %s not found' % name) return if not nsauth.has(fbot): ievent.reply('nickserv not configured on %s' % fbot.name) return nsauth.identify(fbot) ievent.reply('ok')
def reboot_stateful(bot, ievent, fleet, partyline): """ reboot the bot, but keep the connections (IRC only). """ logging.warn("reboot - doing statefull reboot") session = { 'bots': {}, 'name': bot.name, 'channel': ievent.channel, 'partyline': [] } for i in getfleet().bots: logging.warn("reboot - updating %s" % i.name) data = i._resumedata() if not data: continue session['bots'].update(data) if i.bottype == "sxmpp": i.exit() session['partyline'] = partyline._resumedata() sessionfile = tempfile.mkstemp('-session', 'jsb-')[1] json.dump(session, open(sessionfile, 'w')) getfleet().save() args = [] if len(sys.argv) > 1: os.execl(sys.argv[0], sys.argv[0], '-r', sessionfile, *sys.argv[1:]) else: os.execl(sys.argv[0], sys.argv[0], '-r', sessionfile)
def handle(self): try: fleet = getfleet() msg = unicode(self.rfile.readline().strip()) logging.warn("received %s" % msg) dest, msg = self.splitMsg(msg) for chan in dest: logging.info("sending to %s" % chan) for botname in fleet.list(): if botname not in cfg.botnames: continue bot = fleet.byname(botname) if bot: bot.say(chan, msg) else: logging.error("can't find %s bot in fleet" % botname) except Exception, ex: handle_exception()
def fleet_disable(bot, ievent): """ disable a fleet bot. """ if not ievent.rest: ievent.missing("list of fleet bots") return bots = ievent.rest.split() fleet = getfleet() for name in bots: bot = fleet.byname(name) if bot: bot.cfg['enable'] = 0 bot.cfg.save() ievent.reply('disabled %s' % name) fleet.exit(name) else: ievent.reply("can't find %s bot in fleet" % name)
def handle_nsdel(bot, ievent): """ remove a bot from nickserv. """ if bot.jabber: return if len(ievent.args) != 1: ievent.missing('<fleetbot name>') return botname = ievent.args[0] fbot = getfleet().byname(botname) if not fbot: ievent.reply('fleet bot %s not found' % botname) return if not nsauth.has(fbot): ievent.reply('nickserv not configured on %s' % fbot.name) return nsauth.remove(fbot) ievent.reply('ok')
def scan(skip=False): global teller, dostop if dostop: return teller += 1 try: do = int(cfg.sleep) except ValueError: do = 5 if do < 1: do = 5 if teller % do != 0: return logging.info("running") fleet = getfleet() todo = sync() if not todo: logging.info("nothing todo") return for b in todo: uid = str(b.user_id) if not uid in state.data.ids: logging.warn("we don't follow id %s" % uid) continue for channel in state.data.ids[uid]: if dostop: return botname, chan = channel bot = fleet.byname(botname) if bot: if b.post_id: url = ("http://stackoverflow.com/questions/%s" % b.post_id) or "no url found" bot.say( chan, "*%s* %s - *%s* - %s - %s - %s (%s)" % (state.data.names[uid].upper(), b.action, b.description, url, time.ctime(b.creation_date), b.detail or "no detail", b.post_type)) if b.action == "answered": aa = getanswers(b.post_id) if aa: a = aa[-1] try: body = a['body'] except KeyError: continue (urls, c) = geturls(body) if c: bot.say(chan, u"> " + c) else: bot.say(chan, "can't find answers") if urls: bot.say(chan, "urls: %s" % " -=- ".join(urls)) else: logging.warn("no %s bot in fleet" % botname)