Ejemplo n.º 1
0
  def __init_config(self):
    """search for and set all config options to default or user-specified"""

    dup_plugins = False
    duplicates = None

    # we need to get cmd_dir and chat_proto from the config file first
    # don't log the first set of default opts to avoid duplicates later
    self.conf = Config(self.conf_file)
    self.conf.reload(log=False)

    # check for duplicate plugin files
    (_,files) = util.rlistdir(self.opt('cmd_dir'))
    files = [os.path.splitext(x)[0] for x in files if
        ('__init__' not in x and x.split(os.path.extsep)[-1]=='py')]
    files = sorted(files,key=os.path.basename)
    files = [x for x in files if os.path.basename(x) not in self.opt('disable')]
    if self.opt('enable'):
      files = [x for x in files if os.path.basename(x) in self.opt('enable')]

    base_names = [os.path.basename(x) for x in files]
    if len(files)!=len(set(base_names)):
      dup = set([x for x in base_names if base_names.count(x)>1])
      dup_plugins = 'Multiple plugins named %s' % list(dup)

    # register config options from plugins
    for f in files:
      (d,f) = (os.path.dirname(f),os.path.basename(f))

      # import errors will be logged and handled in __load_plugins
      try:
        mod = util.load_module(f,d)
      except:
        continue

      duplicates = (not self.__load_conf(mod,f) or duplicates)

    # load protocol config options if protocols were loaded without errors
    if [x for x in self.opt('protocols').values() if x is not None]:
      for pname in self.opt('protocols'):
        mod = util.load_module('sibyl_'+pname,'protocols')
        duplicates = (not self.__load_conf(mod,pname) or duplicates)

    # now that we know all the options, read every option from the config file
    return (self.conf.reload(),dup_plugins,duplicates)
Ejemplo n.º 2
0
  def __load_plugins(self,d):
    """recursively load all plugins from all sub-directories"""

    success = True

    # build file list before-hand so we can check dependencies
    (_,files) = util.rlistdir(d)
    files = [x for x in files if
        (x.split(os.path.extsep)[-1]=='py' and '__init__' not in x)]
    files = sorted(files,key=os.path.basename)
    mods = {}

    # load hooks from every file
    for f in files:
      (d,f) = (os.path.dirname(f),os.path.basename(f))
      f = os.path.splitext(f)[0]

      # if "enable" is specified, only load plugins found in "enable"
      # the "disable" option overrides anything in the "enable" option
      if ((f not in self.opt('disable')) and
          ((not self.opt('enable')) or (f in self.opt('enable')))):
        self.log.info('Loading plugin "%s"' % f)

        try:
          mod = util.load_module(f,d)
        except Exception as e:
          msg = 'Error loading plugin "%s"' % f
          self.log_ex(e,msg)
          self.errors.append('(startup.sibyl) '+msg)
          continue

        mods[f] = mod
        success = (self.__load_funcs(mod,f) and success)
      else:
        self.log.debug('Skipping plugin "%s" (disabled in config)' % f)

    # check dependencies
    for (name,mod) in mods.items():
      if hasattr(mod,'__depends__'):
        for dep in mod.__depends__:
          if dep not in mods:
            success = False
            self.log.critical('Missing dependency "%s" from plugin "%s"'
                % (dep,name))
      if hasattr(mod,'__wants__'):
        for dep in mod.__wants__:
          if dep not in mods:
            self.log.warning('Missing plugin "%s" limits funcionality of "%s"'
                % (dep,name))

    self.plugins = sorted(mods.keys())

    return success
Ejemplo n.º 3
0
    def parse_protocols(self, opt, val):
        """parse the protocols and return the subclasses"""

        val = util.split_strip(val, ',')
        protocols = {}
        success = False

        for proto in val:

            protocols[proto] = None
            fname = os.path.join('protocols',
                                 'sibyl_' + proto + os.path.extsep + 'py')
            if not os.path.isfile(fname):
                self.log('critical',
                         'No matching file in protocols/ for "%s"' % proto)
                continue

            try:
                mod = util.load_module('sibyl_' + proto, 'protocols')
                for (name, clas) in inspect.getmembers(mod, inspect.isclass):
                    if issubclass(clas, Protocol) and clas != Protocol:
                        protocols[proto] = clas
                if protocols[proto] is None:
                    self.log(
                        'critical',
                        'Protocol "%s" does not contain a lib.protocol.Protocol subclass'
                        % proto)

            except Exception as e:
                full = traceback.format_exc(e)
                short = full.split('\n')[-2]
                self.log(
                    'critical',
                    'Exception importing protocols/%s:' % ('sibyl_' + proto))
                self.log('critical', '  %s' % short)
                self.log('debug', full)

        if None in protocols.values():
            raise ValueError
        return protocols
Ejemplo n.º 4
0
  def parse_protocols(self,opt,val):
    """parse the protocols and return the subclasses"""

    val = util.split_strip(val,',')
    protocols = {}
    success = False

    for proto in val:

      protocols[proto] = None
      fname = os.path.join('protocols','sibyl_'+proto+os.path.extsep+'py')
      if not os.path.isfile(fname):
        self.log('critical','No matching file in protocols/ for "%s"' % proto)
        continue

      try:
        mod = util.load_module('sibyl_'+proto,'protocols')
        for (name,clas) in inspect.getmembers(mod,inspect.isclass):
          if issubclass(clas,Protocol) and clas!=Protocol:
            protocols[proto] = clas
        if protocols[proto] is None:
          self.log('critical',
              'Protocol "%s" does not contain a lib.protocol.Protocol subclass'
              % proto)

      except Exception as e:
        full = traceback.format_exc(e)
        short = full.split('\n')[-2]
        self.log('critical','Exception importing protocols/%s:'
            % ('sibyl_'+proto))
        self.log('critical','  %s' % short)
        self.log('debug',full)

    if None in protocols.values():
      raise ValueError
    return protocols
Ejemplo n.º 5
0
ext = os.path.extsep
pwd = os.path.abspath(os.path.dirname(__file__))
ignore = ['__init__',os.path.basename(__file__).split(ext)[0],'skeleton']
files = [x for x in os.listdir(pwd) if x.startswith('sibyl_') and
    x.endswith(ext+'py') and x.split(ext)[0] not in ignore]

__all__ = ['PROTOCOLS','FAILED']
PROTOCOLS = {}
FAILED = []

for mod in files:

  fname = mod.split(ext)[0]
  protocol = fname.split('_')[1]

  try:
    mod = load_module(fname,pwd)
  except:
    FAILED.append(protocol)
    continue
  
  for (name,clas) in inspect.getmembers(mod,inspect.isclass):
    if issubclass(clas,Protocol) and clas!=Protocol:
      PROTOCOLS[fname] = {'class':clas,'config':None}
      __all__.append(name)
      exec('from %s import %s' % (fname,name))

  for (name,func) in inspect.getmembers(mod,inspect.isfunction):
    if getattr(func,'_sibylbot_dec_conf',False):
      PROTOCOLS[fname]['config'] = func