diff --git a/plugins/steam.py b/plugins/steam.py index 2ec76cc..842a6cb 100644 --- a/plugins/steam.py +++ b/plugins/steam.py @@ -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 [currency] - Gets value of steam account and - total hours played. Uses steamcommunity.com/id/. 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'})) == '
Markdown
': - 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 diff --git a/plugins/steam_calc.py b/plugins/steam_calc.py new file mode 100644 index 0000000..058494d --- /dev/null +++ b/plugins/steam_calc.py @@ -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 [currency] - Gets value of steam account and + total hours played. Uses steamcommunity.com/id/. """ + + 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)