class Server(BaseServer): def __init__(self, opts): BaseServer.__init__(self, opts) self.addons = None #dispatcher placeholder (probably not needed) self.dispatcher = None # TODO: fix the complicated relationship between Factory<->Settings<->Container # also the relationship between Dispatcher<->Settings<->Dispatcher self.container = Container(self) self._factory = BurlyBotFactory(self) def initializeReload(self): # Addons should only be created once if self.addons is None: self.addons = _ADDONS() else: self.addons.clear() # Dispatcher should only be created once. if self.dispatcher is None: #create dispatcher: self.dispatcher = Dispatcher(self) #else reload it else: self.dispatcher.reload() def __getattr__(self, name): # get Server setting if set, else fall back to global Settings if name in self.__dict__: return getattr(self, name) else: return getattr(Settings, name) def getOptions(self, opts, **kwargs): vals = [] for opt in opts: vals.append(self.getOption(opt, **kwargs)) return vals # if channel or server is set, retrieve for that specific thing. # if channel or server is False, retrieve "global" for that thing. # TODO: make sure this optimized as it can be def getOption(self, opt, module=None, channel=None, server=None, default=NoDefault, setDefault=True, inreactor=False): if opt in KEYS_DENY: raise ValueError("Access denied. (%s)" % opt) if module: if server or server is None: # try searching for option in a server object if not server is None: try: moduleopts = Settings.servers[server].moduleopts except KeyError: raise ValueError("Server (%s) not found" % server) else: moduleopts = self.moduleopts if module in moduleopts: mod = moduleopts[module] if channel and "_channels" in mod and channel in mod["_channels"] and opt in mod["_channels"][channel]: value = mod["_channels"][channel][opt] if type(value) in TYPE_COPY: # copy value if compound datatype return deepcopy(value) if inreactor else blockingCallFromThread(reactor, deepcopy, value) else: return value if opt in mod: value = mod[opt] if type(value) in TYPE_COPY: # copy value if compound datatype return deepcopy(value) if inreactor else blockingCallFromThread(reactor, deepcopy, value) else: return value # fall back to global moduleopts (or server was False) moduleopts = Settings.moduleopts # duplicated code from above, micro-optimization because bad. if module in moduleopts: mod = moduleopts[module] if channel and "_channels" in mod and channel in mod["_channels"] and opt in mod["_channels"][channel]: value = mod["_channels"][channel][opt] if type(value) in TYPE_COPY: # copy value if compound datatype return deepcopy(value) if inreactor else blockingCallFromThread(reactor, deepcopy, value) else: return value if opt in mod: value = mod[opt] if type(value) in TYPE_COPY: # copy value if compound datatype return deepcopy(value) if inreactor else blockingCallFromThread(reactor, deepcopy, value) else: return value if default is NoDefault: raise AttributeError("No setting (%s) for module: %s" % (opt, module)) else: if setDefault: moduleopts.setdefault(module, {})[opt] = default return default #non-module (core) options if server is None: server = self elif server: if not server in Settings.servers: raise ValueError("Server label (%s) not found." % server) server = Settings.servers[server] if server and opt in KEYS_SERVER_SET: value = getattr(self, opt) else: if not server or server is self: if opt not in KEYS_MAIN_SET: raise ValueError("Settings has no option: (%s) to get." % opt) else: value = getattr(Settings, opt) else: #case where a server setting is specifically attempted to be got, but it's not in KEYS_SERVER # instead of falling back to KEYS_MAIN, raise error raise ValueError("Server setting has no option: (%s) to get." % opt) if opt in KEYS_COPY: # copy value if compound datatype return deepcopy(value) if inreactor else blockingCallFromThread(reactor, deepcopy, value) else: return value def setOption(self, opt, value, module=None, channel=None, server=None): if opt in KEYS_DENY: raise ValueError("Access denied. (%s)" % opt) if type(value) in TYPE_COPY: value = deepcopy(value) # copy value if compound datatype if module: if server or server is None: # try searching for option in a server object if not server is None: try: moduleopts = Settings.servers[server].moduleopts except KeyError: raise ValueError("Server (%s) not found" % server) else: moduleopts = self.moduleopts mod = moduleopts.setdefault(module, {}) if channel: mod.setdefault("_channels", {}).setdefault(channel, {})[opt] = value else: mod[opt] = value return # if server was False, (setting "global") moduleopts = Settings.moduleopts # duplicated code from above, micro-optimization because bad. mod = moduleopts.setdefault(module, {}) if channel: mod.setdefault("_channels", {}).setdefault(channel, {})[opt] = value else: mod[opt] = value else: if server is None: server = self elif server: if not server in Settings.servers: raise ValueError("Server label (%s) not found." % server) server = Settings.servers[server] if server and opt in KEYS_SERVER_SET: setattr(self, opt, value) else: if not server or server is self: if opt not in KEYS_MAIN_SET: raise ValueError("Settings has no option: (%s) to set." % opt) else: setattr(Settings, opt, value) else: #case where a server setting is specifically attempted to be set, but it's not in KEYS_SERVER # instead of falling back to KEYS_MAIN, raise error raise ValueError("Server settings has no option: (%s) to set." % opt) def getModule(self, modname): if not self.isModuleAvailable(modname): raise ConfigException("Module (%s) is not available." % modname) else: return Dispatcher.MODULEDICT.get(modname) def isModuleAvailable(self, modname): return (modname not in self.denymodules) and (modname in Dispatcher.MODULEDICT) def getAddon(self, addonname): try: modname, f = self.addons._getModuleAddon(addonname) except KeyError: raise AttributeError("No provider for %s" % addonname) if self.isModuleAvailable(modname): return f else: raise AttributeError("Provider %s is not available because module (%s) is not available." % (addonname, modname))