Added config option for specifying services to use.

master
Sean B. Palmer 2009-06-07 09:57:41 +01:00
parent a06ea9e4ba
commit aafac55f7a
6 changed files with 51 additions and 88 deletions

View File

@ -11,79 +11,11 @@ import re, urllib
import web import web
from tools import deprecated from tools import deprecated
formuri = 'http://wordnet.princeton.edu/perl/webwn?s='
r_li = re.compile(r'(?ims)<li>.*?</li>') r_li = re.compile(r'(?ims)<li>.*?</li>')
r_tag = re.compile(r'<[^>]+>') r_tag = re.compile(r'<[^>]+>')
r_parens = re.compile(r'(?<=\()(?:[^()]+|\([^)]+\))*(?=\))') r_parens = re.compile(r'(?<=\()(?:[^()]+|\([^)]+\))*(?=\))')
r_word = re.compile(r'^[A-Za-z0-9\' -]+$') 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' uri = 'http://encarta.msn.com/dictionary_/%s.html'
r_info = re.compile( r_info = re.compile(
r'(?:ResultBody"><br /><br />(.*?)&nbsp;)|(?:<b>(.*?)</b>)' r'(?:ResultBody"><br /><br />(.*?)&nbsp;)|(?:<b>(.*?)</b>)'

View File

@ -22,7 +22,7 @@ abbrs = [
'cf', 'lit', 'etc', 'Ger', 'Du', 'Skt', 'Rus', 'Eng', 'Amer.Eng', 'Sp', 'cf', 'lit', 'etc', 'Ger', 'Du', 'Skt', 'Rus', 'Eng', 'Amer.Eng', 'Sp',
'Fr', 'N', 'E', 'S', 'W', 'L', 'Gen', 'J.C', 'dial', 'Gk', 'Fr', 'N', 'E', 'S', 'W', 'L', 'Gen', 'J.C', 'dial', 'Gk',
'19c', '18c', '17c', '16c', 'St', 'Capt', 'obs', 'Jan', 'Feb', 'Mar', '19c', '18c', '17c', '16c', 'St', 'Capt', 'obs', 'Jan', 'Feb', 'Mar',
'Apr', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec', 'c', 'tr' 'Apr', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec', 'c', 'tr', 'e', 'g'
] ]
t_sentence = r'^.*?(?<!%s)(?:\.(?= [A-Z0-9]|\Z)|\Z)' t_sentence = r'^.*?(?<!%s)(?:\.(?= [A-Z0-9]|\Z)|\Z)'
r_sentence = re.compile(t_sentence % ')(?<!'.join(abbrs)) r_sentence = re.compile(t_sentence % ')(?<!'.join(abbrs))
@ -82,19 +82,17 @@ def f_etymology(self, origin, match, args):
msg = "Can't connect to etymonline.com (%s)" % (etyuri % word) msg = "Can't connect to etymonline.com (%s)" % (etyuri % word)
self.msg(origin.sender, msg) self.msg(origin.sender, msg)
return return
except AttributeError:
result = None
if result is not None: if result is not None:
if (origin.sender == '#esp') and (origin.nick == 'nsh'): self.msg(origin.sender, result)
self.msg(origin.nick, result)
note = 'nsh: see privmsg (yes, this only happens for you)'
self.msg(origin.sender, note)
else: self.msg(origin.sender, result)
else: else:
uri = etysearch % word uri = etysearch % word
msg = 'Can\'t find the etymology for "%s". Try %s' % (word, uri) msg = 'Can\'t find the etymology for "%s". Try %s' % (word, uri)
self.msg(origin.sender, msg) self.msg(origin.sender, msg)
# @@ Cf. http://swhack.com/logs/2006-01-04#T01-50-22 # @@ Cf. http://swhack.com/logs/2006-01-04#T01-50-22
f_etymology.rule = (['ety'], r"([A-Za-z0-9' .-]+)") f_etymology.rule = (['ety'], r"([A-Za-z0-9' .-]+)$")
f_etymology.thread = True f_etymology.thread = True
f_etymology.priority = 'high' f_etymology.priority = 'high'

View File

@ -23,6 +23,7 @@ def mappings(uri):
if not ' ' in item: continue if not ' ' in item: continue
command, template = item.split(' ', 1) command, template = item.split(' ', 1)
if not command.isalpha(): continue
if not template.startswith('http://'): continue if not template.startswith('http://'): continue
result[command] = template.replace('&amp;', '&') result[command] = template.replace('&amp;', '&')
return result return result
@ -57,6 +58,19 @@ def o(phenny, input):
msg = o.services.get(args, 'No such service!') msg = o.services.get(args, 'No such service!')
return phenny.reply(msg) return phenny.reply(msg)
if not o.services.has_key(command):
return phenny.reply('Sorry, no such service. See %s' % services)
if hasattr(phenny.config, 'external'):
default = phenny.config.external.get('*')
manifest = phenny.config.external.get(input.sender, default)
if manifest:
commands = set(manifest)
if (command not in commands) and (manifest[0] != '!'):
return phenny.reply('Sorry, %s is not whitelisted' % command)
elif (command in commands) and (manifest[0] == '!'):
return phenny.reply('Sorry, %s is blacklisted' % command)
if o.services.has_key(command): if o.services.has_key(command):
t = o.services[command] t = o.services[command]
template = t.replace('${args}', urllib.quote(args.encode('utf-8'))) template = t.replace('${args}', urllib.quote(args.encode('utf-8')))
@ -68,10 +82,24 @@ def o(phenny, input):
if lines: if lines:
phenny.say(lines[0][:350]) phenny.say(lines[0][:350])
else: phenny.reply('Sorry, the service is broken.') else: phenny.reply('Sorry, the service is broken.')
else: phenny.reply('Sorry, no such service. See %s' % services)
o.commands = ['o'] o.commands = ['o']
o.example = '.o servicename arg1 arg2 arg3' o.example = '.o servicename arg1 arg2 arg3'
o.services = {} o.services = {}
def py(phenny, input):
command = 'py'
args = input.group(2)
if o.services.has_key(command):
t = o.services[command]
template = t.replace('${args}', urllib.quote(args.encode('utf-8')))
template = template.replace('${nick}', urllib.quote(input.nick))
uri = template.replace('${sender}', urllib.quote(input.sender))
bytes = web.get(uri)
lines = bytes.splitlines()
if lines:
phenny.say(lines[0][:350])
py.commands = ['py']
if __name__ == '__main__': if __name__ == '__main__':
print __doc__.strip() print __doc__.strip()

View File

@ -23,7 +23,7 @@ def text(html):
return text return text
def wiktionary(word): def wiktionary(word):
bytes = web.get(uri % word) bytes = web.get(uri % web.urllib.quote(word.encode('utf-8')))
bytes = r_ul.sub('', bytes) bytes = r_ul.sub('', bytes)
mode = None mode = None

View File

@ -19,12 +19,10 @@ def replaced(phenny, input):
# 'img': 'the .img command has been removed; ask sbp for details', # 'img': 'the .img command has been removed; ask sbp for details',
'v': '.v has been replaced by .val', 'v': '.v has been replaced by .val',
'validate': '.validate has been replaced by .validate', 'validate': '.validate has been replaced by .validate',
'thesaurus': ".thesaurus hasn't been ported to my new codebase yet",
# 'rates': "moon wanter. moOOoon wanter!", # 'rates': "moon wanter. moOOoon wanter!",
'web': 'the .web command has been removed; ask sbp for details', 'web': 'the .web command has been removed; ask sbp for details',
'origin': ".origin hasn't been ported to my new codebase yet", 'origin': ".origin hasn't been ported to my new codebase yet"
# 'gs': 'sorry, .gs no longer works', # 'gs': 'sorry, .gs no longer works'
'swhack': 'sorry, .swhack no longer works'
} }
try: response = responses[command] try: response = responses[command]
except KeyError: return except KeyError: return

21
phenny
View File

@ -43,9 +43,16 @@ def create_default_config(fn):
# #
# enable = [] # enable = []
# Modules to load from the opt directory # Directories to load opt modules from
extra = [] extra = []
# Services to load: maps channel names to white or black lists
external = {
'#liberal': ['!'], # allow all
'#conservative': [], # allow none
'*': ['py', 'whois', 'glyph'] # default whitelist
}
# EOF # EOF
""") """)
f.close() f.close()
@ -98,12 +105,7 @@ def config_names(config):
sys.exit(1) sys.exit(1)
def main(argv=None): def main(argv=None):
# Step One: Check Dependencies # Step One: Parse The Command Line
check_python_version() # require python2.4 or later
check_dotdir() # require ~/.phenny, or make it and exit
# Step Two: Parse The Command Line
parser = optparse.OptionParser('%prog [options]') parser = optparse.OptionParser('%prog [options]')
parser.add_option('-c', '--config', metavar='fn', parser.add_option('-c', '--config', metavar='fn',
@ -111,6 +113,11 @@ def main(argv=None):
opts, args = parser.parse_args(argv) opts, args = parser.parse_args(argv)
if args: print >> sys.stderr, 'Warning: ignoring spurious arguments' if args: print >> sys.stderr, 'Warning: ignoring spurious arguments'
# Step Two: Check Dependencies
check_python_version() # require python2.4 or later
check_dotdir() # require ~/.phenny, or make it and exit
# Step Three: Load The Configurations # Step Three: Load The Configurations
config_modules = [] config_modules = []