mutantmonkey 2011-04-04 16:46:46 -04:00
commit f249e43ba4
7 changed files with 206 additions and 66 deletions

View File

@ -78,6 +78,8 @@ def c(phenny, input):
answer = [p for p in parts if p.startswith('rhs: "')][0][6:]
if answer:
answer = answer.decode('unicode-escape')
answer = ''.join(chr(ord(c)) for c in answer)
answer = answer.decode('utf-8')
answer = answer.replace(u'\xc2\xa0', ',')
answer = answer.replace('<sup>', '^(')
answer = answer.replace('</sup>', ')')
@ -97,7 +99,7 @@ def py(phenny, input):
py.commands = ['py']
def wa(phenny, input):
query = input.group(2)
query = input.group(2).encode('utf-8')
uri = 'http://tumbolia.appspot.com/wa/'
answer = web.get(uri + web.urllib.quote(query))
if answer:

View File

@ -7,11 +7,16 @@ Licensed under the Eiffel Forum License 2.
http://inamidst.com/phenny/
"""
import re, urllib, urllib2, httplib, urlparse, time
import re, urllib, urllib2, httplib, urlparse, time, cookielib
from htmlentitydefs import name2codepoint
from string import join
import web
from tools import deprecated
cj = cookielib.LWPCookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
urllib2.install_opener(opener)
def head(phenny, input):
"""Provide HTTP HEAD information."""
uri = input.group(2)
@ -26,6 +31,7 @@ def head(phenny, input):
if not uri.startswith('htt'):
uri = 'http://' + uri
# uri = uri.replace('#!', '?_escaped_fragment_=')
try: info = web.head(uri)
except IOError: return phenny.say("Can't connect to %s" % uri)
@ -77,9 +83,35 @@ def f_title(self, origin, match, args):
uri = self.last_seen_uri.get(origin.sender)
if not uri:
return self.msg(origin.sender, 'I need a URI to give the title of...')
title = gettitle(uri)
if title:
self.msg(origin.sender, origin.nick + ': ' + title)
else: self.msg(origin.sender, origin.nick + ': No title found')
f_title.commands = ['title']
def noteuri(phenny, input):
uri = input.group(1).encode('utf-8')
if not hasattr(phenny.bot, 'last_seen_uri'):
phenny.bot.last_seen_uri = {}
phenny.bot.last_seen_uri[input.sender] = uri
noteuri.rule = r'.*(http[s]?://[^<> "\x01]+)[,.]?'
noteuri.priority = 'low'
titlecommands = r'(?:' + join(f_title.commands, r'|') + r')'
def snarfuri(phenny, input):
if re.match(r'(?i)' + phenny.config.prefix + titlecommands, input.group()):
return
uri = input.group(1).encode('utf-8')
title = gettitle(uri)
if title:
phenny.msg(input.sender, '[ ' + title + ' ]')
snarfuri.rule = r'.*(http[s]?://[^<> "\x01]+)[,.]?'
snarfuri.priority = 'low'
def gettitle(uri):
if not ':' in uri:
uri = 'http://' + uri
uri = uri.replace('#!', '?_escaped_fragment_=')
try:
redirects = 0
@ -92,7 +124,6 @@ def f_title(self, origin, match, args):
u = urllib2.urlopen(req)
info = u.info()
u.close()
# info = web.head(uri)
if not isinstance(info, list):
status = '200'
@ -105,23 +136,19 @@ def f_title(self, origin, match, args):
redirects += 1
if redirects >= 25:
self.msg(origin.sender, origin.nick + ": Too many redirects")
return
return None
try: mtype = info['content-type']
except:
err = ": Couldn't get the Content-Type, sorry"
return self.msg(origin.sender, origin.nick + err)
return None
if not (('/html' in mtype) or ('/xhtml' in mtype)):
self.msg(origin.sender, origin.nick + ": Document isn't HTML")
return
return None
u = urllib2.urlopen(req)
bytes = u.read(262144)
u.close()
except IOError:
self.msg(origin.sender, "Can't connect to %s" % uri)
return
m = r_title.search(bytes)
@ -155,21 +182,10 @@ def f_title(self, origin, match, args):
try: title = title.decode('iso-8859-1').encode('utf-8')
except: title = title.decode('cp1252').encode('utf-8')
else: pass
else: title = '[The title is empty.]'
title = title.replace('\n', '')
title = title.replace('\r', '')
self.msg(origin.sender, origin.nick + ': ' + title)
else: self.msg(origin.sender, origin.nick + ': No title found')
f_title.commands = ['title']
def noteuri(phenny, input):
uri = input.group(1).encode('utf-8')
if not hasattr(phenny.bot, 'last_seen_uri'):
phenny.bot.last_seen_uri = {}
phenny.bot.last_seen_uri[input.sender] = uri
noteuri.rule = r'.*(http[s]?://[^<> "\x01]+)[,.]?'
noteuri.priority = 'low'
else: title = None
return title
if __name__ == '__main__':
print __doc__.strip()

View File

@ -30,9 +30,9 @@ def mappings(uri):
def service(phenny, input, command, args):
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))
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, ''))
info = web.head(uri)
if isinstance(info, list):

View File

@ -7,6 +7,7 @@ Licensed under the Eiffel Forum License 2.
http://inamidst.com/phenny/
"""
import sys, os.path, time, imp
import irc
def f_reload(phenny, input):
@ -21,18 +22,23 @@ def f_reload(phenny, input):
phenny.setup()
return phenny.reply('done')
try: module = getattr(__import__('modules.' + name), name)
except ImportError:
module = getattr(__import__('opt.' + name), name)
reload(module)
if not sys.modules.has_key(name):
return phenny.reply('%s: no such module!' % name)
# Thanks to moot for prodding me on this
path = sys.modules[name].__file__
if path.endswith('.pyc') or path.endswith('.pyo'):
path = path[:-1]
if not os.path.isfile(path):
return phenny.reply('Found %s, but not the source file' % name)
module = imp.load_source(name, path)
sys.modules[name] = module
if hasattr(module, 'setup'):
module.setup(phenny)
if hasattr(module, '__file__'):
import os.path, time
mtime = os.path.getmtime(module.__file__)
modified = time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime(mtime))
else: modified = 'unknown'
phenny.register(vars(module))
phenny.bind_commands()

136
modules/remind.py Executable file
View File

@ -0,0 +1,136 @@
#!/usr/bin/env python
"""
remind.py - Phenny Reminder Module
Copyright 2011, Sean B. Palmer, inamidst.com
Licensed under the Eiffel Forum License 2.
http://inamidst.com/phenny/
"""
import os, re, time, threading
def filename(self):
name = self.nick + '-' + self.config.host + '.reminders.db'
return os.path.join(os.path.expanduser('~/.phenny'), name)
def load_database(name):
data = {}
if os.path.isfile(name):
f = open(name, 'rb')
for line in f:
unixtime, channel, nick, message = line.split('\t')
message = message.rstrip('\n')
t = int(unixtime)
reminder = (channel, nick, message)
try: data[t].append(reminder)
except KeyError: data[t] = [reminder]
f.close()
return data
def dump_database(name, data):
f = open(name, 'wb')
for unixtime, reminders in data.iteritems():
for channel, nick, message in reminders:
f.write('%s\t%s\t%s\t%s\n' % (unixtime, channel, nick, message))
f.close()
def setup(phenny):
phenny.rfn = filename(phenny)
phenny.rdb = load_database(phenny.rfn)
def monitor(phenny):
time.sleep(5)
while True:
now = int(time.time())
unixtimes = [int(key) for key in phenny.rdb]
oldtimes = [t for t in unixtimes if t <= now]
if oldtimes:
for oldtime in oldtimes:
for (channel, nick, message) in phenny.rdb[oldtime]:
if message:
phenny.msg(channel, nick + ': ' + message)
else: phenny.msg(channel, nick + '!')
del phenny.rdb[oldtime]
dump_database(phenny.rfn, phenny.rdb)
time.sleep(2.5)
targs = (phenny,)
t = threading.Thread(target=monitor, args=targs)
t.start()
scaling = {
'years': 365.25 * 24 * 3600,
'year': 365.25 * 24 * 3600,
'yrs': 365.25 * 24 * 3600,
'y': 365.25 * 24 * 3600,
'months': 29.53059 * 24 * 3600,
'month': 29.53059 * 24 * 3600,
'mo': 29.53059 * 24 * 3600,
'weeks': 7 * 24 * 3600,
'week': 7 * 24 * 3600,
'wks': 7 * 24 * 3600,
'wk': 7 * 24 * 3600,
'w': 7 * 24 * 3600,
'days': 24 * 3600,
'day': 24 * 3600,
'd': 24 * 3600,
'hours': 3600,
'hour': 3600,
'hrs': 3600,
'hr': 3600,
'h': 3600,
'minutes': 60,
'minute': 60,
'mins': 60,
'min': 60,
'm': 60,
'seconds': 1,
'second': 1,
'secs': 1,
'sec': 1,
's': 1
}
periods = '|'.join(scaling.keys())
p_command = r'\.in ([0-9]+(?:\.[0-9]+)?)\s?((?:%s)\b)?:?\s?(.*)' % periods
r_command = re.compile(p_command)
def remind(phenny, input):
m = r_command.match(input.bytes)
if not m:
return phenny.reply("Sorry, didn't understand the input.")
length, scale, message = m.groups()
length = float(length)
factor = scaling.get(scale, 60)
duration = length * factor
if duration % 1:
duration = int(duration) + 1
else: duration = int(duration)
t = int(time.time()) + duration
reminder = (input.sender, input.nick, message)
try: phenny.rdb[t].append(reminder)
except KeyError: phenny.rdb[t] = [reminder]
dump_database(phenny.rfn, phenny.rdb)
if duration >= 60:
w = ''
if duration >= 3600 * 12:
w += time.strftime(' on %d %b %Y', time.gmtime(t))
w += time.strftime(' at %H:%MZ', time.gmtime(t))
phenny.reply('Okay, will remind%s' % w)
else: phenny.reply('Okay, will remind in %s secs' % duration)
remind.commands = ['in']
if __name__ == '__main__':
print __doc__.strip()

View File

@ -82,13 +82,13 @@ def f_remind(phenny, input):
if not phenny.reminders.has_key(tellee):
phenny.reminders[tellee] = [(teller, verb, timenow, msg)]
else:
if len(phenny.reminders[tellee]) >= maximum:
warn = True
# if len(phenny.reminders[tellee]) >= maximum:
# warn = True
phenny.reminders[tellee].append((teller, verb, timenow, msg))
# @@ Stephanie's augmentation
response = "I'll pass that on when %s is around." % tellee_original
if warn: response += (" I'll have to use a pastebin, though, so " +
"your message may get lost.")
# if warn: response += (" I'll have to use a pastebin, though, so " +
# "your message may get lost.")
rand = random.random()
if rand > 0.9999: response = "yeah, yeah"
@ -138,29 +138,9 @@ def message(phenny, input):
phenny.say(line)
if reminders[maximum:]:
try:
if origin.sender in lispchannels:
chan = origin.sender
else: chan = 'None'
result = web.post('http://paste.lisp.org/submit',
{'channel': chan,
'username': phenny.nick,
'title': 'Further Messages for %s' % tellee,
'colorize': 'None',
'text': '\n'.join(reminders[maximum:]) + '\n',
'captcha': 'lisp',
'captchaid': 'bdf447484f62a3e8b23816f9acee79d9'
}
)
uris = re.findall('http://paste.lisp.org/display/\d+', result)
uri = list(reversed(uris)).pop()
if not origin.sender in lispchannels:
message = '%s: see %s for further messages' % (tellee, uri)
phenny.say(message)
except:
error = '[Sorry, some messages were elided and lost...]'
phenny.say(error)
phenny.say('Further messages sent privately')
for line in reminders[maximum:]:
phenny.msg(tellee, line)
if len(phenny.reminders.keys()) != remkeys:
dumpReminders(phenny.tell_filename, phenny.reminders) # @@ tell

View File

@ -24,7 +24,7 @@ r_redirect = re.compile(
abbrs = ['etc', 'ca', 'cf', 'Co', 'Ltd', 'Inc', 'Mt', 'Mr', 'Mrs',
'Dr', 'Ms', 'Rev', 'Fr', 'St', 'Sgt', 'pron', 'approx', 'lit',
'syn', 'transl', 'sess', 'fl', 'Op'] \
'syn', 'transl', 'sess', 'fl', 'Op', 'Dec'] \
+ list('ABCDEFGHIJKLMNOPQRSTUVWXYZ') \
+ list('abcdefghijklmnopqrstuvwxyz')
t_sentence = r'^.{5,}?(?<!\b%s)(?:\.(?=[\[ ][A-Z0-9]|\Z)|\Z)'