def handle_fish(bot, event): """ Handles the fish command """ args = event.rest.rsplit(" ") if not args[0]: event.missing("<commands> [options,...]") ; return command = args[0] if command == 'help': event.reply("help -- shows this text") event.reply("keyx <nick> -- Exchanges key") event.reply("key <user|channel> <key> -- Set the key") event.reply("del <user|channel> -- Removes the key") return False if command == 'keyx': if len(args) != 2: event.missing("keyx <nick>"); return userhost = getwho(bot, args[1]) if userhost == None: return user = users.getuser(userhost) if user == None: event.reply("Unable to exchange key with an unknown user") return target = user.data.name if target == None: return logging.warn("FiSH: Key exchange with %s (%s)" % (args[1], target)) dh = DH1080Ctx() bot.notice(args[1], dh1080_pack(dh)) key = KeyStore(stripname(target)) key.data.dh = pickle.dumps(dh) key.save() if command == 'key': if len(args) != 3: event.missing("key <user|channel> <key>"); return key = KeyStore(stripname(args[1])) key.data.key = args[2] key.save() event.reply("Stored key for %s" % args[1]) if command == 'del': if len(args) != 2: event.missing("del <user|channel>"); return key = KeyStore(stripname(args[1])) if not key.data.key: event.reply("No key found for %s" % args[1]); return key.data.key="" key.data.dh="" key.save() event.reply("Deleted key %s" % args[1])
def enablelogging(botname, channel): """ set loglevel to level_name. """ global loggers global logfiles LOGDIR = initlog(getdatadir()) logging.warn("enabling on (%s,%s)" % (botname, channel)) channel = stripname(channel) logname = "%s_%s" % (botname, channel) #if logname in loggers: logging.warn("there is already a logger for %s" % logname) ; return logfile = LOGDIR + os.sep + logname + ".log" try: filehandler = logging.handlers.TimedRotatingFileHandler(logfile, 'midnight') formatter = logging.Formatter(format) filehandler.setFormatter(formatter) logfiles[logfile] = time.time() except IOError: filehandler = None chatlogger = logging.getLoggerClass()(logname) chatlogger.setLevel(logging.INFO) if chatlogger.handlers: for handler in chatlogger.handlers: chatlogger.removeHandler(handler) if filehandler: chatlogger.addHandler(filehandler) ; logging.warn("%s - logging enabled on %s" % (botname, channel)) else: logging.error("no file handler found - not enabling logging.") global lastlogger lastlogger = chatlogger loggers[logname] = lastlogger
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 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 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 set(target, txtlist): """ set target entry to list. """ cache = Persist(getdatadir() + os.sep + 'run' + os.sep + 'outputcache' + os.sep + stripname(target)) if not cache.data.has_key('msg'): cache.data['msg'] = [] cache.data['msg'] = txtlist cache.save()
def makeircconfig(type=None, opts=None, botname=None): """ make config file based on options. """ if not opts: botname = botname or "default-irc" else: if not botname: botname = opts.name or "default-irc" botname = stripname(botname) cfg = Config('fleet' + os.sep + botname + os.sep + 'config') cfg.type = 'irc' cfg.botname = botname if not opts: cfg.password = "" cfg.ssl = False cfg.port = 6667 cfg.server = "localhost" cfg.owner = [] cfg.ipv6 = False return cfg if opts.password: cfg.password = opts.password if opts.ssl: cfg.ssl = True if opts.nossl: cfg.ssl = False if opts.port: cfg.port = opts.port else: cfg.port = 6667 if opts.server: cfg.server = opts.server else: cfg.server = cfg.server or "localhost" if not cfg.owner: cfg.owner = [] if opts.owner and opts.owner not in cfg.owner: cfg.owner.append(opts.owner) if opts.ipv6: cfg.ipv6 = opts.ipv6 return cfg
def fishin(text, event=None): if event and not (event.bottype == "irc" or event.bottype == "botbase"): return text if text.startswith('+OK '): target = None if event and event.channel and event.channel.startswith("#"): target = event.channel elif event: u = users.getuser(event.userhost) if u: target = u.data.name if not target: return key = KeyStore(stripname(target)) if not key.data.key: logging.debug("FiSHin: No key found for target %s" % target) return text try: #logging.debug("FiSHin raw: key: %s Raw: %s (%s)" % (key.data.key, text, target)) text = decrypt(key.data.key, text) logging.debug("FiSHin raw decrypt: :%s:" % text) return text except (MalformedError, UnicodeDecodeError): return None return text
def enablelogging(botname, channel): """ set loglevel to level_name. """ global loggers logging.warn("chatlog - enabling on (%s,%s)" % (botname, channel)) channel = stripname(channel) logname = "%s_%s" % (botname, channel) #if logname in loggers: logging.warn("chatlog - there is already a logger for %s" % logname) ; return try: filehandler = logging.handlers.TimedRotatingFileHandler( LOGDIR + os.sep + logname + ".log", 'midnight') formatter = logging.Formatter(format) filehandler.setFormatter(formatter) except IOError: filehandler = None chatlogger = logging.getLoggerClass()(logname) chatlogger.setLevel(logging.INFO) if chatlogger.handlers: for handler in chatlogger.handlers: chatlogger.removeHandler(handler) if filehandler: chatlogger.addHandler(filehandler) logging.info("%s - logging enabled on %s" % (botname, channel)) else: logging.warn("chatlog - no file handler found - not enabling logging.") global lastlogger lastlogger = chatlogger loggers[logname] = lastlogger
def __init__(self, cfg=None, usersin=None, plugs=None, botname=None, nick=None, bottype=None, nocbs=None, *args, **kwargs): logging.debug("type is %s" % str(type(self))) if cfg: self.cfg = cfg ; botname = botname or self.cfg.name if not botname: botname = u"default-%s" % str(type(self)).split('.')[-1][:-2] if not botname: raise Exception("can't determine botname") self.fleetdir = u'fleet' + os.sep + stripname(botname) if not self.cfg: self.cfg = Config(self.fleetdir + os.sep + u'config') self.cfg.name = botname or self.cfg.name if not self.cfg.name: raise Exception("name is not set in %s config file" % self.fleetdir) logging.debug("name is %s" % self.cfg.name) LazyDict.__init__(self) logging.debug("created bot with config %s" % self.cfg.tojson(full=True)) self.ecounter = 0 self.ids = [] self.aliases = getaliases() self.reconnectcount = 0 self.plugs = coreplugs self.gatekeeper = GateKeeper(self.cfg.name) self.gatekeeper.allow(self.user or self.jid or self.cfg.server or self.cfg.name) self.starttime = time.time() self.type = bottype or "base" self.status = "init" self.networkname = self.cfg.networkname or self.cfg.name or "" from jsb.lib.datadir import getdatadir datadir = getdatadir() self.datadir = datadir + os.sep + self.fleetdir self.maincfg = getmainconfig() self.owner = self.cfg.owner if not self.owner: logging.debug(u"owner is not set in %s - using mainconfig" % self.cfg.cfile) self.owner = self.maincfg.owner self.users = usersin or getusers() logging.debug(u"owner is %s" % self.owner) self.users.make_owner(self.owner) self.outcache = outcache self.userhosts = LazyDict() self.nicks = LazyDict() self.connectok = threading.Event() self.reconnectcount = 0 self.cfg.nick = nick or self.cfg.nick or u'jsb' try: if not os.isdir(self.datadir): os.mkdir(self.datadir) except: pass self.setstate() self.outputlock = thread.allocate_lock() try: self.outqueue = Queue.PriorityQueue() self.eventqueue = Queue.PriorityQueue() except AttributeError: self.outqueue = Queue.Queue() self.eventqueue = Queue.Queue() self.laterqueue = Queue.Queue() self.encoding = self.cfg.encoding or "utf-8" self.cmndperms = getcmndperms() self.outputmorphs = outputmorphs self.inputmorphs = inputmorphs try: if nocbs: self.nocbs = nocbs.split(",") except ValueError: logging.error("cannot determine %s nocbs argument" % self.nocbs) self.lastiter = 0
def settype(self, name, type): """ set the type of a bot. """ cfg = Config('fleet' + os.sep + stripname(name) + os.sep + 'config') cfg['name'] = name logging.debug("%s - setting type to %s" % (self.cfile, type)) cfg.type = type cfg.save()
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 fishin(text,event = None): if event and not (event.bottype == "irc" or event.bottype == "botbase"): return text if text.startswith('+OK '): target = None if event and event.channel and event.channel.startswith("#"): target = event.channel elif event: u = users.getuser(event.userhost) if u: target = u.data.name if not target: return key = KeyStore(stripname(target)) if not key.data.key: logging.debug("FiSHin: No key found for target %s" % target) return text try: #logging.debug("FiSHin raw: key: %s Raw: %s (%s)" % (key.data.key, text, target)) text = decrypt(key.data.key, text) logging.debug("FiSHin raw decrypt: :%s:" % text) return text except (MalformedError, UnicodeDecodeError): return None return text
def makebot(self, type, name, config={}, domain="", showerror=False): """ create a bot .. use configuration if provided. """ if not name: logging.error(" name is not correct: %s" % name) ; return if not type: type = self.data.types.get(name) if not type: logging.error("no type found for %s bot" % name) ; return if config: logging.debug('making %s (%s) bot - %s - from: %s' % (type, name, config.tojson(), whichmodule())) bot = None if not config: cfg = Config('fleet' + os.sep + stripname(name) + os.sep + 'config') else: cfg = config cfg.init() if not cfg.name: cfg['name'] = name cfg['botname'] = cfg['name'] if cfg.disable: logging.info("%s bot is disabled. see %s" % (name, cfg.cfile)) return if not cfg.type and type: logging.debug("%s - setting type to %s" % (cfg.cfile, type)) cfg.type = type if not cfg['type']: try: self.data['names'].remove(name) self.save() except ValueError: pass raise Exception("no bot type specified") if not cfg.owner: logging.debug("%s - owner not set .. using global config." % cfg.name) cfg.owner = getmainconfig().owner if not cfg.domain and domain: cfg.domain = domain if not cfg: raise Exception("can't make config for %s" % name) #cfg.save() bot = BotFactory().create(type, cfg) return bot
def __init__(self, id, botname=None, type="notset", needexist=False): if not id: raise NoChannelSet() if not botname: Persist.__init__(self, getdatadir() + os.sep + 'channels' + os.sep + stripname(id), needexist=needexist) else: Persist.__init__(self, getdatadir() + os.sep + 'fleet' + os.sep + stripname(botname) + os.sep + 'channels' + os.sep + stripname(id), needexist=needexist) self.id = id self.type = type self.lastmodified = time.time() self.data.id = id self.data.enable = self.data.enable or False self.data.ops = self.data.ops or [] self.data.taglist = self.data.taglist or [] self.data.silentcommands = self.data.silentcommands or [] self.data.allowcommands = self.data.allowcommands or [] self.data.feeds = self.data.feeds or [] self.data.forwards = self.data.forwards or [] self.data.allowwatch = self.data.allowwatch or [] self.data.watched = self.data.watched or [] self.data.passwords = self.data.passwords or {} self.data.cc = self.data.cc or "" self.data.nick = self.data.nick or "jsb" self.data.key = self.data.key or "" self.data.denyplug = self.data.denyplug or [] self.data.createdfrom = whichmodule() self.data.cacheindex = 0 self.data.tokens = self.data.tokens or [] self.data.webchannels = self.data.webchannels or []
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 handle_meet(bot, ievent): """ introduce a new user to the bot. """ try: nick = ievent.args[0] except IndexError: ievent.missing('<nick>') return if bot.users.exist(nick): ievent.reply('there is already a user with username %s' % nick) return userhost = getwho(bot, nick) logging.warn("users - meet - userhost is %s" % userhost) if not userhost: ievent.reply("can't find userhost of %s" % nick) return username = bot.users.getname(userhost) if username: ievent.reply('we already have a user with userhost %s (%s)' % (userhost, username)) return result = 0 name = stripname(nick.lower()) result = bot.users.add(name, [ userhost, ], ['USER', 'GUEST']) if result: ievent.reply('%s - %s - (%s) added to user database' % (nick, userhost, name)) else: ievent.reply('add failed')
def handle_karmagood(bot, event): """ arguments: none - show top karma items of a channel. """ collection = PlugPersistCollection() # event.reply('Processing karma list.') stats = StatDict() objs = collection.objects() for name, obj in objs.iteritems(): if not obj.data: logging.warn("%s is empty" % name) ; continue item = stripname(name).split("-",2)[-1] if stripname(name).split("-",2)[1] == event.channel.lower()[1:]: stats.upitem(item, obj.data.count) ktop = stats.top(limit=20) # event.reply(str(ktop)) res = "" for item in ktop: res += (str(item[0])+':'+str(item[1])+' ') event.reply('Top 20 Karma for '+event.channel+': '+ res)
def byname(self, name): """ return user by name. """ try: name = name.lower() name = stripname(name) user = JsonUser(name) if user.data.userhosts: return user except KeyError: raise NoSuchUser(name)
def handle_chatlogoff(bot, ievent): """ no arguments - disable chatlog. """ try: cfg['channels'].remove([bot.cfg.name, ievent.channel]) ; cfg.save() except ValueError: ievent.reply('chatlog is not enabled in (%s,%s)' % (bot.cfg.name, ievent.channel)) ; return try: del loggers["%s-%s" % (bot.cfg.name, stripname(ievent.channel))] except KeyError: pass except Exception, ex: handle_exception() ievent.reply('chatlog disabled on (%s,%s)' % (bot.cfg.name, ievent.channel))
def makebot(self, type, name, domain="", cfg={}, showerror=False): """ create a bot .. use configuration if provided. """ if not name: logging.warn("fleet - name is not correct: %s" % name) ; return if cfg: logging.warn('fleet - making %s (%s) bot - %s' % (type, name, cfg.dump())) bot = None if not cfg: cfg = Config('fleet' + os.sep + stripname(name) + os.sep + 'config') if not cfg.name: cfg['name'] = cfg['botname'] = name if cfg.disable: logging.warn("fleet - %s bot is disabled. see %s" % (name, cfg.cfile)) if showerror: raise BotNotEnabled(name) return if not cfg.type and type: logging.debug("fleet - %s - setting type to %s" % (cfg.cfile, type)) cfg.type = type if not cfg['type']: try: self.data['names'].remove(name) self.save() except ValueError: pass raise Exception("no bot type specified") if not cfg.owner: cfg.owner = Config().owner if not cfg.domain and domain: cfg.domain = domain if not cfg: raise Exception("can't make config for %s" % name) cfg.save() if type == 'xmpp' or type == 'jabber': try: from jsb.lib.gae.xmpp.bot import XMPPBot bot = XMPPBot(cfg) except ImportError: from jsb.lib.socklib.xmpp.bot import SXMPPBot bot = SXMPPBot(cfg) elif type == 'sxmpp': from jsb.lib.socklib.xmpp.bot import SXMPPBot bot = SXMPPBot(cfg) elif type == 'web': from jsb.lib.gae.web.bot import WebBot bot = WebBot(cfg) elif type == 'wave': from jsb.lib.gae.wave.bot import WaveBot dom = cfg.domain or domain bot = WaveBot(cfg, domain=dom) elif type == 'irc': from jsb.lib.socklib.irc.bot import IRCBot bot = IRCBot(cfg) elif type == 'console': from jsb.lib.console.bot import ConsoleBot bot = ConsoleBot(cfg) elif type == 'base': from jsb.lib.botbase import BotBase bot = BotBase(cfg) else: raise NoSuchBotType('%s bot .. unproper type %s' % (name, type)) if bot: self.addbot(bot) return bot raise Exception("can't make %s bot" % name)
def get(target): """ get output for target. """ cache = Persist(getdatadir() + os.sep + 'run' + os.sep + 'outputcache' + os.sep + stripname(target)) try: result = cache.data['msg'] if result: return result except KeyError: pass return []
def makeconsoleconfig(opts=None, botname=None): """ make config file based on options. """ if not botname: botname = opts.name or "default-console" botname = stripname(botname) cfg = Config('fleet' + os.sep + botname + os.sep + 'config') cfg.type = "console" cfg.name = botname if opts and opts.loglevel: cfg.loglevel = opts.loglevel else: cfg.loglevel = cfg.loglevel or "error" return cfg
def clear(target): """ clear target's outputcache. """ cache = Persist(getdatadir() + os.sep + 'run' + os.sep + 'outputcache' + os.sep + stripname(target)) try: cache.data['msg'] = [] cache.save() except KeyError: pass return []
def makeconsoleconfig(type, opts, botname=None): """ make config file based on options. """ if not botname: botname = opts.name or "default-%s" % str(type) botname = stripname(botname) cfg = Config('fleet' + os.sep + botname + os.sep + 'config') cfg.type = type cfg.botname = botname if opts.loglevel: cfg.loglevel = opts.loglevel else: cfg.loglevel = cfg.loglevel or "error" return cfg
def handle_karmagood(bot, event): """ arguments: none - show top karma items of a channel. """ collection = PlugPersistCollection() # event.reply('Processing karma list.') stats = StatDict() objs = collection.objects() for name, obj in objs.iteritems(): if not obj.data: logging.warn("%s is empty" % name) continue item = stripname(name).split("-", 2)[-1] if stripname(name).split("-", 2)[1] == event.channel.lower()[1:]: stats.upitem(item, obj.data.count) ktop = stats.top(limit=20) # event.reply(str(ktop)) res = "" for item in ktop: res += (str(item[0]) + ':' + str(item[1]) + ' ') event.reply('Top 20 Karma for ' + event.channel + ': ' + res)
def makeconsoleconfig(opts=None, botname=None): """ make config file based on options. """ if not botname: botname = opts.name or "default-console" botname = stripname(botname) from jsb.lib.config import Config cfg = Config('fleet' + os.sep + botname + os.sep + 'config') cfg.type = "console" cfg.name = botname if opts and opts.loglevel: cfg.loglevel = opts.loglevel else: cfg.loglevel = cfg.loglevel or "error" return cfg
def save(self, attributes=[]): target = {} if attributes: for key in attributes: target[key] = self[key] else: target = cpy(self) targetfile = getdatadir() + os.sep + "containers" + os.sep + str( self.createtime) + "_" + stripname(self.origin) p = Persist(targetfile) p.data = getjson().dumps(target) p.save()
def __init__(self, name, userhosts=[], perms=[], permits=[], status=[], email=[]): assert name name = stripname(name.lower()) Persist.__init__(self, getdatadir() + os.sep + 'users' + os.sep + name) self.data.datadir = self.data.datadir or getdatadir() self.data.name = self.data.name or name self.data.userhosts = self.data.userhosts or userhosts self.data.perms = self.data.perms or perms self.data.permits = self.data.permits or permits self.data.status = self.data.status or status self.data.email = self.data.email or email self.state = UserState(name)
def dh1080_exchange(bot, ievent): # Not a known user, so also no key. u = users.getuser(ievent.userhost) if u: target = u.data.name else: return True if ievent.txt.startswith("DH1080_INIT "): logging.warn("FiSH: DH1080_INIT with %s" % target) key = KeyStore(stripname(target)) dh = DH1080Ctx() if dh1080_unpack(ievent.txt, dh) != True: logging.warn("FiSH Key exchange failed!") return False key.data.key = dh1080_secret(dh) key.data.dh = pickle.dumps(dh) key.save() logging.debug("FiSH UserKey: %s Key: %s" % (ievent.txt[12:], key.data.key)) ievent.bot.notice(ievent.nick, dh1080_pack(dh)) return False if ievent.txt.startswith("DH1080_FINISH "): key = KeyStore(stripname(target)) logging.warn("FiSH: DH1080_FINISH") dh = pickle.loads(key.data.dh) if dh1080_unpack(ievent.txt, dh) != True: logging.warn("FiSH Key exchange failed!") return False key.data.key = dh1080_secret(dh) key.save() logging.debug("FiSH: Key set for %s to %s" % (target, key.data.key)) return False return True
def handle_karmagood(bot, event): """ arguments: none - show top karma items of a channel. """ collection = PlugPersistCollection() stats = StatDict() objs = collection.objects(event.channel.lower()) for name, obj in objs.iteritems(): if not obj.data: logging.warn("%s is empty" % name) ; continue item = stripname(name).split("-")[-1] stats.upitem(item, obj.data.count) res = [] for item in stats.top(): res.append("%s - %s" % item) event.reply("top karma items of %s: " % event.channel, res)
def handle_chatlogstats(bot, event): """ no arguments - create log stats of the channel, possible options: --chan <channel> """ what = event.rest.strip() chatlogdir = getdatadir() + os.sep + "chatlogs" if event.options and event.options.channel: chan = event.options.channel else: chan = event.channel logs = os.listdir(chatlogdir) if not logs: event.reply("no logs available for %s" % chan) ; return now = time.time() if what: timetarget = strtotime2(what) ; what = striptime(what) else: timetarget = 0 ; what = None event.reply("creating stats for channel %s (%s)" % (chan, time.ctime(timetarget))) userstats = StatDict() wordstats = StatDict() stop = False for f in logs[::-1]: filename = stripname(f) channel = stripname(chan[1:]) if not channel in filename: continue for line in open(chatlogdir + os.sep + filename, 'r'): splitted = line.strip().split() if len(splitted) < 2: continue who = "unknown" for i in splitted: if i.startswith("<"): who = i[1:-1] if what and who != what: continue timestr = "%s %s" % (splitted[0], splitted[1]) logtime = strtotime2(timestr) if logtime: if logtime > timetarget: userstats.upitem(who) else: continue else: userstats.upitem(who) for word in splitted[4:]: wordstats.upitem(word) if what: result = wordstats.top() else: result = userstats.top() if result: res = ["%s: %s" % item for item in result] event.reply("stat results for %s: " % (what or chan), res) else: event.reply("no result found for %s" % (what or chan))
def api_log(bot, event): channel = event.upath.split("/")[-1] if not channel: event.error(500) ; return logging.warn("in api_log function .. channel is %s" % channel) LOGDIR = initlog(getdatadir()) channel = stripname(channel) logname = "%s_-%s.log" % ("default-irc", channel) logfile = LOGDIR + os.sep + logname f = open(logfile, "r") logdata = f.read() event.reply(logdata) event.finish() f.close()
def resumebot(self, botcfg, chan=None): """ resume single bot. """ botname = botcfg.name logging.warn("resuming %s bot" % botname) if botcfg['type'] == "console": logging.warn("not resuming console bot %s" % botname) ; return oldbot = self.byname(botname) if oldbot and botcfg['type'] in ["sxmpp", "convore"]: oldbot.exit() cfg = Config('fleet' + os.sep + stripname(botname) + os.sep + 'config') if cfg.disable: logging.warn("%s - bot is disabled .. not resuming it" % botname) ; return bot = self.makebot(botcfg.type, botname) if oldbot: self.replace(oldbot, bot) bot._resume(botcfg, botname) bot.start(False) if chan and chan in bot.state["joinedchannels"]: bot.say(chan, "done!")
def add(target, txtlist): """ add list of txt to target entry. """ logging.warn("outputcache - adding %s lines" % len(txtlist)) t = [] for item in txtlist: t.append("[%s] %s" % (hourmin(time.time()), item)) cache = Persist(getdatadir() + os.sep + 'run' + os.sep + 'outputcache' + os.sep + stripname(target)) d = cache.data if not d.has_key('msg'): d['msg'] = [] d['msg'].extend(t) while len(d['msg']) > 10: d['msg'].pop(0) cache.save()
def handle_chatlogsearch(bot, event): """ arguments: <searchtxt> - search in the logs. """ if not event.rest: event.missing("<searchtxt>") ; return result = [] chatlogdir = getdatadir() + os.sep + "chatlogs" chan = event.options.channel or event.channel logs = os.listdir(chatlogdir) logs.sort() for f in logs: filename = stripname(f) if not chan[1:] in filename: continue for line in open(chatlogdir + os.sep + filename, 'r'): if event.rest in line: result.append(line) if result: event.reply("search results for %s: " % event.rest, result, dot= " || ") else: event.reply("no result found for %s" % chan)
def handle_adduser(bot, ievent): """ user-add <name> <userhost> .. introduce a new user to the bot. """ try: (name, userhost) = ievent.args except ValueError: ievent.missing('<name> <userhost>') return username = bot.users.getname(userhost) if username: ievent.reply('we already have a user with userhost %s (%s)' % (userhost, username)) return result = 0 name = stripname(name.lower()) result = bot.users.add(name, [userhost, ], ['USER', 'GUEST']) if result: ievent.reply('%s added to user database' % name) else: ievent.reply('add failed')
def handle_adduser(bot, ievent): """ arguments: <name> <userhost> - introduce a new user to the bot. """ try: (name, userhost) = ievent.args except ValueError: ievent.missing('<name> <userhost>') return username = bot.users.getname(userhost) if username: ievent.reply('we already have a user with userhost %s (%s)' % (userhost, username)) return result = 0 name = stripname(name.lower()) result = bot.users.add(name, [userhost, ], ['USER', 'GUEST']) if result: ievent.reply('%s added to user database' % name) else: ievent.reply('add failed')
def makesxmppconfig(opts=None, botname=None, type="sxmpp"): """ make config file based on options. """ if not opts: botname = botname or "default-%s" % type else: if not botname: botname = opts.name or "default-%s" % type botname = stripname(botname) from jsb.lib.config import Config, makedefaultconfig cfg = Config('fleet' + os.sep + botname + os.sep + 'config') cfg.type = type cfg.name = botname if not opts: cfg.user = cfg.user or "" cfg.host = cfg.host or "" cfg.password = cfg.password or "" cfg.server = cfg.server or "" cfg.owner = cfg.owner or [] cfg.loglevel = cfg.lowlevel or "warn" cfg.nick = cfg.nick or "jsb" cfg.channels = [] cfg.openfire = False return cfg if opts.openfire: cfg.openfire = True ; logging.warn("openfire mode is enabled") else: cfg.openfire = False ; logging.warn("openfire mode is disabled") if opts.doregister: cfg.doregister = True ; logging.warn("register mode is enabled") else: cfg.doregister = False ; logging.warn("register mode is disabled") if not cfg.disable: cfg.disable = False if not cfg.channels: cfg.channels = [] if opts.user: cfg.user = opts.user if not cfg.user: raise NoUserProvided("user is not provided .. try giving the -u option to the bot (and maybe -p as well) or run jsb-init and edit %s" % cfg.cfile) if opts.user: try: cfg.host = opts.user.split('@')[1] except (IndexError, ValueError): print "user is not in the nick@server format" if not cfg.host: try: cfg.host = cfg.user.split('@')[1] except (IndexError, ValueError): print "user is not in the nick@server format" if opts.password: cfg.password = opts.password if opts.server: cfg.server = opts.server else: cfg.server = cfg.server or "" if opts.name: cfg.jid = opts.name if not cfg.owner: cfg.owner = [] if opts.owner and opts.owner not in cfg.owner: cfg.owner.append(opts.owner) if not cfg.owner: raise NoOwnerSet("try using the -o option or run jsb-init and edit %s" % cfg.cfile) if opts.nick: cfg.nick = opts.nick else: cfg.nick = cfg.nick or "jsb" if opts.channel: if not opts.channel in cfg.channels: cfg.channels.append(opts.channel) else: cfg.channels = cfg.channels or [] return cfg
def formatevent(bot, ievent, channels, forwarded=False): m = { 'datetime': datetime.now(), 'separator': format_opt('separator'), 'event_prefix': format_opt('event_prefix'), 'network': bot.cfg.networkname, 'nick': ievent.nick, 'target': stripname(ievent.channel), 'botname': bot.cfg.name, 'txt': ievent.txt, 'type': ievent.cbtype } m = LazyDict(m) if ievent.cmnd == 'PRIVMSG': if ievent.txt.startswith('\001ACTION'): m.txt = '* %s %s' % (m.nick, ievent.txt[7:-1].strip()) else: if bot.type == "irc": m.txt = '<%s> %s' % (m.nick, striphtml(ievent.txt)) elif not forwarded: m.txt = '<%s> %s' % (m.nick, bot.normalize(ievent.txt)) else: m.txt = bot.normalize(ievent.txt) elif ievent.cmnd == 'NOTICE': m.target = ievent.arguments[0] m.txt = "-%s- %s"%(ievent.nick, ievent.txt) elif ievent.cmnd == 'TOPIC': m.txt = '%s changes topic to "%s"'%(ievent.nick, ievent.txt) elif ievent.cmnd == 'MODE': margs = ' '.join(ievent.arguments[1:]) m.txt = '%s sets mode: %s'% (ievent.nick, margs) elif ievent.cmnd == 'JOIN': m.txt = '%s (%s) has joined %s'%(ievent.nick, ievent.userhost, ievent.channel) elif ievent.cmnd == 'KICK': m.txt = '%s was kicked by %s (%s)'% (ievent.arguments[1], ievent.nick, ievent.txt) elif ievent.cmnd == 'PART': m.txt = '%s (%s) has left %s'% (ievent.nick, ievent.userhost, ievent.channel) elif ievent.cmnd in ('QUIT', 'NICK'): if not ievent.user or not ievent.user.data.channels: logging.debug("chatlog - can't find joined channels for %s" % ievent.userhost) return m cmd = ievent.cmnd nick = cmd == 'NICK' and ievent.txt or ievent.nick for c in event.user.channels: if [bot.cfg.name, c] in channels: if True: if cmd == 'NICK': m.txt = '%s (%s) is now known as %s'% (ievent.nick, ievent.userhost, ievent.txt) else: m.txt= '%s (%s) has quit: %s'% (ievent.nick, ievent.userhost, ievent.txt) m.type = ievent.cmnd.lower() m.target = c elif ievent.cbtype == 'PRESENCE': if ievent.type == 'unavailable': m.txt = "%s left" % ievent.nick else: m.txt = "%s joined" % ievent.nick elif ievent.cbtype == "MESSAGE": m.txt = "<%s> %s" % (m.nick, ievent.txt) elif ievent.cbtype == "OUTPUT": m.txt = "<%s> %s" % (bot.cfg.nick, ievent.txt) return m
def resumebot(self, botname, data={}, printto=None): """ resume single bot. """ logging.warn("fleet - resuming %s bot" % botname) # see if we need to exit the old bot if data['type'] == "console": logging.warn("not resuming console bot %s" % botname) ; return oldbot = self.byname(botname) if oldbot and data['type'] == "sxmpp": oldbot.exit() cfg = Config('fleet' + os.sep + stripname(botname) + os.sep + 'config') logging.warn("fleet - resuming %s bot - %s - %s" % (botname, str(data), data['type'])) bot = self.makebot(data['type'], botname) if data['type'] != "sxmpp": if oldbot: self.replace(oldbot, bot) bot._resume(data, printto) bot.start(False) else: start_new_thread(bot.start, ())
def handle_chatlogsearch(bot, event): """ arguments: <searchtxt> - search in the logs. """ if not event.rest: event.missing("<searchtxt>") ; return result = [] chatlogdir = getdatadir() + os.sep + "chatlogs" if event.options and event.options.channel: chan = event.options.channel else: chan = event.channel logs = os.listdir(chatlogdir) logs.sort() for f in logs: filename = stripname(f) if not chan[1:] in filename: continue for line in open(chatlogdir + os.sep + filename, 'r'): if event.rest in line: result.append(line) if result: event.reply("search results for %s: " % event.rest, result, dot= " || ") else: event.reply("no result found for %s" % chan)
def log_write(m): if stopped: return logname = "%s_%s" % (m.botname, stripname(m.target)) if logname not in loggers: return timestamp = timestr(m.datetime) m.type = m.type.upper() line = '%(timestamp)s%(separator)s %(txt)s\n'%({ 'timestamp': timestamp, 'separator': format_opt('separator'), 'nick': m.nick, 'txt': m.txt, 'nick': m.nick, 'type': m.type }) try: loggers[logname].info(line.strip()) except KeyError: logging.error("no logger available for channel %s" % logname) except Exception, ex: handle_exception()
def log_write(m): if stopped: return logname = "%s_%s" % (m.botname, stripname(m.target)) timestamp = timestr(m.datetime) m.type = m.type.upper() line = '%(timestamp)s%(separator)s <%(nick)s %(txt)s\n'%({ 'timestamp': timestamp, 'separator': format_opt('separator'), 'nick': m.nick, 'txt': m.txt, 'nick': m.nick, 'type': m.type }) global loggers try: loggers[logname].info(line.strip()) except KeyError: logging.warn("no logger available for channel %s" % logname) except Exception, ex: handle_exception()
def makeircconfig(opts=None, botname=None): """ make config file based on options. """ if not opts: botname = botname or "default-irc" else: if not botname: botname = opts.name or "default-irc" botname = stripname(botname) from jsb.lib.config import Config cfg = Config('fleet' + os.sep + botname + os.sep + 'config') cfg.type = 'irc' cfg.name = botname if not opts: cfg.password = cfg.password or "" cfg.ssl = cfg.ssl or False cfg.port = cfg.port or 6667 cfg.server = cfg.server or "localhost" cfg.owner = cfg.owner or [] cfg.ipv6 = cfg.ipv6 or False cfg.nick = cfg.nick or "jsb" cfg.channels = [] return cfg if not cfg.channels: cfg.channels = [] if opts.enable: cfg.disable = 0 logging.warn("enabling %s bot in %s" % (botname, cfg.cfile)) if opts.password: cfg.password = opts.password if opts.ipv6: cfg.ipv6 = True else: cfg.ipv6 = cfg.ipv6 or False if opts.ssl: cfg.ssl = True else: cfg.ssl = cfg.ssl or False if opts.nossl: cfg.ssl = False if opts.port: cfg.port = opts.port or cfg.port or 6667 else: cfg.port = cfg.port or 6667 if opts.server: cfg.server = opts.server else: cfg.server = cfg.server or "localhost" if not cfg.owner: cfg.owner = [] if opts.owner and opts.owner not in cfg.owner: cfg.owner.append(opts.owner) if opts.ipv6: cfg.ipv6 = opts.ipv6 if opts.nick: cfg.nick = opts.nick else: cfg.nick = cfg.nick or "jsb" if opts.username: cfg.username = opts.username else: cfg.username = cfg.username or "jsonbot" if opts.channel: if not opts.channel in cfg.channels: cfg.channels.append(opts.channel) else: cfg.channels = cfg.channels or [] return cfg
def fishout(text, event): if event and not (event.bottype == "irc" or event.bottype == "botbase"): return text target = None if event and event.channel and event.channel.startswith("#"): target = event.channel if not target: u = users.getuser(event.userhost) if u: target = u.data.name if not target: return key = KeyStore(stripname(target)) if not key.data.key: logging.debug("FiSHout: No key found for target %s" % target) return text cipher = encrypt(key.data.key, text) return cipher
def makeircconfig(opts=None, botname=None): """ make config file based on options. """ if not opts: botname = botname or "default-irc" else: if not botname: botname = opts.name or "default-irc" botname = stripname(botname) from jsb.lib.config import Config cfg = Config('fleet' + os.sep + botname + os.sep + 'config') cfg.type = 'irc' cfg.name = botname if not opts: cfg.password = cfg.password or "" cfg.ssl = cfg.ssl or False cfg.port = cfg.port or 6667 cfg.server = cfg.server or "localhost" cfg.owner = cfg.owner or [] cfg.ipv6 = cfg.ipv6 or False cfg.nick = cfg.nick or "jsb" cfg.channels = [] return cfg if not cfg.channels: cfg.channels = [] if not cfg.disable: cfg.disable = False if opts.password: cfg.password = opts.password if opts.ipv6: cfg.ipv6 = True else: cfg.ipv6 = cfg.ipv6 or False if opts.ssl: cfg.ssl = True else: cfg.ssl = cfg.ssl or False if opts.nossl: cfg.ssl = False if opts.port: cfg.port = opts.port or cfg.port or 6667 else: cfg.port = cfg.port or 6667 if opts.server: cfg.server = opts.server else: cfg.server = cfg.server or "localhost" if not cfg.owner: cfg.owner = [] if opts.owner and opts.owner not in cfg.owner: cfg.owner.append(opts.owner) if opts.ipv6: cfg.ipv6 = opts.ipv6 if opts.nick: cfg.nick = opts.nick else: cfg.nick = cfg.nick or "jsb" if opts.username: cfg.username = opts.username else: cfg.username = cfg.username or "jsonbot" if opts.channel: if not opts.channel in cfg.channels: cfg.channels.append(opts.channel) else: cfg.channels = cfg.channels or [] return cfg
def handle_delete(bot, ievent): """ remove user. """ if not bot.ownercheck(ievent.userhost): ievent.reply('only owner can use delete') return if len(ievent.args) == 0: ievent.missing('<name>') return name = ievent.args[0] result = 0 name = stripname(name) name = name.lower() try: result = bot.users.delete(name) if result: ievent.reply('%s deleted' % name) return except KeyError: pass ievent.reply('no %s item in database' % name)