diff --git a/monitor.py b/monitor.py index 73a99064..ed6e90d8 100644 --- a/monitor.py +++ b/monitor.py @@ -866,29 +866,38 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below elif event_type == 'shiplocker': # As of 4.0.0.400 (2021-06-10) - # "ShipLocker" will be a full list written to the journal at startup/boarding/disembarking, and also + # "ShipLocker" will be a full list written to the journal at startup/boarding, and also # written to a separate shiplocker.json file - other updates will just update that file and mention it # has changed with an empty shiplocker event in the main journal. - # Always attempt loading of this. - # Confirmed filename for 4.0.0.400 + # Always attempt loading of this, but if it fails we'll hope this was + # a startup/boarding version and thus `entry` contains + # the data anyway. currentdir_path = pathlib.Path(str(self.currentdir)) shiplocker_filename = currentdir_path / 'ShipLocker.json' - try: - with open(shiplocker_filename, 'rb') as h: # type: ignore - entry = json.load(h, object_pairs_hook=OrderedDict) - self.state['ShipLockerJSON'] = entry + shiplocker_max_attempts = 5 + shiplocker_fail_sleep = 0.01 + attempts = 0 + while attempts < shiplocker_max_attempts: + attempts += 1 + try: + with open(shiplocker_filename, 'rb') as h: # type: ignore + entry = json.load(h, object_pairs_hook=OrderedDict) + self.state['ShipLockerJSON'] = entry + break - except FileNotFoundError: - logger.warning('ShipLocker event but no ShipLocker.json file') - pass + except FileNotFoundError: + logger.warning('ShipLocker event but no ShipLocker.json file') + sleep(shiplocker_fail_sleep) + pass - except json.JSONDecodeError as e: - logger.warning(f'ShipLocker.json failed to decode:\n{e!r}\n') - pass + except json.JSONDecodeError as e: + logger.warning(f'ShipLocker.json failed to decode:\n{e!r}\n') + sleep(shiplocker_fail_sleep) + pass if not all(t in entry for t in ('Components', 'Consumables', 'Data', 'Items')): - logger.trace('ShipLocker event is an empty one (missing at least one data type)') + logger.warning('ShipLocker event is missing at least one category') # This event has the current totals, so drop any current data self.state['Component'] = defaultdict(int) @@ -896,10 +905,6 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.state['Item'] = defaultdict(int) self.state['Data'] = defaultdict(int) - # 4.0.0.400 - No longer zeroing out the BackPack in this event, - # as we should now always get either `Backpack` event/file or - # `BackpackChange` as needed. - clean_components = self.coalesce_cargo(entry['Components']) self.state['Component'].update( {self.canonicalise(x['Name']): x['Count'] for x in clean_components}