Fixed formatting.

This commit is contained in:
Fletcher Boyd 2013-09-04 18:30:04 +08:00
parent 146ae3c279
commit 4069dd21a3
89 changed files with 615 additions and 496 deletions

View file

@ -25,4 +25,3 @@ def config():
bot._config_mtime = 0 bot._config_mtime = 0

View file

@ -6,7 +6,7 @@ threaddbs = {}
def get_db_connection(conn, name=''): def get_db_connection(conn, name=''):
"returns an sqlite3 connection to a persistent database" """returns an sqlite3 connection to a persistent database"""
if not name: if not name:
name = '{}.db'.format(conn.name) name = '{}.db'.format(conn.name)

View file

@ -28,7 +28,7 @@ def censor(text):
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 = ""
@ -95,7 +95,8 @@ class crlf_tcp(object):
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)
@ -117,6 +118,7 @@ class crlf_ssl_tcp(crlf_tcp):
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
@ -124,7 +126,8 @@ irc_param_ref = re.compile(r'(?:^|(?<= ))(:.*|[^ ]+)').findall
class IRC(object): class IRC(object):
"handles the IRC protocol" """handles the IRC protocol"""
def __init__(self, name, server, nick, port=6667, channels=[], conf={}): def __init__(self, name, server, nick, port=6667, channels=[], conf={}):
self.name = name self.name = name
self.channels = channels self.channels = channels

View file

@ -77,7 +77,8 @@ def do_sieve(sieve, bot, input, func, type, args):
class Handler(object): class Handler(object):
'''Runs plugins in their own threads (ensures order)''' """Runs plugins in their own threads (ensures order)"""
def __init__(self, func): def __init__(self, func):
self.func = func self.func = func
self.input_queue = Queue.Queue() self.input_queue = Queue.Queue()
@ -103,6 +104,7 @@ class Handler(object):
run(self.func, input) run(self.func, input)
except: except:
import traceback import traceback
traceback.print_exc() traceback.print_exc()
def stop(self): def stop(self):
@ -115,11 +117,10 @@ class Handler(object):
def dispatch(input, kind, func, args, autohelp=False): def dispatch(input, kind, func, args, autohelp=False):
for sieve, in bot.plugs['sieve']: for sieve, in bot.plugs['sieve']:
input = do_sieve(sieve, bot, input, func, kind, args) input = do_sieve(sieve, bot, input, func, kind, args)
if input == None: if input is None:
return return
if autohelp and args.get('autohelp', True) and not input.inp \ if not (not autohelp or not args.get('autohelp', True) or input.inp or not (func.__doc__ is not None)):
and func.__doc__ is not None:
input.notice(input.conn.conf["command_prefix"] + func.__doc__) input.notice(input.conn.conf["command_prefix"] + func.__doc__)
return return

View file

@ -17,7 +17,7 @@ def make_signature(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
def format_plug(plug, kind='', lpad=0, width=40): def format_plug(plug, kind='', lpad=0):
out = ' ' * lpad + '%s:%s:%s' % make_signature(plug[0]) out = ' ' * lpad + '%s:%s:%s' % make_signature(plug[0])
if kind == 'command': if kind == 'command':
out += ' ' * (50 - len(out)) + plug[1]['name'] out += ' ' * (50 - len(out)) + plug[1]['name']

View file

@ -28,7 +28,7 @@ with open("plugins/data/flirts.txt") as f:
@hook.command @hook.command
def slap(inp, me=None, nick=None, conn=None, notice=None): def slap(inp, me=None, nick=None, conn=None, notice=None):
"slap <user> -- Makes the bot slap <user>." """slap <user> -- Makes the bot slap <user>."""
target = inp.strip() target = inp.strip()
if " " in target: if " " in target:
@ -48,7 +48,7 @@ def slap(inp, me=None, nick=None, conn=None, notice=None):
@hook.command @hook.command
def lart(inp, me=None, nick=None, conn=None, notice=None): def lart(inp, me=None, nick=None, conn=None, notice=None):
"lart <user> -- LARTs <user>." """lart <user> -- LARTs <user>."""
target = inp.strip() target = inp.strip()
if " " in target: if " " in target:
@ -68,7 +68,7 @@ def lart(inp, me=None, nick=None, conn=None, notice=None):
@hook.command @hook.command
def kill(inp, me=None, nick=None, conn=None, notice=None): def kill(inp, me=None, nick=None, conn=None, notice=None):
"kill <user> -- Makes the bot kill <user>." """kill <user> -- Makes the bot kill <user>."""
target = inp.strip() target = inp.strip()
if " " in target: if " " in target:
@ -88,7 +88,7 @@ def kill(inp, me=None, nick=None, conn=None, notice=None):
@hook.command @hook.command
def insult(inp, nick=None, me=None, conn=None, notice=None): def insult(inp, nick=None, me=None, conn=None, notice=None):
"insult <user> -- Makes the bot insult <user>." """insult <user> -- Makes the bot insult <user>."""
target = inp.strip() target = inp.strip()
if " " in target: if " " in target:
@ -105,8 +105,8 @@ def insult(inp, nick=None, me=None, conn=None, notice=None):
@hook.command @hook.command
def flirt(inp, nick=None, me=None, conn=None, notice=None): def flirt(inp, me=None, conn=None, notice=None):
"flirt <user> -- Make the bot flirt with <user>." """flirt <user> -- Make the bot flirt with <user>."""
target = inp.strip() target = inp.strip()
if " " in target: if " " in target:

View file

@ -3,7 +3,7 @@ from util import http, hook
@hook.command(autohelp=False) @hook.command(autohelp=False)
def bitcoin(inp, say=None): def bitcoin(inp, say=None):
"bitcoin -- gets current exchange rate for bitcoins from mtgox" """bitcoin -- gets current exchange rate for bitcoins from mtgox"""
data = http.get_json("https://data.mtgox.com/api/2/BTCUSD/money/ticker") data = http.get_json("https://data.mtgox.com/api/2/BTCUSD/money/ticker")
data = data['data'] data = data['data']
ticker = { ticker = {

View file

@ -14,7 +14,7 @@ MAX_STEPS = 1000000
@hook.command('brainfuck') @hook.command('brainfuck')
@hook.command @hook.command
def bf(inp): def bf(inp):
"bf <prog> -- Executes <prog> as Brainfuck code." """bf <prog> -- Executes <prog> as Brainfuck code."""
program = re.sub('[^][<>+-.,]', '', inp) program = re.sub('[^][<>+-.,]', '', inp)
@ -46,9 +46,9 @@ def bf(inp):
while ip < len(program): while ip < len(program):
c = program[ip] c = program[ip]
if c == '+': if c == '+':
memory[mp] = memory[mp] + 1 % 256 memory[mp] += 1 % 256
elif c == '-': elif c == '-':
memory[mp] = memory[mp] - 1 % 256 memory[mp] -= 1 % 256
elif c == '>': elif c == '>':
mp += 1 mp += 1
if mp > rightmost: if mp > rightmost:
@ -57,7 +57,7 @@ def bf(inp):
# 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 -= 1 % len(memory)
elif c == '.': elif c == '.':
output += chr(memory[mp]) output += chr(memory[mp])
if len(output) > 500: if len(output) > 500:

View file

@ -6,8 +6,8 @@ from util import hook
@hook.command @hook.command
def choose(inp): def choose(inp):
"choose <choice1>, [choice2], [choice3], [choice4], ... -- " \ """choose <choice1>, [choice2], [choice3] ... [choiceN]
"Randomly picks one of the given choices." Randomly picks one of the given choices."""
c = re.findall(r'([^,]+)', inp) c = re.findall(r'([^,]+)', inp)
if len(c) == 1: if len(c) == 1:

View file

@ -28,6 +28,7 @@ keylist = ['stimulus', 'start', 'sessionid', 'vText8', 'vText7', 'vText6',
MsgList = list() MsgList = list()
def quote(s, safe='/'): # quote('abc def') -> 'abc%20def' def quote(s, safe='/'): # quote('abc def') -> 'abc%20def'
s = s.encode('utf-8') s = s.encode('utf-8')
s = s.decode('utf-8') s = s.decode('utf-8')
@ -46,6 +47,7 @@ def quote(s, safe='/'): # quote('abc def') -> 'abc%20def'
print "res= " + ''.join(res) print "res= " + ''.join(res)
return ''.join(res) return ''.join(res)
def encode(keylist, arglist): def encode(keylist, arglist):
text = str() text = str()
for i in range(len(keylist)): for i in range(len(keylist)):
@ -55,6 +57,7 @@ def encode(keylist, arglist):
text = text[1:] text = text[1:]
return text return text
def Send(): def Send():
data = encode(keylist, arglist) data = encode(keylist, arglist)
digest_txt = data[9:29] digest_txt = data[9:29]
@ -67,6 +70,7 @@ def Send():
reply = f.read() reply = f.read()
return reply return reply
def parseAnswers(text): def parseAnswers(text):
d = dict() d = dict()
keys = ['text', 'sessionid', 'logurl', 'vText8', 'vText7', 'vText6', keys = ['text', 'sessionid', 'logurl', 'vText8', 'vText7', 'vText6',
@ -81,6 +85,7 @@ def parseAnswers(text):
i += 1 i += 1
return d return d
def ask(inp): def ask(inp):
arglist[keylist.index('stimulus')] = inp arglist[keylist.index('stimulus')] = inp
if MsgList: if MsgList:
@ -99,10 +104,12 @@ def ask(inp):
MsgList.append(text) MsgList.append(text)
return text return text
@hook.command("cb") @hook.command("cb")
def cleverbot(inp, reply=None): def cleverbot(inp, reply=None):
reply(ask(inp)) reply(ask(inp))
''' # TODO: add in command to control extra verbose per channel ''' # TODO: add in command to control extra verbose per channel
@hook.event('PRIVMSG') @hook.event('PRIVMSG')
def cbevent(inp, reply=None): def cbevent(inp, reply=None):

View file

@ -4,7 +4,7 @@ import random
@hook.command(autohelp=False) @hook.command(autohelp=False)
def coin(inp, me=None): def coin(inp, me=None):
"coin [amount] -- Flips [amount] of coins." """coin [amount] -- Flips [amount] of coins."""
if inp: if inp:
try: try:
@ -21,5 +21,5 @@ def coin(inp, me=None):
else: else:
heads = int(random.normalvariate(.5 * amount, (.75 * amount) ** .5)) heads = int(random.normalvariate(.5 * amount, (.75 * amount) ** .5))
tails = amount - heads tails = amount - heads
me("flips %i coins and gets " \ me("flips %i coins and gets "
"%i heads and %i tails." % (amount, heads, tails)) "%i heads and %i tails." % (amount, heads, tails))

View file

@ -1,8 +1,8 @@
''' """
Plugin which (de)cyphers a string Plugin which (de)cyphers a string
Doesn't cypher non-alphanumeric strings yet. Doesn't cypher non-alphanumeric strings yet.
by instanceoftom by instanceoftom
''' """
from util import hook from util import hook
chars = "abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ " chars = "abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ "
@ -11,7 +11,7 @@ len_chars = len(chars)
@hook.command @hook.command
def cypher(inp): def cypher(inp):
"cypher <pass> <string> -- Cyphers <string> with <password>." """cypher <pass> <string> -- Cyphers <string> with <password>."""
passwd = inp.split(" ")[0] passwd = inp.split(" ")[0]
len_passwd = len(passwd) len_passwd = len(passwd)
@ -38,7 +38,7 @@ def cypher(inp):
@hook.command @hook.command
def decypher(inp): def decypher(inp):
"decypher <pass> <string> -- Decyphers <string> with <password>." """decypher <pass> <string> -- Decyphers <string> with <password>."""
passwd = inp.split(" ")[0] passwd = inp.split(" ")[0]
len_passwd = len(passwd) len_passwd = len(passwd)
@ -52,7 +52,7 @@ def decypher(inp):
except ValueError: except ValueError:
continue continue
passwd_index = passwd_index - 1 passwd_index -= 1
reversed_message = inp[::-1] reversed_message = inp[::-1]
out = "" out = ""

View file

@ -15,7 +15,7 @@ split_re = re.compile(r'([\d+-]*)d?(F|\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 == "F": if n == "F":
return [random.randint(-1, 1) for x in xrange(min(count, 100))] return [random.randint(-1, 1) for x in xrange(min(count, 100))]
if n < 2: # it's a coin if n < 2: # it's a coin
@ -36,8 +36,8 @@ def nrolls(count, n):
#@hook.regex(valid_diceroll, re.I) #@hook.regex(valid_diceroll, re.I)
@hook.command @hook.command
def dice(inp): def dice(inp):
"dice <diceroll> -- Simulates dicerolls. Example of <diceroll>:" \ """dice <diceroll> -- Simulates dicerolls. Example of <diceroll>:
" 'dice 2d20-d5+4 roll 2'. D20s, subtract 1D5, add 4" 'dice 2d20-d5+4 roll 2'. D20s, subtract 1D5, add 4"""
try: # if inp is a re.match object... try: # if inp is a re.match object...
(inp, desc) = inp.groups() (inp, desc) = inp.groups()

View file

@ -7,7 +7,7 @@ from util import http
@hook.command('dictionary') @hook.command('dictionary')
@hook.command @hook.command
def define(inp): def define(inp):
"define <word> -- Fetches definition of <word>." """define <word> -- Fetches definition of <word>."""
url = 'http://ninjawords.com/' url = 'http://ninjawords.com/'
@ -67,7 +67,7 @@ def define(inp):
@hook.command('e') @hook.command('e')
@hook.command @hook.command
def etymology(inp): def etymology(inp):
"etymology <word> -- Retrieves the etymology of <word>." """etymology <word> -- Retrieves the etymology of <word>."""
url = 'http://www.etymonline.com/index.php' url = 'http://www.etymonline.com/index.php'

View file

@ -1,15 +1,18 @@
from util import hook, http from util import hook, http
@hook.command @hook.command
def domainr(inp): def domainr(inp):
"""domainr <domain> - Use domain.nr's API to search for a domain, and similar domains.""" """domainr <domain> - Use domain.nr's API to search for a domain, and similar domains."""
try: try:
data = http.get_json('http://domai.nr/api/json/search?q=' + inp); data = http.get_json('http://domai.nr/api/json/search?q=' + inp)
except (http.URLError, http.HTTPError) as e: except (http.URLError, http.HTTPError) as e:
return "Unable to get data for some reason. Try again later." return "Unable to get data for some reason. Try again later."
if data['query'] == "": if data['query'] == "":
return "An error occurrred: {status} - {message}".format(**data['error']) return "An error occurrred: {status} - {message}".format(**data['error'])
domains = ""; domains = ""
for domain in data['results']: for domain in data['results']:
domains += ("\x034" if domain['availability'] == "taken" else ("\x033" if domain['availability'] == "available" else "\x031")) + domain['domain'] + "\x0f" + domain['path'] + ", " domains += ("\x034" if domain['availability'] == "taken" else (
"\x033" if domain['availability'] == "available" else "\x031")) + domain['domain'] + "\x0f" + domain[
'path'] + ", "
return "Domains: " + domains return "Domains: " + domains

View file

@ -5,7 +5,7 @@ from util import hook, http
@hook.command @hook.command
def down(inp): def down(inp):
"down <url> -- Checks if the site at <url> is up or down." """down <url> -- Checks if the site at <url> is up or down."""
if 'http://' not in inp: if 'http://' not in inp:
inp = 'http://' + inp inp = 'http://' + inp

View file

@ -6,8 +6,8 @@ ed_url = "http://encyclopediadramatica.se/"
@hook.command @hook.command
def drama(inp): def drama(inp):
"drama <phrase> -- Gets the first paragraph of" \ """drama <phrase> -- Gets the first paragraph of
" the Encyclopedia Dramatica article on <phrase>." the Encyclopedia Dramatica article on <phrase>."""
j = http.get_json(api_url, search=inp) j = http.get_json(api_url, search=inp)
if not j[1]: if not j[1]:

View file

@ -1,5 +1,5 @@
from util import hook, text
import random import random
from util import hook, text
color_codes = { color_codes = {
"<r>": "\x02\x0305", "<r>": "\x02\x0305",
@ -9,14 +9,13 @@ color_codes = {
with open("plugins/data/8ball_responses.txt") as f: with open("plugins/data/8ball_responses.txt") as f:
responses = [line.strip() for line in responses = [line.strip() for line in
f.readlines()if not line.startswith("//")] f.readlines() if not line.startswith("//")]
@hook.command('8ball') @hook.command('8ball')
def eightball(input, me=None): def eightball(input, me=None):
"8ball <question> -- The all knowing magic eight ball, " \ """8ball <question> -- The all knowing magic eight ball,
"in electronic form. Ask and it shall be answered!" in electronic form. Ask and it shall be answered!"""
# here we use voodoo magic to tell the future
magic = text.multiword_replace(random.choice(responses), color_codes) magic = text.multiword_replace(random.choice(responses), color_codes)
me("shakes the magic 8 ball... %s" % magic) me("shakes the magic 8 ball... %s" % magic)

View file

@ -3,7 +3,7 @@ from util import hook, http, web
@hook.command(autohelp=False) @hook.command(autohelp=False)
def fact(inp, say=False, nick=False): def fact(inp, say=False, nick=False):
"fact -- Gets a random fact from OMGFACTS." """fact -- Gets a random fact from OMGFACTS."""
attempts = 0 attempts = 0

View file

@ -1,19 +1,18 @@
# Written by Scaevolus 2010 # Written by Scaevolus 2010
from util import hook, http, text, execute from util import hook, http, text, execute
import string import string
import sqlite3
import re import re
re_lineends = re.compile(r'[\r\n]*') re_lineends = re.compile(r'[\r\n]*')
# some simple "shortcodes" for formatting purposes # some simple "shortcodes" for formatting purposes
shortcodes = { shortcodes = {
'[b]': '\x02', '[b]': '\x02',
'[/b]': '\x02', '[/b]': '\x02',
'[u]': '\x1F', '[u]': '\x1F',
'[/u]': '\x1F', '[/u]': '\x1F',
'[i]': '\x16', '[i]': '\x16',
'[/i]': '\x16'} '[/i]': '\x16'}
def db_init(db): def db_init(db):
@ -23,7 +22,6 @@ def db_init(db):
def get_memory(db, word): def get_memory(db, word):
row = db.execute("select data from mem where word=lower(?)", row = db.execute("select data from mem where word=lower(?)",
[word]).fetchone() [word]).fetchone()
if row: if row:
@ -34,9 +32,9 @@ def get_memory(db, word):
@hook.command("r", permissions=["addfactoid"]) @hook.command("r", permissions=["addfactoid"])
@hook.command(permissions=["addfactoid"]) @hook.command(permissions=["addfactoid"])
def remember(inp, nick='', db=None, say=None, input=None, notice=None): def remember(inp, nick='', db=None, notice=None):
"remember <word> [+]<data> -- Remembers <data> with <word>. Add +" """remember <word> [+]<data> -- Remembers <data> with <word>. Add +
" to <data> to append." to <data> to append."""
db_init(db) db_init(db)
append = False append = False
@ -76,8 +74,8 @@ def remember(inp, nick='', db=None, say=None, input=None, notice=None):
@hook.command("f", permissions=["delfactoid"]) @hook.command("f", permissions=["delfactoid"])
@hook.command(permissions=["delfactoid"]) @hook.command(permissions=["delfactoid"])
def forget(inp, db=None, input=None, notice=None): def forget(inp, db=None, notice=None):
"forget <word> -- Forgets a remembered <word>." """forget <word> -- Forgets a remembered <word>."""
db_init(db) db_init(db)
data = get_memory(db, inp) data = get_memory(db, inp)
@ -95,7 +93,7 @@ def forget(inp, db=None, input=None, notice=None):
@hook.command @hook.command
def info(inp, notice=None, db=None): def info(inp, notice=None, db=None):
"info <factoid> -- Shows the source of a factoid." """info <factoid> -- Shows the source of a factoid."""
db_init(db) db_init(db)
@ -134,7 +132,8 @@ def factoid(inp, say=None, db=None, bot=None, me=None, conn=None, input=None):
if data.startswith("<py>"): if data.startswith("<py>"):
code = data[4:].strip() code = data[4:].strip()
variables = 'input="""%s"""; nick="%s"; chan="%s"; bot_nick="%s";' % (arguments.replace('"', '\\"'), variables = 'input="""%s"""; nick="%s"; chan="%s"; bot_nick="%s";' % (arguments.replace('"', '\\"'),
input.nick, input.chan, input.conn.nick) input.nick, input.chan,
input.conn.nick)
result = execute.eval_py(variables + code) result = execute.eval_py(variables + code)
else: else:
result = data result = data

View file

@ -7,7 +7,7 @@ api_url = "http://api.fishbans.com/stats/{}/"
@hook.command("bans") @hook.command("bans")
@hook.command @hook.command
def fishbans(inp): def fishbans(inp):
"fishbans <user> -- Gets information on <user>s minecraft bans from fishbans" """fishbans <user> -- Gets information on <user>s minecraft bans from fishbans"""
user = inp.strip() user = inp.strip()
try: try:
@ -15,7 +15,7 @@ def fishbans(inp):
except (http.HTTPError, http.URLError) as e: except (http.HTTPError, http.URLError) as e:
return "Could not fetch ban data from the Fishbans API: {}".format(e) return "Could not fetch ban data from the Fishbans API: {}".format(e)
if request["success"] == False: if not request["success"]:
return "Could not fetch ban data for {}.".format(user) return "Could not fetch ban data for {}.".format(user)
user_url = "http://fishbans.com/u/{}/".format(user) user_url = "http://fishbans.com/u/{}/".format(user)
@ -27,7 +27,7 @@ def fishbans(inp):
@hook.command @hook.command
def bancount(inp): def bancount(inp):
"bancount <user> -- Gets a count of <user>s minecraft bans from fishbans" """bancount <user> -- Gets a count of <user>s minecraft bans from fishbans"""
user = inp.strip() user = inp.strip()
try: try:
@ -35,7 +35,7 @@ def bancount(inp):
except (http.HTTPError, http.URLError) as e: except (http.HTTPError, http.URLError) as e:
return "Could not fetch ban data from the Fishbans API: {}".format(e) return "Could not fetch ban data from the Fishbans API: {}".format(e)
if request["success"] == False: if not request["success"]:
return "Could not fetch ban data for {}.".format(user) return "Could not fetch ban data for {}.".format(user)
user_url = "http://fishbans.com/u/{}/".format(user) user_url = "http://fishbans.com/u/{}/".format(user)

View file

@ -18,7 +18,7 @@ refresh_cache()
@hook.command(autohelp=False) @hook.command(autohelp=False)
def fml(inp, reply=None): def fml(inp, reply=None):
"fml -- Gets a random quote from fmyfife.com." """fml -- Gets a random quote from fmyfife.com."""
# grab the last item in the fml cache and remove it # grab the last item in the fml cache and remove it
id, text = fml_cache.pop() id, text = fml_cache.pop()

View file

@ -8,5 +8,5 @@ with open("plugins/data/fortunes.txt") as f:
@hook.command(autohelp=False) @hook.command(autohelp=False)
def fortune(inp): def fortune(inp):
"fortune -- Fortune cookies on demand." """fortune -- Fortune cookies on demand."""
return random.choice(fortunes) return random.choice(fortunes)

View file

@ -1,9 +1,10 @@
from util import hook, http from util import hook, http
@hook.command("math") @hook.command("math")
@hook.command @hook.command
def calc(inp): def calc(inp):
"calc <term> -- Calculate <term> with Google Calc." """calc <term> -- Calculate <term> with Google Calc."""
soup = http.get_soup('http://www.google.com/search', q=inp) soup = http.get_soup('http://www.google.com/search', q=inp)

View file

@ -18,7 +18,7 @@ else:
string_io = StringIO(download) string_io = StringIO(download)
geoip_file = gzip.GzipFile(fileobj=string_io, mode='rb') geoip_file = gzip.GzipFile(fileobj=string_io, mode='rb')
output = open(os.path.abspath("./plugins/data/GeoLiteCity.dat"),'wb') output = open(os.path.abspath("./plugins/data/GeoLiteCity.dat"), 'wb')
output.write(geoip_file.read()) output.write(geoip_file.read())
output.close() output.close()
@ -27,7 +27,7 @@ else:
@hook.command @hook.command
def geoip(inp): def geoip(inp):
"geoip <host/ip> -- Gets the location of <host/ip>" """geoip <host/ip> -- Gets the location of <host/ip>"""
try: try:
record = geo.record_by_name(inp) record = geo.record_by_name(inp)

View file

@ -4,6 +4,7 @@ import urllib2
shortcuts = {"cloudbot": "ClouDev/CloudBot"} shortcuts = {"cloudbot": "ClouDev/CloudBot"}
def truncate(msg): def truncate(msg):
nmsg = msg.split(" ") nmsg = msg.split(" ")
out = None out = None
@ -14,12 +15,13 @@ def truncate(msg):
out = out + " " + nmsg[x] out = out + " " + nmsg[x]
else: else:
out = nmsg[x] out = nmsg[x]
x = x + 1 x += 1
if x <= 7: if x <= 7:
return out return out
else: else:
return out + "..." return out + "..."
@hook.command @hook.command
def ghissues(inp): def ghissues(inp):
"""ghissues username/repo [number] - Get specified issue summary, or open issue count """ """ghissues username/repo [number] - Get specified issue summary, or open issue count """
@ -33,7 +35,7 @@ def ghissues(inp):
except IndexError: except IndexError:
return "Invalid syntax. .github issues username/repo [number]" return "Invalid syntax. .github issues username/repo [number]"
try: try:
url = url + "/%s" % args[1] url += "/%s" % args[1]
number = True number = True
except IndexError: except IndexError:
number = False number = False
@ -53,7 +55,6 @@ def ghissues(inp):
number = data["number"] number = data["number"]
if data["state"] == "open": if data["state"] == "open":
state = u"\x033\x02OPEN\x02\x0f" state = u"\x033\x02OPEN\x02\x0f"
closedby = None
else: else:
state = u"\x034\x02CLOSED\x02\x0f by %s" % data["closed_by"]["login"] state = u"\x034\x02CLOSED\x02\x0f by %s" % data["closed_by"]["login"]
user = data["user"]["login"] user = data["user"]["login"]
@ -70,8 +71,8 @@ def ghissues(inp):
@hook.command @hook.command
def gitio(inp): def gitio(inp):
"gitio <url> [code] -- Shorten Github URLs with git.io. [code] is" \ """gitio <url> [code] -- Shorten Github URLs with git.io. [code] is
" a optional custom short code." a optional custom short code."""
split = inp.split(" ") split = inp.split(" ")
url = split[0] url = split[0]

View file

@ -13,11 +13,11 @@ def api_get(kind, query):
@hook.command('gis') @hook.command('gis')
@hook.command @hook.command
def googleimage(inp): def googleimage(inp):
"gis <query> -- Returns first Google Image result for <query>." """gis <query> -- Returns first Google Image result for <query>."""
parsed = api_get('images', inp) parsed = api_get('images', inp)
if not 200 <= parsed['responseStatus'] < 300: if not 200 <= parsed['responseStatus'] < 300:
raise IOError('error searching for images: %d: %s' % ( \ raise IOError('error searching for images: %d: %s' % (
parsed['responseStatus'], '')) parsed['responseStatus'], ''))
if not parsed['responseData']['results']: if not parsed['responseData']['results']:
return 'no images found' return 'no images found'
@ -29,7 +29,7 @@ def googleimage(inp):
@hook.command('g') @hook.command('g')
@hook.command @hook.command
def google(inp): def google(inp):
"google <query> -- Returns first google search result for <query>." """google <query> -- Returns first google search result for <query>."""
parsed = api_get('web', inp) parsed = api_get('web', inp)
if not 200 <= parsed['responseStatus'] < 300: if not 200 <= parsed['responseStatus'] < 300:

View file

@ -1,7 +1,7 @@
''' """
A Google API key is required and retrieved from the bot config file. A Google API key is required and retrieved from the bot config file.
Since December 1, 2011, the Google Translate API is a paid service only. Since December 1, 2011, the Google Translate API is a paid service only.
''' """
import htmlentitydefs import htmlentitydefs
import re import re
@ -73,10 +73,10 @@ def match_language(fragment):
@hook.command @hook.command
def translate(inp, bot=None, say=None): def translate(inp, bot=None):
'translate [source language [target language]] <sentence> -- translates' \ """translate [source language [target language]] <sentence> -- translates
' <sentence> from source language (default autodetect) to target' \ <sentence> from source language (default autodetect) to target
' language (default English) using Google Translate' language (default English) using Google Translate"""
api_key = bot.config.get("api_keys", {}).get("googletranslate", None) api_key = bot.config.get("api_keys", {}).get("googletranslate", None)
if not api_key: if not api_key:
@ -102,6 +102,7 @@ def translate(inp, bot=None, say=None):
except IOError, e: except IOError, e:
return e return e
lang_pairs = [ lang_pairs = [
("no", "Norwegian"), ("no", "Norwegian"),
("it", "Italian"), ("it", "Italian"),

View file

@ -4,6 +4,6 @@ from util import hook
@hook.command @hook.command
def hash(inp): def hash(inp):
"hash <text> -- Returns hashes of <text>." """hash <text> -- Returns hashes of <text>."""
return ', '.join(x + ": " + getattr(hashlib, x)(inp).hexdigest() return ', '.join(x + ": " + getattr(hashlib, x)(inp).hexdigest()
for x in ['md5', 'sha1', 'sha256']) for x in ['md5', 'sha1', 'sha256'])

View file

@ -3,8 +3,8 @@ from util import hook
@hook.command(autohelp=False) @hook.command(autohelp=False)
def help(inp, say=None, notice=None, input=None, conn=None, bot=None): def help(inp, notice=None, input=None, conn=None, bot=None):
"help -- Gives a list of commands/help for a command." """help -- Gives a list of commands/help for a command."""
funcs = {} funcs = {}
disabled = bot.config.get('disabled_plugins', []) disabled = bot.config.get('disabled_plugins', [])
@ -37,7 +37,7 @@ def help(inp, say=None, notice=None, input=None, conn=None, bot=None):
notice("Commands I recognise: " + out[0][1:]) notice("Commands I recognise: " + out[0][1:])
if out[1]: if out[1]:
notice(out[1][1:]) notice(out[1][1:])
notice("For detailed help, do '%shelp <example>' where <example> "\ notice("For detailed help, do '%shelp <example>' where <example> "
"is the name of the command you want help for." % conn.conf["command_prefix"]) "is the name of the command you want help for." % conn.conf["command_prefix"])
else: else:

View file

@ -6,7 +6,7 @@ db_ready = False
def db_init(db): def db_init(db):
"check to see that our db has the horoscope table and return a connection." """check to see that our db has the horoscope table and return a connection."""
db.execute("create table if not exists horoscope(nick primary key, sign)") db.execute("create table if not exists horoscope(nick primary key, sign)")
db.commit() db.commit()
db_ready = True db_ready = True
@ -14,7 +14,7 @@ def db_init(db):
@hook.command(autohelp=False) @hook.command(autohelp=False)
def horoscope(inp, db=None, notice=None, nick=None): def horoscope(inp, db=None, notice=None, nick=None):
"horoscope <sign> -- Get your horoscope." """horoscope <sign> -- Get your horoscope."""
if not db_ready: if not db_ready:
db_init(db) db_init(db)

View file

@ -16,11 +16,13 @@ def hulu_url(match):
@hook.command('hulu') @hook.command('hulu')
def hulu_search(inp): def hulu_search(inp):
"""hulu <search> - Search Hulu""" """hulu <search> - Search Hulu"""
result = http.get_soup("http://m.hulu.com/search?dp_identifier=hulu&{}&items_per_page=1&page=1".format(urlencode({'query': inp}))) result = http.get_soup(
"http://m.hulu.com/search?dp_identifier=hulu&{}&items_per_page=1&page=1".format(urlencode({'query': inp})))
data = result.find('results').find('videos').find('video') data = result.find('results').find('videos').find('video')
showname = data.find('show').find('name').text showname = data.find('show').find('name').text
title = data.find('title').text title = data.find('title').text
duration = timeformat.timeformat(int(float(data.find('duration').text))) duration = timeformat.timeformat(int(float(data.find('duration').text)))
description = data.find('description').text description = data.find('description').text
rating = data.find('content-rating').text rating = data.find('content-rating').text
return "{}: {} - {} - {} ({}) {}".format(showname, title, description, duration, rating, "http://www.hulu.com/watch/" + str(data.find('id').text)) return "{}: {} - {} - {} ({}) {}".format(showname, title, description, duration, rating,
"http://www.hulu.com/watch/" + str(data.find('id').text))

View file

@ -31,7 +31,7 @@ def ignore_sieve(bot, input, func, type, args):
@hook.command(autohelp=False) @hook.command(autohelp=False)
def ignored(inp, notice=None, bot=None): def ignored(inp, notice=None, bot=None):
"ignored -- Lists ignored channels/users." """ignored -- Lists ignored channels/users."""
ignorelist = bot.config["plugins"]["ignore"]["ignored"] ignorelist = bot.config["plugins"]["ignore"]["ignored"]
if ignorelist: if ignorelist:
notice("Ignored channels/users are: %s" % ", ".join(ignorelist)) notice("Ignored channels/users are: %s" % ", ".join(ignorelist))
@ -42,7 +42,7 @@ def ignored(inp, notice=None, bot=None):
@hook.command(permissions=["ignore"]) @hook.command(permissions=["ignore"])
def ignore(inp, notice=None, bot=None, config=None): def ignore(inp, notice=None, bot=None, config=None):
"ignore <channel|nick|host> -- Makes the bot ignore <channel|user>." """ignore <channel|nick|host> -- Makes the bot ignore <channel|user>."""
target = inp.lower() target = inp.lower()
ignorelist = bot.config["plugins"]["ignore"]["ignored"] ignorelist = bot.config["plugins"]["ignore"]["ignored"]
if target in ignorelist: if target in ignorelist:
@ -57,8 +57,8 @@ def ignore(inp, notice=None, bot=None, config=None):
@hook.command(permissions=["ignore"]) @hook.command(permissions=["ignore"])
def unignore(inp, notice=None, bot=None, config=None): def unignore(inp, notice=None, bot=None, config=None):
"unignore <channel|user> -- Makes the bot listen to"\ """unignore <channel|user> -- Makes the bot listen to
" <channel|user>." <channel|user>."""
target = inp.lower() target = inp.lower()
ignorelist = bot.config["plugins"]["ignore"]["ignored"] ignorelist = bot.config["plugins"]["ignore"]["ignored"]
if target in ignorelist: if target in ignorelist:

View file

@ -9,7 +9,7 @@ imdb_re = (r'(.*:)//(imdb.com|www.imdb.com)(:[0-9]+)?(.*)', re.I)
@hook.command @hook.command
def imdb(inp): def imdb(inp):
"imdb <movie> -- Gets information about <movie> from IMDb." """imdb <movie> -- Gets information about <movie> from IMDb."""
strip = inp.strip() strip = inp.strip()

View file

@ -1,6 +1,7 @@
from util import hook, http from util import hook, http
import re import re
@hook.command(autohelp=False) @hook.command(autohelp=False)
def kernel(inp, reply=None): def kernel(inp, reply=None):
contents = http.get("https://www.kernel.org/finger_banner") contents = http.get("https://www.kernel.org/finger_banner")

View file

@ -6,9 +6,9 @@ api_url = "http://ws.audioscrobbler.com/2.0/?format=json"
@hook.command('l', autohelp=False) @hook.command('l', autohelp=False)
@hook.command(autohelp=False) @hook.command(autohelp=False)
def lastfm(inp, nick='', say=None, db=None, bot=None, notice=None): def lastfm(inp, nick='', db=None, bot=None, notice=None):
"lastfm [user] [dontsave] -- Displays the now playing (or last played)" \ """lastfm [user] [dontsave] -- Displays the now playing (or last played)
" track of LastFM user [user]." track of LastFM user [user]."""
api_key = bot.config.get("api_keys", {}).get("lastfm") api_key = bot.config.get("api_keys", {}).get("lastfm")
if not api_key: if not api_key:
return "error: no api key set" return "error: no api key set"

View file

@ -3,5 +3,5 @@ from util import hook
@hook.command @hook.command
def length(inp): def length(inp):
"length <message> -- gets the length of <message>" """length <message> -- gets the length of <message>"""
return "The length of that message is {} characters.".format(len(inp)) return "The length of that message is {} characters.".format(len(inp))

View file

@ -3,8 +3,8 @@ from util import hook, web, http
@hook.command('gfy') @hook.command('gfy')
@hook.command @hook.command
def lmgtfy(inp, bot=None): def lmgtfy(inp):
"lmgtfy [phrase] - Posts a google link for the specified phrase" """lmgtfy [phrase] - Posts a google link for the specified phrase"""
link = "http://lmgtfy.com/?q=%s" % http.quote_plus(inp) link = "http://lmgtfy.com/?q=%s" % http.quote_plus(inp)

View file

@ -27,11 +27,11 @@ formats = {
} }
ctcp_formats = { ctcp_formats = {
'ACTION': '* %(nick)s %(ctcpmsg)s', 'ACTION': '* %(nick)s %(ctcpmsg)s',
'VERSION': '%(nick)s has requested CTCP %(ctcpcmd)s from %(chan)s: %(ctcpmsg)s', 'VERSION': '%(nick)s has requested CTCP %(ctcpcmd)s from %(chan)s: %(ctcpmsg)s',
'PING': '%(nick)s has requested CTCP %(ctcpcmd)s from %(chan)s: %(ctcpmsg)s', 'PING': '%(nick)s has requested CTCP %(ctcpcmd)s from %(chan)s: %(ctcpmsg)s',
'TIME': '%(nick)s has requested CTCP %(ctcpcmd)s from %(chan)s: %(ctcpmsg)s', 'TIME': '%(nick)s has requested CTCP %(ctcpcmd)s from %(chan)s: %(ctcpmsg)s',
'FINGER': '%(nick)s has requested CTCP %(ctcpcmd)s from %(chan)s: %(ctcpmsg)s' 'FINGER': '%(nick)s has requested CTCP %(ctcpcmd)s from %(chan)s: %(ctcpmsg)s'
} }
irc_color_re = re.compile(r'(\x03(\d+,\d+|\d)|[\x0f\x02\x16\x1f])') irc_color_re = re.compile(r'(\x03(\d+,\d+|\d)|[\x0f\x02\x16\x1f])')
@ -90,7 +90,7 @@ def get_log_fd(dir, server, chan):
@hook.singlethread @hook.singlethread
@hook.event('*') @hook.event('*')
def log(paraml, input=None, bot=None): def log(input=None, bot=None):
timestamp = gmtime(timestamp_format) timestamp = gmtime(timestamp_format)
fd = get_log_fd(bot.persist_dir, input.server, 'raw') fd = get_log_fd(bot.persist_dir, input.server, 'raw')

View file

@ -9,7 +9,8 @@ from util import hook, http
@hook.command('mc') @hook.command('mc')
@hook.command @hook.command
def metacritic(inp): def metacritic(inp):
"mc [all|movie|tv|album|x360|ps3|wii|pc|ds|3ds|vita] <title> -- Gets rating for <title> from metacritic on the specified medium." """mc [all|movie|tv|album|x360|ps3|wii|pc|ds|3ds|vita] <title>
Gets rating for <title> from metacritic on the specified medium."""
# if the results suck, it's metacritic's fault # if the results suck, it's metacritic's fault
@ -118,7 +119,7 @@ def metacritic(inp):
link = 'http://metacritic.com' + product_title.find('a').attrib['href'] link = 'http://metacritic.com' + product_title.find('a').attrib['href']
try: try:
release = result.find_class('release_date')[0].\ release = result.find_class('release_date')[0]. \
find_class('data')[0].text_content() find_class('data')[0].text_content()
# strip extra spaces out of the release date # strip extra spaces out of the release date

View file

@ -4,7 +4,7 @@ import json
@hook.command(autohelp=False) @hook.command(autohelp=False)
def mcstatus(inp, say=None): def mcstatus(inp, say=None):
"mcstatus -- Checks the status of various Mojang (the creators of Minecraft) servers." """mcstatus -- Checks the status of various Mojang (the creators of Minecraft) servers."""
try: try:
request = http.get("http://status.mojang.com/check") request = http.get("http://status.mojang.com/check")
@ -28,7 +28,7 @@ def mcstatus(inp, say=None):
@hook.command("haspaid") @hook.command("haspaid")
@hook.command @hook.command
def mcpaid(inp): def mcpaid(inp):
"mcpaid <username> -- Checks if <username> has a premium Minecraft account." """mcpaid <username> -- Checks if <username> has a premium Minecraft account."""
user = inp.strip() user = inp.strip()

View file

@ -7,8 +7,8 @@ mc_url = "http://minecraftwiki.net/wiki/"
@hook.command @hook.command
def mcwiki(inp): def mcwiki(inp):
"mcwiki <phrase> -- Gets the first paragraph of" \ """mcwiki <phrase> -- Gets the first paragraph of
" the Minecraft Wiki article on <phrase>." the Minecraft Wiki article on <phrase>."""
j = http.get_json(api_url, search=inp) j = http.get_json(api_url, search=inp)

View file

@ -1,13 +1,14 @@
# Plugin by Infinity - <https://github.com/infinitylabs/UguuBot> # Plugin by Infinity - <https://github.com/infinitylabs/UguuBot>
from util import hook, http
import random import random
from util import hook, http
mlia_cache = [] mlia_cache = []
def refresh_cache(): def refresh_cache():
"gets a page of random MLIAs and puts them into a dictionary " """gets a page of random MLIAs and puts them into a dictionary """
url = 'http://mylifeisaverage.com/%s' % random.randint(1, 11000) url = 'http://mylifeisaverage.com/%s' % random.randint(1, 11000)
soup = http.get_soup(url) soup = http.get_soup(url)

View file

@ -3,5 +3,5 @@ from util import hook, text
@hook.command @hook.command
def munge(inp): def munge(inp):
"munge <text> -- Munges up <text>." """munge <text> -- Munges up <text>."""
return text.munge(inp) return text.munge(inp)

View file

@ -1,7 +1,11 @@
# Plugin by Lukeroge # Plugin by Lukeroge
import json
import random
import re
import os
from util import hook from util import hook
from util.text import get_text_list from util.text import get_text_list
import json, random, re, os
TEMPLATE_RE = re.compile(r"\{(.+?)\}") TEMPLATE_RE = re.compile(r"\{(.+?)\}")
GEN_DIR = "./plugins/data/name_files/" GEN_DIR = "./plugins/data/name_files/"
@ -36,7 +40,7 @@ class NameGenerator(object):
return name return name
def generate_names(self, amount, template=None): def generate_names(self, amount):
names = [] names = []
for i in xrange(amount): for i in xrange(amount):
names.append(self.generate_name()) names.append(self.generate_name())
@ -48,8 +52,8 @@ class NameGenerator(object):
@hook.command(autohelp=False) @hook.command(autohelp=False)
def namegen(inp, notice=None): def namegen(inp, notice=None):
"namegen [generator] -- Generates some names using the chosen generator. " \ """namegen [generator] -- Generates some names using the chosen generator.
"'namegen list' will display a list of all generators." 'namegen list' will display a list of all generators."""
# clean up the input # clean up the input
inp = inp.strip().lower() inp = inp.strip().lower()

View file

@ -35,7 +35,8 @@ def newgrounds_url(match):
# get amount of ratings # get amount of ratings
try: try:
ratings_info = soup.find('dd', {'class': 'star-variable'})['title'].split("Stars &ndash;")[1].replace("Votes", "").strip() ratings_info = soup.find('dd', {'class': 'star-variable'})['title'].split("Stars &ndash;")[1].replace("Votes",
"").strip()
numofratings = " ({})".format(ratings_info) numofratings = " ({})".format(ratings_info)
except: except:
numofratings = "" numofratings = ""

View file

@ -15,73 +15,74 @@ def mode_cmd(mode, text, inp, chan, conn, notice):
notice("Attempting to {} {} in {}...".format(text, target, channel)) notice("Attempting to {} {} in {}...".format(text, target, channel))
conn.send("MODE {} {} {}".format(channel, mode, target)) conn.send("MODE {} {} {}".format(channel, mode, target))
@hook.command(permissions=["op_ban", "op"]) @hook.command(permissions=["op_ban", "op"])
def ban(inp, conn=None, chan=None, notice=None): def ban(inp, conn=None, chan=None, notice=None):
"ban [channel] <user> -- Makes the bot ban <user> in [channel]. "\ """ban [channel] <user> -- Makes the bot ban <user> in [channel].
"If [channel] is blank the bot will ban <user> in "\ If [channel] is blank the bot will ban <user> in
"the channel the command was used in." the channel the command was used in."""
mode_cmd("+b", "ban", inp, chan, conn, notice) mode_cmd("+b", "ban", inp, chan, conn, notice)
@hook.command(permissions=["op_ban", "op"]) @hook.command(permissions=["op_ban", "op"])
def unban(inp, conn=None, chan=None, notice=None): def unban(inp, conn=None, chan=None, notice=None):
"unban [channel] <user> -- Makes the bot unban <user> in [channel]. "\ """unban [channel] <user> -- Makes the bot unban <user> in [channel].
"If [channel] is blank the bot will unban <user> in "\ If [channel] is blank the bot will unban <user> in
"the channel the command was used in." the channel the command was used in."""
mode_cmd("-b", "unban", inp, chan, conn, notice) mode_cmd("-b", "unban", inp, chan, conn, notice)
@hook.command(permissions=["op_quiet", "op"]) @hook.command(permissions=["op_quiet", "op"])
def quiet(inp, conn=None, chan=None, notice=None): def quiet(inp, conn=None, chan=None, notice=None):
"quiet [channel] <user> -- Makes the bot quiet <user> in [channel]. "\ """quiet [channel] <user> -- Makes the bot quiet <user> in [channel].
"If [channel] is blank the bot will quiet <user> in "\ If [channel] is blank the bot will quiet <user> in
"the channel the command was used in." the channel the command was used in."""
mode_cmd("+q", "quiet", inp, chan, conn, notice) mode_cmd("+q", "quiet", inp, chan, conn, notice)
@hook.command(permissions=["op_quiet", "op"]) @hook.command(permissions=["op_quiet", "op"])
def unquiet(inp, conn=None, chan=None, notice=None): def unquiet(inp, conn=None, chan=None, notice=None):
"unquiet [channel] <user> -- Makes the bot unquiet <user> in [channel]. "\ """unquiet [channel] <user> -- Makes the bot unquiet <user> in [channel].
"If [channel] is blank the bot will unquiet <user> in "\ If [channel] is blank the bot will unquiet <user> in
"the channel the command was used in." the channel the command was used in."""
mode_cmd("-q", "unquiet", inp, chan, conn, notice) mode_cmd("-q", "unquiet", inp, chan, conn, notice)
@hook.command(permissions=["op_voice", "op"]) @hook.command(permissions=["op_voice", "op"])
def voice(inp, conn=None, chan=None, notice=None): def voice(inp, conn=None, chan=None, notice=None):
"voice [channel] <user> -- Makes the bot voice <user> in [channel]. "\ """voice [channel] <user> -- Makes the bot voice <user> in [channel].
"If [channel] is blank the bot will voice <user> in "\ If [channel] is blank the bot will voice <user> in
"the channel the command was used in." the channel the command was used in."""
mode_cmd("+v", "voice", inp, chan, conn, notice) mode_cmd("+v", "voice", inp, chan, conn, notice)
@hook.command(permissions=["op_voice", "op"]) @hook.command(permissions=["op_voice", "op"])
def devoice(inp, conn=None, chan=None, notice=None): def devoice(inp, conn=None, chan=None, notice=None):
"devoice [channel] <user> -- Makes the bot devoice <user> in [channel]. "\ """devoice [channel] <user> -- Makes the bot devoice <user> in [channel].
"If [channel] is blank the bot will devoice <user> in "\ If [channel] is blank the bot will devoice <user> in
"the channel the command was used in." the channel the command was used in."""
mode_cmd("-v", "devoice", inp, chan, conn, notice) mode_cmd("-v", "devoice", inp, chan, conn, notice)
@hook.command(permissions=["op_op", "op"]) @hook.command(permissions=["op_op", "op"])
def op(inp, conn=None, chan=None, notice=None): def op(inp, conn=None, chan=None, notice=None):
"op [channel] <user> -- Makes the bot op <user> in [channel]. "\ """op [channel] <user> -- Makes the bot op <user> in [channel].
"If [channel] is blank the bot will op <user> in "\ If [channel] is blank the bot will op <user> in
"the channel the command was used in." the channel the command was used in."""
mode_cmd("+o", "op", inp, chan, conn, notice) mode_cmd("+o", "op", inp, chan, conn, notice)
@hook.command(permissions=["op_op", "op"]) @hook.command(permissions=["op_op", "op"])
def deop(inp, conn=None, chan=None, notice=None): def deop(inp, conn=None, chan=None, notice=None):
"deop [channel] <user> -- Makes the bot deop <user> in [channel]. "\ """deop [channel] <user> -- Makes the bot deop <user> in [channel].
"If [channel] is blank the bot will deop <user> in "\ If [channel] is blank the bot will deop <user> in
"the channel the command was used in." the channel the command was used in."""
mode_cmd("-o", "deop", inp, chan, conn, notice) mode_cmd("-o", "deop", inp, chan, conn, notice)
@hook.command(permissions=["op_topic", "op"]) @hook.command(permissions=["op_topic", "op"])
def topic(inp, conn=None, chan=None): def topic(inp, conn=None, chan=None):
"topic [channel] <topic> -- Change the topic of a channel." """topic [channel] <topic> -- Change the topic of a channel."""
split = inp.split(" ") split = inp.split(" ")
if split[0].startswith("#"): if split[0].startswith("#"):
message = " ".join(split[1:]) message = " ".join(split[1:])
@ -95,9 +96,9 @@ def topic(inp, conn=None, chan=None):
@hook.command(permissions=["op_kick", "op"]) @hook.command(permissions=["op_kick", "op"])
def kick(inp, chan=None, conn=None, notice=None): def kick(inp, chan=None, conn=None, notice=None):
"kick [channel] <user> [reason] -- Makes the bot kick <user> in [channel] "\ """kick [channel] <user> [reason] -- Makes the bot kick <user> in [channel]
"If [channel] is blank the bot will kick the <user> in "\ If [channel] is blank the bot will kick the <user> in
"the channel the command was used in." the channel the command was used in."""
split = inp.split(" ") split = inp.split(" ")
if split[0].startswith("#"): if split[0].startswith("#"):
@ -120,9 +121,10 @@ def kick(inp, chan=None, conn=None, notice=None):
notice("Attempting to kick {} from {}...".format(target, channel)) notice("Attempting to kick {} from {}...".format(target, channel))
conn.send(out) conn.send(out)
@hook.command(permissions=["op_rem", "op"]) @hook.command(permissions=["op_rem", "op"])
def remove(inp, chan=None, conn=None, notice=None): def remove(inp, chan=None, conn=None):
"remove [channel] [user] -- Force a user to part from a channel." """remove [channel] [user] -- Force a user to part from a channel."""
split = inp.split(" ") split = inp.split(" ")
if split[0].startswith("#"): if split[0].startswith("#"):
message = " ".join(split[1:]) message = " ".join(split[1:])

View file

@ -6,7 +6,8 @@ import random
@hook.command @hook.command
def password(inp, notice=None): def password(inp, notice=None):
"password <length> [types] -- Generates a password of <length> (default 10). [types] can include 'alpha', 'no caps', 'numeric', 'symbols' or any combination of the inp, eg. 'numbers symbols'" """password <length> [types] -- Generates a password of <length> (default 10).
[types] can include 'alpha', 'no caps', 'numeric', 'symbols' or any combination of the inp, eg. 'numbers symbols'"""
okay = [] okay = []
# find the length needed for the password # find the length needed for the password
@ -30,7 +31,8 @@ def password(inp, notice=None):
# add symbols # add symbols
if "symbol" in inp: if "symbol" in inp:
sym = ['!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '-', '=', '_', '+', '[', ']', '{', '}', '\\', '|', ';', ':', "'", '.', '>', ',', '<', '/', '?', '`', '~', '"'] sym = ['!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '-', '=', '_', '+', '[', ']', '{', '}', '\\', '|', ';',
':', "'", '.', '>', ',', '<', '/', '?', '`', '~', '"']
okay += okay + sym okay += okay + sym
# defaults to lowercase alpha password if the okay list is empty # defaults to lowercase alpha password if the okay list is empty

View file

@ -9,7 +9,7 @@ ping_regex = re.compile(r"(\d+.\d+)/(\d+.\d+)/(\d+.\d+)/(\d+.\d+)")
@hook.command @hook.command
def ping(inp, reply=None): def ping(inp, reply=None):
"ping <host> [count] -- Pings <host> [count] times." """ping <host> [count] -- Pings <host> [count] times."""
if os.name == "nt": if os.name == "nt":
return "Sorry, this command is not supported on Windows systems." return "Sorry, this command is not supported on Windows systems."

View file

@ -1,13 +1,44 @@
# coding=utf-8
from util import hook from util import hook
import re import re
import random import random
potatoes = ['AC Belmont', 'AC Blue Pride', 'AC Brador', 'AC Chaleur', 'AC Domino', 'AC Dubuc', 'AC Glacier Chip', 'AC Maple Gold', 'AC Novachip', 'AC Peregrine Red', 'AC Ptarmigan', 'AC Red Island', 'AC Saguenor', 'AC Stampede Russet', 'AC Sunbury', 'Abeille', 'Abnaki', 'Acadia', 'Acadia Russet', 'Accent', 'Adirondack Blue', 'Adirondack Red', 'Adora', 'Agria', 'All Blue', 'All Red', 'Alpha', 'Alta Russet', 'Alturas Russet', 'Amandine', 'Amisk', 'Andover', 'Anoka', 'Anson', 'Aquilon', 'Arran Consul', 'Asterix', 'Atlantic', 'Austrian Crescent', 'Avalanche', 'Banana', 'Bannock Russet', 'Batoche', 'BeRus', 'Belle De Fonteney', 'Belleisle', 'Bintje', 'Blossom', 'Blue Christie', 'Blue Mac', 'Brigus', 'Brise du Nord', 'Butte', 'Butterfinger', 'Caesar', 'CalWhite', 'CalRed', 'Caribe', 'Carlingford', 'Carlton', 'Carola', 'Cascade', 'Castile', 'Centennial Russet', 'Century Russet', 'Charlotte', 'Cherie', 'Cherokee', 'Cherry Red', 'Chieftain', 'Chipeta', 'Coastal Russet', 'Colorado Rose', 'Concurrent', 'Conestoga', 'Cowhorn', 'Crestone Russet', 'Crispin', 'Cupids', 'Daisy Gold', 'Dakota Pearl', 'Defender', 'Delikat', 'Denali', 'Desiree', 'Divina', 'Dundrod', 'Durango Red', 'Early Rose', 'Elba', 'Envol', 'Epicure', 'Eramosa', 'Estima', 'Eva', 'Fabula', 'Fambo', 'Fremont Russet', 'French Fingerling', 'Frontier Russet', 'Fundy', 'Garnet Chile', 'Gem Russet', 'GemStar Russet', 'Gemchip', 'German Butterball', 'Gigant', 'Goldrush', 'Granola', 'Green Mountain', 'Haida', 'Hertha', 'Hilite Russet', 'Huckleberry', 'Hunter', 'Huron', 'IdaRose', 'Innovator', 'Irish Cobbler', 'Island Sunshine', 'Ivory Crisp', 'Jacqueline Lee', 'Jemseg', 'Kanona', 'Katahdin', 'Kennebec', "Kerr's Pink", 'Keswick', 'Keuka Gold', 'Keystone Russet', 'King Edward VII', 'Kipfel', 'Klamath Russet', 'Krantz', 'LaRatte', 'Lady Rosetta', 'Latona', 'Lemhi Russet', 'Liberator', 'Lili', 'MaineChip', 'Marfona', 'Maris Bard', 'Maris Piper', 'Matilda', 'Mazama', 'McIntyre', 'Michigan Purple', 'Millenium Russet', 'Mirton Pearl', 'Modoc', 'Mondial', 'Monona', 'Morene', 'Morning Gold', 'Mouraska', 'Navan', 'Nicola', 'Nipigon', 'Niska', 'Nooksack', 'NorValley', 'Norchip', 'Nordonna', 'Norgold Russet', 'Norking Russet', 'Norland', 'Norwis', 'Obelix', 'Ozette', 'Peanut', 'Penta', 'Peribonka', 'Peruvian Purple', 'Pike', 'Pink Pearl', 'Prospect', 'Pungo', 'Purple Majesty', 'Purple Viking', 'Ranger Russet', 'Reba', 'Red Cloud', 'Red Gold', 'Red La Soda', 'Red Pontiac', 'Red Ruby', 'Red Thumb', 'Redsen', 'Rocket', 'Rose Finn Apple', 'Rose Gold', 'Roselys', 'Rote Erstling', 'Ruby Crescent', 'Russet Burbank', 'Russet Legend', 'Russet Norkotah', 'Russet Nugget', 'Russian Banana', 'Saginaw Gold', 'Sangre', 'Sant<EFBFBD>', 'Satina', 'Saxon', 'Sebago', 'Shepody', 'Sierra', 'Silverton Russet', 'Simcoe', 'Snowden', 'Spunta', "St. John's", 'Summit Russet', 'Sunrise', 'Superior', 'Symfonia', 'Tolaas', 'Trent', 'True Blue', 'Ulla', 'Umatilla Russet', 'Valisa', 'Van Gogh', 'Viking', 'Wallowa Russet', 'Warba', 'Western Russet', 'White Rose', 'Willamette', 'Winema', 'Yellow Finn', 'Yukon Gold'] potatoes = ['AC Belmont', 'AC Blue Pride', 'AC Brador', 'AC Chaleur', 'AC Domino', 'AC Dubuc', 'AC Glacier Chip',
'AC Maple Gold', 'AC Novachip', 'AC Peregrine Red', 'AC Ptarmigan', 'AC Red Island', 'AC Saguenor',
'AC Stampede Russet', 'AC Sunbury', 'Abeille', 'Abnaki', 'Acadia', 'Acadia Russet', 'Accent',
'Adirondack Blue', 'Adirondack Red', 'Adora', 'Agria', 'All Blue', 'All Red', 'Alpha', 'Alta Russet',
'Alturas Russet', 'Amandine', 'Amisk', 'Andover', 'Anoka', 'Anson', 'Aquilon', 'Arran Consul', 'Asterix',
'Atlantic', 'Austrian Crescent', 'Avalanche', 'Banana', 'Bannock Russet', 'Batoche', 'BeRus',
'Belle De Fonteney', 'Belleisle', 'Bintje', 'Blossom', 'Blue Christie', 'Blue Mac', 'Brigus',
'Brise du Nord', 'Butte', 'Butterfinger', 'Caesar', 'CalWhite', 'CalRed', 'Caribe', 'Carlingford',
'Carlton', 'Carola', 'Cascade', 'Castile', 'Centennial Russet', 'Century Russet', 'Charlotte', 'Cherie',
'Cherokee', 'Cherry Red', 'Chieftain', 'Chipeta', 'Coastal Russet', 'Colorado Rose', 'Concurrent',
'Conestoga', 'Cowhorn', 'Crestone Russet', 'Crispin', 'Cupids', 'Daisy Gold', 'Dakota Pearl', 'Defender',
'Delikat', 'Denali', 'Desiree', 'Divina', 'Dundrod', 'Durango Red', 'Early Rose', 'Elba', 'Envol',
'Epicure', 'Eramosa', 'Estima', 'Eva', 'Fabula', 'Fambo', 'Fremont Russet', 'French Fingerling',
'Frontier Russet', 'Fundy', 'Garnet Chile', 'Gem Russet', 'GemStar Russet', 'Gemchip', 'German Butterball',
'Gigant', 'Goldrush', 'Granola', 'Green Mountain', 'Haida', 'Hertha', 'Hilite Russet', 'Huckleberry',
'Hunter', 'Huron', 'IdaRose', 'Innovator', 'Irish Cobbler', 'Island Sunshine', 'Ivory Crisp',
'Jacqueline Lee', 'Jemseg', 'Kanona', 'Katahdin', 'Kennebec', "Kerr's Pink", 'Keswick', 'Keuka Gold',
'Keystone Russet', 'King Edward VII', 'Kipfel', 'Klamath Russet', 'Krantz', 'LaRatte', 'Lady Rosetta',
'Latona', 'Lemhi Russet', 'Liberator', 'Lili', 'MaineChip', 'Marfona', 'Maris Bard', 'Maris Piper',
'Matilda', 'Mazama', 'McIntyre', 'Michigan Purple', 'Millenium Russet', 'Mirton Pearl', 'Modoc', 'Mondial',
'Monona', 'Morene', 'Morning Gold', 'Mouraska', 'Navan', 'Nicola', 'Nipigon', 'Niska', 'Nooksack',
'NorValley', 'Norchip', 'Nordonna', 'Norgold Russet', 'Norking Russet', 'Norland', 'Norwis', 'Obelix',
'Ozette', 'Peanut', 'Penta', 'Peribonka', 'Peruvian Purple', 'Pike', 'Pink Pearl', 'Prospect', 'Pungo',
'Purple Majesty', 'Purple Viking', 'Ranger Russet', 'Reba', 'Red Cloud', 'Red Gold', 'Red La Soda',
'Red Pontiac', 'Red Ruby', 'Red Thumb', 'Redsen', 'Rocket', 'Rose Finn Apple', 'Rose Gold', 'Roselys',
'Rote Erstling', 'Ruby Crescent', 'Russet Burbank', 'Russet Legend', 'Russet Norkotah', 'Russet Nugget',
'Russian Banana', 'Saginaw Gold', 'Sangre', 'Sant<EFBFBD>', 'Satina', 'Saxon', 'Sebago', 'Shepody', 'Sierra',
'Silverton Russet', 'Simcoe', 'Snowden', 'Spunta', "St. John's", 'Summit Russet', 'Sunrise', 'Superior',
'Symfonia', 'Tolaas', 'Trent', 'True Blue', 'Ulla', 'Umatilla Russet', 'Valisa', 'Van Gogh', 'Viking',
'Wallowa Russet', 'Warba', 'Western Russet', 'White Rose', 'Willamette', 'Winema', 'Yellow Finn',
'Yukon Gold']
@hook.command @hook.command
def potato(inp, me=None, input=None): def potato(inp, me=None, input=None):
"potato <user> - Makes <user> a tasty little potato." """potato <user> - Makes <user> a tasty little potato."""
inp = inp.strip() inp = inp.strip()
if not re.match("^[A-Za-z0-9_|.-\]\[]*$", inp.lower()): if not re.match("^[A-Za-z0-9_|.-\]\[]*$", inp.lower()):
@ -19,4 +50,5 @@ def potato(inp, me=None, input=None):
method = random.choice(['bakes', 'fries', 'boils', 'roasts']) method = random.choice(['bakes', 'fries', 'boils', 'roasts'])
side_dish = random.choice(['side salad', 'dollop of sour cream', 'piece of chicken', 'bowl of shredded bacon']) side_dish = random.choice(['side salad', 'dollop of sour cream', 'piece of chicken', 'bowl of shredded bacon'])
me("%s a %s %s %s potato for %s and serves it with a small %s!" % (method, flavor, size, potato_type, inp, side_dish)) me("%s a %s %s %s potato for %s and serves it with a small %s!" % (
method, flavor, size, potato_type, inp, side_dish))

View file

@ -4,8 +4,8 @@ from util import hook, web, http
@hook.command('qr') @hook.command('qr')
@hook.command @hook.command
def qrcode(inp, bot=None): def qrcode(inp):
"qrcode [link] returns a link for a QR code." """qrcode [link] returns a link for a QR code."""
args = { args = {
"cht": "qr", # chart type "cht": "qr", # chart type
@ -16,5 +16,3 @@ def qrcode(inp, bot=None):
link = http.prepare_url("http://chart.googleapis.com/chart", args) link = http.prepare_url("http://chart.googleapis.com/chart", args)
return web.try_isgd(link) return web.try_isgd(link)

View file

@ -49,7 +49,7 @@ def get_quote_num(num, count, name):
if num and num < 0: # Count back if possible if num and num < 0: # Count back if possible
num = count + num + 1 if num + count > -1 else count + 1 num = count + num + 1 if num + count > -1 else count + 1
if num and num > count: # If there are not enough quotes, raise an error if num and num > count: # If there are not enough quotes, raise an error
raise Exception("I only have %d quote%s for %s."\ raise Exception("I only have %d quote%s for %s."
% (count, ('s', '')[count == 1], name)) % (count, ('s', '')[count == 1], name))
if num and num == 0: # If the number is zero, set it to one if num and num == 0: # If the number is zero, set it to one
num = 1 num = 1
@ -124,8 +124,8 @@ def get_quote_by_chan(db, chan, num=False):
@hook.command('q') @hook.command('q')
@hook.command @hook.command
def quote(inp, nick='', chan='', db=None, notice=None): def quote(inp, nick='', chan='', db=None, notice=None):
"quote [#chan] [nick] [#n]/.quote add <nick> <msg> -- Gets " \ """quote [#chan] [nick] [#n]/.quote add <nick> <msg>
"random or [#n]th quote by <nick> or from <#chan>/adds quote." Gets random or [#n]th quote by <nick> or from <#chan>/adds quote."""
create_table_if_not_exists(db) create_table_if_not_exists(db)
add = re.match(r"add[^\w@]+(\S+?)>?\s+(.*)", inp, re.I) add = re.match(r"add[^\w@]+(\S+?)>?\s+(.*)", inp, re.I)

View file

@ -1,23 +1,30 @@
import urllib
import json
import re
from util import hook from util import hook
import oauth2 as oauth import oauth2 as oauth
import urllib, json
CONSUMER_KEY = "KEY" CONSUMER_KEY = "KEY"
CONSUMER_SECRET = "SECRET" CONSUMER_SECRET = "SECRET"
def getdata(inp, types): def getdata(inp, types):
consumer = oauth.Consumer(CONSUMER_KEY, CONSUMER_SECRET) consumer = oauth.Consumer(CONSUMER_KEY, CONSUMER_SECRET)
client = oauth.Client(consumer) client = oauth.Client(consumer)
response = client.request('http://api.rdio.com/1/', 'POST', urllib.urlencode({'method': 'search', 'query': inp, 'types': types, 'count': '1'})) response = client.request('http://api.rdio.com/1/', 'POST',
urllib.urlencode({'method': 'search', 'query': inp, 'types': types, 'count': '1'}))
data = json.loads(response[1]) data = json.loads(response[1])
return data return data
def checkkeys(): def checkkeys():
if CONSUMER_KEY == "KEY" or CONSUMER_SECRET == "SECRET": if CONSUMER_KEY == "KEY" or CONSUMER_SECRET == "SECRET":
return True return True
else: else:
return False return False
@hook.command @hook.command
def rdio(inp): def rdio(inp):
""" rdio <search term> - alternatives: .rdiot (track), .rdioar (artist), .rdioal (album) """ """ rdio <search term> - alternatives: .rdiot (track), .rdioar (artist), .rdioal (album) """
@ -45,6 +52,7 @@ def rdio(inp):
url = info['shortUrl'] url = info['shortUrl']
return u"\x02{}\x02 {}".format(name, url) return u"\x02{}\x02 {}".format(name, url)
@hook.command @hook.command
def rdiot(inp): def rdiot(inp):
""" rdiot <search term> - Search for tracks on rdio """ """ rdiot <search term> - Search for tracks on rdio """
@ -61,6 +69,7 @@ def rdiot(inp):
url = info['shortUrl'] url = info['shortUrl']
return u"\x02{}\x02 by \x02{}\x02 - {} {}".format(name, artist, album, url) return u"\x02{}\x02 by \x02{}\x02 - {} {}".format(name, artist, album, url)
@hook.command @hook.command
def rdioar(inp): def rdioar(inp):
""" rdioar <search term> - Search for artists on rdio """ """ rdioar <search term> - Search for artists on rdio """
@ -75,6 +84,7 @@ def rdioar(inp):
url = info['shortUrl'] url = info['shortUrl']
return u"\x02{}\x02 {}".format(name, url) return u"\x02{}\x02 {}".format(name, url)
@hook.command @hook.command
def rdioal(inp): def rdioal(inp):
""" rdioal <search term> - Search for albums on rdio """ """ rdioal <search term> - Search for albums on rdio """
@ -90,11 +100,10 @@ def rdioal(inp):
url = info['shortUrl'] url = info['shortUrl']
return u"\x02{}\x02 by \x02{}\x02 - {}".format(name, artist, url) return u"\x02{}\x02 by \x02{}\x02 - {}".format(name, artist, url)
import re
import urllib2
rdio_re = (r'(.*:)//(rd.io|www.rdio.com|rdio.com)(:[0-9]+)?(.*)', re.I) rdio_re = (r'(.*:)//(rd.io|www.rdio.com|rdio.com)(:[0-9]+)?(.*)', re.I)
@hook.regex(*rdio_re) @hook.regex(*rdio_re)
def rdio_url(match): def rdio_url(match):
if checkkeys(): if checkkeys():
@ -102,7 +111,8 @@ def rdio_url(match):
url = match.group(1) + "//" + match.group(2) + match.group(4) url = match.group(1) + "//" + match.group(2) + match.group(4)
consumer = oauth.Consumer(CONSUMER_KEY, CONSUMER_SECRET) consumer = oauth.Consumer(CONSUMER_KEY, CONSUMER_SECRET)
client = oauth.Client(consumer) client = oauth.Client(consumer)
response = client.request('http://api.rdio.com/1/', 'POST', urllib.urlencode({'method': 'getObjectFromUrl', 'url': url})) response = client.request('http://api.rdio.com/1/', 'POST',
urllib.urlencode({'method': 'getObjectFromUrl', 'url': url}))
data = json.loads(response[1]) data = json.loads(response[1])
info = data['result'] info = data['result']
if 'name' in info: if 'name' in info:

View file

@ -3,9 +3,9 @@ import re
reddit_re = (r'.*((www\.)?reddit\.com/r[^ ]+)', re.I) reddit_re = (r'.*((www\.)?reddit\.com/r[^ ]+)', re.I)
@hook.regex(*reddit_re) @hook.regex(*reddit_re)
def reddit_url(match): def reddit_url(match):
thread = http.get_html(match.group(0)) thread = http.get_html(match.group(0))
title = thread.xpath('//title/text()')[0] title = thread.xpath('//title/text()')[0]

View file

@ -7,7 +7,7 @@ movie_reviews_url = api_root + 'movies/%s/reviews.json'
@hook.command('rt') @hook.command('rt')
def rottentomatoes(inp, bot=None): def rottentomatoes(inp, bot=None):
'rt <title> -- gets ratings for <title> from Rotten Tomatoes' """rt <title> -- gets ratings for <title> from Rotten Tomatoes"""
api_key = bot.config.get("api_keys", {}).get("rottentomatoes", None) api_key = bot.config.get("api_keys", {}).get("rottentomatoes", None)
if not api_key: if not api_key:

View file

@ -4,7 +4,7 @@ from util import hook, http, web, text
@hook.command("feed") @hook.command("feed")
@hook.command @hook.command
def rss(inp, say=None): def rss(inp, say=None):
"rss <feed> -- Gets the first three items from the RSS feed <feed>." """rss <feed> -- Gets the first three items from the RSS feed <feed>."""
limit = 3 limit = 3
# preset news feeds # preset news feeds
@ -36,5 +36,5 @@ def rss(inp, say=None):
@hook.command(autohelp=False) @hook.command(autohelp=False)
def rb(inp, say=None): def rb(inp, say=None):
"rb -- Shows the latest Craftbukkit recommended build" """rb -- Shows the latest Craftbukkit recommended build"""
rss("bukkit", say) rss("bukkit", say)

View file

@ -1,4 +1,4 @@
" seen.py: written by sklnd in about two beers July 2009" """seen.py: written by sklnd in about two beers July 2009"""
import time import time
import re import re
@ -9,7 +9,7 @@ db_ready = False
def db_init(db): def db_init(db):
"check to see that our db has the the seen table and return a connection." """check to see that our db has the the seen table and return a connection."""
db.execute("create table if not exists seen_user(name, time, quote, chan, host, " db.execute("create table if not exists seen_user(name, time, quote, chan, host, "
"primary key(name, chan))") "primary key(name, chan))")
db.commit() db.commit()
@ -18,7 +18,7 @@ def db_init(db):
@hook.singlethread @hook.singlethread
@hook.event('PRIVMSG', ignorebots=False) @hook.event('PRIVMSG', ignorebots=False)
def seen_sieve(paraml, input=None, db=None, bot=None): def seen_sieve(input=None, db=None):
if not db_ready: if not db_ready:
db_init(db) db_init(db)
# keep private messages private # keep private messages private
@ -31,7 +31,7 @@ def seen_sieve(paraml, input=None, db=None, bot=None):
@hook.command @hook.command
def seen(inp, nick='', chan='', db=None, input=None): def seen(inp, nick='', chan='', db=None, input=None):
"seen <nick> -- Tell when a nickname was last in active in one of this bot's channels." """seen <nick> -- Tell when a nickname was last in active in one of this bot's channels."""
if input.conn.nick.lower() == inp.lower(): if input.conn.nick.lower() == inp.lower():
return "You need to get your eyes checked." return "You need to get your eyes checked."
@ -52,7 +52,7 @@ def seen(inp, nick='', chan='', db=None, input=None):
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]
if last_seen[2][0:1]=="\x01": if last_seen[2][0:1] == "\x01":
return '{} was last seen {} ago: * {} {}'.format(inp, reltime, inp, return '{} was last seen {} ago: * {} {}'.format(inp, reltime, inp,
last_seen[2][8:-1]) last_seen[2][8:-1])
else: else:

View file

@ -3,7 +3,7 @@ from util import hook, http, web
@hook.command @hook.command
def shorten(inp): def shorten(inp):
"shorten <url> - Makes an is.gd shortlink to the url provided." """shorten <url> - Makes an is.gd shortlink to the url provided."""
try: try:
return web.isgd(inp) return web.isgd(inp)

View file

@ -9,7 +9,7 @@ with open("plugins/data/slogans.txt") as f:
@hook.command @hook.command
def slogan(inp): def slogan(inp):
"slogan <word> -- Makes a slogan for <word>." """slogan <word> -- Makes a slogan for <word>."""
out = random.choice(slogans) out = random.choice(slogans)
if inp.lower() and out.startswith("<text>"): if inp.lower() and out.startswith("<text>"):
inp = text.capitalize_first(inp) inp = text.capitalize_first(inp)

View file

@ -8,7 +8,7 @@ search_url = "http://search.atomz.com/search/?sp_a=00062d45-sp00000000"
@hook.command @hook.command
def snopes(inp): def snopes(inp):
"snopes <topic> -- Searches snopes for an urban legend about <topic>." """snopes <topic> -- Searches snopes for an urban legend about <topic>."""
search_page = http.get_html(search_url, sp_q=inp, sp_c="1") search_page = http.get_html(search_url, sp_q=inp, sp_c="1")
result_urls = search_page.xpath("//a[@target='_self']/@href") result_urls = search_page.xpath("//a[@target='_self']/@href")

View file

@ -21,7 +21,9 @@ def soundcloud(url, api_key):
url = web.try_isgd(data['permalink_url']) url = web.try_isgd(data['permalink_url'])
return u"SoundCloud track: \x02{}\x02 by \x02{}user\x02 {}{}- {} plays, {} downloads, {} comments - \x02{}\x02".format(data['title'], data['user']['username'], desc, genre, data['playback_count'], data['download_count'], data['comment_count'], url) return u"SoundCloud track: \x02{}\x02 by \x02{}user\x02 {}{}- {} plays, {} downloads, {} comments - \x02{}\x02".format(
data['title'], data['user']['username'], desc, genre, data['playback_count'], data['download_count'],
data['comment_count'], url)
@hook.regex(*sc_re) @hook.regex(*sc_re)
@ -30,7 +32,8 @@ def soundcloud_url(match, bot=None):
if not api_key: if not api_key:
print "Error: no api key set" print "Error: no api key set"
return None return None
url = match.group(1).split(' ')[-1] + "//" + (match.group(2) if match.group(2) else "") + match.group(3) + match.group(4).split(' ')[0] url = match.group(1).split(' ')[-1] + "//" + (match.group(2) if match.group(2) else "") + match.group(3) + \
match.group(4).split(' ')[0]
return soundcloud(url, api_key) return soundcloud(url, api_key)
@ -40,5 +43,6 @@ def sndsc_url(match, bot=None):
if not api_key: if not api_key:
print "Error: no api key set" print "Error: no api key set"
return None return None
url = match.group(1).split(' ')[-1] + "//" + (match.group(2) if match.group(2) else "") + match.group(3) + match.group(4).split(' ')[0] url = match.group(1).split(' ')[-1] + "//" + (match.group(2) if match.group(2) else "") + match.group(3) + \
match.group(4).split(' ')[0]
return soundcloud(http.open(url).url, api_key) return soundcloud(http.open(url).url, api_key)

View file

@ -6,7 +6,7 @@ locale = "en_US"
@hook.command @hook.command
def spell(inp): def spell(inp):
"spell <word> -- Check spelling of <word>." """spell <word> -- Check spelling of <word>."""
if ' ' in inp: if ' ' in inp:
return "This command only supports one word at a time." return "This command only supports one word at a time."

View file

@ -10,10 +10,12 @@ spotify_re = (r'(spotify:(track|album|artist|user):([a-zA-Z0-9]+))', re.I)
http_re = (r'(open\.spotify\.com\/(track|album|artist|user)\/' http_re = (r'(open\.spotify\.com\/(track|album|artist|user)\/'
'([a-zA-Z0-9]+))', re.I) '([a-zA-Z0-9]+))', re.I)
def sptfy(inp, sptfy=False): def sptfy(inp, sptfy=False):
if sptfy: if sptfy:
shortenurl = "http://sptfy.com/index.php" shortenurl = "http://sptfy.com/index.php"
data = urlencode({'longUrl': inp, 'shortUrlDomain': 1, 'submitted': 1, "shortUrlFolder": 6, "customUrl": "", "shortUrlPassword": "", "shortUrlExpiryDate": "", "shortUrlUses": 0, "shortUrlType": 0}) data = urlencode({'longUrl': inp, 'shortUrlDomain': 1, 'submitted': 1, "shortUrlFolder": 6, "customUrl": "",
"shortUrlPassword": "", "shortUrlExpiryDate": "", "shortUrlUses": 0, "shortUrlType": 0})
try: try:
soup = http.get_soup(shortenurl, post_data=data, cookies=True) soup = http.get_soup(shortenurl, post_data=data, cookies=True)
except: except:
@ -22,7 +24,8 @@ def sptfy(inp, sptfy=False):
link = soup.find('div', {'class': 'resultLink'}).text.strip() link = soup.find('div', {'class': 'resultLink'}).text.strip()
return link return link
except: except:
message = "Unable to shorten URL: %s" % soup.find('div', {'class': 'messagebox_text'}).find('p').text.split("<br/>")[0] message = "Unable to shorten URL: %s" % \
soup.find('div', {'class': 'messagebox_text'}).find('p').text.split("<br/>")[0]
return message return message
else: else:
return web.try_isgd(inp) return web.try_isgd(inp)
@ -31,7 +34,7 @@ def sptfy(inp, sptfy=False):
@hook.command('sptrack') @hook.command('sptrack')
@hook.command @hook.command
def spotify(inp): def spotify(inp):
"spotify <song> -- Search Spotify for <song>" """spotify <song> -- Search Spotify for <song>"""
try: try:
data = http.get_json("http://ws.spotify.com/search/1/track.json", q=inp.strip()) data = http.get_json("http://ws.spotify.com/search/1/track.json", q=inp.strip())
except Exception as e: except Exception as e:
@ -42,11 +45,13 @@ def spotify(inp):
except IndexError: except IndexError:
return "Could not find track." return "Could not find track."
url = sptfy(gateway.format(type, id)) url = sptfy(gateway.format(type, id))
return u"\x02{}\x02 by \x02{}\x02 - \x02{}\x02".format(data["tracks"][0]["name"], data["tracks"][0]["artists"][0]["name"], url) return u"\x02{}\x02 by \x02{}\x02 - \x02{}\x02".format(data["tracks"][0]["name"],
data["tracks"][0]["artists"][0]["name"], url)
@hook.command @hook.command
def spalbum(inp): def spalbum(inp):
"spalbum <album> -- Search Spotify for <album>" """spalbum <album> -- Search Spotify for <album>"""
try: try:
data = http.get_json("http://ws.spotify.com/search/1/album.json", q=inp.strip()) data = http.get_json("http://ws.spotify.com/search/1/album.json", q=inp.strip())
except Exception as e: except Exception as e:
@ -57,11 +62,13 @@ def spalbum(inp):
except IndexError: except IndexError:
return "Could not find album." return "Could not find album."
url = sptfy(gateway.format(type, id)) url = sptfy(gateway.format(type, id))
return u"\x02{}\x02 by \x02{}\x02 - \x02{}\x02".format(data["albums"][0]["name"], data["albums"][0]["artists"][0]["name"], url) return u"\x02{}\x02 by \x02{}\x02 - \x02{}\x02".format(data["albums"][0]["name"],
data["albums"][0]["artists"][0]["name"], url)
@hook.command @hook.command
def spartist(inp): def spartist(inp):
"spartist <artist> -- Search Spotify for <artist>" """spartist <artist> -- Search Spotify for <artist>"""
try: try:
data = http.get_json("http://ws.spotify.com/search/1/artist.json", q=inp.strip()) data = http.get_json("http://ws.spotify.com/search/1/artist.json", q=inp.strip())
except Exception as e: except Exception as e:
@ -74,6 +81,7 @@ def spartist(inp):
url = sptfy(gateway.format(type, id)) url = sptfy(gateway.format(type, id))
return u"\x02{}\x02 - \x02{}\x02".format(data["artists"][0]["name"], url) return u"\x02{}\x02 - \x02{}\x02".format(data["artists"][0]["name"], url)
@hook.regex(*http_re) @hook.regex(*http_re)
@hook.regex(*spotify_re) @hook.regex(*spotify_re)
def spotify_url(match): def spotify_url(match):
@ -86,8 +94,13 @@ def spotify_url(match):
name = data["track"]["name"] name = data["track"]["name"]
artist = data["track"]["artists"][0]["name"] artist = data["track"]["artists"][0]["name"]
album = data["track"]["album"]["name"] album = data["track"]["album"]["name"]
return u"Spotify Track: \x02{}\x02 by \x02{}\x02 from the album \x02{}\x02 - \x02{}\x02".format(name, artist, album, sptfy(gateway.format(type, spotify_id))) return u"Spotify Track: \x02{}\x02 by \x02{}\x02 from the album \x02{}\x02 - \x02{}\x02".format(name, artist,
album, sptfy(
gateway.format(type, spotify_id)))
elif type == "artist": elif type == "artist":
return u"Spotify Artist: \x02{}\x02 - \x02{}\x02".format(data["artist"]["name"], sptfy(gateway.format(type, spotify_id))) return u"Spotify Artist: \x02{}\x02 - \x02{}\x02".format(data["artist"]["name"],
sptfy(gateway.format(type, spotify_id)))
elif type == "album": elif type == "album":
return u"Spotify Album: \x02{}\x02 - \x02{}\x02 - \x02{}\x02".format(data["album"]["artist"], data["album"]["name"], sptfy(gateway.format(type, spotify_id))) return u"Spotify Album: \x02{}\x02 - \x02{}\x02 - \x02{}\x02".format(data["album"]["artist"],
data["album"]["name"],
sptfy(gateway.format(type, spotify_id)))

View file

@ -1,5 +1,4 @@
from util import hook, http, web, text, timesince from util import hook, http, web, text
from datetime import datetime
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
import re import re
@ -54,7 +53,8 @@ def steamcalc(inp, nick='', db=None):
if inp.split(" ")[2] == "dontsave": if inp.split(" ")[2] == "dontsave":
dontsave = True dontsave = True
url = http.prepare_url("http://steamdb.info/calculator/", {"player": inp, "currency": currency if currency else "us"}) url = http.prepare_url("http://steamdb.info/calculator/",
{"player": inp, "currency": currency if currency else "us"})
soup = http.get_soup(url) soup = http.get_soup(url)
out = u"" out = u""
@ -64,7 +64,8 @@ def steamcalc(inp, nick='', db=None):
except Exception as e: except Exception as e:
print e print e
return u"\x02Unable to retrieve info for %s!\x02 Is it a valid SteamCommunity profile username (%s)? " \ return u"\x02Unable to retrieve info for %s!\x02 Is it a valid SteamCommunity profile username (%s)? " \
"Check if your profile is private, or go here to search: %s" % (inp, web.try_isgd("http://steamcommunity.com/id/%s" % inp), web.try_isgd(url)) "Check if your profile is private, or go here to search: %s" % (
inp, web.try_isgd("http://steamcommunity.com/id/%s" % inp), web.try_isgd(url))
nextone = False nextone = False
status = "Unknown" status = "Unknown"
@ -73,7 +74,7 @@ def steamcalc(inp, nick='', db=None):
status = i.text status = i.text
break break
elif i.text == "Status": elif i.text == "Status":
nextone=True nextone = True
if status == "Online": if status == "Online":
status = "\x033\x02Online\x02\x0f" status = "\x033\x02Online\x02\x0f"
elif status == "Offline": elif status == "Offline":
@ -96,7 +97,8 @@ def steamcalc(inp, nick='', db=None):
nppercent = data[3].text.split(" ")[-1] nppercent = data[3].text.split(" ")[-1]
time = data[4].text.split(" ")[-1].replace("h", "hours") time = data[4].text.split(" ")[-1].replace("h", "hours")
out += " This account is worth \x02%s\x02, and they've spent \x02%s\x02 playing games! " % (money, time) out += " This account is worth \x02%s\x02, and they've spent \x02%s\x02 playing games! " % (money, time)
out += " They have \x02%s games\x02, but \x02%s of them haven't been touched\x02! That's \x02%s\x02! " % (totalgames, notplayed, nppercent) out += " They have \x02%s games\x02, but \x02%s of them haven't been touched\x02! That's \x02%s\x02! " % (
totalgames, notplayed, nppercent)
if not dontsave: if not dontsave:
db.execute("insert or replace into steam(nick, acc) values (?,?)", (nick.lower(), inp)) db.execute("insert or replace into steam(nick, acc) values (?,?)", (nick.lower(), inp))

View file

@ -4,9 +4,10 @@ import json
url = 'http://www.google.com/ig/api' url = 'http://www.google.com/ig/api'
@hook.command @hook.command
def stock(inp): def stock(inp):
"stock <symbol> -- Gets information about stock symbol <symbol>." """stock <symbol> -- Gets information about stock symbol <symbol>."""
parsed = http.get_xml(url, stock=inp) parsed = http.get_xml(url, stock=inp)
@ -19,7 +20,8 @@ def stock(inp):
# if we dont get a company name back, the symbol doesn't match a company # if we dont get a company name back, the symbol doesn't match a company
if not "company" in results: if not "company" in results:
guess_data = json.loads(http.get("http://d.yimg.com/autoc.finance.yahoo.com/autoc", query=inp, callback="YAHOO.Finance.SymbolSuggest.ssCallback")[39:-1]) guess_data = json.loads(http.get("http://d.yimg.com/autoc.finance.yahoo.com/autoc", query=inp,
callback="YAHOO.Finance.SymbolSuggest.ssCallback")[39:-1])
guess = guess_data['ResultSet']['Result'] guess = guess_data['ResultSet']['Result']
if len(guess) > 0: if len(guess) > 0:
guess = guess[0]["symbol"] guess = guess[0]["symbol"]
@ -29,7 +31,7 @@ def stock(inp):
if results['last'] == '0.00': if results['last'] == '0.00':
return "%(company)s - last known stock value was 0.00 %(currency)s" \ return "%(company)s - last known stock value was 0.00 %(currency)s" \
" as of %(trade_timestamp)s" % (results) " as of %(trade_timestamp)s" % results
if results['change'][0] == '-': if results['change'][0] == '-':
results['color'] = "5" results['color'] = "5"

View file

@ -17,7 +17,7 @@ def convert_kilobytes(kilobytes):
@hook.command(autohelp=False) @hook.command(autohelp=False)
def system(inp): def system(inp):
"system -- Retrieves information about the host system." """system -- Retrieves information about the host system."""
hostname = platform.node() hostname = platform.node()
os = platform.platform() os = platform.platform()
python_imp = platform.python_implementation() python_imp = platform.python_implementation()
@ -31,7 +31,7 @@ def system(inp):
@hook.command(autohelp=False) @hook.command(autohelp=False)
def memory(inp): def memory(inp):
"memory -- Displays the bot's current memory usage." """memory -- Displays the bot's current memory usage."""
if os.name == "posix": if os.name == "posix":
# get process info # get process info
status_file = open('/proc/self/status').read() status_file = open('/proc/self/status').read()
@ -63,7 +63,7 @@ def memory(inp):
@hook.command(autohelp=False) @hook.command(autohelp=False)
def uptime(inp, bot=None): def uptime(inp, bot=None):
"uptime -- Shows the bot's uptime." """uptime -- Shows the bot's uptime."""
uptime_raw = round(time.time() - bot.start_time) uptime_raw = round(time.time() - bot.start_time)
uptime = timedelta(seconds=uptime_raw) uptime = timedelta(seconds=uptime_raw)
return "Uptime: \x02%s\x02" % uptime return "Uptime: \x02%s\x02" % uptime
@ -71,5 +71,5 @@ def uptime(inp, bot=None):
@hook.command(autohelp=False) @hook.command(autohelp=False)
def pid(inp): def pid(inp):
"pid -- Prints the bot's PID." """pid -- Prints the bot's PID."""
return "PID: \x02%s\x02" % os.getpid() return "PID: \x02%s\x02" % os.getpid()

View file

@ -1,5 +1,5 @@
" tell.py: written by sklnd in July 2009" """ tell.py: written by sklnd in July 2009
" 2010.01.25 - modified by Scaevolus" 2010.01.25 - modified by Scaevolus"""
import time import time
import re import re
@ -8,7 +8,7 @@ from util import hook, timesince
def db_init(db): def db_init(db):
"check to see that our db has the tell table and return a dbection." """check to see that our db has the tell table and return a dbection."""
db.execute("create table if not exists tell" db.execute("create table if not exists tell"
"(user_to, user_from, message, chan, time," "(user_to, user_from, message, chan, time,"
"primary key(user_to, message))") "primary key(user_to, message))")
@ -72,7 +72,7 @@ def showtells(inp, nick='', chan='', notice=None, db=None):
@hook.command @hook.command
def tell(inp, nick='', chan='', db=None, input=None, notice=None): def tell(inp, nick='', chan='', db=None, input=None, notice=None):
"tell <nick> <message> -- Relay <message> to <nick> when <nick> is around." """tell <nick> <message> -- Relay <message> to <nick> when <nick> is around."""
query = inp.split(' ', 1) query = inp.split(' ', 1)
if len(query) != 2: if len(query) != 2:

View file

@ -7,7 +7,7 @@ api_url = 'http://api.wolframalpha.com/v2/query?format=plaintext'
@hook.command("time") @hook.command("time")
def time_command(inp, bot=None): def time_command(inp, bot=None):
"time <area> -- Gets the time in <area>" """time <area> -- Gets the time in <area>"""
query = "current time in %s" % inp query = "current time in %s" % inp
@ -16,8 +16,7 @@ def time_command(inp, bot=None):
return "error: no wolfram alpha api key set" return "error: no wolfram alpha api key set"
request = http.get_xml(api_url, input=query, appid=api_key) request = http.get_xml(api_url, input=query, appid=api_key)
time = " ".join(request.xpath("//pod[@title='Result']/subpod/plain" \ time = " ".join(request.xpath("//pod[@title='Result']/subpod/plaintext/text()"))
"text/text()"))
time = time.replace(" | ", ", ") time = time.replace(" | ", ", ")
if time: if time:
@ -25,8 +24,9 @@ def time_command(inp, bot=None):
if inp.lower() == "unix": if inp.lower() == "unix":
place = "Unix Epoch" place = "Unix Epoch"
else: else:
place = capitalize_first(" ".join(request.xpath("//pod[@" \ place = capitalize_first(" ".join(request.xpath("//pod[@"
"title='Input interpretation']/subpod/plaintext/text()"))[16:]) "title='Input interpretation']/subpod/plaintext/text()"))[
16:])
return "%s - \x02%s\x02" % (time, place) return "%s - \x02%s\x02" % (time, place)
else: else:
return "Could not get the time for '%s'." % inp return "Could not get the time for '%s'." % inp
@ -34,7 +34,7 @@ def time_command(inp, bot=None):
@hook.command(autohelp=False) @hook.command(autohelp=False)
def beats(inp): def beats(inp):
"beats -- Gets the current time in .beats (Swatch Internet Time). " """beats -- Gets the current time in .beats (Swatch Internet Time). """
if inp.lower() == "wut": if inp.lower() == "wut":
return "Instead of hours and minutes, the mean solar day is divided " \ return "Instead of hours and minutes, the mean solar day is divided " \

View file

@ -4,7 +4,7 @@ from bs4 import BeautifulSoup
@hook.command @hook.command
def title(inp): def title(inp):
"title <url> -- gets the title of a web page" """title <url> -- gets the title of a web page"""
url = urlnorm.normalize(inp.encode('utf-8'), assume_scheme="http") url = urlnorm.normalize(inp.encode('utf-8'), assume_scheme="http")
try: try:

View file

@ -79,13 +79,13 @@ def get_episode_info(episode, api_key):
episode_desc = '%s' % episode_num episode_desc = '%s' % episode_num
if episode_name: if episode_name:
episode_desc += ' - %s' % episode_name episode_desc += ' - %s' % episode_name
return (first_aired, airdate, episode_desc) return first_aired, airdate, episode_desc
@hook.command @hook.command
@hook.command('tv') @hook.command('tv')
def tv_next(inp, bot=None): def tv_next(inp, bot=None):
"tv <series> -- Get the next episode of <series>." """tv <series> -- Get the next episode of <series>."""
api_key = bot.config.get("api_keys", {}).get("tvdb", None) api_key = bot.config.get("api_keys", {}).get("tvdb", None)
if api_key is None: if api_key is None:
@ -135,7 +135,7 @@ def tv_next(inp, bot=None):
@hook.command @hook.command
@hook.command('tv_prev') @hook.command('tv_prev')
def tv_last(inp, bot=None): def tv_last(inp, bot=None):
"tv_last <series> -- Gets the most recently aired episode of <series>." """tv_last <series> -- Gets the most recently aired episode of <series>."""
api_key = bot.config.get("api_keys", {}).get("tvdb", None) api_key = bot.config.get("api_keys", {}).get("tvdb", None)
if api_key is None: if api_key is None:

View file

@ -21,7 +21,7 @@ def truncate(msg):
out = out + " " + nmsg[x] out = out + " " + nmsg[x]
else: else:
out = nmsg[x] out = nmsg[x]
x = x + 1 x += 1
if x <= 7: if x <= 7:
return out return out
else: else:
@ -44,7 +44,7 @@ def multitwitch_url(match):
@hook.regex(*twitch_re) @hook.regex(*twitch_re)
def twitch_url(match, chan=''): def twitch_url(match):
bit = match.group(4).split("#")[0] bit = match.group(4).split("#")[0]
location = "/".join(bit.split("/")[1:]) location = "/".join(bit.split("/")[1:])
if not test(location): if not test(location):

View file

@ -8,7 +8,7 @@ from datetime import datetime
@hook.command("tw") @hook.command("tw")
@hook.command("twatter") @hook.command("twatter")
@hook.command @hook.command
def twitter(inp, bot=None, say=None): def twitter(inp, bot=None):
"twitter <user> [n] -- Gets last/[n]th tweet from <user>" "twitter <user> [n] -- Gets last/[n]th tweet from <user>"
consumer_key = bot.config.get("api_keys", {}).get("twitter_consumer_key") consumer_key = bot.config.get("api_keys", {}).get("twitter_consumer_key")
@ -100,7 +100,7 @@ def twitter(inp, bot=None, say=None):
@hook.command("twinfo") @hook.command("twinfo")
@hook.command @hook.command
def twuser(inp, bot=None): def twuser(inp, bot=None):
"twuser <user> -- Get info on the Twitter user <user>" """twuser <user> -- Get info on the Twitter user <user>"""
consumer_key = bot.config.get("api_keys", {}).get("twitter_consumer_key") consumer_key = bot.config.get("api_keys", {}).get("twitter_consumer_key")
consumer_secret = bot.config.get("api_keys", {}).get("twitter_consumer_secret") consumer_secret = bot.config.get("api_keys", {}).get("twitter_consumer_secret")
@ -131,4 +131,5 @@ def twuser(inp, bot=None):
prefix = "" prefix = ""
return u"{}@\x02{}\x02 ({}) is located in \x02{}\x02 and has \x02{:,}\x02 tweets and \x02{:,}\x02 followers. The users description is \"{}\" " \ return u"{}@\x02{}\x02 ({}) is located in \x02{}\x02 and has \x02{:,}\x02 tweets and \x02{:,}\x02 followers. The users description is \"{}\" " \
"".format(prefix, user.screen_name, user.name, user.location, user.statuses_count, user.followers_count, user.description) "".format(prefix, user.screen_name, user.name, user.location, user.statuses_count, user.followers_count,
user.description)

View file

@ -1,4 +1,4 @@
from util import hook, http, text, web from util import hook, http, text
import re import re
base_url = 'http://www.urbandictionary.com/iphone/search/define' base_url = 'http://www.urbandictionary.com/iphone/search/define'
@ -7,7 +7,7 @@ base_url = 'http://www.urbandictionary.com/iphone/search/define'
@hook.command('u') @hook.command('u')
@hook.command @hook.command
def urban(inp): def urban(inp):
"urban <phrase> [id] -- Looks up <phrase> on urbandictionary.com." """urban <phrase> [id] -- Looks up <phrase> on urbandictionary.com."""
# clean and split the input # clean and split the input
input = inp.lower().strip() input = inp.lower().strip()
@ -22,7 +22,6 @@ def urban(inp):
else: else:
id = 1 id = 1
# fetch the definitions # fetch the definitions
page = http.get_json(base_url, term=input, referer="http://m.urbandictionary.com") page = http.get_json(base_url, term=input, referer="http://m.urbandictionary.com")
defs = page['list'] defs = page['list']

View file

@ -9,6 +9,7 @@ control = {'bold': '\x02', 'color': '\x03', 'italic': '\x09',
'strikethrough': '\x13', 'reset': '\x0f', 'underline': '\x15', 'strikethrough': '\x13', 'reset': '\x0f', 'underline': '\x15',
'underline2': '\x1f', 'reverse': '\x16'} 'underline2': '\x1f', 'reverse': '\x16'}
def color(color): def color(color):
return control['color'] + colors[color] return control['color'] + colors[color]

View file

@ -33,7 +33,7 @@ jar = cookielib.CookieJar()
class HTMLTextExtractor(HTMLParser): class HTMLTextExtractor(HTMLParser):
def __init__(self): def __init__(self):
HTMLParser.__init__(self) HTMLParser.__init__(self)
self.result = [ ] self.result = []
def handle_data(self, d): def handle_data(self, d):
self.result.append(d) self.result.append(d)
@ -76,7 +76,6 @@ def get_json(*args, **kwargs):
def open(url, query_params=None, user_agent=None, post_data=None, def open(url, query_params=None, user_agent=None, post_data=None,
referer=None, get_method=None, cookies=False, **kwargs): referer=None, get_method=None, cookies=False, **kwargs):
if query_params is None: if query_params is None:
query_params = {} query_params = {}

View file

@ -8,7 +8,7 @@ import re
def munge(text, munge_count=0): def munge(text, munge_count=0):
"munges up text." """munges up text."""
reps = 0 reps = 0
for n in xrange(len(text)): for n in xrange(len(text)):
rep = character_replacements.get(text[n]) rep = character_replacements.get(text[n])
@ -96,7 +96,7 @@ def multiword_replace(text, wordDic):
def truncate_words(content, length=10, suffix='...'): def truncate_words(content, length=10, suffix='...'):
"Truncates a string after a certain number of words." """Truncates a string after a certain number of words."""
nmsg = content.split(" ") nmsg = content.split(" ")
out = None out = None
x = 0 x = 0
@ -106,7 +106,7 @@ def truncate_words(content, length=10, suffix='...'):
out = out + " " + nmsg[x] out = out + " " + nmsg[x]
else: else:
out = nmsg[x] out = nmsg[x]
x = x + 1 x += 1
if x <= length: if x <= length:
return out return out
else: else:
@ -115,7 +115,7 @@ def truncate_words(content, length=10, suffix='...'):
# from <http://stackoverflow.com/questions/250357/smart-truncate-in-python> # from <http://stackoverflow.com/questions/250357/smart-truncate-in-python>
def truncate_str(content, length=100, suffix='...'): def truncate_str(content, length=100, suffix='...'):
"Truncates a string after a certain number of chars." """Truncates a string after a certain number of chars."""
if len(content) <= length: if len(content) <= length:
return content return content
else: else:
@ -197,5 +197,5 @@ def get_text_list(list_, last_word='or'):
return list_[0] return list_[0]
return '%s %s %s' % ( return '%s %s %s' % (
# Translators: This string is used as a separator between list elements # Translators: This string is used as a separator between list elements
(', ').join([i for i in list_][:-1]), ', '.join([i for i in list_][:-1]),
last_word, list_[-1]) last_word, list_[-1])

View file

@ -38,13 +38,15 @@ class Normalizer(object):
self.regex = regex self.regex = regex
self.normalize = normalize_func self.normalize = normalize_func
normalizers = ( Normalizer( re.compile(r'(?:https?://)?(?:[a-zA-Z0-9\-]+\.)?(?:amazon|amzn){1}\.(?P<tld>[a-zA-Z\.]{2,})\/(gp/(?:product|offer-listing|customer-media/product-gallery)/|exec/obidos/tg/detail/-/|o/ASIN/|dp/|(?:[A-Za-z0-9\-]+)/dp/)?(?P<ASIN>[0-9A-Za-z]{10})'),
normalizers = (Normalizer(re.compile(
r'(?:https?://)?(?:[a-zA-Z0-9\-]+\.)?(?:amazon|amzn){1}\.(?P<tld>[a-zA-Z\.]{2,})\/(gp/(?:product|offer-listing|customer-media/product-gallery)/|exec/obidos/tg/detail/-/|o/ASIN/|dp/|(?:[A-Za-z0-9\-]+)/dp/)?(?P<ASIN>[0-9A-Za-z]{10})'),
lambda m: r'http://amazon.%s/dp/%s' % (m.group('tld'), m.group('ASIN'))), lambda m: r'http://amazon.%s/dp/%s' % (m.group('tld'), m.group('ASIN'))),
Normalizer( re.compile(r'.*waffleimages\.com.*/([0-9a-fA-F]{40})'), Normalizer(re.compile(r'.*waffleimages\.com.*/([0-9a-fA-F]{40})'),
lambda m: r'http://img.waffleimages.com/%s' % m.group(1) ), lambda m: r'http://img.waffleimages.com/%s' % m.group(1)),
Normalizer( re.compile(r'(?:youtube.*?(?:v=|/v/)|youtu\.be/|yooouuutuuube.*?id=)([-_a-zA-Z0-9]+)'), Normalizer(re.compile(r'(?:youtube.*?(?:v=|/v/)|youtu\.be/|yooouuutuuube.*?id=)([-_a-zA-Z0-9]+)'),
lambda m: r'http://youtube.com/watch?v=%s' % m.group(1) ), lambda m: r'http://youtube.com/watch?v=%s' % m.group(1)),
) )
def normalize(url, assume_scheme=False): def normalize(url, assume_scheme=False):
@ -78,6 +80,7 @@ def normalize(url, assume_scheme=False):
def clean(string): def clean(string):
string = unicode(unquote(string), 'utf-8', 'replace') string = unicode(unquote(string), 'utf-8', 'replace')
return unicodedata.normalize('NFC', string).encode('utf-8') return unicodedata.normalize('NFC', string).encode('utf-8')
path = quote(clean(path), "~:/?#[]@!$&'()*+,;=") path = quote(clean(path), "~:/?#[]@!$&'()*+,;=")
fragment = quote(clean(fragment), "~") fragment = quote(clean(fragment), "~")

View file

@ -1,7 +1,9 @@
""" web.py - handy functions for web services """ """ web.py - handy functions for web services """
import http, urlnorm import http
import json, urllib import urlnorm
import json
import urllib
import yql import yql
short_url = "http://is.gd/create.php" short_url = "http://is.gd/create.php"
@ -39,11 +41,12 @@ def try_isgd(url):
out = url out = url
return out return out
def haste(text, ext='txt'): def haste(text, ext='txt'):
""" pastes text to a hastebin server """ """ pastes text to a hastebin server """
page = http.get(paste_url + "/documents", post_data=text) page = http.get(paste_url + "/documents", post_data=text)
data = json.loads(page) data = json.loads(page)
return("%s/%s.%s" % (paste_url, data['key'], ext)) return ("%s/%s.%s" % (paste_url, data['key'], ext))
def query(query, params={}): def query(query, params={}):

View file

@ -1,8 +1,8 @@
''' """
Runs a given url through the w3c validator Runs a given url through the w3c validator
by Vladi by Vladi
''' """
from util import hook, http from util import hook, http
@ -10,7 +10,7 @@ from util import hook, http
@hook.command('w3c') @hook.command('w3c')
@hook.command @hook.command
def validate(inp): def validate(inp):
"validate <url> -- Runs url through the w3c markup validator." """validate <url> -- Runs url through the w3c markup validator."""
if not inp.startswith('http://'): if not inp.startswith('http://'):
inp = 'http://' + inp inp = 'http://' + inp

View file

@ -25,22 +25,23 @@ def getSoundInfo(url, inp, jsondata=False):
quote = inp quote = inp
data = http.get_json(url + "list.php?" + urlencode({"quote": quote, "who": who})) data = http.get_json(url + "list.php?" + urlencode({"quote": quote, "who": who}))
if len(data) > 3: if len(data) > 3:
numresults = data[2]
newdata = data[3:] newdata = data[3:]
text = newdata[0]["text"] text = newdata[0]["text"]
if "music" in url: if "music" in url:
textsplit = text.split('"') textsplit = text.split('"')
text = "" text = ""
for i in xrange(len(textsplit)): for i in xrange(len(textsplit)):
if i%2 != 0 and i < 6: if i % 2 != 0 and i < 6:
if text: if text:
text += " / " + textsplit[i] text += " / " + textsplit[i]
else: else:
text = textsplit[i] text = textsplit[i]
if not jsondata: if not jsondata:
return "%s - %s %s" % (newdata[0]["who"], return "%s - %s %s" % (newdata[0]["who"],
text if len(text) < 325 else text[:325]+"...", text if len(text) < 325 else text[:325] + "...",
web.try_isgd(url + newdata[0]["id"] if not dostream else url+"sound.php?id="+newdata[0]["id"]+"&stream")) web.try_isgd(
url + newdata[0]["id"] if not dostream else url + "sound.php?id=" + newdata[0][
"id"] + "&stream"))
else: else:
if not jsondata: if not jsondata:
return "No results." return "No results."
@ -49,50 +50,72 @@ def getSoundInfo(url, inp, jsondata=False):
@hook.command @hook.command
def portal2(inp): def portal2(inp):
"""portal2 [who - ]<quote> - Look up Portal 2 quote. Example: .portal2 cave johnson - demand to see life's manager , .portal2 i own the place | If - is not included, no 'who' data will be sent.""" """portal2 [who - ]<quote> - Look up Portal 2 quote.
Example: .portal2 cave johnson - demand to see life's manager,
.portal2 i own the place | If - is not included, no 'who' data will be sent."""
return getSoundInfo(portal2url, inp) return getSoundInfo(portal2url, inp)
@hook.command @hook.command
def portal2dlc(inp): def portal2dlc(inp):
"""portal2dlc [who - ]<quote> - Look up Portal 2 DLC quote. Example: .portal2dlc1 glados - I lie when i'm nervous , .portal2 these exhibits are interactive | If - is not included, no 'who' data will be sent.""" """portal2dlc [who - ]<quote> - Look up Portal 2 DLC quote.
Example: .portal2dlc1 glados - I lie when i'm nervous
.portal2 these exhibits are interactive
If - is not included, no 'who' data will be sent."""
return getSoundInfo(portal2dlc1url, inp) return getSoundInfo(portal2dlc1url, inp)
@hook.command("portal2pti") @hook.command("portal2pti")
@hook.command @hook.command
def portal2dlc2(inp): def portal2dlc2(inp):
"""portal2dlc2 [who - ]<quote> - Look up Portal 2 Perpetual Testing Inititive quote. Example: .portal2 glados - I lie when i'm nervous , .portal2dlc2 these exhibits are interactive | If - is not included, no 'who' data will be sent.""" """portal2dlc2 [who - ]<quote> - Look up Portal 2 Perpetual Testing Inititive quote.
Example: .portal2 glados - I lie when i'm nervous
.portal2dlc2 these exhibits are interactive
If - is not included, no 'who' data will be sent."""
return getSoundInfo(portal2dlc2url, inp) return getSoundInfo(portal2dlc2url, inp)
@hook.command @hook.command
def portal2music(inp): def portal2music(inp):
"""portal2music <title> - Look up Portal 2 music. Example: .portal2 turret opera , .portal2music want you gone | If - is not included, no 'title' data will be sent.""" """portal2music <title> - Look up Portal 2 music.
Example: .portal2 turret opera
.portal2music want you gone
If - is not included, no 'title' data will be sent."""
return getSoundInfo(portal2musicurl, inp + " - ") return getSoundInfo(portal2musicurl, inp + " - ")
@hook.command('portal1') @hook.command('portal1')
@hook.command @hook.command
def portal(inp): def portal(inp):
"""portal [who - ]<quote> - Look up Portal quote. Example: .portal glados - the last thing you want to do is hurt me , .portal this is your fault | If - is not included, no 'who' data will be sent.""" """portal [who - ]<quote> - Look up Portal quote.
Example: .portal glados - the last thing you want to do is hurt me
.portal this is your fault
If - is not included, no 'who' data will be sent."""
return getSoundInfo(portal1url, inp) return getSoundInfo(portal1url, inp)
@hook.command('portal1music') @hook.command('portal1music')
@hook.command @hook.command
def portalmusic(inp): def portalmusic(inp):
"""portalmusic <title> - Look up Portal music. Example: .portalmusic still alive | If - is not included, no 'title' data will be sent.""" """portalmusic <title> - Look up Portal music.
Example: .portalmusic still alive
If - is not included, no 'title' data will be sent."""
return getSoundInfo(portal1musicurl, inp + " - ") return getSoundInfo(portal1musicurl, inp + " - ")
@hook.command('tf2sound') @hook.command('tf2sound')
@hook.command @hook.command
def tf2(inp): def tf2(inp):
"""tf2 [who - ]<quote> - Look up TF2 quote. Example: .tf2 spy - may i borrow your earpiece , .tf2 nom nom nom | If - is not included, no 'who' data will be sent.""" """tf2 [who - ]<quote> - Look up TF2 quote.
Example: .tf2 spy - may i borrow your earpiece
.tf2 nom nom nom
If - is not included, no 'who' data will be sent."""
return getSoundInfo(tf2url, inp) return getSoundInfo(tf2url, inp)
@hook.command @hook.command
def tf2music(inp): def tf2music(inp):
"""tf2music title - Look up TF2 music lyrics. Example: .tf2music rocket jump waltz | If - is not included, no 'title' data will be sent.""" """tf2music title - Look up TF2 music lyrics.
Example: .tf2music rocket jump waltz
If - is not included, no 'title' data will be sent."""
return getSoundInfo(tf2musicurl, inp + " - ") return getSoundInfo(tf2musicurl, inp + " - ")

View file

@ -3,7 +3,7 @@ from util import hook, http, timeformat
@hook.regex(r'vimeo.com/([0-9]+)') @hook.regex(r'vimeo.com/([0-9]+)')
def vimeo_url(match): def vimeo_url(match):
"vimeo <url> -- returns information on the Vimeo video at <url>" """vimeo <url> -- returns information on the Vimeo video at <url>"""
info = http.get_json('http://vimeo.com/api/v2/video/%s.json' info = http.get_json('http://vimeo.com/api/v2/video/%s.json'
% match.group(1)) % match.group(1))

View file

@ -5,8 +5,8 @@ base_url = "http://api.wunderground.com/api/{}/{}/q/{}.json"
@hook.command(autohelp=None) @hook.command(autohelp=None)
def weather(inp, reply=None, db=None, nick=None, bot=None, notice=None): def weather(inp, reply=None, db=None, nick=None, bot=None, notice=None):
"weather <location> [dontsave] -- Gets weather data"\ """weather <location> [dontsave] -- Gets weather data
" for <location> from Wunderground." for <location> from Wunderground."""
api_key = bot.config.get("api_keys", {}).get("wunderground") api_key = bot.config.get("api_keys", {}).get("wunderground")
@ -55,7 +55,8 @@ def weather(inp, reply=None, db=None, nick=None, bot=None, notice=None):
if response['location']['state']: if response['location']['state']:
place_name = "\x02{}\x02, \x02{}\x02 (\x02{}\x02)".format(response['location']['city'], place_name = "\x02{}\x02, \x02{}\x02 (\x02{}\x02)".format(response['location']['city'],
response['location']['state'], response['location']['country']) response['location']['state'],
response['location']['country'])
else: else:
place_name = "\x02{}\x02 (\x02{}\x02)".format(response['location']['city'], place_name = "\x02{}\x02 (\x02{}\x02)".format(response['location']['city'],
response['location']['country']) response['location']['country'])

View file

@ -1,5 +1,5 @@
'''Searches wikipedia and returns first sentence of article """Searches wikipedia and returns first sentence of article
Scaevolus 2009''' Scaevolus 2009"""
import re import re
@ -15,14 +15,14 @@ paren_re = re.compile('\s*\(.*\)$')
@hook.command('w') @hook.command('w')
@hook.command @hook.command
def wiki(inp): def wiki(inp):
"wiki <phrase> -- Gets first sentence of Wikipedia article on <phrase>." """wiki <phrase> -- Gets first sentence of Wikipedia article on <phrase>."""
x = http.get_xml(search_url, search=inp) x = http.get_xml(search_url, search=inp)
ns = '{http://opensearch.org/searchsuggest2}' ns = '{http://opensearch.org/searchsuggest2}'
items = x.findall(ns + 'Section/' + ns + 'Item') items = x.findall(ns + 'Section/' + ns + 'Item')
if items == []: if not items:
if x.find('error') is not None: if x.find('error') is not None:
return 'error: %(code)s: %(info)s' % x.find('error').attrib return 'error: %(code)s: %(info)s' % x.find('error').attrib
else: else:

View file

@ -6,7 +6,7 @@ from util import hook, http, text, web
@hook.command('wa') @hook.command('wa')
@hook.command @hook.command
def wolframalpha(inp, bot=None): def wolframalpha(inp, bot=None):
"wa <query> -- Computes <query> using Wolfram Alpha." """wa <query> -- Computes <query> using Wolfram Alpha."""
api_key = bot.config.get("api_keys", {}).get("wolframalpha", None) api_key = bot.config.get("api_keys", {}).get("wolframalpha", None)

View file

@ -3,7 +3,7 @@ from util import hook, web, text
@hook.command @hook.command
def answer(inp): def answer(inp):
"answer <query> -- find the answer to a question on Yahoo! Answers" """answer <query> -- find the answer to a question on Yahoo! Answers"""
query = "SELECT Subject, ChosenAnswer, Link FROM answers.search WHERE query=@query LIMIT 1" query = "SELECT Subject, ChosenAnswer, Link FROM answers.search WHERE query=@query LIMIT 1"
result = web.query(query, {"query": inp.strip()}).one() result = web.query(query, {"query": inp.strip()}).one()

View file

@ -70,7 +70,7 @@ def youtube_url(match):
@hook.command('y') @hook.command('y')
@hook.command @hook.command
def youtube(inp): def youtube(inp):
"youtube <query> -- Returns the first YouTube search result for <query>." """youtube <query> -- Returns the first YouTube search result for <query>."""
request = http.get_json(search_api_url, q=inp) request = http.get_json(search_api_url, q=inp)
@ -84,8 +84,10 @@ def youtube(inp):
return get_video_description(video_id) + " - " + video_url % video_id return get_video_description(video_id) + " - " + video_url % video_id
ytpl_re = (r'(.*:)//(www.youtube.com/playlist|youtube.com/playlist)(:[0-9]+)?(.*)', re.I) ytpl_re = (r'(.*:)//(www.youtube.com/playlist|youtube.com/playlist)(:[0-9]+)?(.*)', re.I)
@hook.regex(*ytpl_re) @hook.regex(*ytpl_re)
def ytplaylist_url(match): def ytplaylist_url(match):
location = match.group(4).split("=")[-1] location = match.group(4).split("=")[-1]
@ -95,8 +97,6 @@ def ytplaylist_url(match):
return "\x034\x02Invalid response." return "\x034\x02Invalid response."
title = soup.find('title').text.split('-')[0].strip() title = soup.find('title').text.split('-')[0].strip()
author = soup.find('img', {'class': 'channel-header-profile-image'})['title'] author = soup.find('img', {'class': 'channel-header-profile-image'})['title']
numofratings = int(soup.find('span', {'class': 'likes'}).text) + int(soup.find('span', {'class': 'dislikes'}).text)
rating = (int(soup.find('span', {'class': 'likes'}).text) / numofratings) * 100 / 20
numvideos = soup.find('ul', {'class': 'header-stats'}).findAll('li')[0].text.split(' ')[0] numvideos = soup.find('ul', {'class': 'header-stats'}).findAll('li')[0].text.split(' ')[0]
views = soup.find('ul', {'class': 'header-stats'}).findAll('li')[1].text.split(' ')[0] views = soup.find('ul', {'class': 'header-stats'}).findAll('li')[1].text.split(' ')[0]
return u"\x02%s\x02 - \x02%s\x02 views - \x02%s\x02 videos - \x02%s\x02" % (title, views, numvideos, author) return u"\x02%s\x02 - \x02%s\x02 views - \x02%s\x02 videos - \x02%s\x02" % (title, views, numvideos, author)