From 8ce49faf3ae9e1873b0835d18391618b0562f63a Mon Sep 17 00:00:00 2001 From: Jonathan Harris Date: Sun, 5 Jul 2015 18:58:13 +0100 Subject: [PATCH] Handle sparse arrays in the Companion API's json data. Fixes #13. --- companion.py | 23 +++++++++++++++++++++++ eddn.py | 2 +- stats.py | 12 ++++++------ 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/companion.py b/companion.py index 02804ac6..aec5bf94 100644 --- a/companion.py +++ b/companion.py @@ -71,6 +71,29 @@ ship_map = { } +# Companion API sometimes returns an array as a json array, sometimes as a json object indexed by "int". +# This seems to depend on whether the there are 'gaps' in the Cmdr's data - i.e. whether the array is sparse. +# In practice these arrays aren't very sparse so just convert them to lists with any 'gaps' holding None. +def listify(thing): + if thing is None: + return [] # data is not present + elif isinstance(thing, list): + return thing # array is not sparse + elif isinstance(thing, dict): + retval = [] + for k,v in thing.iteritems(): + idx = int(k) + if idx >= len(retval): + retval.extend([None] * (idx - len(retval))) + retval.append(v) + else: + retval[idx] = v + return retval + else: + assert False, thing # we expect an array or a sparse array + return list(thing) # hope for the best + + class ServerError(Exception): def __str__(self): return 'Error: Server is down' diff --git a/eddn.py b/eddn.py index 74c5e0de..ca1d0147 100644 --- a/eddn.py +++ b/eddn.py @@ -97,6 +97,6 @@ def export(data): 'systemName' : data['lastSystem']['name'].strip(), 'stationName' : data['lastStarport']['name'].strip(), 'timestamp' : time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime(querytime)), - 'ships' : [ship_map.get(ship['name'],ship['name']) for ship in data['lastStarport']['ships'].get('shipyard_list', {}).values() + data['lastStarport']['ships'].get('unavailable_list', [])], + 'ships' : [ship_map.get(ship,ship) for ship in (data['lastStarport']['ships'].get('shipyard_list') or {}).keys() + (data['lastStarport']['ships'].get('unavailable_list') or {}).keys()], } }) diff --git a/stats.py b/stats.py index d1b620ca..a49854cf 100644 --- a/stats.py +++ b/stats.py @@ -262,10 +262,10 @@ class StatsResults(tk.Toplevel): try: current = data['commander'].get('currentShipId') # 'ships' can be an array or a dict indexed by str(int). Perhaps the latter if you've sold ships? - for key in (isinstance(data['ships'], list) and range(len(data['ships'])) or sorted(data['ships'].keys(), key=int)): - ship = data['ships'][key] - self.addpagerow(page, [companion.ship_map.get(ship['name'], ship['name']) + (int(key)==current and ' *' or ''), - ship['starsystem']['name'], ship['station']['name']], align=tk.W) + for key, ship in enumerate(companion.listify(data.get('ships'))): + if ship: + self.addpagerow(page, [companion.ship_map.get(ship['name'], ship['name']) + (key==current and ' *' or ''), + ship['starsystem']['name'], ship['station']['name']], align=tk.W) except: if __debug__: print_exc() notebook.add(page, text='Ships') @@ -322,14 +322,14 @@ class StatsResults(tk.Toplevel): def addranking(self, parent, data, category): try: rank = data['commander']['rank'].get(category) - progress = list(data['stats']['ranks'].get(category, [])) # shallow copy + progress = companion.listify(data['stats']['ranks'].get(category)) if not rank or not progress: self.addpageheader(parent, ['Rank']) self.addpagerow(parent, [self.ranktitle(category, rank)]) else: self.addpageheader(parent, ['Rank', 'Achieved', 'Elapsed']) while rank > 0: - if rank>=len(progress) or not progress[rank]['ts']: + if rank>=len(progress) or not progress[rank] or not progress[rank]['ts']: self.addpagerow(parent, [self.ranktitle(category, rank)]) else: self.addpagerow(parent, [self.ranktitle(category, rank),