Added brand new steam_calc.py plugin

This commit is contained in:
Luke Rogers 2013-09-08 02:34:55 +12:00
parent fac18416a8
commit b40b4640d8
2 changed files with 80 additions and 130 deletions

View file

@ -1,140 +1,10 @@
import urllib2
import re
import json
from xml.dom import minidom
from util import hook, http, web, text
from bs4 import BeautifulSoup
db_ready = False
steam_re = (r'(.*:)//(store.steampowered.com)(:[0-9]+)?(.*)', re.I)
currencies = {'USD': 'us', 'euro1': "de", 'euro2': 'no',
'pound': 'uk', 'rubles': 'ru', 'real': 'br',
'yen': 'jp', 'dollars': 'us', 'german': 'de',
'pounds': 'uk', 'russian': 'ru', 'brazil': 'br',
'japan': 'jp', 'us': 'us', 'de': 'de', 'no': 'no',
'uk': 'uk', 'ru': 'ru', 'br': 'br', 'jp': 'jp'}
def db_init(db):
db.execute("create table if not exists steam(nick primary key, acc)")
db.commit()
db_ready = True
def get_steam_info(name):
dom = minidom.parse(urllib2.urlopen(re.sub("{USER}", name, "http://steamcommunity.com/id/{USER}/?xml=1")))
ID = int(dom.getElementsByTagName("steamID64")[0].firstChild.data)
key = bot.config.get("api_keys", {}).get("steam_key")
url = "http://api.steampowered.com/IPlayerService/GetOwnedGames/v0001/?key={}&steamid={}&format=json".format(key,
ID)
data = json.load(urllib2.urlopen(url))
useable = data['response']['games']
games = []
played = []
data = {}
playtime = 0
for x in useable:
games.append(x)
if x['playtime_forever'] > 0:
played.append(x)
playtime += x['playtime_forever']
played.sort(key=lambda x: x['playtime_forever'])
played.reverse()
data['playtime'] = int(playtime / 60.0)
data['played'] = played
data['games'] = games
data['%played'] = round(float(len(played)) / len(games) * 100, 2)
return data
@hook.command('sc', autohelp=False)
@hook.command(autohelp=False)
def steamcalc(inp, nick='', db=None):
"""steamcalc <username> [currency] - Gets value of steam account and
total hours played. Uses steamcommunity.com/id/<nickname>. Uses
IRC nickname if none provided. """
if not db_ready:
db_init(db)
currency = None
dontsave = False
if not inp:
user = db.execute("select acc from steam where nick=lower(?)", (nick,)).fetchone()
if not user:
inp = nick
else:
inp = user[0]
dontsave = True
else:
if len(inp.split(" ")) > 1:
if inp.split(" ")[1] in currencies:
currency = currencies[inp.split(" ")[1]]
dontsave = False
elif inp.split(" ")[1] == "dontsave":
dontsave = True
else:
return "Invalid currency!"
inp = inp.split(" ")[0]
if len(inp.split(" ")) > 2:
if inp.split(" ")[2] == "dontsave":
dontsave = True
url = http.prepare_url("http://steamdb.info/calculator/",
{"player": inp, "currency": currency if currency else "us"})
soup = http.get_soup(url)
out = u""
try:
out += soup.findAll('h1', {'class': 'header-title'})[1].text.strip()
except Exception as e:
print e
return u"\x02Unable to retrieve info for {}!\x02 Is it a valid SteamCommunity profile username ({})? " \
"Check if your profile is private, or go here to search: {}".format(
inp, web.try_isgd("http://steamcommunity.com/id/%s" % inp), web.try_isgd(url))
nextone = False
status = "Unknown"
for i in soup.findAll('td'):
if nextone:
status = i.text
break
elif i.text == "Status":
nextone = True
if status == "Online":
status = "\x033\x02Online\x02\x0f"
elif status == "Offline":
status = "\x034\x02Offline\x02\x0f"
elif status == "Away":
status = "\x038\x02Away\x02\x0f"
elif status == "Busy":
status = "\x035\x02Busy\x02\x0f"
elif "Looking to" in status:
status = "\x036\x02%s\x02\x0f" % status
out += " (%s)" % status
for i in soup.findAll('div', {'class': 'panel'}):
if str(i.find('div', {'class': 'panel-heading'})) == '<div class="panel-heading">Markdown</div>':
data = i
data = data.findAll('p')[1:]
print data
money = data[0].text.split(" ")[-1]
totalgames = data[1].text.split(" ")[-1]
time = data[2].text.split(" ")[-1].replace("h", "").replace(",", "")
time = str(int(round(float(time))))
out += " This account is worth \x02{}\x02, and they've spent \x02{}\x02 hour(s) playing games! ".format(money, time)
out += "They have \x02{} games\x02 - {}".format(totalgames, web.try_isgd(url))
if not dontsave:
db.execute("insert or replace into steam(nick, acc) values (?,?)", (nick.lower(), inp))
db.commit()
return out
def get_steam_info(url):
# we get the soup manually because the steam pages have some odd encoding troubles

80
plugins/steam_calc.py Normal file
View file

@ -0,0 +1,80 @@
from util import hook, http
import csv
import StringIO
api_url = "http://mysteamgauge.com/user/{}.csv"
steam_api_url = "http://steamcommunity.com/id/{}/?xml=1"
def is_number(s):
try:
float(s)
return True
except ValueError:
return False
def unicode_dictreader(utf8_data, **kwargs):
csv_reader = csv.DictReader(utf8_data, **kwargs)
for row in csv_reader:
yield dict([(key, unicode(value, 'utf-8')) for key, value in row.iteritems()])
@hook.command('sc')
@hook.command
def steamcalc(inp):
"""steamcalc <username> [currency] - Gets value of steam account and
total hours played. Uses steamcommunity.com/id/<nickname>. """
name = inp.strip()
try:
request = http.get(api_url.format(name))
except (http.HTTPError, http.URLError):
return "Could not get data for {}!".format(name)
csv_data = StringIO.StringIO(request)
reader = unicode_dictreader(csv_data)
games = []
for row in reader:
games.append(row)
data = {}
# basic information
steam_profile = http.get_xml(steam_api_url.format(name))
data["name"] = steam_profile.find('steamID').text
online_state = steam_profile.find('onlineState').text
data["state"] = online_state # will make this pretty later
# work out the average metascore for all games
ms = [float(game["Metascore"]) for game in games if is_number(game["Metascore"])]
metascore = float(sum(ms))/len(ms) if len(ms) > 0 else float('nan')
data["average_metascore"] = "{0:.1f}".format(metascore)
# work out the totals
data["games"] = len(games)
total_value = sum([float(game["Value"]) for game in games if is_number(game["Value"])])
data["value"] = str(int(round(total_value)))
# work out the total size
total_size = 0.0
for game in games:
if not is_number(game["Size"]):
continue
if game["Unit"] == "GB":
total_size += float(game["Size"])
else:
total_size += float(game["Size"])/1024
data["size"] = "{0:.1f}".format(total_size)
return "{name} ({state}) has {games} games with a total value of ${value}" \
" and a total size of {size}GB! The average metascore for these" \
" games is {average_metascore}.".format(**data)