Exemplo n.º 1
0
 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()
Exemplo n.º 2
0
def savealiases(ddir=None):
    """ return global aliases. """
    global aliases
    if aliases:
        logging.warn("saving aliases")
        from tl.lib.persist import Persist
        from tl.utils.lazydict import LazyDict
        d = ddir or getdatadir()
        p = Persist(d + os.sep + "run" + os.sep + "aliases")
        p.data = aliases
        p.save()
    return aliases
Exemplo n.º 3
0
class Config(LazyDict):

    """ 
        config class is a dict containing json strings. is writable to file 
        and human editable.

    """

    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))

    def setcfile(self, ddir, filename):
        self._origname = filename
        self._logname = "config" + os.sep + filename
        self._origdir = ddir or getdatadir()
        self._filename = filename or 'mainconfig'
        self._datadir = ddir or getdatadir()
        if self._datadir[-1] != os.sep: self._datadir += os.sep
        self._dir = self._datadir + 'config'
        self._cfile = self._dir + os.sep + self._filename
        logging.debug("self._cfile is %s" % self._cfile)
        self.cfile = self._cfile

    def setuuid(self, save=True):
        logging.debug("setting uuid")
        self.uuid = str(uuid.uuid4())
        if save: self.save()

    def __deepcopy__(self, a):
        """ accessor function. """
        cfg = Config(self._filename, input=self, nolog=True)
        return cfg

    def __getitem__(self, item):
        """ accessor function. """
        if item not in self: return None
        else: return LazyDict.__getitem__(self, item)

    def merge(self, cfg):
        """ merge in another cfg. """
        self.update(cfg)

    def set(self, item, value):
        """ set item to value. """
        LazyDict.__setitem__(self, item, value)

    def fromdb(self):
        """ read config from database. """
        from tl.lib.persist import Persist
        tmp = Persist(self._cfile)
        logging.debug("fromdb - %s - %s" % (self._cfile, tmp.data.tojson()))
        self.update(tmp.data)

    def todb(self):
        """ save config to database. """
        cp = dict(self)
        del cp['jsondb']
        if not self.jsondb:
            from tl.lib.persist import Persist
            self.jsondb = Persist(self._cfile)
        self.jsondb.data = cp
        self.jsondb.save()

    def fromfile(self, filename=None):
        """ read config object from filename. """
        curline = ""
        fname = filename or self._cfile
        if not fname: raise Exception("no name found - %s - %s" % (self._cfile, self.dump()))
        if not os.path.exists(fname): logging.warn("config file %s doesn't exist yet" % fname) ; return False 
        comment = ""
        for line in open(fname, 'r'):
            curline = line
            curline = curline.strip()
            if curline == "": continue
            if curline.startswith('#'): comment = curline; continue
            if True:
                try:
                    key, value = curline.split('=', 1)
                    kkey = key.strip()
                    self[kkey] = json.loads(str(value.strip()))
                    if comment:
                        if not self._comments: self._comments = {}
                        self._comments[kkey] = comment 
                    comment = ""
                except ValueError: logging.error("skipping line - unable to parse: %s" % line)
        #self.cfile = fname
        return

    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))

    @savelocked
    def save(self):
        """ save the config. """
        logging.info("save called from %s" % calledfrom(sys._getframe(2)))
        self.issaved = True
        if self.isdb: self.todb()
        else: self.tofile(self._cfile)
     
    def load_config(self, verbose=False):
        """ load the config file. """
        if self.isdb: self.fromdb()
        else: self.fromfile(self._filename)
        self.init()
        if verbose: logging.debug('%s' % self.dump())

    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
        
    def reload(self):
        """ reload the config file. """
        self.load_config()
        return self
Exemplo n.º 4
0
 def save(self):
     """ save the hubbub items data. """
     Persist.save(self)
     self.itemslists.save()
     self.markup.save()