From cbdf9ebd7312bf570a212057ad793ae520bac38f Mon Sep 17 00:00:00 2001
From: "Sean B. Palmer"
Date: Sat, 23 Feb 2008 12:17:06 +0000
Subject: [PATCH] And some new modules too...
---
modules/calc.py | 66 ++++++++++++++++++++++++
modules/dict.py | 120 ++++++++++++++++++++++++++++++++++++++++++++
modules/validate.py | 41 +++++++++++++++
opt/swhack.py | 34 +++++++++++++
4 files changed, 261 insertions(+)
create mode 100644 modules/calc.py
create mode 100755 modules/dict.py
create mode 100755 modules/validate.py
create mode 100644 opt/swhack.py
diff --git a/modules/calc.py b/modules/calc.py
new file mode 100644
index 0000000..6768035
--- /dev/null
+++ b/modules/calc.py
@@ -0,0 +1,66 @@
+#!/usr/bin/env python
+# coding=utf-8
+"""
+calc.py - Phenny Calculator Module
+Copyright 2008, Sean B. Palmer, inamidst.com
+Licensed under the Eiffel Forum License 2.
+
+http://inamidst.com/phenny/
+"""
+
+import re
+import web
+
+r_result = re.compile(r'(?i)(.*?)')
+r_tag = re.compile(r'<\S+.*?>')
+
+subs = [
+ (' in ', ' -> '),
+ (' over ', ' / '),
+ (u'£', 'GBP '),
+ (u'€', 'EUR '),
+ ('\$', 'USD '),
+ (r'\bKB\b', 'kilobytes'),
+ (r'\bMB\b', 'megabytes'),
+ (r'\bGB\b', 'kilobytes'),
+ ('kbps', '(kilobits / second)'),
+ ('mbps', '(megabits / second)')
+]
+
+def calc(phenny, input):
+ q = input.group(2)
+
+ query = q[:]
+ for a, b in subs:
+ query = re.sub(a, b, query)
+ query = query.rstrip(' \t')
+
+ precision = 5
+ if query[-3:] in ('GBP', 'USD', 'EUR', 'NOK'):
+ precision = 2
+ query = web.urllib.quote(query.encode('utf-8'))
+
+ uri = 'http://futureboy.homeip.net/fsp/frink.fsp?fromVal='
+ bytes = web.get(uri + query)
+ m = r_result.search(bytes)
+ if m:
+ result = m.group(1)
+ result = r_tag.sub('', result) # strip span.warning tags
+ result = result.replace('>', '>')
+ result = result.replace('(undefined symbol)', '(?) ')
+
+ if '.' in result:
+ try: result = str(round(float(result), precision))
+ except ValueError: pass
+
+ if not result.strip():
+ result = '?'
+ elif ' in ' in q:
+ result += ' ' + q.split(' in ', 1)[1]
+
+ phenny.say(q + ' = ' + result)
+ else: phenny.reply("Sorry, can't calculate that.")
+calc.commands = ['calc']
+
+if __name__ == '__main__':
+ print __doc__.strip()
diff --git a/modules/dict.py b/modules/dict.py
new file mode 100755
index 0000000..7ecaf0a
--- /dev/null
+++ b/modules/dict.py
@@ -0,0 +1,120 @@
+#!/usr/bin/env python
+"""
+dict.py - Phenny Dictionary Module
+Copyright 2008, Sean B. Palmer, inamidst.com
+Licensed under the Eiffel Forum License 2.
+
+http://inamidst.com/phenny/
+"""
+
+import re, urllib
+import web
+from tools import deprecated
+
+formuri = 'http://wordnet.princeton.edu/perl/webwn?s='
+
+r_li = re.compile(r'(?ims)
.*?')
+r_tag = re.compile(r'<[^>]+>')
+r_parens = re.compile(r'(?<=\()(?:[^()]+|\([^)]+\))*(?=\))')
+r_word = re.compile(r'^[A-Za-z0-9\' -]+$')
+
+@deprecated
+def f_wordnet(self, origin, match, args):
+ """Gives the definition of a word using Wordnet."""
+ command = 'w'
+ term = match.group(2)
+ term = term.encode('utf-8')
+
+ if origin.sender != '#inamidst':
+ if not r_word.match(term):
+ msg = "Words must match the regexp %s" % r'^[A-Za-z0-9\' -]+$'
+ return self.msg(origin.sender, origin.nick + ": " + msg)
+ if ('--' in term) or ("''" in term) or (' ' in term):
+ self.msg(origin.sender, origin.nick + ": That's not in WordNet.")
+ return
+
+ bytes = web.get(formuri + web.urllib.quote(term)) # @@ ugh!
+ items = r_li.findall(bytes)
+
+ nouns, verbs, adjectives = [], [], []
+ for item in items:
+ item = r_tag.sub('', item)
+ chunks = r_parens.findall(item)
+ # self.msg(origin.sender, item)
+ if len(chunks) < 2: continue
+
+ kind, defn = chunks[0], chunks[1]
+ if command != 'wordnet':
+ defn = defn.split(';')[0]
+ if not defn: continue
+ defn = defn[0].upper() + defn[1:]
+
+ if kind == 'n':
+ nouns.append(defn)
+ elif kind == 'v':
+ verbs.append(defn)
+ elif kind == 'adj':
+ adjectives.append(defn)
+
+ if not (nouns or verbs or adjectives):
+ self.msg(origin.sender, "I couldn't find '%s' in WordNet." % term)
+ return
+
+ while len(nouns + verbs + adjectives) > 3:
+ if len(nouns) >= len(verbs) and len(nouns) >= len(adjectives):
+ nouns.pop()
+ elif len(verbs) >= len(nouns) and len(verbs) >= len(adjectives):
+ verbs.pop()
+ elif len(adjectives) >= len(nouns) and len(adjectives) >= len(verbs):
+ adjectives.pop()
+
+ if adjectives:
+ adjectives[-1] = adjectives[-1] + '.'
+ elif verbs:
+ verbs[-1] = verbs[-1] + '.'
+ elif nouns:
+ nouns[-1] = nouns[-1] + '.'
+
+ for (i, defn) in enumerate(nouns):
+ self.msg(origin.sender, '%s n. %r: %s' % (term, i+1, defn))
+ for (i, defn) in enumerate(verbs):
+ self.msg(origin.sender, '%s v. %r: %s' % (term, i+1, defn))
+ for (i, defn) in enumerate(adjectives):
+ self.msg(origin.sender, '%s a. %r: %s' % (term, i+1, defn))
+f_wordnet.commands = ['wordnet']
+f_wordnet.priority = 'low'
+
+uri = 'http://encarta.msn.com/dictionary_/%s.html'
+r_info = re.compile(
+ r'(?:ResultBody">
(.*?) )|(?:(.*?))'
+)
+
+def dict(phenny, input):
+ word = input.group(2)
+ word = urllib.quote(word.encode('utf-8'))
+
+ def trim(thing):
+ if thing.endswith(' '):
+ thing = thing[:-6]
+ return thing.strip(' :.')
+
+ bytes = web.get(uri % word)
+ results = {}
+ wordkind = None
+ for kind, sense in r_info.findall(bytes):
+ kind, sense = trim(kind), trim(sense)
+ if kind: wordkind = kind
+ elif sense:
+ results.setdefault(wordkind, []).append(sense)
+ result = input.group(2).encode('utf-8') + ' - '
+ for key in sorted(results.keys()):
+ if results[key]:
+ result += key + ' 1. ' + results[key][0]
+ if len(results[key]) > 1:
+ result += ', 2. ' + results[key][1]
+ result += '; '
+ phenny.say(result.rstrip('; '))
+dict.commands = ['dict']
+
+if __name__ == '__main__':
+ print __doc__.strip()
diff --git a/modules/validate.py b/modules/validate.py
new file mode 100755
index 0000000..3e179e7
--- /dev/null
+++ b/modules/validate.py
@@ -0,0 +1,41 @@
+#!/usr/bin/env python
+"""
+validate.py - Phenny Validation Module
+Copyright 2008, Sean B. Palmer, inamidst.com
+Licensed under the Eiffel Forum License 2.
+
+http://inamidst.com/phenny/
+"""
+
+import web
+
+def val(phenny, input):
+ """Check a webpage using the W3C Markup Validator."""
+ uri = input.group(2)
+ if not uri.startswith('http://'):
+ uri = 'http://' + uri
+
+ path = '/check?uri=%s;output=xml' % web.urllib.quote(uri)
+ info = web.head('http://validator.w3.org' + path)
+
+ result = uri + ' is '
+
+ if isinstance(info, list):
+ return phenny.say('Got HTTP response %s' % info[1])
+
+ if info.has_key('X-W3C-Validator-Status'):
+ result += str(info['X-W3C-Validator-Status'])
+ if info['X-W3C-Validator-Status'] != 'Valid':
+ if info.has_key('X-W3C-Validator-Errors'):
+ n = int(info['X-W3C-Validator-Errors'].split(' ')[0])
+ if n != 1:
+ result += ' (%s errors)' % n
+ else: result += ' (%s error)' % n
+ else: result += 'Unvalidatable: no X-W3C-Validator-Status'
+
+ phenny.say(' ' + result)
+val.rule = (['val'], r'(?i)(\S+)')
+val.example = '.val http://www.w3.org/'
+
+if __name__ == '__main__':
+ print __doc__.strip()
diff --git a/opt/swhack.py b/opt/swhack.py
new file mode 100644
index 0000000..60914c0
--- /dev/null
+++ b/opt/swhack.py
@@ -0,0 +1,34 @@
+#!/usr/bin/env python
+"""
+swhack.py - Phenny Swhack Module
+Copyright 2008, Sean B. Palmer, inamidst.com
+Licensed under the Eiffel Forum License 2.
+
+http://inamidst.com/phenny/
+"""
+
+import urllib
+
+def swhack(phenny, input):
+ if not input.sender in ('#swhack', '#inamidst'):
+ return
+
+ query = input.group(2)
+ pattern = urllib.quote(query, safe='./')
+
+ u = urllib.urlopen('http://swhack.com/scripts/tail/' + pattern)
+
+ i = None
+ for i, line in enumerate(u.readlines()):
+ line = line.rstrip('\r\n')
+ if i == 0:
+ phenny.reply(line)
+ else: phenny.say('[off] ' + line)
+ if i is None:
+ phenny.reply('Sorry, no results found.')
+
+ u.close()
+swhack.commands = ['swhack']
+
+if __name__ == '__main__':
+ print __doc__.strip()