diff --git a/plugins/namegen.py b/plugins/namegen.py index 6e081c0..ff9a2f0 100755 --- a/plugins/namegen.py +++ b/plugins/namegen.py @@ -36,7 +36,7 @@ class NameGenerator(object): for name_part in name_parts: part = random.choice(self.parts[name_part]) - name = name.replace("{{}}".format(name_part), part) + name = name.replace("\{{}\}".format(name_part), part) return name 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..10d7f8a --- /dev/null +++ b/plugins/steam_calc.py @@ -0,0 +1,86 @@ +from util import hook, http +import csv +import time +import StringIO + +gauge_url = "http://www.mysteamgauge.com/search?username={}" + +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.lower(), unicode(value, 'utf-8')) for key, value in row.iteritems()]) + + +@hook.command('sc') +@hook.command +def steamcalc(inp, reply=None): + """steamcalc [currency] - Gets value of steam account and + total hours played. Uses steamcommunity.com/id/. """ + + name = inp.strip() + + try: + reply("Collecting data, this may take a few seconds.") + http.get(gauge_url.format(name), timeout=15, get_method='HEAD') + request = http.get(api_url.format(name)) + except (http.HTTPError, http.URLError): + return "Could not get data for this user." + + csv_data = StringIO.StringIO(request) # we use StringIO because CSV can't read a string + reader = unicode_dictreader(csv_data) + + # put the games in a list + 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('stateMessage').text + data["state"] = online_state.replace("
", ": ") # 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) diff --git a/plugins/util/formatting.py b/plugins/util/formatting.py new file mode 100644 index 0000000..442adf5 --- /dev/null +++ b/plugins/util/formatting.py @@ -0,0 +1,34 @@ +def raw(format_string): + """Replace based irc formatting""" + stuff = {} + stuff['col'] = {'[white]':'\x030', + '[black]':'\x031', + '[dblue]':'\x032', + '[dgreen]':'\x033', + '[dred]':'\x034', + '[brown]':'\x035', + '[purple]':'\x036', + '[gold]':'\x037', + '[yellow]':'\x038', + '[green]':'\x039', + '[cyan]':'\x0310', + '[lblue]':'\x0311', + '[blue]':'\x0312', + '[pink]':'\x0313', + '[gray]':'\x0314', + '[lgray]':'\x0315', + '[err]':'\x034\x02' + '[/err]':'\x030\x02'} + stuff['style'] = {'[b]':'\x02', + '[clear]':'\x0f'} + stuff['sym'] = {'[point]':'\x07'} + stuff['text'] = {'[url]':'http://'} + final = {} + for x in stuff: + final.update(stuff[x]) + for x in final: + format_string = format_string.replace(x,final[x]) + return format_string +def err(format_string): + """Format the string with standard error styling""" + return "\x034\x02{}\x0f".format(format_string) \ No newline at end of file diff --git a/plugins/util/http.py b/plugins/util/http.py index 4eccdf0..4409211 100755 --- a/plugins/util/http.py +++ b/plugins/util/http.py @@ -52,7 +52,7 @@ def get_json(*args, **kwargs): def open(url, query_params=None, user_agent=None, post_data=None, - referer=None, get_method=None, cookies=False, **kwargs): + referer=None, get_method=None, cookies=False, timeout=None, **kwargs): if query_params is None: query_params = {} @@ -78,7 +78,10 @@ def open(url, query_params=None, user_agent=None, post_data=None, else: opener = urllib2.build_opener() - return opener.open(request) + if timeout: + return opener.open(request, timeout=timeout) + else: + return opener.open(request) def prepare_url(url, queries):