Exemple #1
0
 def bind(self, bot=None, user=None, chan=None, force=False, dolog=None):
     """ bind event.bot event.user and event.chan to execute a command on it. """
     dolog = dolog or 'TICK' not in self.cbtype
     if dolog and not force and self.dontbind: logging.debug("dontbind is set on event . .not binding"); return
     if not force and self.bonded: logging.debug("already bonded") ; return
     dolog and logging.debug("starting bind on %s - %s" % (self.userhost, self.txt)) 
     target = self.auth or self.userhost
     bot = bot or self.bot
     if not self.chan:
         if chan: self.chan = chan
         elif self.channel: self.chan = ChannelBase(self.channel, bot.cfg.name)
         elif self.userhost: self.chan = ChannelBase(self.userhost, bot.cfg.name)
         if self.chan: dolog and logging.debug("channel bonded - %s" % self.chan.data.id)
     if not target: self.prepare(bot) ; self.bonded = True ; return
     if not self.user and target and not self.nodispatch:
         if user: u = user
         else: u = bot.users.getuser(target)
         if not u: u = bot.users.by_uid(target)
         if not u: 
             cfg = getmainconfig()
             if cfg.auto_register and self.iscommand:
                 u = bot.users.addguest(target, self.nick)
                 if u: logging.warn("auto_register applied")
                 else: logging.error("can't add %s to users database" % target)
         if u:
             msg = "!! %s -=- %s -=- %s -=- (%s) !!" % (u.data.name, self.usercmnd or "none", self.cbtype, self.bot.cfg.name)
             dolog and logging.warn(msg)
             self.user = u
         if self.user: dolog and logging.debug("user bonded from %s" % whichmodule())
     if not self.user and target: dolog and self.iscommand and logging.warn("no %s user found" % target) ; self.nodispatch = True
     self.prepare(bot)
     if self.bot: self.inchan = self.channel in self.bot.cfg.channels
     if not self.auth: self.auth = self.userhost
     self.bonded = True
     return self
Exemple #2
0
 def addjob(self, sleeptime, repeat, function, description="" , *args, **kw): 
     """ add a periodical job. """
     job = JobInterval(sleeptime, repeat, function, *args, **kw)
     job.group = calledfrom(sys._getframe())
     job.description = str(description) or whichmodule()
     self.jobs.append(job)
     return job.pid
Exemple #3
0
 def __init__(self, id, botname=None, type="notset"):
     if not id: raise NoChannelSet()
     if not botname: Persist.__init__(self, getdatadir() + os.sep + 'channels' + os.sep + stripname(id))
     else: Persist.__init__(self, getdatadir() + os.sep + 'fleet' + os.sep + stripname(botname) + os.sep + 'channels' + os.sep + stripname(id))
     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.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 "tl"
     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 []
Exemple #4
0
 def get(self, type, name, config={}):
     try:
         bot = self.makebot(type, name, config)
     except KeyError: logging.warn("no %s (%s) bot found" % (type, name)) ; bot = None
     except BotNotEnabled: logging.warn("%s (%s) bot is not enabled" % (type, name)) ; bot = None 
     except NoSuchBotType: logging.warn("no such bottype %s" % type) ; bot = None
     except Exception as ex: logging.error("%s: %s" % (name, (ex))) ; bot = None
     if not bot: logging.error("failed to get bot %s (%s) from %s" % (type, name, whichmodule(3)))
     return bot
Exemple #5
0
 def __init__(self, filename, verbose=False, input={}, ddir=None, nolog=False, *args, **kwargs):
     assert filename
     if ddir: ddir = normdir(ddir)
     if input: LazyDict.__init__(self, input, *args, **kwargs)
     else: LazyDict.__init__(self, *args, **kwargs)
     self.filename = filename
     self.setcfile(ddir, filename)
     if not self._comments: self._comments = {}
     logging.info("%s from %s" % (self._logname, whichmodule(2)))
     self.fromfile(self._cfile)
     self.cid = get_cid(self)
     self.init()
     if self.owner: logging.info("owner is %s" % self.owner)
     if "uuid" not in self: self.setuuid()
     if not self._origdir in self._cfile: raise WrongFileName("%s not in %s" % (self._origdir, self._cfile))
Exemple #6
0
 def doit(self, bot, event, target, direct=False):
     """ do the dispatching. """
     if not target.enable: return
     if target.modname in event.chan.data.denyplug:
          logging.warn("%s is denied in channel %s - %s" % (target.plugname, event.channel, event.userhost))
          return
     id = event.auth or event.userhost
     event.iscommand = True
     event.how = event.how or target.how or "overwrite"
     event.thecommand = target
     aliascheck(event)
     logging.warning('dispatching %s (%s)' % (event.usercmnd, bot.cfg.name))
     try:
         if direct or event.direct: target.func(bot, event)
         elif target.threaded and not event.nothreads:
             logging.warning("launching thread for %s (%s)" % (event.usercmnd, bot.cfg.name))
             t = start_bot_command(target.func, (bot, event))
             event.thread = t
         else: event.dontclose = False; cmndrunner.put(target.speed or event.speed, target.modname, target.func, bot, event)
     except Exception as ex:
         logging.error('%s - error executing %s' % (whichmodule(), str(target.func)))
         raise
     return event
Exemple #7
0
 def register(self, cbtypes, cbs=None, userhosts=None, event=None, queue=None):
     """ add a wait object to the waiters dict. """
     logging.warn("waiter - registering wait object: %s - %s" % (str(cbtypes), str(userhosts)))
     key = str(uuid.uuid4())
     self.waiters[key] = Wait(cbtypes, cbs, userhosts, modname=whichmodule(), event=event, queue=queue)
     return key
Exemple #8
0
 def init(self):
     """ initialize the config object. """
     if not self._comments: self._comments = {}
     if self._filename == 'mainconfig':
         self._comments["whitelist"] = "# - whitelist used to allow ips .. bot maintains this"
         self.setdefault("whitelist", [])
         self._comments["blacklist"] = "# - blacklist used to deny ips .. bot maintains this"
         self.setdefault("blacklist", [])
         self.setdefault('owner', [])
         self._comments["loglist"] = "# - loglist .. maintained by the bot."
         self.setdefault('loglist',  [])
         self._comments["loglevel"] = "# - loglevel of all bots"
         self.setdefault('loglevel',  "warn")
         self._comments["loadlist"] = "# - loadlist .. not used yet."
         self.setdefault('loadlist', [])
         self._comments["quitmsg"] = "# - message to send on quit"
         self.setdefault('quitmsg', "http://github.com/feedbackflow/tl")
         self._comments["dotchars"] = "# - characters to used as seperator."
         self.setdefault('dotchars',  ", ")
         self._comments["floodallow"] = "# - whether the bot is allowed to flood."
         self.setdefault('floodallow', 1)
         self._comments["auto_register"] = "# - enable automatic registration of new users."
         self.setdefault('auto_register', 0)
         self._comments["guestasuser"] = "******"
         self.setdefault('guestasuser', 0)
         self._comments["globalcc"] = "# - global control character"
         self.setdefault('globalcc', "")
         self._comments["app_id"] = "# - application id used by appengine."
         self.setdefault('app_id', "tl")
         self._comments["appname"] = "# - application name as used by the bot."
         self.setdefault('appname', "T I M E L I N E")
         self._comments["domain"] = "# - domain .. used for WAVE."
         self.setdefault('domain', "")
         self._comments["color"] = "# - color used in the webconsole."
         self.setdefault('color', "")
         self._comments["colors"] = "# - enable colors in logging."
         self.setdefault('colors', "")
         self._comments["memcached"] = "# - enable memcached."
         self.setdefault('memcached', 0)
         self._comments["allowrc"] = "# - allow execution of rc files."
         self.setdefault('allowrc', 0)
         self._comments["allowremoterc"] = "# - allow execution of remote rc files."
         self.setdefault('allowremoterc', 0)
         self._comments['dbenable'] = "# - enable database support"
         self.setdefault('dbenable', 1)
         self._comments['dbtype'] = "# - type of database .. sqlite or mysql at this time."
         self.setdefault('dbtype', 'sqlite')
         self._comments['dbname'] = "# - database name"
         self.setdefault('dbname', "main.db")
         self._comments['dbhost'] = "# - database hostname"
         self.setdefault('dbhost', "localhost") 
         self._comments['dbuser'] = "******"
         self.setdefault('dbuser', "bart")
         self._comments['dbpasswd'] = "# - database password"
         self.setdefault('dbpasswd', "mekker2")
         self._comments['ticksleep'] = "# - nr of seconds to sleep before creating a TICK event."
         self.setdefault('ticksleep', 1)
         self._comments['bindhost'] = "# - host to bind to"
         self.setdefault("bindhost", "")
     self['createdfrom'] = whichmodule()
     if 'xmpp' in self._cfile: self.setdefault('fulljids', 1)
     if 'fleet' in self._cfile:
         self.setdefault('nick', "timeliner")
         self.setdefault('disable', 1)
         self.setdefault("owner", [])
         self.setdefault("user", "")
         self.setdefault("host", "")
         self.setdefault("server", "")
         self.setdefault("ssl", 0)
         self.setdefault("ipv6", 0)
         self.setdefault("channels", [])
     self.setdefault("port", "")
     self.setdefault("password", "")
     self._comments['datadir'] = "# - directory to store bot data in."
     self._comments["owner"] = "# - owner of the bot."
     self._comments["uuid"] = "# - bot generated uuid for this config file."
     self._comments["user"] = "******"
     self._comments["host"] = "# - host part of the user, derived from user var."
     self._comments["server"] = "# - server to connect to (only when different from users host)."
     self._comments["password"] = "******"
     self._comments["port"] = "# - port to connect to (IRC)."
     self._comments["ssl"] = "# - whether to enable ssl (set to 1 to enable)."
     self._comments["ipv6"] = "# - whether to enable ssl (set to 1 to enable)."
     self._comments["name"] = "# - the name of the bot."
     self._comments["disable"] = "# - set this to 0 to enable the bot."
     self._comments["followlist"] = "# - who to follow on the bot .. bot maintains this list."
     self._comments["networkname"] = "# - networkname .. not used right now."
     self._comments["type"] = "# - the bot's type."
     self._comments["nick"] = "# - the bot's nick."
     self._comments["channels"] = "# - channels to join."
     self._comments["cfile"] = "# - filename of this config file. edit this when you move this file."
     self._comments["createdfrom"] = "# - function that created this config file. bot generated"
     self._comments["dir"] = "# - directory in which this config file lives."
     self._comments["isdb"] = "# - whether this config file lives in the database and not on file."
     self._comments["filename"] = "# - filename of this config file."
     self._comments["username"] = "******"
     self._comments["fulljids"] = "# - use fulljids of bot users (used in non anonymous conferences."
     self._comments["servermodes"] = "# - string of modes to send to the server after connect."
     self._comments["realname"] = "# - name used in the ident of the bot."
     self._comments["onconnect"] = "# - string to send to server after connect."
     self._comments["onconnectmode"] = "# - MODE string to send to server after connect."
     self._comments["realname"] = "# - mode string to send to the server after connect."
     self._comments["issaved"] = "# - whether this config file has been saved. "
     self._comments["origdir"] = "# - original datadir for this configfile. "
     self._comments["origname"] = "# - displayable name of the config file name. "
     return self
Exemple #9
0
    def tofile(self, filename=None, stdout=False):
        """ save config object to file. """
        if not filename: filename = self._cfile
        if not filename: raise Exception("no cfile found  - %s" % whichmodule(3))
        logging.warn("%s saved" % self._logname)
        if filename.startswith(os.sep): d = [os.sep,]
        else: d = []
        for p in filename.split(os.sep)[:-1]:
            if not p: continue
            d.append(p)
            ddir = os.sep.join(d)
            if not os.path.isdir(ddir):
                logging.debug("persist - creating %s dir" % ddir)
                try: os.mkdir(ddir)
                except OSError as ex:
                    logging.error("persist - not saving - failed to make %s - %s" % (ddir, str(ex)))
                    return
        written = []
        curitem = None
        later = []
        try:
            if stdout: configtmp = sys.stdout
            else: configtmp = open(filename + '.tmp', 'w')
            configtmp.write('# ===========================================================\n#\n')
            configtmp.write("# T I M E L I N E CONFIGURATION FILE - %s\n" % filename)
            configtmp.write("#\n")
            configtmp.write('# last changed on %s\n#\n' % time.ctime(time.time()))
            configtmp.write("# This file contains configration data for the T I M E L I N E.\n")
            configtmp.write('# Variables are defined by "name = json value" pairs.\n')
            configtmp.write('# Make sure to use " in strings.\n#\n')
            configtmp.write('# The bot can edit this file!.\n#\n')
            configtmp.write('# ===========================================================\n\n')
            teller = 0
            keywords = list(self.keys())
            keywords.sort()
            for keyword in keywords:
                value = self[keyword]
                if keyword in written: continue
                if keyword.startswith("_"): continue
                if keyword in ['origdir', 'origname', 'issaved', 'blacklist', 'whitelist', 'followlist', 'uuid', 'whitelist', 'datadir', 'name', 'createdfrom', 'cfile', 'filename', 'dir', 'isdb']: later.append(keyword) ; continue
                if keyword == 'jsondb': continue
                if keyword == 'optionslist': continue
                if keyword == 'gatekeeper': continue
                if keyword == "_comments": continue
                if self._comments and keyword in self._comments:
                    configtmp.write(self._comments[keyword] + "\n")
                curitem = keyword
                try: configtmp.write('%s = %s\n' % (keyword, json.dumps(value)))
                except TypeError: logging.error("%s - can't serialize %s" % (filename, keyword)) ; continue
                teller += 1
                #configtmp.write("\n")
            configtmp.write('\n\n# ============================================================\n#\n')
            configtmp.write("# bot generated stuff.\n#\n")
            configtmp.write('# ============================================================\n\n')
            for keyword in later:
                if self._comments and keyword in self._comments:
                    configtmp.write(self._comments[keyword] + "\n")
                curitem = keyword
                value = self[keyword]
                try: configtmp.write(keyword + " = " + json.dumps(value) + "\n")
                except TypeError: logging.error("%s - can't serialize %s" % (filename, keyword)) ; continue
                teller += 1
                #configtmp.write("\n")
            if not "mainconfig" in filename and self._comments:
                try:
                    configtmp.write('\n\n# ============================================================\n#\n')
                    configtmp.write("# possible other config variables.\n#\n")
                    configtmp.write('# ============================================================\n\n')
                    items = list(self._comments.keys())
                    keys = list(self.keys())
                    do = []
                    for var in items:
                        if var not in keys: do.append(var)
                    do.sort()
                    for var in do:
                         configtmp.write("# %s -=- %s\n" % (var, self._comments[var]))
                    configtmp.write("\n\n")
                except Exception as ex: handle_exception()
            else: configtmp.write("\n\n# tl can run multiple bots at once. see %s/config/fleet for their configurations.\n\n" % self.origdir)
            if not stdout: 
                configtmp.close()
                os.rename(filename + '.tmp', filename)
            return teller

        except Exception as ex:
            handle_exception()
            logging.error("ERROR WRITING %s CONFIG FILE: %s .. %s" % (filename, str(ex), curitem))
Exemple #10
0
 def wrapper(*args, **kw):
     job = JobInterval(86400, 0, function, *args, **kw)
     job.group =  group
     job.description = whichmodule()
     periodical.jobs.append(job)
     logging.warb('new interval job %d running daily' % job.id())
Exemple #11
0
 def wrapper(*args, **kw):
     job = JobInterval(1, 0, function, *args, **kw)
     job.group = group
     job.description = whichmodule()
     periodical.jobs.append(job)
     logging.debug('new interval job %d running per second' % job.id())
Exemple #12
0
 def wrapper(*args, **kw):
     job = JobAt(start, interval, repeat, function, *args, **kw)
     job.group = group
     job.description = whichmodule()
     periodical.jobs.append(job)
Exemple #13
0
 def wrapper(*args, **kw):
     job = JobInterval(sleeptime, repeat, function, *args, **kw)
     job.group = group
     job.description = whichmodule()
     periodical.jobs.append(job)
     logging.warn('new interval job %d with sleeptime %d' % (job.id(), sleeptime))
Exemple #14
0
 def makebot(self, type, name, config={}, domain="", showerror=False):
     """ create a bot .. use configuration if provided. """
     if not name: raise RequireError("name is not provided")
     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))
         raise BotNotEnabled(name)
     if not type: type = self.data.types.get(name)
     if not type: cfg.type or logging.error("no type found for %s bot" % name) ; 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 NoSuchBotType()
     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)
     bot = BotFactory().create(type, cfg)
     return bot
Exemple #15
0
 def __setattr__(self, attr, value):
     """ set attribute. """
     if not self.overload and attr in self and type(self[attr]) in [types.FunctionType, types.MethodType]:
         mod = whichmodule(2)
         raise Exception("lazydict - cannot change a function of method: %s - called from %s" % (attr, mod))
     self[attr] = value