Chris Mulligan  committed 7d8a066

Added local extensions - you create a python file with @commands/@contains entries,
specify the path to that file in your yaml conf, and it will be execed in the pmxbot
context to add your commands as if they were build in. Pretty awesome! Two examples are included:
* yahoolunch
* paste - using

  • Participants
  • Parent commits 8884c80
  • Branches default

Comments (0)

Files changed (5)

+syntax: glob
 daemontools to make it automatically restart if it crashes. 
+Adding a custom, local feature
+Adding a new feature is easy, you just need to add them to a local_extensions
+file, following the established convention. The files to load are specified
+in the local_extensions configuration setting. All files in the list are run
+with execfile, so they inherit the existing globals. As a result you can
+assume that most things you'll need are already imported, like @command,
+@contains, re, urllib, httplib2 and get_html. There's an example in
+that you can use as the basis for yours..
-Writing a new feature
-Adding new features is very easy, you just need to add them to
-following the established convention. A command gets the @command deocator::
+A command (!g) gets the @command deocator::
   @command("tinytear", aliases=('tt', 'tear', 'cry'), doc="I cry a tiny tear for you.")
   def tinytear(client, event, channel, nick, rest):
   		return "/me sits and cries as a single tear slowly trickles down its cheek"
-A response uses the @contains decorator::
+A response (when someone says something) uses the @contains decorator::
   def yay_sor(client, event, channel, nick, rest):
   	karmaChange(botbase.logger.db, 'sql on rails', 1)
   	return "Only 76,417 lines..."
       channel : "#bottwo"
       linkurl : ""
       url     : ""
+local_extensions: ['']
+Local pmxbot extensions, incude the path to this file in your config.yaml.
+@command("yahoolunch", doc="Find a random neary restaurant for lunch using Yahoo Local. Defaults to 1 mile radius, but append Xmi to the end to change the radius.")
+def lunch(client, event, channel, nick, rest):
+    yahooid = "eeGETYOUROWN.yu"
+    from import LocalSearch
+    location = rest.strip()
+    if location.endswith('mi'):
+        radius, location = ''.join(reversed(location)).split(' ', 1)
+        location = ''.join(reversed(location))
+        radius = ''.join(reversed(radius))
+        radius = float(radius.replace('mi', ''))
+    else:
+        radius = 1
+    srch = LocalSearch(app_id=yahooid, category=96926236, results=20, query="lunch", location=location, radius=radius)
+    res = srch.parse_results()
+    max = res.totalResultsAvailable if res.totalResultsAvailable < 250 else 250
+    num = random.randint(1, max) - 1
+    if num < 19:
+        choice = res.results[num]
+    else:
+        srch = LocalSearch(app_id=yahooid, category=96926236, results=20, query="lunch", location=location, start=num)
+        res = srch.parse_results()
+        choice = res.results[0]
+    return '%s @ %s - %s' % (choice['Title'], choice['Address'], choice['Url'])
+@command("paste", aliases=(), doc="Drop a link to your latest paste on")
+def paste(client, event, channel, nick, rest):
+    request = urllib.urlopen("" % nick)
+    post_url = request.geturl()
+    if post_url and request.getcode() == 200:
+        return post_url
+    else:
+        return "hmm.. I didn't find a recent paste of yours, %s. Checkout" % nick

File pmxbot/

 	config_file = sys.argv[1]
 	class O(object): 
 		def __init__(self, d):
-			for k, v in d.iteritems(): setattr(self, k, v)
+			for k, v in d.iteritems():
+			    setattr(self, k, v)
 	config = O(yaml.load(open(config_file)))
 	def rand_bot2(*args):
 		return rand_bot(*args)
+    for extension in config.local_extensions:
+        print "Loading", extension
+        execfile(extension)
 	bot = LoggingCommandBot(config.database_dir, config.server_host, config.server_port, 
 		config.bot_nickname, config.log_channels, config.other_channels,