From 7e75fc93b8e92f8d14efb3fdf48338f004b2621c Mon Sep 17 00:00:00 2001
From: Edward Powell <powell.518@gmail.com>
Date: Fri, 31 May 2013 17:55:02 -0400
Subject: [PATCH] [countdown, reddit, etymology, remind, unicode_info] update
 to 4.0 standard

issue #276
---
 countdown.py    | 21 +++++-------
 etymology.py    | 19 ++++++-----
 reddit-info.py  | 37 ++++++++++----------
 remind.py       | 90 ++++++++++++++++++++++++-------------------------
 unicode_info.py | 10 +++---
 5 files changed, 86 insertions(+), 91 deletions(-)

diff --git a/countdown.py b/countdown.py
index f8a215dca0..39e798c70a 100644
--- a/countdown.py
+++ b/countdown.py
@@ -5,34 +5,29 @@
 
 http://willie.dfbta.net
 """
-
+from willie.module import command, NOLIMIT
 import datetime
 
 
-def generic_countdown(willie, trigger):
+@command('countdown')
+def generic_countdown(bot, trigger):
     """
     .countdown <year> <month> <day> - displays a countdown to a given date.
     """
     text = trigger.group(2)
     if not text:
-        willie.say("Please use correct format: .countdown 2012 12 21")
-        return willie.NOLIMIT
+        bot.say("Please use correct format: .countdown 2012 12 21")
+        return NOLIMIT
     text = trigger.group(2).split()
     if text and (text[0].isdigit() and text[1].isdigit() and text[2].isdigit()
             and len(text) == 3):
         diff = (datetime.datetime(int(text[0]), int(text[1]), int(text[2]))
                 - datetime.datetime.today())
-        willie.say(str(diff.days) + " days, " + str(diff.seconds / 60 / 60)
+        bot.say(str(diff.days) + " days, " + str(diff.seconds / 60 / 60)
                    + " hours and "
                    + str(diff.seconds / 60 - diff.seconds / 60 / 60 * 60)
                    + " minutes until "
                    + text[0] + " " + text[1] + " " + text[2])
     else:
-        willie.say("Please use correct format: .countdown 2012 12 21")
-        return willie.NOLIMIT
-generic_countdown.commands = ['countdown']
-generic_countdown.priority = 'low'
-
-
-if __name__ == '__main__':
-    print __doc__.strip()
+        bot.say("Please use correct format: .countdown 2012 12 21")
+        return NOLIMIT
diff --git a/etymology.py b/etymology.py
index 3085b88aed..7a5187eef4 100644
--- a/etymology.py
+++ b/etymology.py
@@ -7,7 +7,8 @@
 """
 
 import re
-import willie.web as web
+from willie import web
+from willie.module import command, example, NOLIMIT
 
 etyuri = 'http://etymonline.com/?term=%s'
 etysearch = 'http://etymonline.com/?search=%s'
@@ -70,7 +71,9 @@ def etymology(word):
     return sentence + ' - ' + (etyuri % word)
 
 
-def f_etymology(willie, trigger):
+@command('ety')
+@example('word')
+def f_etymology(bot, trigger):
     """Look up the etymology of a word"""
     word = trigger.group(2)
 
@@ -78,17 +81,15 @@ def f_etymology(willie, trigger):
         result = etymology(word)
     except IOError:
         msg = "Can't connect to etymonline.com (%s)" % (etyuri % word)
-        willie.msg(trigger.sender, msg)
-        return willie.NOLIMIT
+        bot.msg(trigger.sender, msg)
+        return NOLIMIT
     except AttributeError:
         result = None
 
     if result is not None:
-        willie.msg(trigger.sender, result)
+        bot.msg(trigger.sender, result)
     else:
         uri = etysearch % word
         msg = 'Can\'t find the etymology for "%s". Try %s' % (word, uri)
-        willie.msg(trigger.sender, msg)
-        return willie.NOLIMIT
-f_etymology.commands = ['ety']
-f_etymology.example = '.ety word'
+        bot.msg(trigger.sender, msg)
+        return NOLIMIT
diff --git a/reddit-info.py b/reddit-info.py
index 784ba43b95..04dd17e421 100644
--- a/reddit-info.py
+++ b/reddit-info.py
@@ -6,6 +6,7 @@
 This module provides special tools for reddit, namely showing detailed info about reddit posts
 """
 
+from willie.module import command, rule, example, NOLIMIT
 import praw
 import re
 domain = r'https?://(?:www\.|np\.)?reddit\.com'
@@ -13,16 +14,17 @@
 user_url = '%s/u(ser)?/([\w-]+)' % domain
 
 
-def setup(willie):
+def setup(bot):
     post_regex = re.compile(post_url)
     user_regex = re.compile(user_url)
-    if not willie.memory.contains('url_callbacks'):
-        willie.memory['url_callbacks'] = {}
-    willie.memory['url_callbacks'][post_regex] = rpost_info
-    willie.memory['url_callbacks'][user_regex] = redditor_info
+    if not bot.memory.contains('url_callbacks'):
+        bot.memory['url_callbacks'] = {}
+    bot.memory['url_callbacks'][post_regex] = rpost_info
+    bot.memory['url_callbacks'][user_regex] = redditor_info
 
 
-def rpost_info(willie, trigger, match=None):
+@rule('.*%s.*' % post_url)
+def rpost_info(bot, trigger, match=None):
     r = praw.Reddit(user_agent='phenny / willie IRC bot - see dft.ba/-williesource for more')
     match = match or trigger
     s = r.get_submission(url=match.group(1))
@@ -39,21 +41,22 @@ def rpost_info(willie, trigger, match=None):
                + str(s.ups) + '|05' + str(s.downs) + ') | ' +
                str(s.num_comments) + ' comments | Posted by ' + s.author.name)
     #TODO add creation time with s.created
-    willie.say(message)
-rpost_info.rule = '.*%s.*' % post_url
+    bot.say(message)
 
 
-def redditor_info(willie, trigger, match=None):
+#If you change this, you'll have to change some other things...
+@command('redditor')
+def redditor_info(bot, trigger, match=None):
     """Show information about the given Redditor"""
-    commanded = re.match(willie.config.prefix + 'redditor', trigger)
+    commanded = re.match(bot.config.prefix + 'redditor', trigger)
     r = praw.Reddit(user_agent='phenny / willie IRC bot - see dft.ba/-williesource for more')
     match = match or trigger
     try:
         u = r.get_redditor(match.group(2))
     except:
         if commanded:
-            willie.say('No such Redditor.')
-            return willie.NOLIMIT
+            bot.say('No such Redditor.')
+            return NOLIMIT
         else:
             return
         #Fail silently if it wasn't an explicit command.
@@ -68,12 +71,10 @@ def redditor_info(willie, trigger, match=None):
     message = message + ' | Link: ' + str(u.link_karma) + ' | Comment: ' + str(u.comment_karma)
 
     #TODO detect cake day with u.created
-    willie.say(message)
-#If you change this, you'll have to change some things above.
-redditor_info.commands = ['redditor']
+    bot.say(message)
 
 
-def auto_redditor_info(willie, trigger):
-    redditor_info(willie, trigger)
 #If you change the groups here, you'll have to change some things above.
-auto_redditor_info.rule = '.*%s.*' % user_url
+@rule('.*%s.*' % user_url)
+def auto_redditor_info(bot, trigger):
+    redditor_info(bot, trigger)
diff --git a/remind.py b/remind.py
index b8d6604730..41435d7f2e 100644
--- a/remind.py
+++ b/remind.py
@@ -14,6 +14,7 @@
 import pytz
 import codecs
 from datetime import tzinfo, timedelta, datetime
+from willie.module import command, example, NOLIMIT
 
 
 def filename(self):
@@ -46,34 +47,34 @@ def dump_database(name, data):
     f.close()
 
 
-def setup(willie):
-    #Having a db means pref's exists. Later, we can just use `if willie.db`.
-    if willie.db and not willie.db.preferences.has_columns('tz'):
-        willie.db.preferences.add_columns(['tz'])
-    if willie.db and not willie.db.preferences.has_columns('time_format'):
-        willie.db.preferences.add_columns(['tz'])
+def setup(bot):
+    #Having a db means pref's exists. Later, we can just use `if bot.db`.
+    if bot.db and not bot.db.preferences.has_columns('tz'):
+        bot.db.preferences.add_columns(['tz'])
+    if bot.db and not bot.db.preferences.has_columns('time_format'):
+        bot.db.preferences.add_columns(['tz'])
 
-    willie.rfn = filename(willie)
-    willie.rdb = load_database(willie.rfn)
+    bot.rfn = filename(bot)
+    bot.rdb = load_database(bot.rfn)
 
-    def monitor(willie):
+    def monitor(bot):
         time.sleep(5)
         while True:
             now = int(time.time())
-            unixtimes = [int(key) for key in willie.rdb]
+            unixtimes = [int(key) for key in bot.rdb]
             oldtimes = [t for t in unixtimes if t <= now]
             if oldtimes:
                 for oldtime in oldtimes:
-                    for (channel, nick, message) in willie.rdb[oldtime]:
+                    for (channel, nick, message) in bot.rdb[oldtime]:
                         if message:
-                            willie.msg(channel, nick + ': ' + message)
+                            bot.msg(channel, nick + ': ' + message)
                         else:
-                            willie.msg(channel, nick + '!')
-                    del willie.rdb[oldtime]
-                dump_database(willie.rfn, willie.rdb)
+                            bot.msg(channel, nick + '!')
+                    del bot.rdb[oldtime]
+                dump_database(bot.rfn, bot.rdb)
             time.sleep(2.5)
 
-    targs = (willie,)
+    targs = (bot,)
     t = threading.Thread(target=monitor, args=targs)
     t.start()
 
@@ -119,7 +120,9 @@ def monitor(willie):
 periods = '|'.join(scaling.keys())
 
 
-def remind(willie, trigger):
+@command('in')
+@example('.in 3h45m Go to class')
+def remind(bot, trigger):
     """Gives you a reminder in the given amount of time."""
     duration = 0
     message = re.split('(\d+ ?(?:' + periods + ')) ?', trigger.group(2))[1:]
@@ -135,22 +138,22 @@ def remind(willie, trigger):
             reminder = reminder + piece
             stop = True
     if duration == 0:
-        return willie.reply("Sorry, didn't understand the input.")
+        return bot.reply("Sorry, didn't understand the input.")
 
     if duration % 1:
         duration = int(duration) + 1
     else:
         duration = int(duration)
     tzi = timezone('UTC')
-    if willie.db and trigger.nick in willie.db.preferences:
-        tz = willie.db.preferences.get(trigger.nick, 'tz') or 'UTC'
+    if bot.db and trigger.nick in bot.db.preferences:
+        tz = bot.db.preferences.get(trigger.nick, 'tz') or 'UTC'
         tzi = timezone(tz)
-    create_reminder(willie, trigger, duration, reminder, tzi)
-remind.commands = ['in']
-remind.example = '.in 3h45m Go to class'
+    create_reminder(bot, trigger, duration, reminder, tzi)
 
 
-def at(willie, trigger):
+@command('at')
+@example('.at 13:47 Do your homework!')
+def at(bot, trigger):
     """
     Gives you a reminder at the given time. Takes hh:mm:ssContinent/Large_City
     message. Continent/Large_City is a timezone from the tzdb; a list of valid
@@ -160,26 +163,26 @@ def at(willie, trigger):
     regex = re.compile(r'(\d+):(\d+)(?::(\d+))?([^\s\d]+)? (.*)')
     match = regex.match(trigger.group(2))
     if not match:
-        willie.reply("Sorry, but I didn't understand your input.")
-        return willie.NOLIMIT
+        bot.reply("Sorry, but I didn't understand your input.")
+        return NOLIMIT
     hour, minute, second, tz, message = match.groups()
     if not second:
         second = '0'
     if tz:
         if tz not in all_timezones_set:
             good_tz = False
-            if willie.db and tz in willie.db.preferences:
-                tz = willie.db.preferences.get(tz, 'tz')
+            if bot.db and tz in bot.db.preferences:
+                tz = bot.db.preferences.get(tz, 'tz')
                 if tz:
                     tzi = timezone(tz)
                     good_tz = True
             if not good_tz:
-                willie.reply("I don't know that timezone or user.")
-                return willie.NOLIMIT
+                bot.reply("I don't know that timezone or user.")
+                return NOLIMIT
         else:
             tzi = timezone(tz)
-    elif willie.db and trigger.nick in willie.db.preferences:
-        tz = willie.db.preferences.get(trigger.nick, 'tz')
+    elif bot.db and trigger.nick in bot.db.preferences:
+        tz = bot.db.preferences.get(trigger.nick, 'tz')
         if tz:
             tzi = timezone(tz)
         else:
@@ -195,31 +198,26 @@ def at(willie, trigger):
 
     if duration < 0:
         duration += 86400
-    create_reminder(willie, trigger, duration, message, timezone('UTC'))
-at.commands = ['at']
-at.example = '.at 13:47 Do your homework!'
+    create_reminder(bot, trigger, duration, message, timezone('UTC'))
 
 
-def create_reminder(willie, trigger, duration, message, tz):
+def create_reminder(bot, trigger, duration, message, tz):
     t = int(time.time()) + duration
     reminder = (trigger.sender, trigger.nick, message)
     try:
-        willie.rdb[t].append(reminder)
+        bot.rdb[t].append(reminder)
     except KeyError:
-        willie.rdb[t] = [reminder]
+        bot.rdb[t] = [reminder]
 
-    dump_database(willie.rfn, willie.rdb)
+    dump_database(bot.rfn, bot.rdb)
 
     if duration >= 60:
         tformat = "%F - %T%Z"
-        if willie.db and trigger.nick in willie.db.preferences:
-            tformat = (willie.db.preferences.get(trigger.nick, 'time_format')
+        if bot.db and trigger.nick in bot.db.preferences:
+            tformat = (bot.db.preferences.get(trigger.nick, 'time_format')
                        or "%F - %T%Z")
         timef = datetime.fromtimestamp(t, tz).strftime(tformat)
 
-        willie.reply('Okay, will remind at %s' % timef)
+        bot.reply('Okay, will remind at %s' % timef)
     else:
-        willie.reply('Okay, will remind in %s secs' % duration)
-
-if __name__ == '__main__':
-    print __doc__.strip()
+        bot.reply('Okay, will remind in %s secs' % duration)
diff --git a/unicode_info.py b/unicode_info.py
index 2158d10830..4f35a33710 100644
--- a/unicode_info.py
+++ b/unicode_info.py
@@ -7,19 +7,22 @@
 http://willie.dfbta.net
 """
 import unicodedata
+from willie.module import command, example, NOLIMIT
 
 
+@command('u')
+@example('.u 203D')
 def codepoint(willie, trigger):
     arg = trigger.group(2).strip()
     if len(arg) == 0:
         willie.reply('What code point do you want me to look up?')
-        return willie.NOLIMIT
+        return NOLIMIT
     elif len(arg) > 1:
         try:
             arg = unichr(int(arg, 16))
         except:
             willie.reply("That's not a valid code point.")
-            return willie.NOLIMIT
+            return NOLIMIT
 
     # Get the hex value for the code point, and drop the 0x from the front
     point = str(hex(ord(u'' + arg)))[2:]
@@ -35,6 +38,3 @@ def codepoint(willie, trigger):
     else:
         template = 'U+%s %s (\xe2\x97\x8c%s)'
     willie.say(template % (point, name, arg))
-
-codepoint.commands = ['u']
-codepoint.example = '.u 203D'