Merge branch 'develop' into refresh
This commit is contained in:
commit
0384fd16ab
5 changed files with 135 additions and 210 deletions
|
@ -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"""
|
||||
|
|
134
plugins/karma.py
134
plugins/karma.py
|
@ -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
|
|
@ -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)
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
|
Reference in a new issue