예제 #1
0
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))