Skip to content

Instantly share code, notes, and snippets.

@psobot
Created July 9, 2017 16:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save psobot/8c4d420f69f930da8163e5d34d968284 to your computer and use it in GitHub Desktop.
Save psobot/8c4d420f69f930da8163e5d34d968284 to your computer and use it in GitHub Desktop.
Xbox API Downloader

This tiny script hits the Xbox API and downloads a user's entire Xbox360 achievement history into flat JSON files on disk, as well as a Sqlite DB.

Needs:

import os
import json
import requests
AUTH_TOKEN = "" # XboxAPI Auth Token from https://xboxapi.com
XUID = "" # Your Xbox account's user ID
XBOX360_URL = "https://xboxapi.com/v2/%s/xbox360games"
ACHIEVEMENT_URL = "https://xboxapi.com/v2/%s/achievements/%s"
HEADERS = {"X-AUTH": AUTH_TOKEN}
def download_and_save_json(get_data, filename):
try:
if os.path.exists(filename):
return json.load(open(filename, 'r'))
except Exception as e:
print e
print "Redownloading..."
data = get_data()
with open(filename, 'w') as f:
f.write(json.dumps(
data,
sort_keys=True,
indent=4,
separators=(',', ': ')))
return data
def read_xbox360_games():
return download_and_save_json(
lambda: requests.get(XBOX360_URL % XUID, headers=HEADERS).json(),
'titles.json')
def get_achievement_for_title(title_id):
return download_and_save_json(
lambda: requests.get(
ACHIEVEMENT_URL % (XUID, str(title_id)),
headers=HEADERS).json(),
'%s.achievements.json' % str(title_id))
def download_achievements():
for title in read_xbox360_games()['titles']:
print "Downloading achievements for", title["name"], "... ",
achievements = get_achievement_for_title(title['titleId'])
print "got", len(achievements), "."
if __name__ == "__main__":
download_achievements()
import os
import glob
import json
import sqlite3
db_path = 'xbox360.db'
conn = None
TITLES_PATH = "titles.json"
ACHIEVEMENTS_PATH = "*.achievements.json"
SCHEMAS = ["""
CREATE TABLE titles (
titleId integer,
name text,
titleType integer,
currentAchievements integer,
totalAchievements integer,
currentGamerscore integer,
totalGamerscore integer,
sequence integer,
lastPlayed integer
);""", """CREATE TABLE achievements (
id integer,
name string,
description string,
gamerscore integer,
imageId integer,
imageUnlocked string,
isRevoked boolean,
isSecret boolean,
lockedDescription string,
platform integer,
sequence integer,
timeUnlocked integer,
titleId integer,
type integer,
unlocked boolean,
unlockedOnline boolean
);"""]
def init_schema():
c = conn.cursor()
for schema in SCHEMAS:
c.execute(schema)
conn.commit()
COLUMN_NAME_CACHE = {}
def column_names(table):
if table not in COLUMN_NAME_CACHE:
c = conn.cursor()
COLUMN_NAME_CACHE[table] = set([
column_name
for (_, column_name, _, _, _, _)
in c.execute("PRAGMA table_info([%s])" % table)])
return COLUMN_NAME_CACHE[table]
def insert_dict(c, table, data):
data = dict([
(k, v)
for (k, v) in data.iteritems()
if k in column_names(table)])
keys = data.keys()
values = data.values()
c.execute("""
INSERT INTO %s (%s) VALUES (%s);
""" % (table, ', '.join(keys), ', '.join(['?' for _ in values])), values)
def load_json():
titles = json.load(open(TITLES_PATH))
c = conn.cursor()
for title in titles['titles']:
insert_dict(c, 'titles', title)
conn.commit()
for achievement_path in glob.glob(ACHIEVEMENTS_PATH):
achievements = json.load(open(achievement_path))
for achievement in achievements:
insert_dict(c, 'achievements', achievement)
conn.commit()
if __name__ == "__main__":
try:
os.unlink(db_path)
except OSError:
pass
conn = sqlite3.connect(db_path)
init_schema()
load_json()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment