#!/usr/bin/python

# https://developer.valvesoftware.com/wiki/Steam_Web_API
# https://partner.steamgames.com/documentation/community_data

from elementtree.ElementTree import parse
from elementtree.ElementTree import fromstring
from elementtree.ElementTree import dump
import simplejson as json
from urllib2 import urlopen
import os
import Queue
from commands import getstatusoutput as gso
import time

gso("mkdir -p /media/external/steam/parsedachievements /media/external/steam/rawJson /media/external/steam/rawXml")
key = "624629B773D5C3EB250FE8141DB55EA0"

def getData(query, rawname):
  if (".json" in rawname): folder = "/media/external/steam/rawJson"
  else: folder = "/media/external/steam/rawXml"
  path = folder + '/' + rawname
  if os.path.exists(path):
    a = open(path, 'r')
    s = a.read()
    a.close()
  else:
    q2 = str(query)
    print q2.encode("ascii")
    print query
    retry = 0
    while retry < 3:
      try:
        a = urlopen(query)
        break
      except Exception as e:
        print "Got exception:", e
        retry += 1
        time.sleep(1)
    if retry == 3:
      print "Failed after 3 retries"
      return
    s = a.read()
    a.close()
    print path
    a = open(path, 'w')
    a.write(s)
    a.close()
  if ".json" in rawname:
    return json.loads(s)
  else:
    return fromstring(s)

def getPlayerSummaries(playerIds, friendId):
  query = "http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=" + key + "&steamids=" + ','.join(playerIds)
  resp = getData(query, "friendsummaries_" + friendId + '.json')
  res = {}
  for player in resp["response"]["players"]:
    res[player["steamid"]] = player
  return res
  
def getFriendList(playerId):
  query = "http://api.steampowered.com/ISteamUser/GetFriendList/v0001/?key=" + key + "&steamid=" + playerId + "&relationship=friend"
  resp = getData(query, "friendlist_" + playerId + ".json")
  friends = resp["friendslist"]["friends"]
  return [(k["steamid"], k["friend_since"]) for k in friends if k["relationship"] == "friend"]

def getPlayerProfile(playerId):
  query = "http://steamcommunity.com/profiles/" + playerId + "/?xml=1"
  resp = getData(query, "profile_" + playerId + ".xml")
  playerName = resp.find("steamID").text
  groups = resp.find("groups").findall("group")
  groupIds = [x.find("groupID64").text for x in groups]
  return playerName, groupIds
  
def getPlayerGames(playerName):
  query = "http://steamcommunity.com/id/" + playerName + "/games?tab=all&xml=1"
  resp = getData(query, "games_" + playerName + ".xml")
  res = []
  for games in resp.findall("games"):
    for game in games.findall("game"):
      gameLink = None
      for statsLink in game.findall("statsLink"):
        gameLink = statsLink.text.split('/')[-1]
      res.append((game.find("appID").text, game.find("name").text, gameLink))
  return res

def getPlayerGameStats(playerId, gameName):
  query = "http://steamcommunity.com/profiles/" + playerId + "/stats/" + gameName + "/?xml=1"
  resp = getData(query, "stats_" + playerId + '_' + gameName + ".xml")
  res = []
  for achievements in resp.findall("achievements"):
    for achievement in achievements.findall("achievement"):
      res.append(achievement.find("apiname").text)
  return res
  
def getGroupMembers(groupId):
  query = "http://steamcommunity.com/gid/" + groupId + "/memberslistxml/?xml=1"
  resp = getData(query, "group_" + groupId + ".xml")
  members = []
  for memberss in resp.findall("members"):
    for uid in memberss.findall("steamID64"):
      members.append(uid.text)
  return members


#getFriendList("76561197968575517")
#pname, groups = getPlayerProfile("76561197968575517")
#getPlayerGames(pname)
#print getPlayerGameStats("76561197968575517", "Ziro")
#print getGroupMembers(groups[0])

allUsers = set()

userQueue = Queue.Queue()
#userQueue.put("76561197960389850")
#userQueue.put("76561197960265731")
#userQueue.put("76561197968575517")
userQueue.put("76561197995820381") # Iceland

userAchievements = {}
userFriends = {}

got = 0

while not userQueue.empty():
  got += 1
  userId = userQueue.get()
  print userId
  try:
    userName, userGroups = getPlayerProfile(userId)
  except Exception as e:
    print e
    continue
  try:
    games = getPlayerGames(userName)
  except Exception as e:
    print e
    continue
  achievements = {}
  for appID, name, gameName in games:
    if gameName:
      try:
        achievements[gameName] = getPlayerGameStats(userId, gameName)
      except Exception as e:
        print e
  userAchievements[userId] = achievements
  try:
    friends = getFriendList(userId)
    summaries = getPlayerSummaries([f[0] for f in friends], userId)
  except Exception as e:
    print e
    continue
  friends_ = []
  for f,_ in friends:
    print f
    if not f in allUsers and f in summaries and summaries[f].has_key("loccountrycode") and summaries[f]["loccountrycode"] == "IS":
      allUsers.add(f)
      userQueue.put(f)
      friends_.append(f)
  userFriends[userId] = friends_

b = open("/media/external/steam/network.txt", 'w')
for userId in userFriends.keys():
  a = open("/media/external/steam/parsedachievements/" + userId + ".txt", 'w')
  for game in userAchievements[userId].keys():
    a.write(game + ' ' + ' '.join(userAchievements[userId][game]) + '\n')
  a.close()
  b.write(userId + ' ' + ' '.join(userFriends[userId]) + '\n')
b.close()

dumpDir = "/media/external/steam/dump_" + str(int(time.time()))
gso("mkdir -p " + dumpDir)
gso("mv /media/external/steam/network.txt /media/external/steam/parsedachievements /media/external/steam/rawJson /media/external/steam/rawXml " + dumpDir)

