master
commit
f249e43ba4
|
@ -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:
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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()
|
|
@ -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
|
||||
|
|
|
@ -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)'
|
||||
|
|
Loading…
Reference in New Issue