# xivapi.py
# A library of functions useful when working with xivapi.
# Need to create the directory core/xivapi before using.
# Written by Catuse167 of FFWiki.
import json
import urllib.request
import pickle
HTTP_HEADERS = {
# stupid ass hack to avoid Error 403
'User-Agent': 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.7) Gecko/2009021910 Firefox/3.0.7'
}
XIVAPI_URL = 'https://v2.xivapi.com/api/sheet/'
def load_dict(file):
# Downloads a JSON file from XIVAPI_URL + file and stores it as a dict.
# Throws a urllib.error.URLError if we cannot connect to xivapi.com.
# Will _not_ work on JSON files which should be stored as lists and have at least 100 entries.
url = XIVAPI_URL + file
request = urllib.request.Request(XIVAPI_URL + file, None, HTTP_HEADERS)
return json.load(urllib.request.urlopen(request))
def load_list(file, offset=0):
# Downloads a JSON file from XIVAPI_URL + file, whose entries are listed by numbers, and stores it as a dict.
# Starts at row "offset"
# For such a table, XIVAPI always stops on entries 99, 199, ... and you have to tell it to keep going
if "?" not in file:
file = file + "?" # prepare to add a GET attr
tbl = []
i = 0
while len(tbl) == i:
j = offset + i - 1
if j < 0:
tbl = tbl + load_dict(file)["rows"]
else:
tbl = tbl + load_dict(file + "&after=" + str(j))["rows"]
i = i + 100
return tbl
def lookup(table, keys):
# Returns table["fields"][keys[0]]["fields"] ... ["fields"][keys[len(keys)]]
# This works on tables with _fields_, but not _rows_
if len(keys) == 0:
return table
return lookup(table["fields"][keys[0]], keys[1:])
def load_backup(fn, default=None):
# Since making calls to xivapi and Fandom are slow, we want to save our progress locally frequently.
# This loads a backup stored at core/xivapi/fn, or a default value if that is not possible.
try:
with open("xivapi/" + fn, 'rb') as f:
return pickle.load(f)
except FileNotFoundError:
if default is None:
return dict()
return default
def save_backup(fn, d):
# This saves a backup of d stored at core/xivapi/fn.
with open("xivapi/" + fn, 'wb') as f:
pickle.dump(d, f)
def url():
# Returns the base URL
return XIVAPI_URL