Commits

chmullig committed d17c96a

Added some new arguments to the @contains decorator so you can specify channels to only run in, or never run it, and a rate (0.0 - 1.0) for it to run. Also fixed the ticket unit tests because they didn't handle negative change well.

Comments (0)

Files changed (2)

pmxbot/botbase.py

 		lc_cmd = msg.split()[0]
 		res = None
 		secret = False
-		for typ, name, f, doc in sorted(_handler_registry, key=lambda x: (_handler_sort_order[x[0]], 0-len(x[1]), x[1])):
+		for typ, name, f, doc, channels, exclude, rate in _handler_registry:
 			if typ in ('command', 'alias') and lc_cmd == '!%s' % name:
 				try:
 					if ' ' in msg:
 					traceback.print_exc()
 				break
 			elif typ in('contains', '#') and name in lc_msg:
-				try:
-					res = f(c, e, channel, nick, msg)
-				except Exception, e:
-					res = "DO NOT TRY TO BREAK PMXBOT!!!"
-					res += '\n%s' % e
-					traceback.print_exc()
-				break
+				if (channels and channel in channels) \
+				and (exclude and channel not in exclude) \
+				and (rate == 1.0 or random.random() <= rate):
+					try:
+						res = f(c, e, channel, nick, msg)
+					except Exception, e:
+						res = "DO NOT TRY TO BREAK PMXBOT!!!"
+						res += '\n%s' % e
+						traceback.print_exc()
+					break
 		def out(s):
 			if s.startswith('/me '):
 				c.action(channel, s.split(' ', 1)[-1].lstrip())
 _handler_sort_order = {'command' : 1, 'alias' : 2, 'contains' : 3}
 _delay_registry = []
 
-def contains(name, doc=None):
+def contains(name, channels=None, exclude=None, rate=1.0, priority=1, doc=None):
 	def deco(func):
-		if name == '#':
-			_handler_registry.append(('#', name.lower(), func, doc))
+		if name == '#' or priority == 2:
+			_handler_registry.append(('#', name.lower(), func, doc, channels, exclude, rate))
 		else:
-			_handler_registry.append(('contains', name.lower(), func, doc))
+			_handler_registry.append(('contains', name.lower(), func, doc, channels, exclude, rate))
+		_handler_registry.sort(key=lambda x: (_handler_sort_order[x[0]], 0-len(x[1]), x[1]))
 		return func
 	return deco
 
 def command(name, aliases=None, doc=None):
 	def deco(func):
-		_handler_registry.append(('command', name.lower(), func, doc))
+		_handler_registry.append(('command', name.lower(), func, doc, None, None, None))
 		if aliases:
 			for a in aliases:
 				if not a.endswith(' '):
 					pass
 					#a += ' '
-				_handler_registry.append(('alias', a, func, doc))
+				_handler_registry.append(('alias', a, func, doc, None, None, None))
+		_handler_registry.sort(key=lambda x: (_handler_sort_order[x[0]], 0-len(x[1]), x[1]))
 		return func
 	return deco
 	

tests/unit/test_commands.py

 		GOOG at 4:00pm (ET): 484.81 (1.5%)
 		"""
 		res = pmxbot.ticker(c, e, "#test", "testrunner", "goog")
-		assert re.match(r"""^GOOG at \d{1,2}:\d{2}(?:am|pm) \([A-z]{1,3}\): \d{2,4}.\d{2} \(\d{1,3}.\d%\)$""", res)
+		assert re.match(r"""^GOOG at \d{1,2}:\d{2}(?:am|pm) \([A-z]{1,3}\): \d{2,4}.\d{2} \(\-?\d{1,3}.\d%\)$""", res), res
 		
 	def test_ticker_yougov(self):
 		"""
 		YOU.L at 10:37am (ET): 39.40 (0.4%)
 		"""
 		res = pmxbot.ticker(c, e, "#test", "testrunner", "you.l")
-		assert re.match(r"""^YOU.L at \d{1,2}:\d{2}(?:am|pm) \([A-z]{1,3}\): \d{1,4}.\d{2} \(\d{1,3}.\d%\)$""", res)
+		assert re.match(r"""^YOU.L at \d{1,2}:\d{2}(?:am|pm) \([A-z]{1,3}\): \d{1,4}.\d{2} \(\-?\d{1,3}.\d%\)$""", res), res
 		
 	def test_ticker_dow(self):
 		"""
 		^DJI at 10:37am (ET): 39.40 (0.4%)
 		"""
 		res = pmxbot.ticker(c, e, "#test", "testrunner", "^dji")
-		assert re.match(r"""^\^DJI at \d{1,2}:\d{2}(?:am|pm) \([A-z]{1,3}\): \d{4,5}.\d{2} \(\d{1,3}.\d%\)$""", res)
+		assert re.match(r"""^\^DJI at \d{1,2}:\d{2}(?:am|pm) \([A-z]{1,3}\): \d{4,5}.\d{2} \(\-?\d{1,3}.\d%\)$""", res), res
 		
 	def test_pick_or(self):
 		"""