PEP8 compliance + clean dotnetpad
This commit is contained in:
parent
ab8f316eb9
commit
253881f4b4
18
bot.py
18
bot.py
|
@ -5,9 +5,9 @@ import Queue
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
|
|
||||||
sys.path += ['plugins'] # so 'import hook' works without duplication
|
sys.path += ['plugins'] # so 'import hook' works without duplication
|
||||||
sys.path += ['lib']
|
sys.path += ['lib']
|
||||||
os.chdir(sys.path[0] or '.') # do stuff relative to the installation directory
|
os.chdir(sys.path[0] or '.') # do stuff relative to the install directory
|
||||||
|
|
||||||
|
|
||||||
class Bot(object):
|
class Bot(object):
|
||||||
|
@ -19,7 +19,7 @@ bot = Bot()
|
||||||
print 'Loading plugins'
|
print 'Loading plugins'
|
||||||
|
|
||||||
# bootstrap the reloader
|
# bootstrap the reloader
|
||||||
eval(compile(open(os.path.join('core', 'reload.py'), 'U').read(),
|
eval(compile(open(os.path.join('core', 'reload.py'), 'U').read(),
|
||||||
os.path.join('core', 'reload.py'), 'exec'))
|
os.path.join('core', 'reload.py'), 'exec'))
|
||||||
reload(init=True)
|
reload(init=True)
|
||||||
|
|
||||||
|
@ -30,12 +30,12 @@ bot.conns = {}
|
||||||
try:
|
try:
|
||||||
for name, conf in bot.config['connections'].iteritems():
|
for name, conf in bot.config['connections'].iteritems():
|
||||||
if conf.get('ssl'):
|
if conf.get('ssl'):
|
||||||
bot.conns[name] = SSLIRC(conf['server'], conf['nick'],
|
bot.conns[name] = SSLIRC(conf['server'], conf['nick'], conf=conf,
|
||||||
port=conf.get('port', 6667), channels=conf['channels'], conf=conf,
|
port=conf.get('port', 6667), channels=conf['channels'],
|
||||||
ignore_certificate_errors=conf.get('ignore_cert', True))
|
ignore_certificate_errors=conf.get('ignore_cert', True))
|
||||||
else:
|
else:
|
||||||
bot.conns[name] = IRC(conf['server'], conf['nick'],
|
bot.conns[name] = IRC(conf['server'], conf['nick'], conf=conf,
|
||||||
port=conf.get('port', 6667), channels=conf['channels'], conf=conf)
|
port=conf.get('port', 6667), channels=conf['channels'])
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
print 'ERROR: malformed config file', Exception, e
|
print 'ERROR: malformed config file', Exception, e
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
@ -47,8 +47,8 @@ if not os.path.exists(bot.persist_dir):
|
||||||
print 'Running main loop'
|
print 'Running main loop'
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
reload() # these functions only do things
|
reload() # these functions only do things
|
||||||
config() # if changes have occured
|
config() # if changes have occured
|
||||||
|
|
||||||
for conn in bot.conns.itervalues():
|
for conn in bot.conns.itervalues():
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -2,8 +2,10 @@ import inspect
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
|
||||||
def load():
|
def load():
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
def save(conf):
|
def save(conf):
|
||||||
json.dump(conf, open('config', 'w'), sort_keys=True, indent=2)
|
json.dump(conf, open('config', 'w'), sort_keys=True, indent=2)
|
||||||
|
@ -26,7 +28,8 @@ if not os.path.exists('config'):
|
||||||
bot.config = json.load(open('config'))
|
bot.config = json.load(open('config'))
|
||||||
bot._config_mtime = os.stat('config').st_mtime
|
bot._config_mtime = os.stat('config').st_mtime
|
||||||
|
|
||||||
|
|
||||||
def config():
|
def config():
|
||||||
# reload config from file if file has changed
|
# reload config from file if file has changed
|
||||||
if bot._config_mtime != os.stat('config').st_mtime:
|
if bot._config_mtime != os.stat('config').st_mtime:
|
||||||
bot.config = json.load(open('config'))
|
bot.config = json.load(open('config'))
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import os
|
import os
|
||||||
import sqlite3
|
import sqlite3
|
||||||
|
|
||||||
|
|
||||||
def get_db_connection(server, name='skybot.%s.db'):
|
def get_db_connection(server, name='skybot.%s.db'):
|
||||||
"returns an sqlite3 connection to a persistent database"
|
"returns an sqlite3 connection to a persistent database"
|
||||||
filename = os.path.join(bot.persist_dir, name % server)
|
filename = os.path.join(bot.persist_dir, name % server)
|
||||||
return sqlite3.connect(filename, timeout=10)
|
return sqlite3.connect(filename, timeout=10)
|
||||||
|
|
||||||
bot.get_db_connection = get_db_connection
|
bot.get_db_connection = get_db_connection
|
||||||
|
|
46
core/irc.py
46
core/irc.py
|
@ -7,6 +7,7 @@ import Queue
|
||||||
|
|
||||||
from ssl import wrap_socket, CERT_NONE, CERT_REQUIRED, SSLError
|
from ssl import wrap_socket, CERT_NONE, CERT_REQUIRED, SSLError
|
||||||
|
|
||||||
|
|
||||||
def decode(txt):
|
def decode(txt):
|
||||||
for codec in ('utf-8', 'iso-8859-1', 'shift_jis', 'cp1252'):
|
for codec in ('utf-8', 'iso-8859-1', 'shift_jis', 'cp1252'):
|
||||||
try:
|
try:
|
||||||
|
@ -15,14 +16,15 @@ def decode(txt):
|
||||||
continue
|
continue
|
||||||
return txt.decode('utf-8', 'ignore')
|
return txt.decode('utf-8', 'ignore')
|
||||||
|
|
||||||
|
|
||||||
class crlf_tcp(object):
|
class crlf_tcp(object):
|
||||||
"Handles tcp connections that consist of utf-8 lines ending with crlf"
|
"Handles tcp connections that consist of utf-8 lines ending with crlf"
|
||||||
|
|
||||||
def __init__(self, host, port, timeout=300):
|
def __init__(self, host, port, timeout=300):
|
||||||
self.ibuffer = ""
|
self.ibuffer = ""
|
||||||
self.obuffer = ""
|
self.obuffer = ""
|
||||||
self.oqueue = Queue.Queue() # lines to be sent out
|
self.oqueue = Queue.Queue() # lines to be sent out
|
||||||
self.iqueue = Queue.Queue() # lines that were received
|
self.iqueue = Queue.Queue() # lines that were received
|
||||||
self.socket = self.create_socket()
|
self.socket = self.create_socket()
|
||||||
self.host = host
|
self.host = host
|
||||||
self.port = port
|
self.port = port
|
||||||
|
@ -30,7 +32,7 @@ class crlf_tcp(object):
|
||||||
|
|
||||||
def create_socket(self):
|
def create_socket(self):
|
||||||
return socket.socket(socket.AF_INET, socket.TCP_NODELAY)
|
return socket.socket(socket.AF_INET, socket.TCP_NODELAY)
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
self.socket.connect((self.host, self.port))
|
self.socket.connect((self.host, self.port))
|
||||||
thread.start_new_thread(self.recv_loop, ())
|
thread.start_new_thread(self.recv_loop, ())
|
||||||
|
@ -38,10 +40,10 @@ class crlf_tcp(object):
|
||||||
|
|
||||||
def recv_from_socket(self, nbytes):
|
def recv_from_socket(self, nbytes):
|
||||||
return self.socket.recv(nbytes)
|
return self.socket.recv(nbytes)
|
||||||
|
|
||||||
def get_timeout_exception_type(self):
|
def get_timeout_exception_type(self):
|
||||||
return socket.timeout
|
return socket.timeout
|
||||||
|
|
||||||
def handle_receive_exception(self, error, last_timestamp):
|
def handle_receive_exception(self, error, last_timestamp):
|
||||||
if time.time() - last_timestamp > self.timeout:
|
if time.time() - last_timestamp > self.timeout:
|
||||||
self.iqueue.put(StopIteration)
|
self.iqueue.put(StopIteration)
|
||||||
|
@ -81,28 +83,30 @@ class crlf_tcp(object):
|
||||||
sent = self.socket.send(self.obuffer)
|
sent = self.socket.send(self.obuffer)
|
||||||
self.obuffer = self.obuffer[sent:]
|
self.obuffer = self.obuffer[sent:]
|
||||||
|
|
||||||
|
|
||||||
class crlf_ssl_tcp(crlf_tcp):
|
class crlf_ssl_tcp(crlf_tcp):
|
||||||
"Handles ssl tcp connetions that consist of utf-8 lines ending with crlf"
|
"Handles ssl tcp connetions that consist of utf-8 lines ending with crlf"
|
||||||
def __init__(self, host, port, ignore_cert_errors, timeout=300):
|
def __init__(self, host, port, ignore_cert_errors, timeout=300):
|
||||||
self.ignore_cert_errors = ignore_cert_errors
|
self.ignore_cert_errors = ignore_cert_errors
|
||||||
crlf_tcp.__init__(self, host, port, timeout)
|
crlf_tcp.__init__(self, host, port, timeout)
|
||||||
|
|
||||||
def create_socket(self):
|
def create_socket(self):
|
||||||
return wrap_socket(crlf_tcp.create_socket(self), server_side=False,
|
return wrap_socket(crlf_tcp.create_socket(self), server_side=False,
|
||||||
cert_reqs = [CERT_REQUIRED, CERT_NONE][self.ignore_cert_errors])
|
cert_reqs=CERT_NONE if self.ignore_cert_errors else
|
||||||
|
CERT_REQUIRED)
|
||||||
|
|
||||||
def recv_from_socket(self, nbytes):
|
def recv_from_socket(self, nbytes):
|
||||||
return self.socket.read(nbytes)
|
return self.socket.read(nbytes)
|
||||||
|
|
||||||
def get_timeout_exception_type(self):
|
def get_timeout_exception_type(self):
|
||||||
return SSLError
|
return SSLError
|
||||||
|
|
||||||
def handle_receive_exception(self, error, last_timestamp):
|
def handle_receive_exception(self, error, last_timestamp):
|
||||||
# this is terrible
|
# this is terrible
|
||||||
if not "timed out" in error.args[0]:
|
if not "timed out" in error.args[0]:
|
||||||
raise
|
raise
|
||||||
return crlf_tcp.handle_receive_exception(self, error, last_timestamp)
|
return crlf_tcp.handle_receive_exception(self, error, last_timestamp)
|
||||||
|
|
||||||
irc_prefix_rem = re.compile(r'(.*?) (.*?) (.*)').match
|
irc_prefix_rem = re.compile(r'(.*?) (.*?) (.*)').match
|
||||||
irc_noprefix_rem = re.compile(r'()(.*?) (.*)').match
|
irc_noprefix_rem = re.compile(r'()(.*?) (.*)').match
|
||||||
irc_netmask_rem = re.compile(r':?([^!@]*)!?([^@]*)@?(.*)').match
|
irc_netmask_rem = re.compile(r':?([^!@]*)!?([^@]*)@?(.*)').match
|
||||||
|
@ -119,7 +123,7 @@ class IRC(object):
|
||||||
self.port = port
|
self.port = port
|
||||||
self.nick = nick
|
self.nick = nick
|
||||||
|
|
||||||
self.out = Queue.Queue() #responses from the server are placed here
|
self.out = Queue.Queue() # responses from the server are placed here
|
||||||
# format: [rawline, prefix, command, params,
|
# format: [rawline, prefix, command, params,
|
||||||
# nick, user, host, paramlist, msg]
|
# nick, user, host, paramlist, msg]
|
||||||
self.connect()
|
self.connect()
|
||||||
|
@ -128,7 +132,7 @@ class IRC(object):
|
||||||
|
|
||||||
def create_connection(self):
|
def create_connection(self):
|
||||||
return crlf_tcp(self.server, self.port)
|
return crlf_tcp(self.server, self.port)
|
||||||
|
|
||||||
def connect(self):
|
def connect(self):
|
||||||
self.conn = self.create_connection()
|
self.conn = self.create_connection()
|
||||||
thread.start_new_thread(self.conn.run, ())
|
thread.start_new_thread(self.conn.run, ())
|
||||||
|
@ -146,7 +150,7 @@ class IRC(object):
|
||||||
self.connect()
|
self.connect()
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if msg.startswith(":"): #has a prefix
|
if msg.startswith(":"): # has a prefix
|
||||||
prefix, command, params = irc_prefix_rem(msg).groups()
|
prefix, command, params = irc_prefix_rem(msg).groups()
|
||||||
else:
|
else:
|
||||||
prefix, command, params = irc_noprefix_rem(msg).groups()
|
prefix, command, params = irc_noprefix_rem(msg).groups()
|
||||||
|
@ -178,13 +182,14 @@ class IRC(object):
|
||||||
def cmd(self, command, params=None):
|
def cmd(self, command, params=None):
|
||||||
if params:
|
if params:
|
||||||
params[-1] = ':' + params[-1]
|
params[-1] = ':' + params[-1]
|
||||||
self.send(command+' '+' '.join(params))
|
self.send(command + ' ' + ' '.join(params))
|
||||||
else:
|
else:
|
||||||
self.send(command)
|
self.send(command)
|
||||||
|
|
||||||
def send(self, str):
|
def send(self, str):
|
||||||
self.conn.oqueue.put(str)
|
self.conn.oqueue.put(str)
|
||||||
|
|
||||||
|
|
||||||
class FakeIRC(IRC):
|
class FakeIRC(IRC):
|
||||||
def __init__(self, server, nick, port=6667, channels=[], conf={}, fn=""):
|
def __init__(self, server, nick, port=6667, channels=[], conf={}, fn=""):
|
||||||
self.channels = channels
|
self.channels = channels
|
||||||
|
@ -193,7 +198,7 @@ class FakeIRC(IRC):
|
||||||
self.port = port
|
self.port = port
|
||||||
self.nick = nick
|
self.nick = nick
|
||||||
|
|
||||||
self.out = Queue.Queue() #responses from the server are placed here
|
self.out = Queue.Queue() # responses from the server are placed here
|
||||||
|
|
||||||
self.f = open(fn, 'rb')
|
self.f = open(fn, 'rb')
|
||||||
|
|
||||||
|
@ -207,7 +212,7 @@ class FakeIRC(IRC):
|
||||||
print "!!!!DONE READING FILE!!!!"
|
print "!!!!DONE READING FILE!!!!"
|
||||||
return
|
return
|
||||||
|
|
||||||
if msg.startswith(":"): #has a prefix
|
if msg.startswith(":"): # has a prefix
|
||||||
prefix, command, params = irc_prefix_rem(msg).groups()
|
prefix, command, params = irc_prefix_rem(msg).groups()
|
||||||
else:
|
else:
|
||||||
prefix, command, params = irc_noprefix_rem(msg).groups()
|
prefix, command, params = irc_noprefix_rem(msg).groups()
|
||||||
|
@ -225,12 +230,13 @@ class FakeIRC(IRC):
|
||||||
|
|
||||||
def cmd(self, command, params=None):
|
def cmd(self, command, params=None):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class SSLIRC(IRC):
|
class SSLIRC(IRC):
|
||||||
def __init__(self, server, nick, port=6667, channels=[], conf={},
|
def __init__(self, server, nick, port=6667, channels=[], conf={},
|
||||||
ignore_certificate_errors=True):
|
ignore_certificate_errors=True):
|
||||||
self.ignore_cert_errors = ignore_certificate_errors
|
self.ignore_cert_errors = ignore_certificate_errors
|
||||||
IRC.__init__(self, server, nick, port, channels, conf)
|
IRC.__init__(self, server, nick, port, channels, conf)
|
||||||
|
|
||||||
def create_connection(self):
|
def create_connection(self):
|
||||||
return crlf_ssl_tcp(self.server, self.port, self.ignore_cert_errors)
|
return crlf_ssl_tcp(self.server, self.port, self.ignore_cert_errors)
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
import thread
|
import thread
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
|
|
||||||
class Input(dict):
|
class Input(dict):
|
||||||
def __init__(self, conn, raw, prefix, command, params,
|
def __init__(self, conn, raw, prefix, command, params,
|
||||||
nick, user, host, paraml, msg):
|
nick, user, host, paraml, msg):
|
||||||
|
|
||||||
chan = paraml[0].lower()
|
chan = paraml[0].lower()
|
||||||
if chan == conn.nick: # is a PM
|
if chan == conn.nick: # is a PM
|
||||||
chan = nick
|
chan = nick
|
||||||
|
|
||||||
def say(msg):
|
def say(msg):
|
||||||
|
@ -20,9 +21,9 @@ class Input(dict):
|
||||||
|
|
||||||
dict.__init__(self, conn=conn, raw=raw, prefix=prefix, command=command,
|
dict.__init__(self, conn=conn, raw=raw, prefix=prefix, command=command,
|
||||||
params=params, nick=nick, user=user, host=host,
|
params=params, nick=nick, user=user, host=host,
|
||||||
paraml=paraml, msg=msg, server=conn.server, chan=chan,
|
paraml=paraml, msg=msg, server=conn.server, chan=chan,
|
||||||
say=say, reply=reply, pm=pm, bot=bot)
|
say=say, reply=reply, pm=pm, bot=bot)
|
||||||
self.__dict__ = self # permits attribute access to values
|
self.__dict__ = self # permits attribute access to values
|
||||||
|
|
||||||
|
|
||||||
def run(func, input):
|
def run(func, input):
|
||||||
|
|
|
@ -10,12 +10,14 @@ if 'mtimes' not in globals():
|
||||||
if 'lastfiles' not in globals():
|
if 'lastfiles' not in globals():
|
||||||
lastfiles = set()
|
lastfiles = set()
|
||||||
|
|
||||||
|
|
||||||
def format_plug(plug, lpad=0, width=40):
|
def format_plug(plug, lpad=0, width=40):
|
||||||
out = ' ' * lpad + '%s:%s:%s' % (plug[0])
|
out = ' ' * lpad + '%s:%s:%s' % (plug[0])
|
||||||
if len(plug) == 3 and 'hook' in plug[2]:
|
if len(plug) == 3 and 'hook' in plug[2]:
|
||||||
out += '%s%s' % (' ' * (width - len(out)), plug[2]['hook'])
|
out += '%s%s' % (' ' * (width - len(out)), plug[2]['hook'])
|
||||||
return out
|
return out
|
||||||
|
|
||||||
|
|
||||||
def reload(init=False):
|
def reload(init=False):
|
||||||
if init:
|
if init:
|
||||||
bot.plugs = collections.defaultdict(lambda: [])
|
bot.plugs = collections.defaultdict(lambda: [])
|
||||||
|
@ -25,12 +27,12 @@ def reload(init=False):
|
||||||
if mtime != mtimes.get(filename):
|
if mtime != mtimes.get(filename):
|
||||||
mtimes[filename] = mtime
|
mtimes[filename] = mtime
|
||||||
try:
|
try:
|
||||||
eval(compile(open(filename, 'U').read(), filename, 'exec'),
|
eval(compile(open(filename, 'U').read(), filename, 'exec'),
|
||||||
globals())
|
globals())
|
||||||
except Exception:
|
except Exception:
|
||||||
traceback.print_exc(Exception)
|
traceback.print_exc(Exception)
|
||||||
if init: # stop if there's a syntax error in a core
|
if init: # stop if there's a syntax error in a core
|
||||||
sys.exit() # script on startup
|
sys.exit() # script on startup
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if filename == os.path.join('core', 'reload.py'):
|
if filename == os.path.join('core', 'reload.py'):
|
||||||
|
@ -38,7 +40,7 @@ def reload(init=False):
|
||||||
return
|
return
|
||||||
|
|
||||||
fileset = set(glob.glob(os.path.join('plugins', '*py')))
|
fileset = set(glob.glob(os.path.join('plugins', '*py')))
|
||||||
for name, data in bot.plugs.iteritems(): # remove deleted/moved plugins
|
for name, data in bot.plugs.iteritems(): # remove deleted/moved plugins
|
||||||
bot.plugs[name] = filter(lambda x: x[0][0] in fileset, data)
|
bot.plugs[name] = filter(lambda x: x[0][0] in fileset, data)
|
||||||
|
|
||||||
for filename in fileset:
|
for filename in fileset:
|
||||||
|
@ -56,7 +58,7 @@ def reload(init=False):
|
||||||
# remove plugins already loaded from this filename
|
# remove plugins already loaded from this filename
|
||||||
for name, data in bot.plugs.iteritems():
|
for name, data in bot.plugs.iteritems():
|
||||||
|
|
||||||
if name == 'tee': # signal tee trampolines to stop
|
if name == 'tee': # signal tee trampolines to stop
|
||||||
for csig, func, args in data:
|
for csig, func, args in data:
|
||||||
if csig[0] == filename:
|
if csig[0] == filename:
|
||||||
func._iqueue.put(StopIteration)
|
func._iqueue.put(StopIteration)
|
||||||
|
@ -64,7 +66,7 @@ def reload(init=False):
|
||||||
bot.plugs[name] = filter(lambda x: x[0][0] != filename, data)
|
bot.plugs[name] = filter(lambda x: x[0][0] != filename, data)
|
||||||
|
|
||||||
for obj in namespace.itervalues():
|
for obj in namespace.itervalues():
|
||||||
if hasattr(obj, '_skybot_hook'): #check for magic
|
if hasattr(obj, '_skybot_hook'): # check for magic
|
||||||
for type, data in obj._skybot_hook:
|
for type, data in obj._skybot_hook:
|
||||||
bot.plugs[type] += [data]
|
bot.plugs[type] += [data]
|
||||||
|
|
||||||
|
|
|
@ -7,8 +7,8 @@ from util import hook
|
||||||
|
|
||||||
########### from http://effbot.org/zone/re-sub.htm#unescape-html #############
|
########### from http://effbot.org/zone/re-sub.htm#unescape-html #############
|
||||||
|
|
||||||
def unescape(text):
|
|
||||||
|
|
||||||
|
def unescape(text):
|
||||||
def fixup(m):
|
def fixup(m):
|
||||||
text = m.group(0)
|
text = m.group(0)
|
||||||
if text[:2] == "&#":
|
if text[:2] == "&#":
|
||||||
|
@ -26,7 +26,7 @@ def unescape(text):
|
||||||
text = unichr(htmlentitydefs.name2codepoint[text[1:-1]])
|
text = unichr(htmlentitydefs.name2codepoint[text[1:-1]])
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
return text # leave as is
|
return text # leave as is
|
||||||
|
|
||||||
return re.sub("&#?\w+;", fixup, text)
|
return re.sub("&#?\w+;", fixup, text)
|
||||||
|
|
||||||
|
|
|
@ -21,8 +21,8 @@ def bf(inp):
|
||||||
program = re.sub('[^][<>+-.,]', '', inp)
|
program = re.sub('[^][<>+-.,]', '', inp)
|
||||||
|
|
||||||
# create a dict of brackets pairs, for speed later on
|
# create a dict of brackets pairs, for speed later on
|
||||||
brackets={}
|
brackets = {}
|
||||||
open_brackets=[]
|
open_brackets = []
|
||||||
for pos in range(len(program)):
|
for pos in range(len(program)):
|
||||||
if program[pos] == '[':
|
if program[pos] == '[':
|
||||||
open_brackets.append(pos)
|
open_brackets.append(pos)
|
||||||
|
@ -40,9 +40,9 @@ def bf(inp):
|
||||||
ip = 0 # instruction pointer
|
ip = 0 # instruction pointer
|
||||||
mp = 0 # memory pointer
|
mp = 0 # memory pointer
|
||||||
steps = 0
|
steps = 0
|
||||||
memory = [0] * BUFFER_SIZE #initial memory area
|
memory = [0] * BUFFER_SIZE # initial memory area
|
||||||
rightmost = 0
|
rightmost = 0
|
||||||
output = "" #we'll save the output here
|
output = "" # we'll save the output here
|
||||||
|
|
||||||
# the main program loop:
|
# the main program loop:
|
||||||
while ip < len(program):
|
while ip < len(program):
|
||||||
|
@ -57,7 +57,7 @@ def bf(inp):
|
||||||
rightmost = mp
|
rightmost = mp
|
||||||
if mp >= len(memory):
|
if mp >= len(memory):
|
||||||
# no restriction on memory growth!
|
# no restriction on memory growth!
|
||||||
memory.extend([0]*BUFFER_SIZE)
|
memory.extend([0] * BUFFER_SIZE)
|
||||||
elif c == '<':
|
elif c == '<':
|
||||||
mp = mp - 1 % len(memory)
|
mp = mp - 1 % len(memory)
|
||||||
elif c == '.':
|
elif c == '.':
|
||||||
|
|
|
@ -3,13 +3,14 @@ import random
|
||||||
|
|
||||||
from util import hook
|
from util import hook
|
||||||
|
|
||||||
|
|
||||||
@hook.command
|
@hook.command
|
||||||
def choose(inp):
|
def choose(inp):
|
||||||
".choose <choice1>, <choice2>, ... <choicen> -- makes a decision"
|
".choose <choice1>, <choice2>, ... <choicen> -- makes a decision"
|
||||||
|
|
||||||
if not inp:
|
if not inp:
|
||||||
return choose.__doc__
|
return choose.__doc__
|
||||||
|
|
||||||
c = re.findall(r'([^,]+)', inp)
|
c = re.findall(r'([^,]+)', inp)
|
||||||
if len(c) == 1:
|
if len(c) == 1:
|
||||||
c = re.findall(r'(\S+)', inp)
|
c = re.findall(r'(\S+)', inp)
|
||||||
|
|
|
@ -9,7 +9,7 @@ from util import hook
|
||||||
|
|
||||||
|
|
||||||
whitespace_re = re.compile(r'\s+')
|
whitespace_re = re.compile(r'\s+')
|
||||||
valid_diceroll_re = re.compile(r'^[+-]?(\d+|\d*d\d+)([+-](\d+|\d*d\d+))*$',
|
valid_diceroll_re = re.compile(r'^[+-]?(\d+|\d*d\d+)([+-](\d+|\d*d\d+))*$',
|
||||||
re.I)
|
re.I)
|
||||||
sign_re = re.compile(r'[+-]?(?:\d*d)?\d+', re.I)
|
sign_re = re.compile(r'[+-]?(?:\d*d)?\d+', re.I)
|
||||||
split_re = re.compile(r'([\d+-]*)d?(\d*)', re.I)
|
split_re = re.compile(r'([\d+-]*)d?(\d*)', re.I)
|
||||||
|
@ -17,15 +17,15 @@ split_re = re.compile(r'([\d+-]*)d?(\d*)', re.I)
|
||||||
|
|
||||||
def nrolls(count, n):
|
def nrolls(count, n):
|
||||||
"roll an n-sided die count times"
|
"roll an n-sided die count times"
|
||||||
if n < 2: #it's a coin
|
if n < 2: # it's a coin
|
||||||
if count < 5000:
|
if count < 5000:
|
||||||
return sum(random.randint(0, 1) for x in xrange(count))
|
return sum(random.randint(0, 1) for x in xrange(count))
|
||||||
else: #fake it
|
else: # fake it
|
||||||
return int(random.normalvariate(.5*count, (.75*count)**.5))
|
return int(random.normalvariate(.5*count, (.75*count)**.5))
|
||||||
else:
|
else:
|
||||||
if count < 5000:
|
if count < 5000:
|
||||||
return sum(random.randint(1, n) for x in xrange(count))
|
return sum(random.randint(1, n) for x in xrange(count))
|
||||||
else: #fake it
|
else: # fake it
|
||||||
return int(random.normalvariate(.5*(1+n)*count,
|
return int(random.normalvariate(.5*(1+n)*count,
|
||||||
(((n+1)*(2*n+1)/6.-(.5*(1+n))**2)*count)**.5))
|
(((n+1)*(2*n+1)/6.-(.5*(1+n))**2)*count)**.5))
|
||||||
|
|
||||||
|
|
|
@ -59,38 +59,39 @@ def cs(snippet):
|
||||||
|
|
||||||
if not snippet:
|
if not snippet:
|
||||||
return cs.__doc__
|
return cs.__doc__
|
||||||
|
|
||||||
file_template = ('using System; '
|
file_template = ('using System; '
|
||||||
'using System.Linq; '
|
'using System.Linq; '
|
||||||
'using System.Collections.Generic; '
|
'using System.Collections.Generic; '
|
||||||
'using System.Text; '
|
'using System.Text; '
|
||||||
'%(class)s')
|
'%s')
|
||||||
|
|
||||||
class_template = ('public class Default '
|
class_template = ('public class Default '
|
||||||
'{ '
|
'{'
|
||||||
' %(main)s '
|
' %s '
|
||||||
'}')
|
'}')
|
||||||
|
|
||||||
main_template = ('public static void Main(String[] args) '
|
main_template = ('public static void Main(String[] args) '
|
||||||
'{ '
|
'{'
|
||||||
' %(snippet)s '
|
' %s '
|
||||||
'}')
|
'}')
|
||||||
|
|
||||||
# There are probably better ways to do the following, but I'm feeling lazy
|
# There are probably better ways to do the following, but I'm feeling lazy
|
||||||
# if no main is found in the snippet, then we use the template with Main in it
|
# if no main is found in the snippet, use the template with Main in it
|
||||||
if 'public static void Main' not in snippet:
|
if 'public static void Main' not in snippet:
|
||||||
code = main_template % { 'snippet': snippet }
|
code = main_template % snippet
|
||||||
code = class_template % { 'main': code }
|
code = class_template % code
|
||||||
code = file_template % { 'class' : code }
|
code = file_template % code
|
||||||
|
|
||||||
# if Main is found, check for class and see if we need to use the classed template
|
# if Main is found, check for class and see if we need to use the
|
||||||
|
# classed template
|
||||||
elif 'class' not in snippet:
|
elif 'class' not in snippet:
|
||||||
code = class_template % { 'main': snippet }
|
code = class_template % snippet
|
||||||
code = file_template % { 'class' : code }
|
code = file_template % code
|
||||||
|
|
||||||
return 'Error using dotnetpad'
|
return 'Error using dotnetpad'
|
||||||
# if we found class, then use the barebones template
|
# if we found class, then use the barebones template
|
||||||
else:
|
else:
|
||||||
code = file_template % { 'class' : snippet }
|
code = file_template % snippet
|
||||||
|
|
||||||
return dotnetpad('csharp', code)
|
return dotnetpad('csharp', code)
|
||||||
|
|
|
@ -3,6 +3,7 @@ import urlparse
|
||||||
|
|
||||||
from util import hook
|
from util import hook
|
||||||
|
|
||||||
|
|
||||||
@hook.command
|
@hook.command
|
||||||
def down(inp):
|
def down(inp):
|
||||||
'''.down <url> -- checks to see if the site is down'''
|
'''.down <url> -- checks to see if the site is down'''
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
from util import hook
|
from util import hook
|
||||||
from pycparser.cdecl import explain_c_declaration
|
from pycparser.cdecl import explain_c_declaration
|
||||||
|
|
||||||
|
|
||||||
@hook.command
|
@hook.command
|
||||||
def explain(inp):
|
def explain(inp):
|
||||||
".explain <c expression> -- gives an explanation of C expression"
|
".explain <c expression> -- gives an explanation of C expression"
|
||||||
|
@ -9,7 +10,7 @@ def explain(inp):
|
||||||
|
|
||||||
inp = inp.encode('utf8', 'ignore')
|
inp = inp.encode('utf8', 'ignore')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
return explain_c_declaration(inp)
|
return explain_c_declaration(inp)
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
return 'error: %s' % e
|
return 'error: %s' % e
|
||||||
|
|
|
@ -5,6 +5,7 @@ from lxml import html
|
||||||
|
|
||||||
from util import hook
|
from util import hook
|
||||||
|
|
||||||
|
|
||||||
@hook.command
|
@hook.command
|
||||||
def calc(inp):
|
def calc(inp):
|
||||||
'''.calc <term> -- returns Google Calculator result'''
|
'''.calc <term> -- returns Google Calculator result'''
|
||||||
|
@ -22,7 +23,7 @@ def calc(inp):
|
||||||
if m is None:
|
if m is None:
|
||||||
return "could not calculate " + inp
|
return "could not calculate " + inp
|
||||||
|
|
||||||
result = m.group(1).replace("<font size=-2> </font>",",")
|
result = m.group(1).replace("<font size=-2> </font>", ",")
|
||||||
result = result.replace(" × 10<sup>","E").replace("</sup>","")
|
result = result.replace(" × 10<sup>", "E").replace("</sup>", "")
|
||||||
result = result.replace("\xa0",",")
|
result = result.replace("\xa0", ",")
|
||||||
return result
|
return result
|
||||||
|
|
|
@ -27,8 +27,8 @@ def gis(inp):
|
||||||
parsed['responseStatus'], ''))
|
parsed['responseStatus'], ''))
|
||||||
if not parsed['responseData']['results']:
|
if not parsed['responseData']['results']:
|
||||||
return 'no images found'
|
return 'no images found'
|
||||||
return random.choice(parsed['responseData']['results'][:10]
|
return random.choice(parsed['responseData']['results'][:10]) \
|
||||||
)['unescapedUrl'] # squares is dumb
|
['unescapedUrl'] # squares is dumb
|
||||||
|
|
||||||
|
|
||||||
@hook.command
|
@hook.command
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
from util import hook
|
from util import hook
|
||||||
|
|
||||||
#Scaevolus: factormystic if you commit a re-enabled goonsay I'm going to revoke your commit access
|
|
||||||
|
#Scaevolus: factormystic if you commit a re-enabled goonsay I'm
|
||||||
|
# going to revoke your commit access
|
||||||
#@hook.command
|
#@hook.command
|
||||||
def goonsay(inp, say=None):
|
def goonsay(inp, say=None):
|
||||||
say(' __________ /')
|
say(' __________ /')
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
from util import hook
|
from util import hook
|
||||||
|
|
||||||
|
|
||||||
@hook.command
|
@hook.command
|
||||||
def help(inp, bot=None, pm=None):
|
def help(inp, bot=None, pm=None):
|
||||||
".help [command] -- gives a list of commands/help for a command"
|
".help [command] -- gives a list of commands/help for a command"
|
||||||
|
|
||||||
funcs = {}
|
funcs = {}
|
||||||
for csig, func, args in bot.plugs['command']:
|
for csig, func, args in bot.plugs['command']:
|
||||||
if args['hook'] != r'(.*)':
|
if args['hook'] != r'(.*)':
|
||||||
|
|
|
@ -12,7 +12,7 @@ from util import hook
|
||||||
|
|
||||||
|
|
||||||
lock = thread.allocate_lock()
|
lock = thread.allocate_lock()
|
||||||
log_fds = {} # '%(net)s %(chan)s' : (filename, fd)
|
log_fds = {} # '%(net)s %(chan)s' : (filename, fd)
|
||||||
|
|
||||||
timestamp_format = '%H:%M:%S'
|
timestamp_format = '%H:%M:%S'
|
||||||
|
|
||||||
|
@ -69,8 +69,8 @@ def get_log_fd(dir, server, chan):
|
||||||
cache_key = '%s %s' % (server, chan)
|
cache_key = '%s %s' % (server, chan)
|
||||||
filename, fd = log_fds.get(cache_key, ('', 0))
|
filename, fd = log_fds.get(cache_key, ('', 0))
|
||||||
|
|
||||||
if fn != filename: # we need to open a file for writing
|
if fn != filename: # we need to open a file for writing
|
||||||
if fd != 0: # is a valid fd
|
if fd != 0: # is a valid fd
|
||||||
fd.flush()
|
fd.flush()
|
||||||
fd.close()
|
fd.close()
|
||||||
dir = os.path.split(fn)[0]
|
dir = os.path.split(fn)[0]
|
||||||
|
@ -90,14 +90,14 @@ def log(bot, input):
|
||||||
fd = get_log_fd(bot.persist_dir, input.server, 'raw')
|
fd = get_log_fd(bot.persist_dir, input.server, 'raw')
|
||||||
fd.write(timestamp + ' ' + input.raw + '\n')
|
fd.write(timestamp + ' ' + input.raw + '\n')
|
||||||
|
|
||||||
if input.command == 'QUIT': # these are temporary fixes until proper
|
if input.command == 'QUIT': # these are temporary fixes until proper
|
||||||
input.chan = 'quit' # presence tracking is implemented
|
input.chan = 'quit' # presence tracking is implemented
|
||||||
if input.command == 'NICK':
|
if input.command == 'NICK':
|
||||||
input.chan = 'nick'
|
input.chan = 'nick'
|
||||||
|
|
||||||
beau = beautify(input)
|
beau = beautify(input)
|
||||||
|
|
||||||
if beau == '': # don't log this
|
if beau == '': # don't log this
|
||||||
return
|
return
|
||||||
|
|
||||||
if input.chan:
|
if input.chan:
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from util import hook
|
from util import hook
|
||||||
import socket
|
import socket
|
||||||
|
|
||||||
socket.setdefaulttimeout(5) # global setting
|
socket.setdefaulttimeout(5) # global setting
|
||||||
|
|
||||||
|
|
||||||
#autorejoin channels
|
#autorejoin channels
|
||||||
|
@ -11,12 +11,14 @@ def rejoin(inp, paraml=[], conn=None):
|
||||||
if paraml[0].lower() in conn.channels:
|
if paraml[0].lower() in conn.channels:
|
||||||
conn.join(paraml[0])
|
conn.join(paraml[0])
|
||||||
|
|
||||||
|
|
||||||
#join channels when invited
|
#join channels when invited
|
||||||
@hook.event('INVITE')
|
@hook.event('INVITE')
|
||||||
def invite(inp, command='', conn=None):
|
def invite(inp, command='', conn=None):
|
||||||
if command == 'INVITE':
|
if command == 'INVITE':
|
||||||
conn.join(inp)
|
conn.join(inp)
|
||||||
|
|
||||||
|
|
||||||
#join channels when server says hello & identify bot
|
#join channels when server says hello & identify bot
|
||||||
@hook.event('004')
|
@hook.event('004')
|
||||||
def onjoin(inp, conn=None):
|
def onjoin(inp, conn=None):
|
||||||
|
|
|
@ -8,7 +8,7 @@ from util import hook
|
||||||
|
|
||||||
@hook.command
|
@hook.command
|
||||||
def mtg(inp):
|
def mtg(inp):
|
||||||
".mtg <card> -- gets information about Magic the Gathering card <card name>"
|
".mtg <name> -- gets information about Magic the Gathering card <name>"
|
||||||
url = 'http://magiccards.info/query.php?cardname='
|
url = 'http://magiccards.info/query.php?cardname='
|
||||||
url += urllib2.quote(inp, safe='')
|
url += urllib2.quote(inp, safe='')
|
||||||
h = html.parse(url)
|
h = html.parse(url)
|
||||||
|
@ -20,11 +20,11 @@ def mtg(inp):
|
||||||
|
|
||||||
type = text.text
|
type = text.text
|
||||||
text = text.find('b').text_content()
|
text = text.find('b').text_content()
|
||||||
text = re.sub(r'\(.*?\)', '', text) # strip parenthetical explanations
|
text = re.sub(r'\(.*?\)', '', text) # strip parenthetical explanations
|
||||||
text = re.sub(r'\.(\S)', r'. \1', text) # fix spacing
|
text = re.sub(r'\.(\S)', r'. \1', text) # fix spacing
|
||||||
|
|
||||||
printings = card.find('table/tr/td/img').getparent().text_content()
|
printings = card.find('table/tr/td/img').getparent().text_content()
|
||||||
printings = re.findall(r'\s*(.+?(?: \([^)]+\))*) \((.*?)\)',
|
printings = re.findall(r'\s*(.+?(?: \([^)]+\))*) \((.*?)\)',
|
||||||
' '.join(printings.split()))
|
' '.join(printings.split()))
|
||||||
printing_out = ', '.join('%s (%s)' % (set_abbrevs.get(x[0], x[0]),
|
printing_out = ', '.join('%s (%s)' % (set_abbrevs.get(x[0], x[0]),
|
||||||
rarity_abbrevs.get(x[1], x[1]))
|
rarity_abbrevs.get(x[1], x[1]))
|
||||||
|
|
|
@ -8,15 +8,17 @@ from util import hook
|
||||||
def add_quote(db, chan, nick, add_nick, msg):
|
def add_quote(db, chan, nick, add_nick, msg):
|
||||||
now = time.time()
|
now = time.time()
|
||||||
db.execute('''insert or fail into quote (chan, nick, add_nick,
|
db.execute('''insert or fail into quote (chan, nick, add_nick,
|
||||||
msg, time) values(?,?,?,?,?)''',
|
msg, time) values(?,?,?,?,?)''',
|
||||||
(chan, nick, add_nick, msg, now))
|
(chan, nick, add_nick, msg, now))
|
||||||
db.commit()
|
db.commit()
|
||||||
|
|
||||||
|
|
||||||
def get_quotes_by_nick(db, chan, nick):
|
def get_quotes_by_nick(db, chan, nick):
|
||||||
return db.execute("select time, nick, msg from quote where deleted!=1 "
|
return db.execute("select time, nick, msg from quote where deleted!=1 "
|
||||||
"and chan=? and lower(nick)=lower(?) order by time",
|
"and chan=? and lower(nick)=lower(?) order by time",
|
||||||
(chan, nick)).fetchall()
|
(chan, nick)).fetchall()
|
||||||
|
|
||||||
|
|
||||||
def get_quotes_by_chan(db, chan):
|
def get_quotes_by_chan(db, chan):
|
||||||
return db.execute("select time, nick, msg from quote where deleted!=1 "
|
return db.execute("select time, nick, msg from quote where deleted!=1 "
|
||||||
"and chan=? order by time", (chan,)).fetchall()
|
"and chan=? order by time", (chan,)).fetchall()
|
||||||
|
@ -24,9 +26,10 @@ def get_quotes_by_chan(db, chan):
|
||||||
|
|
||||||
def format_quote(q, num, n_quotes):
|
def format_quote(q, num, n_quotes):
|
||||||
ctime, nick, msg = q
|
ctime, nick, msg = q
|
||||||
return "[%d/%d] %s <%s> %s" % (num, n_quotes,
|
return "[%d/%d] %s <%s> %s" % (num, n_quotes,
|
||||||
time.strftime("%Y-%m-%d", time.gmtime(ctime)), nick, msg)
|
time.strftime("%Y-%m-%d", time.gmtime(ctime)), nick, msg)
|
||||||
|
|
||||||
|
|
||||||
@hook.command('q')
|
@hook.command('q')
|
||||||
@hook.command
|
@hook.command
|
||||||
def quote(inp, nick='', chan='', db=None):
|
def quote(inp, nick='', chan='', db=None):
|
||||||
|
@ -46,12 +49,12 @@ def quote(inp, nick='', chan='', db=None):
|
||||||
quoted_nick, msg = add.groups()
|
quoted_nick, msg = add.groups()
|
||||||
try:
|
try:
|
||||||
add_quote(db, chan, quoted_nick, nick, msg)
|
add_quote(db, chan, quoted_nick, nick, msg)
|
||||||
except db.IntegrityError:
|
except db.IntegrityError:
|
||||||
return "message already stored, doing nothing."
|
return "message already stored, doing nothing."
|
||||||
return "quote added."
|
return "quote added."
|
||||||
elif retrieve:
|
elif retrieve:
|
||||||
select, num = retrieve.groups()
|
select, num = retrieve.groups()
|
||||||
|
|
||||||
by_chan = False
|
by_chan = False
|
||||||
if select.startswith('#'):
|
if select.startswith('#'):
|
||||||
by_chan = True
|
by_chan = True
|
||||||
|
@ -69,7 +72,7 @@ def quote(inp, nick='', chan='', db=None):
|
||||||
|
|
||||||
if num:
|
if num:
|
||||||
if num > n_quotes:
|
if num > n_quotes:
|
||||||
return "I only have %d quote%s for %s" % (n_quotes,
|
return "I only have %d quote%s for %s" % (n_quotes,
|
||||||
('s', '')[n_quotes == 1], select)
|
('s', '')[n_quotes == 1], select)
|
||||||
else:
|
else:
|
||||||
selected_quote = quotes[num - 1]
|
selected_quote = quotes[num - 1]
|
||||||
|
|
|
@ -1,24 +1,23 @@
|
||||||
'''
|
'''
|
||||||
regular.py
|
regular.py
|
||||||
|
|
||||||
skybot plugin for testing regular expressions
|
skybot plugin for testing regular expressions
|
||||||
by Ipsum
|
by Ipsum
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from util import hook
|
from util import hook
|
||||||
|
|
||||||
|
|
||||||
@hook.command('re')
|
@hook.command('re')
|
||||||
def reg(inp):
|
def reg(inp):
|
||||||
".re <regex> <string> -- matches regular expression in given <string> "\
|
".re <regex> <string> -- matches regular expression in given <string> "\
|
||||||
"(leave 2 spaces between)"
|
"(leave 2 spaces between)"
|
||||||
|
|
||||||
query = inp.split(" ", 1)
|
query = inp.split(" ", 1)
|
||||||
|
|
||||||
if not inp or len(query) != 2:
|
if not inp or len(query) != 2:
|
||||||
return reg.__doc__
|
return reg.__doc__
|
||||||
|
|
||||||
return '|'.join(re.findall(query[0], query[1]))
|
return '|'.join(re.findall(query[0], query[1]))
|
||||||
|
|
||||||
|
|
|
@ -4,11 +4,13 @@ remember.py: written by Scaevolus 2010
|
||||||
|
|
||||||
from util import hook
|
from util import hook
|
||||||
|
|
||||||
|
|
||||||
def db_init(db):
|
def db_init(db):
|
||||||
db.execute("create table if not exists memory(chan, word, data, nick,"
|
db.execute("create table if not exists memory(chan, word, data, nick,"
|
||||||
" primary key(chan, word))")
|
" primary key(chan, word))")
|
||||||
db.commit()
|
db.commit()
|
||||||
|
|
||||||
|
|
||||||
def get_memory(db, chan, word):
|
def get_memory(db, chan, word):
|
||||||
row = db.execute("select data from memory where chan=? and word=lower(?)",
|
row = db.execute("select data from memory where chan=? and word=lower(?)",
|
||||||
(chan, word)).fetchone()
|
(chan, word)).fetchone()
|
||||||
|
@ -17,6 +19,7 @@ def get_memory(db, chan, word):
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
@hook.command
|
@hook.command
|
||||||
def remember(inp, nick='', chan='', db=None):
|
def remember(inp, nick='', chan='', db=None):
|
||||||
".remember <word> <data> -- maps word to data in the memory"
|
".remember <word> <data> -- maps word to data in the memory"
|
||||||
|
@ -37,6 +40,7 @@ def remember(inp, nick='', chan='', db=None):
|
||||||
else:
|
else:
|
||||||
return 'done.'
|
return 'done.'
|
||||||
|
|
||||||
|
|
||||||
@hook.command
|
@hook.command
|
||||||
def forget(inp, chan='', db=None):
|
def forget(inp, chan='', db=None):
|
||||||
".forget <word> -- forgets the mapping that word had"
|
".forget <word> -- forgets the mapping that word had"
|
||||||
|
@ -57,6 +61,7 @@ def forget(inp, chan='', db=None):
|
||||||
else:
|
else:
|
||||||
return "I don't know about that."
|
return "I don't know about that."
|
||||||
|
|
||||||
|
|
||||||
@hook.command(hook='\?(.+)', prefix=False)
|
@hook.command(hook='\?(.+)', prefix=False)
|
||||||
def question(inp, chan='', say=None, db=None):
|
def question(inp, chan='', say=None, db=None):
|
||||||
"?<word> -- shows what data is associated with word"
|
"?<word> -- shows what data is associated with word"
|
||||||
|
|
|
@ -13,7 +13,7 @@ def seeninput(bot, input):
|
||||||
db = bot.get_db_connection(input.server)
|
db = bot.get_db_connection(input.server)
|
||||||
db_init(db)
|
db_init(db)
|
||||||
db.execute("insert or replace into seen(name, time, quote, chan)"
|
db.execute("insert or replace into seen(name, time, quote, chan)"
|
||||||
"values(?,?,?,?)", (input.nick.lower(), time.time(), input.msg,
|
"values(?,?,?,?)", (input.nick.lower(), time.time(), input.msg,
|
||||||
input.chan))
|
input.chan))
|
||||||
db.commit()
|
db.commit()
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ def seen(inp, nick='', chan='', db=None):
|
||||||
|
|
||||||
if last_seen:
|
if last_seen:
|
||||||
reltime = timesince.timesince(last_seen[1])
|
reltime = timesince.timesince(last_seen[1])
|
||||||
if last_seen[0] != inp.lower(): # for glob matching
|
if last_seen[0] != inp.lower(): # for glob matching
|
||||||
inp = last_seen[0]
|
inp = last_seen[0]
|
||||||
return '%s was last seen %s ago saying: %s' % \
|
return '%s was last seen %s ago saying: %s' % \
|
||||||
(inp, reltime, last_seen[2])
|
(inp, reltime, last_seen[2])
|
||||||
|
|
|
@ -17,7 +17,7 @@ def sieve_suite(bot, input, func, args):
|
||||||
hook = args.get('hook', r'(.*)')
|
hook = args.get('hook', r'(.*)')
|
||||||
|
|
||||||
if args.get('prefix', True):
|
if args.get('prefix', True):
|
||||||
if input.chan == input.nick: # private message, prefix not required
|
if input.chan == input.nick: # private message, prefix not required
|
||||||
prefix = r'^(?:[.!]?|'
|
prefix = r'^(?:[.!]?|'
|
||||||
else:
|
else:
|
||||||
prefix = r'^(?:[.!]|'
|
prefix = r'^(?:[.!]|'
|
||||||
|
|
|
@ -6,12 +6,13 @@ import json
|
||||||
|
|
||||||
from util import hook
|
from util import hook
|
||||||
|
|
||||||
|
|
||||||
@hook.command
|
@hook.command
|
||||||
def suggest(inp, inp_unstripped=''):
|
def suggest(inp, inp_unstripped=''):
|
||||||
".suggest [#n] <phrase> -- gets a random/the nth suggested google search"
|
".suggest [#n] <phrase> -- gets a random/the nth suggested google search"
|
||||||
if not inp:
|
if not inp:
|
||||||
return suggest.__doc__
|
return suggest.__doc__
|
||||||
|
|
||||||
inp = inp_unstripped
|
inp = inp_unstripped
|
||||||
m = re.match('^#(\d+) (.+)$', inp)
|
m = re.match('^#(\d+) (.+)$', inp)
|
||||||
if m:
|
if m:
|
||||||
|
|
|
@ -5,9 +5,10 @@ import time
|
||||||
|
|
||||||
from util import hook, timesince
|
from util import hook, timesince
|
||||||
|
|
||||||
|
|
||||||
def get_tells(db, user_to, chan):
|
def get_tells(db, user_to, chan):
|
||||||
return db.execute("select user_from, message, time from tell where"
|
return db.execute("select user_from, message, time from tell where"
|
||||||
" user_to=lower(?) and chan=? order by time",
|
" user_to=lower(?) and chan=? order by time",
|
||||||
(user_to.lower(), chan)).fetchall()
|
(user_to.lower(), chan)).fetchall()
|
||||||
|
|
||||||
|
|
||||||
|
@ -18,7 +19,7 @@ def tellinput(bot, input):
|
||||||
|
|
||||||
if 'showtells' in input.msg.lower():
|
if 'showtells' in input.msg.lower():
|
||||||
return
|
return
|
||||||
|
|
||||||
db = bot.get_db_connection(input.server)
|
db = bot.get_db_connection(input.server)
|
||||||
db = db_init(db)
|
db = db_init(db)
|
||||||
|
|
||||||
|
@ -37,14 +38,15 @@ def tellinput(bot, input):
|
||||||
db.commit()
|
db.commit()
|
||||||
input.reply(reply)
|
input.reply(reply)
|
||||||
|
|
||||||
|
|
||||||
@hook.command
|
@hook.command
|
||||||
def showtells(inp, nick='', chan='', pm=None, db=None):
|
def showtells(inp, nick='', chan='', pm=None, db=None):
|
||||||
".showtells -- view all pending tell messages (sent in PM)."
|
".showtells -- view all pending tell messages (sent in PM)."
|
||||||
|
|
||||||
db_init(db)
|
db_init(db)
|
||||||
|
|
||||||
tells = get_tells(db, nick, chan)
|
tells = get_tells(db, nick, chan)
|
||||||
|
|
||||||
if not tells:
|
if not tells:
|
||||||
pm("You have no pending tells.")
|
pm("You have no pending tells.")
|
||||||
return
|
return
|
||||||
|
@ -53,11 +55,12 @@ def showtells(inp, nick='', chan='', pm=None, db=None):
|
||||||
user_from, message, time = tell
|
user_from, message, time = tell
|
||||||
reltime = timesince.timesince(time)
|
reltime = timesince.timesince(time)
|
||||||
pm("%s said %s ago: %s" % (user_from, reltime, message))
|
pm("%s said %s ago: %s" % (user_from, reltime, message))
|
||||||
|
|
||||||
db.execute("delete from tell where user_to=lower(?) and chan=?",
|
db.execute("delete from tell where user_to=lower(?) and chan=?",
|
||||||
(nick, chan))
|
(nick, chan))
|
||||||
db.commit()
|
db.commit()
|
||||||
|
|
||||||
|
|
||||||
@hook.command
|
@hook.command
|
||||||
def tell(inp, nick='', chan='', db=None):
|
def tell(inp, nick='', chan='', db=None):
|
||||||
".tell <nick> <message> -- relay <message> to <nick> when <nick> is around"
|
".tell <nick> <message> -- relay <message> to <nick> when <nick> is around"
|
||||||
|
@ -70,7 +73,7 @@ def tell(inp, nick='', chan='', db=None):
|
||||||
user_to = query[0].lower()
|
user_to = query[0].lower()
|
||||||
message = query[1].strip()
|
message = query[1].strip()
|
||||||
user_from = nick
|
user_from = nick
|
||||||
|
|
||||||
if user_to == user_from.lower():
|
if user_to == user_from.lower():
|
||||||
return "No."
|
return "No."
|
||||||
|
|
||||||
|
@ -97,5 +100,5 @@ def db_init(db):
|
||||||
"(user_to, user_from, message, chan, time,"
|
"(user_to, user_from, message, chan, time,"
|
||||||
"primary key(user_to, message))")
|
"primary key(user_to, message))")
|
||||||
db.commit()
|
db.commit()
|
||||||
|
|
||||||
return db
|
return db
|
||||||
|
|
|
@ -26,10 +26,12 @@ def unescape_xml(string):
|
||||||
history = []
|
history = []
|
||||||
history_max_size = 250
|
history_max_size = 250
|
||||||
|
|
||||||
|
|
||||||
@hook.command
|
@hook.command
|
||||||
def twitter(inp):
|
def twitter(inp):
|
||||||
".twitter <user>/<user> <n>/<id>/#<hashtag>/@<user> -- gets last/<n>th tweet from"\
|
".twitter <user>/<user> <n>/<id>/#<hashtag>/@<user> -- gets last/<n>th "\
|
||||||
"<user>/gets tweet <id>/gets random tweet with #<hashtag>/gets replied tweet from @<user>"
|
"tweet from <user>/gets tweet <id>/gets random tweet with #<hashtag>/"\
|
||||||
|
"gets replied tweet from @<user>"
|
||||||
|
|
||||||
if not inp:
|
if not inp:
|
||||||
return twitter.__doc__
|
return twitter.__doc__
|
||||||
|
@ -89,7 +91,7 @@ def twitter(inp):
|
||||||
try:
|
try:
|
||||||
xml = urllib2.urlopen(url).read()
|
xml = urllib2.urlopen(url).read()
|
||||||
except urllib2.HTTPError, e:
|
except urllib2.HTTPError, e:
|
||||||
errors = {400 : 'bad request (ratelimited?)',
|
errors = {400: 'bad request (ratelimited?)',
|
||||||
401: 'tweet is private',
|
401: 'tweet is private',
|
||||||
404: 'invalid user/id',
|
404: 'invalid user/id',
|
||||||
500: 'twitter is broken',
|
500: 'twitter is broken',
|
||||||
|
@ -125,10 +127,11 @@ def twitter(inp):
|
||||||
reply_name = tweet.find(reply_name).text
|
reply_name = tweet.find(reply_name).text
|
||||||
reply_id = tweet.find(reply_id).text
|
reply_id = tweet.find(reply_id).text
|
||||||
reply_user = tweet.find(reply_user).text
|
reply_user = tweet.find(reply_user).text
|
||||||
if reply_name is not None and (reply_id is not None or reply_user is not None):
|
if reply_name is not None and (reply_id is Not None or
|
||||||
|
reply_user is not None):
|
||||||
add_reply(reply_name, reply_id if reply_id else -1)
|
add_reply(reply_name, reply_id if reply_id else -1)
|
||||||
|
|
||||||
time = strftime('%Y-%m-%d %H:%M:%S',
|
time = strftime('%Y-%m-%d %H:%M:%S',
|
||||||
strptime(time.text,
|
strptime(time.text,
|
||||||
'%a %b %d %H:%M:%S +0000 %Y'))
|
'%a %b %d %H:%M:%S +0000 %Y'))
|
||||||
text = unescape_xml(tweet.find(text).text.replace('\n', ''))
|
text = unescape_xml(tweet.find(text).text.replace('\n', ''))
|
||||||
|
|
|
@ -6,10 +6,11 @@ from util import hook, urlnorm, timesince
|
||||||
|
|
||||||
url_re = re.compile(r'([a-zA-Z]+://|www\.)[^ ]*')
|
url_re = re.compile(r'([a-zA-Z]+://|www\.)[^ ]*')
|
||||||
|
|
||||||
expiration_period = 60 * 60 * 24 # 1 day
|
expiration_period = 60 * 60 * 24 # 1 day
|
||||||
|
|
||||||
ignored_urls = [urlnorm.normalize("http://google.com")]
|
ignored_urls = [urlnorm.normalize("http://google.com")]
|
||||||
|
|
||||||
|
|
||||||
def db_connect(bot, server):
|
def db_connect(bot, server):
|
||||||
"check to see that our db has the the seen table and return a dbection."
|
"check to see that our db has the the seen table and return a dbection."
|
||||||
db = bot.get_db_connection(server)
|
db = bot.get_db_connection(server)
|
||||||
|
@ -18,18 +19,21 @@ def db_connect(bot, server):
|
||||||
db.commit()
|
db.commit()
|
||||||
return db
|
return db
|
||||||
|
|
||||||
|
|
||||||
def insert_history(db, chan, url, nick):
|
def insert_history(db, chan, url, nick):
|
||||||
now = time.time()
|
now = time.time()
|
||||||
db.execute("insert into urlhistory(chan, url, nick, time) "
|
db.execute("insert into urlhistory(chan, url, nick, time) "
|
||||||
"values(?,?,?,?)", (chan, url, nick, time.time()))
|
"values(?,?,?,?)", (chan, url, nick, time.time()))
|
||||||
db.commit()
|
db.commit()
|
||||||
|
|
||||||
|
|
||||||
def get_history(db, chan, url):
|
def get_history(db, chan, url):
|
||||||
db.execute("delete from urlhistory where time < ?",
|
db.execute("delete from urlhistory where time < ?",
|
||||||
(time.time() - expiration_period,))
|
(time.time() - expiration_period,))
|
||||||
return db.execute("select nick, time from urlhistory where "
|
return db.execute("select nick, time from urlhistory where "
|
||||||
"chan=? and url=? order by time desc", (chan, url)).fetchall()
|
"chan=? and url=? order by time desc", (chan, url)).fetchall()
|
||||||
|
|
||||||
|
|
||||||
def nicklist(nicks):
|
def nicklist(nicks):
|
||||||
nicks = sorted(dict(nicks), key=unicode.lower)
|
nicks = sorted(dict(nicks), key=unicode.lower)
|
||||||
if len(nicks) <= 2:
|
if len(nicks) <= 2:
|
||||||
|
@ -37,6 +41,7 @@ def nicklist(nicks):
|
||||||
else:
|
else:
|
||||||
return ', and '.join((', '.join(nicks[:-1]), nicks[-1]))
|
return ', and '.join((', '.join(nicks[:-1]), nicks[-1]))
|
||||||
|
|
||||||
|
|
||||||
def format_reply(history):
|
def format_reply(history):
|
||||||
if not history:
|
if not history:
|
||||||
return
|
return
|
||||||
|
@ -57,10 +62,11 @@ def format_reply(history):
|
||||||
last = "last linked %s ago" % last_time
|
last = "last linked %s ago" % last_time
|
||||||
else:
|
else:
|
||||||
last = "last linked by %s %s ago" % (last_nick, last_time)
|
last = "last linked by %s %s ago" % (last_nick, last_time)
|
||||||
|
|
||||||
return "that url has been posted %s in the past %s by %s (%s)." % (ordinal,
|
return "that url has been posted %s in the past %s by %s (%s)." % (ordinal,
|
||||||
hour_span, nicklist(history), last)
|
hour_span, nicklist(history), last)
|
||||||
|
|
||||||
|
|
||||||
@hook.command(hook=r'(.*)', prefix=False)
|
@hook.command(hook=r'(.*)', prefix=False)
|
||||||
def urlinput(inp, nick='', chan='', server='', reply=None, bot=None):
|
def urlinput(inp, nick='', chan='', server='', reply=None, bot=None):
|
||||||
m = url_re.search(inp.encode('utf8'))
|
m = url_re.search(inp.encode('utf8'))
|
||||||
|
|
|
@ -3,6 +3,7 @@ import thread
|
||||||
import traceback
|
import traceback
|
||||||
import Queue
|
import Queue
|
||||||
|
|
||||||
|
|
||||||
def _isfunc(x):
|
def _isfunc(x):
|
||||||
if type(x) == type(_isfunc):
|
if type(x) == type(_isfunc):
|
||||||
return True
|
return True
|
||||||
|
@ -24,7 +25,7 @@ def _hook_add(func, add, name=''):
|
||||||
if argspec.varargs:
|
if argspec.varargs:
|
||||||
n_args -= 1
|
n_args -= 1
|
||||||
if n_args != 1:
|
if n_args != 1:
|
||||||
err = '%ss must take 1 non-keyword argument (%s)' % (name,
|
err = '%ss must take 1 non-keyword argument (%s)' % (name,
|
||||||
func.__name__)
|
func.__name__)
|
||||||
raise ValueError(err)
|
raise ValueError(err)
|
||||||
|
|
||||||
|
@ -34,9 +35,10 @@ def _hook_add(func, add, name=''):
|
||||||
args.extend(argspec.args[-len(argspec.defaults):
|
args.extend(argspec.args[-len(argspec.defaults):
|
||||||
end if end else None])
|
end if end else None])
|
||||||
if argspec.keywords:
|
if argspec.keywords:
|
||||||
args.append(0) # means kwargs present
|
args.append(0) # means kwargs present
|
||||||
func._skybot_args = args
|
func._skybot_args = args
|
||||||
|
|
||||||
|
|
||||||
def _make_sig(f):
|
def _make_sig(f):
|
||||||
return f.func_code.co_filename, f.func_name, f.func_code.co_firstlineno
|
return f.func_code.co_filename, f.func_name, f.func_code.co_firstlineno
|
||||||
|
|
||||||
|
|
|
@ -1,34 +1,35 @@
|
||||||
# Copyright (c) Django Software Foundation and individual contributors.
|
# Copyright (c) Django Software Foundation and individual contributors.
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
# Redistribution and use in source and binary forms, with or without modification,
|
# Redistribution and use in source and binary forms, with or without
|
||||||
# are permitted provided that the following conditions are met:
|
# modification, are permitted provided that the following conditions are met:
|
||||||
#
|
#
|
||||||
# 1. Redistributions of source code must retain the above copyright notice,
|
# 1. Redistributions of source code must retain the above copyright notice,
|
||||||
# this list of conditions and the following disclaimer.
|
# this list of conditions and the following disclaimer.
|
||||||
#
|
|
||||||
# 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
# notice, this list of conditions and the following disclaimer in the
|
|
||||||
# documentation and/or other materials provided with the distribution.
|
|
||||||
#
|
#
|
||||||
# 3. Neither the name of Django nor the names of its contributors may be used
|
# 2. Redistributions in binary form must reproduce the above copyright
|
||||||
# to endorse or promote products derived from this software without
|
# notice, this list of conditions and the following disclaimer in the
|
||||||
# specific prior written permission.
|
# documentation and/or other materials provided with the distribution.
|
||||||
#
|
#
|
||||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
# 3. Neither the name of Django nor the names of its contributors may be used
|
||||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
# to endorse or promote products derived from this software without
|
||||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
# specific prior written permission.
|
||||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
#
|
||||||
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"AND
|
||||||
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
#ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
#WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
#DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
#ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
#(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
#LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
#ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
#(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
#SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
|
||||||
def timesince(d, now=None):
|
def timesince(d, now=None):
|
||||||
"""
|
"""
|
||||||
Takes two datetime objects and returns the time between d and now
|
Takes two datetime objects and returns the time between d and now
|
||||||
|
@ -86,11 +87,12 @@ def timesince(d, now=None):
|
||||||
count2 = (since - (seconds * count)) // seconds2
|
count2 = (since - (seconds * count)) // seconds2
|
||||||
if count2 != 0:
|
if count2 != 0:
|
||||||
if count2 == 1:
|
if count2 == 1:
|
||||||
s += ', %(number)d %(type)s' % {'number': count2, 'type': name2[0]}
|
s += ', %d %s' % (count2, name2[0])
|
||||||
else:
|
else:
|
||||||
s += ', %(number)d %(type)s' % {'number': count2, 'type': name2[1]}
|
s += ', %d %s' % (count2, name2[1])
|
||||||
return s
|
return s
|
||||||
|
|
||||||
|
|
||||||
def timeuntil(d, now=None):
|
def timeuntil(d, now=None):
|
||||||
"""
|
"""
|
||||||
Like timesince, but returns a string measuring the time until
|
Like timesince, but returns a string measuring the time until
|
||||||
|
|
|
@ -8,7 +8,7 @@ from util import hook
|
||||||
|
|
||||||
@hook.command
|
@hook.command
|
||||||
def weather(inp, nick='', server='', reply=None, db=None):
|
def weather(inp, nick='', server='', reply=None, db=None):
|
||||||
".weather <location> [dontsave] -- queries the google weather API for weather data"
|
".weather <location> [dontsave] -- gets weather data from Google"
|
||||||
|
|
||||||
loc = inp
|
loc = inp
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ def weather(inp, nick='', server='', reply=None, db=None):
|
||||||
|
|
||||||
db.execute("create table if not exists weather(nick primary key, loc)")
|
db.execute("create table if not exists weather(nick primary key, loc)")
|
||||||
|
|
||||||
if not loc: # blank line
|
if not loc: # blank line
|
||||||
loc = db.execute("select loc from weather where nick=lower(?)",
|
loc = db.execute("select loc from weather where nick=lower(?)",
|
||||||
(nick,)).fetchone()
|
(nick,)).fetchone()
|
||||||
if not loc:
|
if not loc:
|
||||||
|
|
|
@ -26,7 +26,8 @@ def wiki(inp):
|
||||||
q = search_url % (urllib2.quote(inp, safe=''))
|
q = search_url % (urllib2.quote(inp, safe=''))
|
||||||
|
|
||||||
request = urllib2.Request(q)
|
request = urllib2.Request(q)
|
||||||
request.add_header('User-Agent', 'Skybot/1.0 http://bitbucket.org/Scaevolus/skybot/')
|
request.add_header('User-Agent',
|
||||||
|
'Skybot/1.0 http://bitbucket.org/Scaevolus/skybot/')
|
||||||
opener = urllib2.build_opener()
|
opener = urllib2.build_opener()
|
||||||
xml = opener.open(request).read()
|
xml = opener.open(request).read()
|
||||||
x = etree.fromstring(xml)
|
x = etree.fromstring(xml)
|
||||||
|
@ -54,7 +55,7 @@ def wiki(inp):
|
||||||
if title.lower() not in desc.lower():
|
if title.lower() not in desc.lower():
|
||||||
desc = title + desc
|
desc = title + desc
|
||||||
|
|
||||||
desc = re.sub('\s+', ' ', desc).strip() #remove excess spaces
|
desc = re.sub('\s+', ' ', desc).strip() # remove excess spaces
|
||||||
|
|
||||||
if len(desc) > 300:
|
if len(desc) > 300:
|
||||||
desc = desc[:300] + '...'
|
desc = desc[:300] + '...'
|
||||||
|
|
|
@ -5,6 +5,7 @@ from lxml import html
|
||||||
|
|
||||||
from util import hook
|
from util import hook
|
||||||
|
|
||||||
|
|
||||||
@hook.command
|
@hook.command
|
||||||
@hook.command('wa')
|
@hook.command('wa')
|
||||||
def wolframalpha(inp):
|
def wolframalpha(inp):
|
||||||
|
@ -21,7 +22,7 @@ def wolframalpha(inp):
|
||||||
pods = h.xpath("//div[@class='pod ']")
|
pods = h.xpath("//div[@class='pod ']")
|
||||||
|
|
||||||
pod_texts = []
|
pod_texts = []
|
||||||
for pod in pods:
|
for pod in pods:
|
||||||
heading = pod.find('h1/span')
|
heading = pod.find('h1/span')
|
||||||
if heading is not None:
|
if heading is not None:
|
||||||
heading = heading.text_content().strip()
|
heading = heading.text_content().strip()
|
||||||
|
@ -40,7 +41,7 @@ def wolframalpha(inp):
|
||||||
if results:
|
if results:
|
||||||
pod_texts.append(heading + ' ' + '|'.join(results))
|
pod_texts.append(heading + ' ' + '|'.join(results))
|
||||||
|
|
||||||
ret = '. '.join(pod_texts) # first pod is the input
|
ret = '. '.join(pod_texts)
|
||||||
|
|
||||||
if not pod_texts:
|
if not pod_texts:
|
||||||
return 'no results'
|
return 'no results'
|
||||||
|
@ -52,7 +53,7 @@ def wolframalpha(inp):
|
||||||
|
|
||||||
ret = re.sub(r'\\:([0-9a-z]{4})', unicode_sub, ret)
|
ret = re.sub(r'\\:([0-9a-z]{4})', unicode_sub, ret)
|
||||||
|
|
||||||
if len(ret) > 430:
|
if len(ret) > 430:
|
||||||
ret = ret[:ret.rfind(' ', 0, 430)]
|
ret = ret[:ret.rfind(' ', 0, 430)]
|
||||||
ret = re.sub(r'\W+$', '', ret) + '...'
|
ret = re.sub(r'\W+$', '', ret) + '...'
|
||||||
|
|
||||||
|
|
|
@ -17,11 +17,12 @@ url = base_url + 'videos/%s?v=2&alt=jsonc'
|
||||||
search_api_url = base_url + 'videos?v=2&alt=jsonc&max-results=1&q=%s'
|
search_api_url = base_url + 'videos?v=2&alt=jsonc&max-results=1&q=%s'
|
||||||
video_url = "http://youtube.com/watch?v=%s"
|
video_url = "http://youtube.com/watch?v=%s"
|
||||||
|
|
||||||
|
|
||||||
def get_video_description(vid_id):
|
def get_video_description(vid_id):
|
||||||
j = json.load(urllib2.urlopen(url % vid_id))
|
j = json.load(urllib2.urlopen(url % vid_id))
|
||||||
|
|
||||||
if j.get('error'):
|
if j.get('error'):
|
||||||
return
|
return
|
||||||
|
|
||||||
j = j['data']
|
j = j['data']
|
||||||
|
|
||||||
|
@ -29,7 +30,7 @@ def get_video_description(vid_id):
|
||||||
|
|
||||||
out += ' - length \x02'
|
out += ' - length \x02'
|
||||||
length = j['duration']
|
length = j['duration']
|
||||||
if length / 3600: # > 1 hour
|
if length / 3600: # > 1 hour
|
||||||
out += '%dh ' % (length / 3600)
|
out += '%dh ' % (length / 3600)
|
||||||
if length / 60:
|
if length / 60:
|
||||||
out += '%dm ' % (length / 60 % 60)
|
out += '%dm ' % (length / 60 % 60)
|
||||||
|
@ -38,12 +39,11 @@ def get_video_description(vid_id):
|
||||||
if 'rating' in j:
|
if 'rating' in j:
|
||||||
out += ' - rated \x02%.2f/5.0\x02 (%d)' % (j['rating'],
|
out += ' - rated \x02%.2f/5.0\x02 (%d)' % (j['rating'],
|
||||||
j['ratingCount'])
|
j['ratingCount'])
|
||||||
|
|
||||||
|
|
||||||
if 'viewCount' in j:
|
if 'viewCount' in j:
|
||||||
out += ' - \x02%s\x02 views' % locale.format('%d',
|
out += ' - \x02%s\x02 views' % locale.format('%d',
|
||||||
j['viewCount'], 1)
|
j['viewCount'], 1)
|
||||||
|
|
||||||
upload_time = time.strptime(j['uploaded'], "%Y-%m-%dT%H:%M:%S.000Z")
|
upload_time = time.strptime(j['uploaded'], "%Y-%m-%dT%H:%M:%S.000Z")
|
||||||
out += ' - \x02%s\x02 on \x02%s\x02' % (j['uploader'],
|
out += ' - \x02%s\x02 on \x02%s\x02' % (j['uploader'],
|
||||||
time.strftime("%Y.%m.%d", upload_time))
|
time.strftime("%Y.%m.%d", upload_time))
|
||||||
|
@ -52,7 +52,7 @@ def get_video_description(vid_id):
|
||||||
out += ' - \x034NSFW\x02'
|
out += ' - \x034NSFW\x02'
|
||||||
|
|
||||||
return out
|
return out
|
||||||
|
|
||||||
|
|
||||||
@hook.command(hook=r'(.*)', prefix=False)
|
@hook.command(hook=r'(.*)', prefix=False)
|
||||||
def youtube_url(inp):
|
def youtube_url(inp):
|
||||||
|
|
Loading…
Reference in New Issue