From f9efe0e5a90d091b02f5a56132e3b394590fa6bb Mon Sep 17 00:00:00 2001 From: A_D Date: Fri, 4 Jun 2021 12:18:00 +0200 Subject: [PATCH 1/2] Fixed erroring on empty backpack.json closes EDCD/EDMarketConnector#1138 --- monitor.py | 70 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 41 insertions(+), 29 deletions(-) diff --git a/monitor.py b/monitor.py index eff8799f..ae6395d6 100644 --- a/monitor.py +++ b/monitor.py @@ -1,6 +1,7 @@ """Monitor for new Journal files and contents of latest.""" import json +import pathlib import queue import re import threading @@ -880,43 +881,54 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below elif event_type in ('BackPack', 'Backpack'): # WORKAROUND 4.0.0.200: BackPack becomes Backpack # TODO: v31 doc says this is`backpack.json` ... but Howard Chalkley # said it's `Backpack.json` - with open(join(self.currentdir, 'Backpack.json'), 'rb') as backpack: # type: ignore + backpack_file = pathlib.Path(str(self.currentdir)) / 'Backpack.json' + backpack_data = None + if backpack_file.exists(): + backpack_data = backpack_file.read_bytes() + else: + logger.warning(f'Failed to find backpack.json file as it appears not to exist? {backpack_file=}') + + parsed = None + + if backpack_data is not None and len(backpack_data) > 0: try: - # Preserve property order because why not? - entry = json.load(backpack, object_pairs_hook=OrderedDict) - + parsed = json.loads(backpack_data) except json.JSONDecodeError: - logger.exception('Failed decoding Backpack.json', exc_info=True) + logger.exception('Unable to parse Backpack.json') - else: - # Store in monitor.state - self.state['BackpackJSON'] = entry + else: + logger.warning('Unable to read backpack data! Either the file was empty or it didn\'t exist!') - # Assume this reflects the current state when written - self.state['BackPack']['Component'] = defaultdict(int) - self.state['BackPack']['Consumable'] = defaultdict(int) - self.state['BackPack']['Item'] = defaultdict(int) - self.state['BackPack']['Data'] = defaultdict(int) + if parsed is not None: + entry = parsed # set entry so that it ends up in plugins with the right data + # Store in monitor.state + self.state['BackpackJSON'] = entry - clean_components = self.coalesce_cargo(entry['Components']) - self.state['BackPack']['Component'].update( - {self.canonicalise(x['Name']): x['Count'] for x in clean_components} - ) + # Assume this reflects the current state when written + self.state['BackPack']['Component'] = defaultdict(int) + self.state['BackPack']['Consumable'] = defaultdict(int) + self.state['BackPack']['Item'] = defaultdict(int) + self.state['BackPack']['Data'] = defaultdict(int) - clean_consumables = self.coalesce_cargo(entry['Consumables']) - self.state['BackPack']['Consumable'].update( - {self.canonicalise(x['Name']): x['Count'] for x in clean_consumables} - ) + clean_components = self.coalesce_cargo(entry['Components']) + self.state['BackPack']['Component'].update( + {self.canonicalise(x['Name']): x['Count'] for x in clean_components} + ) - clean_items = self.coalesce_cargo(entry['Items']) - self.state['BackPack']['Item'].update( - {self.canonicalise(x['Name']): x['Count'] for x in clean_items} - ) + clean_consumables = self.coalesce_cargo(entry['Consumables']) + self.state['BackPack']['Consumable'].update( + {self.canonicalise(x['Name']): x['Count'] for x in clean_consumables} + ) - clean_data = self.coalesce_cargo(entry['Data']) - self.state['BackPack']['Data'].update( - {self.canonicalise(x['Name']): x['Count'] for x in clean_data} - ) + clean_items = self.coalesce_cargo(entry['Items']) + self.state['BackPack']['Item'].update( + {self.canonicalise(x['Name']): x['Count'] for x in clean_items} + ) + + clean_data = self.coalesce_cargo(entry['Data']) + self.state['BackPack']['Data'].update( + {self.canonicalise(x['Name']): x['Count'] for x in clean_data} + ) elif event_type == 'BackpackChange': # Changes to Odyssey Backpack contents *other* than from a Transfer From caf594752f10376ee00516e94b919b423156f361 Mon Sep 17 00:00:00 2001 From: A_D Date: Fri, 4 Jun 2021 16:26:07 +0200 Subject: [PATCH 2/2] Made use of guard clauses where possible --- monitor.py | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/monitor.py b/monitor.py index ae6395d6..752026f8 100644 --- a/monitor.py +++ b/monitor.py @@ -883,21 +883,27 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below # said it's `Backpack.json` backpack_file = pathlib.Path(str(self.currentdir)) / 'Backpack.json' backpack_data = None - if backpack_file.exists(): - backpack_data = backpack_file.read_bytes() - else: + + if not backpack_file.exists(): logger.warning(f'Failed to find backpack.json file as it appears not to exist? {backpack_file=}') + else: + backpack_data = backpack_file.read_bytes() + parsed = None - if backpack_data is not None and len(backpack_data) > 0: - try: - parsed = json.loads(backpack_data) - except json.JSONDecodeError: - logger.exception('Unable to parse Backpack.json') + if backpack_data is None: + logger.warning('Unable to read backpack data!') + + elif len(backpack_data) == 0: + logger.warning('Backpack.json was empty when we read it!') else: - logger.warning('Unable to read backpack data! Either the file was empty or it didn\'t exist!') + try: + parsed = json.loads(backpack_data) + + except json.JSONDecodeError: + logger.exception('Unable to parse Backpack.json') if parsed is not None: entry = parsed # set entry so that it ends up in plugins with the right data