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:
python
pip install requests
- An XboxApi account and API key: from https://xboxapi.com
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:
python
pip install requests
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() |