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 re
import json
from xml.dom import minidom
from util import hook, http, web, text from util import hook, http, web, text
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
db_ready = False
steam_re = (r'(.*:)//(store.steampowered.com)(:[0-9]+)?(.*)', re.I) 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): def get_steam_info(url):
# we get the soup manually because the steam pages have some odd encoding troubles # 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)