Merge branch 'develop' into refresh

This commit is contained in:
Luke Rogers 2013-12-11 17:14:38 +13:00
commit 0384fd16ab
5 changed files with 135 additions and 210 deletions

View file

@ -1,38 +1,41 @@
from util import http, hook
## CONSTANTS
exchanges = {
"blockchain": {
"api_url": "https://blockchain.info/ticker",
"func": lambda data: u"Blockchain // Buy: \x0307${:,.2f}\x0f - Sell: \x0307${:,.2f}\x0f".format(data["USD"]["buy"], \
data["USD"]["sell"])
},
"mtgox": {
"api_url": "https://mtgox.com/api/1/BTCUSD/ticker",
"func": lambda data: u"MtGox // Current: \x0307{}\x0f - High: \x0307{}\x0f - Low: \x0307{}\x0f - Best Ask: \x0307{}\x0f - Volume: {}".format(data['return']['last']['display'], \
data['return']['high']['display'], data['return']['low']['display'], data['return']['buy']['display'], \
data['return']['vol']['display'])
},
"coinbase":{
"api_url": "https://coinbase.com/api/v1/prices/spot_rate",
"func": lambda data: u"Coinbase // Current: \x0307${:,.2f}\x0f".format(float(data['amount']))
},
"bitpay": {
"api_url": "https://bitpay.com/api/rates",
"func": lambda data: u"Bitpay // Current: \x0307${:,.2f}\x0f".format(data[0]['rate'])
},
"bitstamp": {
"api_url": "https://www.bitstamp.net/api/ticker/",
"func": lambda data: u"BitStamp // Current: \x0307${:,.2f}\x0f - High: \x0307${:,.2f}\x0f - Low: \x0307${:,.2f}\x0f - Volume: {:,.2f} BTC".format(float(data['last']), float(data['high']), float(data['low']), \
float(data['volume']))
}
}
## HOOK FUNCTIONS
@hook.command("butt", autohelp=False)
@hook.command("btc", autohelp=False)
@hook.command(autohelp=False)
def bitcoin(inp):
"bitcoin <exchange> -- Gets current exchange rate for bitcoins from several exchanges, default is Blockchain. Supports MtGox, Bitpay, Coinbase and BitStamp."
exchanges = {
"blockchain": {
"api_url": "https://blockchain.info/ticker",
"func": lambda data: u"Blockchain // Buy: \x0307${:,.2f}\x0f - Sell: \x0307${:,.2f}\x0f".format(data["USD"]["buy"], \
data["USD"]["sell"])
},
"mtgox": {
"api_url": "https://mtgox.com/api/1/BTCUSD/ticker",
"func": lambda data: u"MtGox // Current: \x0307{}\x0f - High: \x0307{}\x0f - Low: \x0307{}\x0f - Best Ask: \x0307{}\x0f - Volume: {}".format(data['return']['last']['display'], \
data['return']['high']['display'], data['return']['low']['display'], data['return']['buy']['display'], \
data['return']['vol']['display'])
},
"coinbase":{
"api_url": "https://coinbase.com/api/v1/prices/spot_rate",
"func": lambda data: u"Coinbase // Current: \x0307${:,.2f}\x0f".format(float(data['amount']))
},
"bitpay": {
"api_url": "https://bitpay.com/api/rates",
"func": lambda data: u"Bitpay // Current: \x0307${:,.2f}\x0f".format(data[0]['rate'])
},
"bitstamp": {
"api_url": "https://www.bitstamp.net/api/ticker/",
"func": lambda data: u"BitStamp // Current: \x0307${:,.2f}\x0f - High: \x0307${:,.2f}\x0f - Low: \x0307${:,.2f}\x0f - Volume: {:,.2f} BTC".format(float(data['last']), float(data['high']), float(data['low']), \
float(data['volume']))
}
}
"""bitcoin <exchange> -- Gets current exchange rate for bitcoins from several exchanges, default is Blockchain. Supports MtGox, Bitpay, Coinbase and BitStamp."""
inp = inp.lower()
if inp:
@ -48,6 +51,7 @@ def bitcoin(inp):
return func(data)
@hook.command("ltc", autohelp=False)
@hook.command(autohelp=False)
def litecoin(inp, message=None):
"""litecoin -- gets current exchange rate for litecoins from BTC-E"""

View file

@ -1,134 +0,0 @@
from util import hook, timesince
import time
import re
db_ready = False
CAN_DOWNVOTE = False
def db_init(db):
db.execute("""CREATE TABLE if not exists karma(
nick_vote TEXT PRIMARY KEY,
up_karma INTEGER,
down_karma INTEGER,
total_karma INTEGER)""")
db.execute("""CREATE TABLE if not exists karma_voters(
voter TEXT,
votee TEXT,
epoch FLOAT,
PRIMARY KEY(voter, votee))""")
db_ready = True
def up(db, nick_vote):
db.execute("""UPDATE karma SET
up_karma = up_karma + 1,
total_karma = total_karma + 1 WHERE nick_vote=?""", (nick_vote.lower(),))
db.commit()
def down(db, nick_vote):
db.execute("""UPDATE karma SET
down_karma = down_karma + 1,
total_karma = total_karma + 1 WHERE nick_vote=?""", (nick_vote.lower(),))
db.commit()
def allowed(db, nick, nick_vote):
time_restriction = 3600
db.execute("""DELETE FROM karma_voters WHERE ? - epoch >= 3600""",
(time.time(),))
db.commit()
check = db.execute("""SELECT epoch FROM karma_voters WHERE voter=? AND votee=?""",
(nick.lower(), nick_vote.lower())).fetchone()
if check:
check = check[0]
if time.time() - check >= time_restriction:
db.execute("""INSERT OR REPLACE INTO karma_voters(
voter,
votee,
epoch) values(?,?,?)""", (nick.lower(), nick_vote.lower(), time.time()))
db.commit()
return True, 0
else:
return False, timesince.timeuntil(check, now=time.time() - time_restriction)
else:
db.execute("""INSERT OR REPLACE INTO karma_voters(
voter,
votee,
epoch) values(?,?,?)""", (nick.lower(), nick_vote.lower(), time.time()))
db.commit()
return True, 0
# TODO Make this work on multiple matches in a string, right now it'll only
# work on one match.
# karma_re = ('((\S+)(\+\+|\-\-))+', re.I)
karma_re = ('(.+)(\+\+|\-\-)$', re.I)
@hook.regex(*karma_re)
def karma_add(match, nick='', chan='', db=None, notice=None):
if not db_ready:
db_init(db)
nick_vote = match.group(1).strip().replace("+", "")
if nick.lower() == nick_vote.lower():
notice("You can't vote on yourself!")
return
if len(nick_vote) < 3 or " " in nick_vote:
return # ignore anything below 3 chars in length or with spaces
vote_allowed, when = allowed(db, nick, nick_vote)
if vote_allowed:
if match.group(2) == '++':
db.execute("""INSERT or IGNORE INTO karma(
nick_vote,
up_karma,
down_karma,
total_karma) values(?,?,?,?)""", (nick_vote.lower(), 0, 0, 0))
up(db, nick_vote)
notice("Gave {} 1 karma!".format(nick_vote))
if match.group(2) == '--' and CAN_DOWNVOTE:
db.execute("""INSERT or IGNORE INTO karma(
nick_vote,
up_karma,
down_karma,
total_karma) values(?,?,?,?)""", (nick_vote.lower(), 0, 0, 0))
down(db, nick_vote)
notice("Took away 1 karma from {}.".format(nick_vote))
else:
return
else:
notice("You are trying to vote too often. You can vote again in {}!".format(when))
return
@hook.command('k')
@hook.command
def karma(inp, nick='', chan='', db=None):
"""k/karma <nick> -- returns karma stats for <nick>"""
if not db_ready:
db_init(db)
if not chan.startswith('#'):
return
nick_vote = inp
out = db.execute("""SELECT * FROM karma WHERE nick_vote=?""",
(nick_vote.lower(),)).fetchall()
if not out:
return "That user has no karma."
else:
out = out[0]
return "{} has {} karma points.".format(nick_vote, out[1] - out[2])
return

View file

@ -1,13 +1,19 @@
from util import hook, http, web
from util import hook, http, web, text
import time
import random
## CONSTANTS
base_url = "http://api.bukget.org/3/"
search_url = base_url + "search/plugin_name/like/{}"
random_url = base_url + "plugins/bukkit/?start={}&size=1"
details_url = base_url + "plugins/bukkit/{}"
categories = http.get_json("http://api.bukget.org/3/categories")
total_plugins = sum([cat["count"] for cat in categories])
count_total = sum([cat["count"] for cat in categories])
count_categores = {cat["name"].lower() : int(cat["count"]) for cat in categories} # dict conps!
class BukgetError(Exception):
@ -19,6 +25,8 @@ class BukgetError(Exception):
return self.text
## DATA FUNCTIONS
def plugin_search(term):
""" searches for a plugin with the bukget API and returns the slug """
term = term.lower().strip()
@ -40,6 +48,21 @@ def plugin_search(term):
return results[0]["slug"]
def plugin_random():
""" gets a random plugin from the bukget API and returns the slug """
results = None
while not results:
plugin_number = random.randint(1, count_total)
print "trying {}".format(plugin_number)
try:
results = http.get_json(random_url.format(plugin_number))
except (http.HTTPError, http.URLError) as e:
raise BukgetError(500, "Error Fetching Search Page: {}".format(e))
return results[0]["slug"]
def plugin_details(slug):
""" takes a plugin slug and returns details from the bukget API """
slug = slug.lower().strip()
@ -51,27 +74,12 @@ def plugin_details(slug):
return details
## OTHER FUNCTIONS
@hook.command('plugin')
@hook.command
def bukkitplugin(inp, reply=None, message=None):
"""plugin <slug/name> - Look up a plugin on dev.bukkit.org"""
# get the plugin slug using search
print total_plugins
try:
slug = plugin_search(inp)
except BukgetError as e:
return e
# get the plugin info using the slug
try:
data = plugin_details(slug)
except BukgetError as e:
return e
def format_output(data):
""" takes plugin data and returns two strings representing information about that plugin """
name = data["plugin_name"]
description = data['description']
description = text.truncate_str(data['description'], 30)
url = data['website']
authors = data['authors'][0]
authors = authors[0] + u"\u200b" + authors[1:]
@ -87,8 +95,58 @@ def bukkitplugin(inp, reply=None, message=None):
link = web.try_isgd(current_version['link'])
if description:
reply(u"\x02{}\x02, by \x02{}\x02 - {} - ({}) \x02{}".format(name, authors, description, stage, url))
line_a = u"\x02{}\x02, by \x02{}\x02 - {} - ({}) \x02{}".format(name, authors, description, stage, url)
else:
reply(u"\x02{}\x02, by \x02{}\x02 ({}) \x02{}".format(name, authors, stage, url))
line_a = u"\x02{}\x02, by \x02{}\x02 ({}) \x02{}".format(name, authors, stage, url)
message(u"Last release: \x02v{}\x02 for \x02{}\x02 at {} \x02{}\x02".format(version_number, bukkit_versions, last_update, link))
line_b = u"Last release: \x02v{}\x02 for \x02{}\x02 at {} \x02{}\x02".format(version_number, bukkit_versions, last_update, link)
return line_a, line_b
## HOOK FUNCTIONS
@hook.command('plugin')
@hook.command
def bukkitplugin(inp, reply=None, message=None):
"""plugin <slug/name> - Look up a plugin on dev.bukkit.org"""
# get the plugin slug using search
try:
slug = plugin_search(inp)
except BukgetError as e:
return e
# get the plugin info using the slug
try:
data = plugin_details(slug)
except BukgetError as e:
return e
# format the final message and send it to IRC
line_a, line_b = format_output(data)
reply(line_a)
message(line_b)
@hook.command(autohelp=None)
def randomplugin(inp, reply=None, message=None):
"""randomplugin - Gets a random plugin from dev.bukkit.org"""
# get a random plugin slug
try:
slug = plugin_random()
except BukgetError as e:
return e
# get the plugin info using the slug
try:
data = plugin_details(slug)
except BukgetError as e:
return e
# format the final message and send it to IRC
line_a, line_b = format_output(data)
reply(line_a)
message(line_b)

View file

@ -10,7 +10,7 @@ API_SEARCH = "http://www.ows.newegg.com/Search.egg/Advanced"
NEWEGG_RE = (r"(?:(?:www.newegg.com|newegg.com)/Product/Product\.aspx\?Item=)([-_a-zA-Z0-9]+)", re.I)
def format_item(item):
def format_item(item, show_url=True):
""" takes a newegg API item object and returns a description """
title = text.truncate_str(item["Title"], 50)
@ -45,18 +45,23 @@ def format_item(item):
# join all the tags together in a comma seperated string ("tag1, tag2, tag3")
tag_text = u", ".join(tags)
# create the item URL and shorten it
url = web.try_isgd(ITEM_URL.format(item["NeweggItemNumber"]))
if show_url:
# create the item URL and shorten it
url = web.try_isgd(ITEM_URL.format(item["NeweggItemNumber"]))
return u"\x02{}\x02 ({}) - {} - {} - {}".format(title, price, rating,
tag_text, url)
else:
return u"\x02{}\x02 ({}) - {} - {}".format(title, price, rating,
tag_text)
return u"\x02{}\x02 ({}) - {} - {} - {}".format(title, price, rating,
tag_text, url)
## HOOK FUNCTIONS
@hook.regex(*NEWEGG_RE)
def newegg_url(match):
item_id = match.group(1)
item = http.get_json(API_PRODUCT.format(item_id))
return format_item(item)
return format_item(item, show_url=False)
@hook.command
@ -65,17 +70,8 @@ def newegg(inp):
# form the search request
request = {
"PageNumber": 1,
"BrandId": -1,
"NValue": "",
"StoreDepaId": -1,
"NodeId": -1,
"Keyword": inp,
"IsSubCategorySearch": False,
"SubCategoryId": -1,
"Sort": "FEATURED",
"CategoryId": -1,
"IsUPCCodeSearch": False
"Sort": "FEATURED"
}
# submit the search request

View file

@ -74,13 +74,13 @@ def get_video_description(video_id):
data = request['data']
out = '\x02{}\x02'.format(data['title'])
out = u'\x02{}\x02'.format(data['title'])
if not data.get('duration'):
return out
length = data['duration']
out += ' - length \x02{}\x02'.format(format_time(length, simple=True))
out += u' - length \x02{}\x02'.format(format_time(length, simple=True))
if 'ratingCount' in data:
# format
@ -88,12 +88,12 @@ def get_video_description(video_id):
dislikes = plural(data['ratingCount'] - int(data['likeCount']), "dislike")
percent = 100 * float(data['likeCount'])/float(data['ratingCount'])
out += ' - {}, {} (\x02{:.1f}\x02%)'.format(likes,
out += u' - {}, {} (\x02{:.1f}\x02%)'.format(likes,
dislikes, percent)
if 'viewCount' in data:
views = data['viewCount']
out += ' - \x02{:,}\x02 view{}'.format(views, "s"[views==1:])
out += u' - \x02{:,}\x02 view{}'.format(views, "s"[views==1:])
try:
uploader = http.get_json(base_url + "users/{}?alt=json".format(data["uploader"]))["entry"]["author"][0]["name"]["$t"]
@ -101,11 +101,11 @@ def get_video_description(video_id):
uploader = data["uploader"]
upload_time = time.strptime(data['uploaded'], "%Y-%m-%dT%H:%M:%S.000Z")
out += ' - \x02{}\x02 on \x02{}\x02'.format(uploader,
out += u' - \x02{}\x02 on \x02{}\x02'.format(uploader,
time.strftime("%Y.%m.%d", upload_time))
if 'contentRating' in data:
out += ' - \x034NSFW\x02'
out += u' - \x034NSFW\x02'
return out
@ -115,6 +115,7 @@ def youtube_url(match):
return get_video_description(match.group(1))
@hook.command('you')
@hook.command('yt')
@hook.command('y')
@hook.command
@ -130,7 +131,7 @@ def youtube(inp):
video_id = request['data']['items'][0]['id']
return get_video_description(video_id) + " - " + video_url % video_id
return get_video_description(video_id) + u" - " + video_url % video_id