Esempio n. 1
0
class Triggers(object):
	"""Match/action triggers for a server.
	"""
	def __init__(self, commandFunc):
		self.runCommand = commandFunc
		self.triggers = OrderedDict()
		self.thr = None
		self._q = []

	def __hash__(self):
		"""For sets.
		"""
		return hash(self.triggers)

	def __eq__(self, other):
		"""Makes comparison for equality work reasonably.
		"""
		return self.triggers == other.triggers
	def __ne__(self, other):
		"""Makes comparison for equality work reasonably.
		"""
		return not self.__eq__(other)

	def get(self, name):
		"""Get and/or make the trigger object for the given name.
		"""
		if not self.triggers.get(name):
			self.triggers[name] = Trigger(self, name)
		return self.triggers[name]

	def addMatch(self, triggerName, matchSpec, matchName=""):
		"""Add one match to a trigger.
		triggerName should uniquely identify a set of matches and associated
		actions, to separate them from any other match/action sets.
		matchSpec should be a ParmLine where the event and parameter values are regexps.
		matchName can name the match arbitrarily.
		"""
		trigger = self.get(triggerName)
		trigger.addMatch(matchSpec, matchName)

	def addAction(self, triggerName, actionSpec, actionName=""):
		"""Add one action to a trigger.
		triggerName should uniquely identify a set of matches and associated
		actions, to separate them from any other match/action sets.
		actionSpec should be an action to perform.
		actionName can name the action arbitrarily.
		"""
		trigger = self.get(triggerName)
		trigger.addAction(actionSpec, actionName)

	def apply(self, parmline):
		"""Apply actions where there is a match.
		As many match/action sets as match will have their actions applied.
		"""
		# config file triggers first.
		[trigger.apply(parmline) for trigger in self.triggers.values()]
		# Then custom code triggers if any.
		trigger_cc.apply(self.server, parmline, self.runCommand)

	@classmethod
	def loadCustomCode(cls):
		"""Load custom trigger code if it exists.
		"""
		reload(trigger_cc)

	def queue(self, parmline):
		"""Queues a trigger check instead of applying it immediately.
		"""
		self._q.append(parmline)
		if not self.thr:
			thr = threading.Thread(target=self._queueWatch)
			thr.daemon = True
			thr.start()

	def _queueWatch(self):
		"""Watch the queue for things to do.
		Runs in its own thread as started by queue().
		"""
		while True:
			if not self._q:
				sleep(0.5)
				continue
			parmline = self._q.pop(0)
			self.apply(parmline)