From 37c53e233e02cc7c3c3f3bba4dc293c1f10404b4 Mon Sep 17 00:00:00 2001 From: A_D Date: Tue, 18 Aug 2020 10:19:08 +0200 Subject: [PATCH 01/22] autoformatted code with autopep8 --- plugins/edsm.py | 69 ++++++++++++++++++++++++++++--------------------- 1 file changed, 39 insertions(+), 30 deletions(-) diff --git a/plugins/edsm.py b/plugins/edsm.py index 895127ac..7ad6f7c2 100644 --- a/plugins/edsm.py +++ b/plugins/edsm.py @@ -31,17 +31,17 @@ EDSM_POLL = 0.1 _TIMEOUT = 20 -this = sys.modules[__name__] # For holding module globals +this = sys.modules[__name__] # For holding module globals this.session = requests.Session() this.queue = Queue() # Items to be sent to EDSM by worker thread -this.discardedEvents = [] # List discarded events from EDSM +this.discardedEvents = [] # List discarded events from EDSM this.lastlookup = False # whether the last lookup succeeded # Game state this.multicrew = False # don't send captain's ship info to EDSM while on a crew this.coordinates = None this.newgame = False # starting up - batch initial burst of events -this.newgame_docked = False # starting up while docked +this.newgame_docked = False # starting up while docked this.navbeaconscan = 0 # batch up burst of Scan events after NavBeaconScan this.system_link = None this.system = None @@ -53,8 +53,6 @@ this.station_marketid = None # Frontier MarketID STATION_UNDOCKED: str = '×' # "Station" name to display when not docked = U+00D7 - - # Main window clicks def system_url(system_name): if this.system_address: @@ -65,6 +63,7 @@ def system_url(system_name): return '' + def station_url(system_name, station_name): if system_name and station_name: return requests.utils.requote_uri(f'https://www.edsm.net/en/system?systemName={system_name}&stationName={station_name}') @@ -80,10 +79,10 @@ def station_url(system_name, station_name): def plugin_start3(plugin_dir): # Can't be earlier since can only call PhotoImage after window is created - this._IMG_KNOWN = tk.PhotoImage(data = 'R0lGODlhEAAQAMIEAFWjVVWkVWS/ZGfFZ////////////////yH5BAEKAAQALAAAAAAQABAAAAMvSLrc/lAFIUIkYOgNXt5g14Dk0AQlaC1CuglM6w7wgs7rMpvNV4q932VSuRiPjQQAOw==') # green circle - this._IMG_UNKNOWN = tk.PhotoImage(data = 'R0lGODlhEAAQAKEDAGVLJ+ddWO5fW////yH5BAEKAAMALAAAAAAQABAAAAItnI+pywYRQBtA2CtVvTwjDgrJFlreEJRXgKSqwB5keQ6vOKq1E+7IE5kIh4kCADs=') # red circle - this._IMG_NEW = tk.PhotoImage(data = 'R0lGODlhEAAQAMZwANKVHtWcIteiHuiqLPCuHOS1MN22ZeW7ROG6Zuu9MOy+K/i8Kf/DAuvCVf/FAP3BNf/JCf/KAPHHSv7ESObHdv/MBv/GRv/LGP/QBPXOPvjPQfjQSvbRSP/UGPLSae7Sfv/YNvLXgPbZhP7dU//iI//mAP/jH//kFv7fU//fV//ebv/iTf/iUv/kTf/iZ/vgiP/hc/vgjv/jbfriiPriiv7ka//if//jd//sJP/oT//tHv/mZv/sLf/rRP/oYv/rUv/paP/mhv/sS//oc//lkf/mif/sUf/uPv/qcv/uTv/uUv/vUP/qhP/xP//pm//ua//sf//ubf/wXv/thv/tif/slv/tjf/smf/yYP/ulf/2R//2Sv/xkP/2av/0gP/ylf/2df/0i//0j//0lP/5cP/7a//1p//5gf/7ev/3o//2sf/5mP/6kv/2vP/3y//+jP///////////////////////////////////////////////////////////////yH5BAEKAH8ALAAAAAAQABAAAAePgH+Cg4SFhoJKPIeHYT+LhVppUTiPg2hrUkKPXWdlb2xHJk9jXoNJQDk9TVtkYCUkOy4wNjdGfy1UXGJYOksnPiwgFwwYg0NubWpmX1ArHREOFYUyWVNIVkxXQSoQhyMoNVUpRU5EixkcMzQaGy8xhwsKHiEfBQkSIg+GBAcUCIIBBDSYYGiAAUMALFR6FAgAOw==') - this._IMG_ERROR = tk.PhotoImage(data = 'R0lGODlhEAAQAKEBAAAAAP///////////yH5BAEKAAIALAAAAAAQABAAAAIwlBWpeR0AIwwNPRmZuVNJinyWuClhBlZjpm5fqnIAHJPtOd3Hou9mL6NVgj2LplEAADs=') # BBC Mode 5 '?' + this._IMG_KNOWN = tk.PhotoImage(data='R0lGODlhEAAQAMIEAFWjVVWkVWS/ZGfFZ////////////////yH5BAEKAAQALAAAAAAQABAAAAMvSLrc/lAFIUIkYOgNXt5g14Dk0AQlaC1CuglM6w7wgs7rMpvNV4q932VSuRiPjQQAOw==') # green circle + this._IMG_UNKNOWN = tk.PhotoImage(data='R0lGODlhEAAQAKEDAGVLJ+ddWO5fW////yH5BAEKAAMALAAAAAAQABAAAAItnI+pywYRQBtA2CtVvTwjDgrJFlreEJRXgKSqwB5keQ6vOKq1E+7IE5kIh4kCADs=') # red circle + this._IMG_NEW = tk.PhotoImage(data='R0lGODlhEAAQAMZwANKVHtWcIteiHuiqLPCuHOS1MN22ZeW7ROG6Zuu9MOy+K/i8Kf/DAuvCVf/FAP3BNf/JCf/KAPHHSv7ESObHdv/MBv/GRv/LGP/QBPXOPvjPQfjQSvbRSP/UGPLSae7Sfv/YNvLXgPbZhP7dU//iI//mAP/jH//kFv7fU//fV//ebv/iTf/iUv/kTf/iZ/vgiP/hc/vgjv/jbfriiPriiv7ka//if//jd//sJP/oT//tHv/mZv/sLf/rRP/oYv/rUv/paP/mhv/sS//oc//lkf/mif/sUf/uPv/qcv/uTv/uUv/vUP/qhP/xP//pm//ua//sf//ubf/wXv/thv/tif/slv/tjf/smf/yYP/ulf/2R//2Sv/xkP/2av/0gP/ylf/2df/0i//0j//0lP/5cP/7a//1p//5gf/7ev/3o//2sf/5mP/6kv/2vP/3y//+jP///////////////////////////////////////////////////////////////yH5BAEKAH8ALAAAAAAQABAAAAePgH+Cg4SFhoJKPIeHYT+LhVppUTiPg2hrUkKPXWdlb2xHJk9jXoNJQDk9TVtkYCUkOy4wNjdGfy1UXGJYOksnPiwgFwwYg0NubWpmX1ArHREOFYUyWVNIVkxXQSoQhyMoNVUpRU5EixkcMzQaGy8xhwsKHiEfBQkSIg+GBAcUCIIBBDSYYGiAAUMALFR6FAgAOw==') + this._IMG_ERROR = tk.PhotoImage(data='R0lGODlhEAAQAKEBAAAAAP///////////yH5BAEKAAIALAAAAAAQABAAAAIwlBWpeR0AIwwNPRmZuVNJinyWuClhBlZjpm5fqnIAHJPtOd3Hou9mL6NVgj2LplEAADs=') # BBC Mode 5 '?' # Migrate old settings if not config.get('edsm_cmdrs'): @@ -102,17 +101,19 @@ def plugin_start3(plugin_dir): config.delete('edsm_autoopen') config.delete('edsm_historical') - this.thread = Thread(target = worker, name = 'EDSM worker') + this.thread = Thread(target=worker, name='EDSM worker') this.thread.daemon = True this.thread.start() return 'EDSM' + def plugin_app(parent): this.system_link = parent.children['system'] # system label in main window this.system_link.bind_all('<>', update_status) this.station_link = parent.children['station'] # station label in main window + def plugin_stop(): # Signal thread to close and wait for it this.queue.put(None) @@ -121,35 +122,39 @@ def plugin_stop(): # Suppress 'Exception ignored in: ' errors this._IMG_KNOWN = this._IMG_UNKNOWN = this._IMG_NEW = this._IMG_ERROR = None + def plugin_prefs(parent, cmdr, is_beta): PADX = 10 - BUTTONX = 12 # indent Checkbuttons and Radiobuttons + BUTTONX = 12 # indent Checkbuttons and Radiobuttons PADY = 2 # close spacing frame = nb.Frame(parent) frame.columnconfigure(1, weight=1) - HyperlinkLabel(frame, text='Elite Dangerous Star Map', background=nb.Label().cget('background'), url='https://www.edsm.net/', underline=True).grid(columnspan=2, padx=PADX, sticky=tk.W) # Don't translate - this.log = tk.IntVar(value = config.getint('edsm_out') and 1) - this.log_button = nb.Checkbutton(frame, text=_('Send flight log and Cmdr status to EDSM'), variable=this.log, command=prefsvarchanged) - this.log_button.grid(columnspan=2, padx=BUTTONX, pady=(5,0), sticky=tk.W) + HyperlinkLabel(frame, text='Elite Dangerous Star Map', background=nb.Label().cget('background'), + url='https://www.edsm.net/', underline=True).grid(columnspan=2, padx=PADX, sticky=tk.W) # Don't translate + this.log = tk.IntVar(value=config.getint('edsm_out') and 1) + this.log_button = nb.Checkbutton(frame, text=_('Send flight log and Cmdr status to EDSM'), + variable=this.log, command=prefsvarchanged) + this.log_button.grid(columnspan=2, padx=BUTTONX, pady=(5, 0), sticky=tk.W) - nb.Label(frame).grid(sticky=tk.W) # big spacer - this.label = HyperlinkLabel(frame, text=_('Elite Dangerous Star Map credentials'), background=nb.Label().cget('background'), url='https://www.edsm.net/settings/api', underline=True) # Section heading in settings + nb.Label(frame).grid(sticky=tk.W) # big spacer + this.label = HyperlinkLabel(frame, text=_('Elite Dangerous Star Map credentials'), background=nb.Label().cget( + 'background'), url='https://www.edsm.net/settings/api', underline=True) # Section heading in settings this.label.grid(columnspan=2, padx=PADX, sticky=tk.W) - this.cmdr_label = nb.Label(frame, text=_('Cmdr')) # Main window + this.cmdr_label = nb.Label(frame, text=_('Cmdr')) # Main window this.cmdr_label.grid(row=10, padx=PADX, sticky=tk.W) this.cmdr_text = nb.Label(frame) this.cmdr_text.grid(row=10, column=1, padx=PADX, pady=PADY, sticky=tk.W) - this.user_label = nb.Label(frame, text=_('Commander Name')) # EDSM setting + this.user_label = nb.Label(frame, text=_('Commander Name')) # EDSM setting this.user_label.grid(row=11, padx=PADX, sticky=tk.W) this.user = nb.Entry(frame) this.user.grid(row=11, column=1, padx=PADX, pady=PADY, sticky=tk.EW) - this.apikey_label = nb.Label(frame, text=_('API Key')) # EDSM setting + this.apikey_label = nb.Label(frame, text=_('API Key')) # EDSM setting this.apikey_label.grid(row=12, padx=PADX, sticky=tk.W) this.apikey = nb.Entry(frame) this.apikey.grid(row=12, column=1, padx=PADX, pady=PADY, sticky=tk.EW) @@ -158,6 +163,7 @@ def plugin_prefs(parent, cmdr, is_beta): return frame + def prefs_cmdr_changed(cmdr, is_beta): this.log_button['state'] = cmdr and not is_beta and tk.NORMAL or tk.DISABLED this.user['state'] = tk.NORMAL @@ -174,9 +180,11 @@ def prefs_cmdr_changed(cmdr, is_beta): this.cmdr_text['text'] = _('None') # No hotkey/shortcut currently defined this.label['state'] = this.cmdr_label['state'] = this.cmdr_text['state'] = this.user_label['state'] = this.user['state'] = this.apikey_label['state'] = this.apikey['state'] = cmdr and not is_beta and this.log.get() and tk.NORMAL or tk.DISABLED + def prefsvarchanged(): this.label['state'] = this.cmdr_label['state'] = this.cmdr_text['state'] = this.user_label['state'] = this.user['state'] = this.apikey_label['state'] = this.apikey['state'] = this.log.get() and this.log_button['state'] or tk.DISABLED + def prefs_changed(cmdr, is_beta): config.set('edsm_out', this.log.get()) @@ -293,9 +301,9 @@ entry: {entry!r}''' materials = { 'timestamp': entry['timestamp'], 'event': 'Materials', - 'Raw': [ { 'Name': k, 'Count': v } for k,v in state['Raw'].items() ], - 'Manufactured': [ { 'Name': k, 'Count': v } for k,v in state['Manufactured'].items() ], - 'Encoded': [ { 'Name': k, 'Count': v } for k,v in state['Encoded'].items() ], + 'Raw': [{'Name': k, 'Count': v} for k, v in state['Raw'].items()], + 'Manufactured': [{'Name': k, 'Count': v} for k, v in state['Manufactured'].items()], + 'Encoded': [{'Name': k, 'Count': v} for k, v in state['Encoded'].items()], } materials.update(transient) this.queue.put((cmdr, materials)) @@ -346,7 +354,7 @@ def cmdr_data(data, is_beta): # Worker thread def worker(): - pending = [] # Unsent events + pending = [] # Unsent events closing = False while True: @@ -354,7 +362,7 @@ def worker(): if item: (cmdr, entry) = item else: - closing = True # Try to send any unsent events before we close + closing = True # Try to send any unsent events before we close retrying = 0 while retrying < 3: @@ -372,9 +380,10 @@ def worker(): r = this.session.get('https://www.edsm.net/api-journal-v1/discard', timeout=_TIMEOUT) r.raise_for_status() this.discardedEvents = set(r.json()) - this.discardedEvents.discard('Docked') # should_send() assumes that we send 'Docked' events + this.discardedEvents.discard('Docked') # should_send() assumes that we send 'Docked' events assert this.discardedEvents # wouldn't expect this to be empty - pending = [x for x in pending if x['event'] not in this.discardedEvents] # Filter out unwanted events + pending = [x for x in pending if x['event'] + not in this.discardedEvents] # Filter out unwanted events if should_send(pending): if any([p for p in pending if p['event'] in ('CarrierJump', 'FSDJump', 'Location', 'Docked')]): @@ -450,9 +459,9 @@ def should_send(entries): return True elif this.newgame: pass - elif entry['event'] not in ['CommunityGoal', # Spammed periodically + elif entry['event'] not in ['CommunityGoal', # Spammed periodically 'ModuleBuy', 'ModuleSell', 'ModuleSwap', # will be shortly followed by "Loadout" - 'ShipyardBuy', 'ShipyardNew', 'ShipyardSwap']: # " + 'ShipyardBuy', 'ShipyardNew', 'ShipyardSwap']: # " return True return False @@ -469,7 +478,7 @@ def edsm_notify_system(reply): if not reply: this.system_link['image'] = this._IMG_ERROR plug.show_error(_("Error: Can't connect to EDSM")) - elif reply['msgnum'] // 100 not in (1,4): + elif reply['msgnum'] // 100 not in (1, 4): this.system_link['image'] = this._IMG_ERROR plug.show_error(_('Error: EDSM {MSG}').format(MSG=reply['msg'])) elif reply.get('systemCreated'): From d2a1f09fac98aeaaec5361e00d6bc11b49db987d Mon Sep 17 00:00:00 2001 From: A_D Date: Tue, 18 Aug 2020 10:19:36 +0200 Subject: [PATCH 02/22] sorted imports --- plugins/edsm.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/plugins/edsm.py b/plugins/edsm.py index 7ad6f7c2..9edb78a5 100644 --- a/plugins/edsm.py +++ b/plugins/edsm.py @@ -12,18 +12,21 @@ # text is always fired. i.e. CAPI cmdr_data() processing. import json -import requests +import logging import sys +import tkinter as tk +import urllib.error +import urllib.parse +import urllib.request from queue import Queue from threading import Thread -import logging -import tkinter as tk -from ttkHyperlinkLabel import HyperlinkLabel +import requests + import myNotebook as nb # noqa: N813 - -from config import appname, applongname, appversion, config import plug +from config import applongname, appname, appversion, config +from ttkHyperlinkLabel import HyperlinkLabel logger = logging.getLogger(appname) From 743984eb11052a7c6fc637bf9924f75956aa9a3d Mon Sep 17 00:00:00 2001 From: A_D Date: Tue, 18 Aug 2020 10:22:59 +0200 Subject: [PATCH 03/22] Added fake definition for _ _ is added by magic in the plugin loading system, which means there are no imports to indicate its existence to static analysis tools. --- plugins/edsm.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/plugins/edsm.py b/plugins/edsm.py index 9edb78a5..4023f843 100644 --- a/plugins/edsm.py +++ b/plugins/edsm.py @@ -20,6 +20,7 @@ import urllib.parse import urllib.request from queue import Queue from threading import Thread +from typing import TYPE_CHECKING, Any import requests @@ -28,6 +29,10 @@ import plug from config import applongname, appname, appversion, config from ttkHyperlinkLabel import HyperlinkLabel +if TYPE_CHECKING: + def _(x: str) -> str: + return x + logger = logging.getLogger(appname) EDSM_POLL = 0.1 From 199e76701df1b540e1bb88f343e1190975dedf17 Mon Sep 17 00:00:00 2001 From: A_D Date: Tue, 18 Aug 2020 10:28:32 +0200 Subject: [PATCH 04/22] Added line breaks around scope changes --- plugins/edsm.py | 46 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 11 deletions(-) diff --git a/plugins/edsm.py b/plugins/edsm.py index 4023f843..f5438b6c 100644 --- a/plugins/edsm.py +++ b/plugins/edsm.py @@ -39,7 +39,7 @@ EDSM_POLL = 0.1 _TIMEOUT = 20 -this = sys.modules[__name__] # For holding module globals +this: Any = sys.modules[__name__] # For holding module globals this.session = requests.Session() this.queue = Queue() # Items to be sent to EDSM by worker thread this.discardedEvents = [] # List discarded events from EDSM @@ -97,15 +97,19 @@ def plugin_start3(plugin_dir): if isinstance(config.get('cmdrs'), list) and config.get('edsm_usernames') and config.get('edsm_apikeys'): # Migrate <= 2.34 settings config.set('edsm_cmdrs', config.get('cmdrs')) + elif config.get('edsm_cmdrname'): # Migrate <= 2.25 settings. edsm_cmdrs is unknown at this time config.set('edsm_usernames', [config.get('edsm_cmdrname') or '']) config.set('edsm_apikeys', [config.get('edsm_apikey') or '']) + config.delete('edsm_cmdrname') config.delete('edsm_apikey') + if config.getint('output') & 256: # Migrate <= 2.34 setting config.set('edsm_out', 1) + config.delete('edsm_autoopen') config.delete('edsm_historical') @@ -140,16 +144,13 @@ def plugin_prefs(parent, cmdr, is_beta): frame = nb.Frame(parent) frame.columnconfigure(1, weight=1) - HyperlinkLabel(frame, text='Elite Dangerous Star Map', background=nb.Label().cget('background'), - url='https://www.edsm.net/', underline=True).grid(columnspan=2, padx=PADX, sticky=tk.W) # Don't translate + HyperlinkLabel(frame, text='Elite Dangerous Star Map', background=nb.Label().cget('background'), url='https://www.edsm.net/', underline=True).grid(columnspan=2, padx=PADX, sticky=tk.W) # Don't translate this.log = tk.IntVar(value=config.getint('edsm_out') and 1) - this.log_button = nb.Checkbutton(frame, text=_('Send flight log and Cmdr status to EDSM'), - variable=this.log, command=prefsvarchanged) + this.log_button = nb.Checkbutton(frame, text=_('Send flight log and Cmdr status to EDSM'), variable=this.log, command=prefsvarchanged) this.log_button.grid(columnspan=2, padx=BUTTONX, pady=(5, 0), sticky=tk.W) nb.Label(frame).grid(sticky=tk.W) # big spacer - this.label = HyperlinkLabel(frame, text=_('Elite Dangerous Star Map credentials'), background=nb.Label().cget( - 'background'), url='https://www.edsm.net/settings/api', underline=True) # Section heading in settings + this.label = HyperlinkLabel(frame, text=_('Elite Dangerous Star Map credentials'), background=nb.Label().cget('background'), url='https://www.edsm.net/settings/api', underline=True) # Section heading in settings this.label.grid(columnspan=2, padx=PADX, sticky=tk.W) this.cmdr_label = nb.Label(frame, text=_('Cmdr')) # Main window @@ -181,11 +182,14 @@ def prefs_cmdr_changed(cmdr, is_beta): if cmdr: this.cmdr_text['text'] = cmdr + (is_beta and ' [Beta]' or '') cred = credentials(cmdr) + if cred: this.user.insert(0, cred[0]) this.apikey.insert(0, cred[1]) + else: this.cmdr_text['text'] = _('None') # No hotkey/shortcut currently defined + this.label['state'] = this.cmdr_label['state'] = this.cmdr_text['state'] = this.user_label['state'] = this.user['state'] = this.apikey_label['state'] = this.apikey['state'] = cmdr and not is_beta and this.log.get() and tk.NORMAL or tk.DISABLED @@ -206,10 +210,12 @@ def prefs_changed(cmdr, is_beta): usernames[idx] = this.user.get().strip() apikeys.extend([''] * (1 + idx - len(apikeys))) apikeys[idx] = this.apikey.get().strip() + else: config.set('edsm_cmdrs', cmdrs + [cmdr]) usernames.append(this.user.get().strip()) apikeys.append(this.apikey.get().strip()) + config.set('edsm_usernames', usernames) config.set('edsm_apikeys', apikeys) @@ -228,6 +234,7 @@ def credentials(cmdr): if cmdr in cmdrs and config.get('edsm_usernames') and config.get('edsm_apikeys'): idx = cmdrs.index(cmdr) return (config.get('edsm_usernames')[idx], config.get('edsm_apikeys')[idx]) + else: return None @@ -275,6 +282,7 @@ entry: {entry!r}''' this.multicrew = bool(state['Role']) if 'StarPos' in entry: this.coordinates = entry['StarPos'] + elif entry['event'] == 'LoadGame': this.coordinates = None @@ -282,14 +290,17 @@ entry: {entry!r}''' this.newgame = True this.newgame_docked = False this.navbeaconscan = 0 + elif entry['event'] == 'StartUp': this.newgame = False this.newgame_docked = False this.navbeaconscan = 0 + elif entry['event'] == 'Location': this.newgame = True this.newgame_docked = entry.get('Docked', False) this.navbeaconscan = 0 + elif entry['event'] == 'NavBeaconScan': this.navbeaconscan = entry['NumBodies'] @@ -302,6 +313,7 @@ entry: {entry!r}''' '_stationName': station, '_shipId': state['ShipID'], } + entry.update(transient) if entry['event'] == 'LoadGame': @@ -330,6 +342,7 @@ def cmdr_data(data, is_beta): # Always store initially, even if we're not the *current* system provider. if not this.station_marketid: this.station_marketid = data['commander']['docked'] and data['lastStarport']['id'] + # Only trust CAPI if these aren't yet set this.system = this.system or data['lastSystem']['name'] this.station = this.station or data['commander']['docked'] and data['lastStarport']['name'] @@ -340,11 +353,14 @@ def cmdr_data(data, is_beta): # Do *NOT* set 'url' here, as it's set to a function that will call # through correctly. We don't want a static string. this.system_link.update_idletasks() + if config.get('station_provider') == 'EDSM': if data['commander']['docked']: this.station_link['text'] = this.station + elif data['lastStarport']['name'] and data['lastStarport']['name'] != "": this.station_link['text'] = STATION_UNDOCKED + else: this.station_link['text'] = '' @@ -361,7 +377,6 @@ def cmdr_data(data, is_beta): # Worker thread def worker(): - pending = [] # Unsent events closing = False @@ -409,9 +424,7 @@ def worker(): if any([p for p in pending if p['event'] in ('CarrierJump', 'FSDJump', 'Location', 'Docked')]): data_elided = data.copy() data_elided['apiKey'] = '' - logger.debug(f'''CarrierJump (or FSDJump): Attempting API call -data: {data_elided!r}''' - ) + logger.debug(f'CarrierJump (or FSDJump): Attempting API call\ndata: {data_elided!r}') r = this.session.post('https://www.edsm.net/api-journal-v1', data=data, timeout=_TIMEOUT) r.raise_for_status() reply = r.json() @@ -423,6 +436,7 @@ data: {data_elided!r}''' if msgnum // 100 == 2: logger.warning(f'EDSM\t{msgnum} {msg}\t{json.dumps(pending, separators = (",", ": "))}') plug.show_error(_('Error: EDSM {MSG}').format(MSG=msg)) + else: for e, r in zip(pending, reply['events']): if not closing and e['event'] in ['StartUp', 'Location', 'FSDJump', 'CarrierJump']: @@ -430,15 +444,18 @@ data: {data_elided!r}''' this.lastlookup = r # calls update_status in main thread this.system_link.event_generate('<>', when="tail") + elif r['msgnum'] // 100 != 1: logger.warning(f'EDSM\t{r["msgnum"]} {r["msg"]}\t' f'{json.dumps(e, separators = (",", ": "))}') + pending = [] break except Exception as e: logger.debug('Sending API events', exc_info=e) retrying += 1 + else: plug.show_error(_("Error: Can't connect to EDSM")) @@ -455,6 +472,7 @@ def should_send(entries): this.navbeaconscan -= 1 if this.navbeaconscan: return False + else: assert(False) this.navbeaconscan = 0 @@ -465,12 +483,15 @@ def should_send(entries): this.newgame = False this.newgame_docked = False return True + elif this.newgame: pass + elif entry['event'] not in ['CommunityGoal', # Spammed periodically 'ModuleBuy', 'ModuleSell', 'ModuleSwap', # will be shortly followed by "Loadout" 'ShipyardBuy', 'ShipyardNew', 'ShipyardSwap']: # " return True + return False @@ -486,10 +507,13 @@ def edsm_notify_system(reply): if not reply: this.system_link['image'] = this._IMG_ERROR plug.show_error(_("Error: Can't connect to EDSM")) + elif reply['msgnum'] // 100 not in (1, 4): this.system_link['image'] = this._IMG_ERROR plug.show_error(_('Error: EDSM {MSG}').format(MSG=reply['msg'])) + elif reply.get('systemCreated'): this.system_link['image'] = this._IMG_NEW + else: this.system_link['image'] = this._IMG_KNOWN From 14617e72da9ea370255dceef7a79204c4d181878 Mon Sep 17 00:00:00 2001 From: A_D Date: Tue, 18 Aug 2020 10:52:44 +0200 Subject: [PATCH 05/22] cleaned up overlong lines --- plugins/edsm.py | 117 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 98 insertions(+), 19 deletions(-) diff --git a/plugins/edsm.py b/plugins/edsm.py index f5438b6c..4b40d14e 100644 --- a/plugins/edsm.py +++ b/plugins/edsm.py @@ -59,6 +59,31 @@ this.station_link = None this.station = None this.station_marketid = None # Frontier MarketID STATION_UNDOCKED: str = '×' # "Station" name to display when not docked = U+00D7 +__cleanup = str.maketrans({' ': None, '\n': None}) +IMG_KNOWN_B64 = """ +R0lGODlhEAAQAMIEAFWjVVWkVWS/ZGfFZ////////////////yH5BAEKAAQALAAAAAAQABAAAAMvSLrc/lAFIUIkYOgNXt5g14Dk0AQlaC1CuglM6w7wgs7r +MpvNV4q932VSuRiPjQQAOw== +""".translate(__cleanup) + +IMG_UNKNOWN_B64 = """ +R0lGODlhEAAQAKEDAGVLJ+ddWO5fW////yH5BAEKAAMALAAAAAAQABAAAAItnI+pywYRQBtA2CtVvTwjDgrJFlreEJRXgKSqwB5keQ6vOKq1E+7IE5kIh4kC +ADs= +""".translate(__cleanup) + +IMG_NEW_B64 = """ +R0lGODlhEAAQAMZwANKVHtWcIteiHuiqLPCuHOS1MN22ZeW7ROG6Zuu9MOy+K/i8Kf/DAuvCVf/FAP3BNf/JCf/KAPHHSv7ESObHdv/MBv/GRv/LGP/QBPXO +PvjPQfjQSvbRSP/UGPLSae7Sfv/YNvLXgPbZhP7dU//iI//mAP/jH//kFv7fU//fV//ebv/iTf/iUv/kTf/iZ/vgiP/hc/vgjv/jbfriiPriiv7ka//if//j +d//sJP/oT//tHv/mZv/sLf/rRP/oYv/rUv/paP/mhv/sS//oc//lkf/mif/sUf/uPv/qcv/uTv/uUv/vUP/qhP/xP//pm//ua//sf//ubf/wXv/thv/tif/s +lv/tjf/smf/yYP/ulf/2R//2Sv/xkP/2av/0gP/ylf/2df/0i//0j//0lP/5cP/7a//1p//5gf/7ev/3o//2sf/5mP/6kv/2vP/3y//+jP////////////// +/////////////////////////////////////////////////yH5BAEKAH8ALAAAAAAQABAAAAePgH+Cg4SFhoJKPIeHYT+LhVppUTiPg2hrUkKPXWdlb2xH +Jk9jXoNJQDk9TVtkYCUkOy4wNjdGfy1UXGJYOksnPiwgFwwYg0NubWpmX1ArHREOFYUyWVNIVkxXQSoQhyMoNVUpRU5EixkcMzQaGy8xhwsKHiEfBQkSIg+G +BAcUCIIBBDSYYGiAAUMALFR6FAgAOw== +""".translate(__cleanup) + +IMG_ERR_B64 = """ +R0lGODlhEAAQAKEBAAAAAP///////////yH5BAEKAAIALAAAAAAQABAAAAIwlBWpeR0AIwwNPRmZuVNJinyWuClhBlZjpm5fqnIAHJPtOd3Hou9mL6NVgj2L +plEAADs= +""".translate(__cleanup) # Main window clicks @@ -87,10 +112,10 @@ def station_url(system_name, station_name): def plugin_start3(plugin_dir): # Can't be earlier since can only call PhotoImage after window is created - this._IMG_KNOWN = tk.PhotoImage(data='R0lGODlhEAAQAMIEAFWjVVWkVWS/ZGfFZ////////////////yH5BAEKAAQALAAAAAAQABAAAAMvSLrc/lAFIUIkYOgNXt5g14Dk0AQlaC1CuglM6w7wgs7rMpvNV4q932VSuRiPjQQAOw==') # green circle - this._IMG_UNKNOWN = tk.PhotoImage(data='R0lGODlhEAAQAKEDAGVLJ+ddWO5fW////yH5BAEKAAMALAAAAAAQABAAAAItnI+pywYRQBtA2CtVvTwjDgrJFlreEJRXgKSqwB5keQ6vOKq1E+7IE5kIh4kCADs=') # red circle - this._IMG_NEW = tk.PhotoImage(data='R0lGODlhEAAQAMZwANKVHtWcIteiHuiqLPCuHOS1MN22ZeW7ROG6Zuu9MOy+K/i8Kf/DAuvCVf/FAP3BNf/JCf/KAPHHSv7ESObHdv/MBv/GRv/LGP/QBPXOPvjPQfjQSvbRSP/UGPLSae7Sfv/YNvLXgPbZhP7dU//iI//mAP/jH//kFv7fU//fV//ebv/iTf/iUv/kTf/iZ/vgiP/hc/vgjv/jbfriiPriiv7ka//if//jd//sJP/oT//tHv/mZv/sLf/rRP/oYv/rUv/paP/mhv/sS//oc//lkf/mif/sUf/uPv/qcv/uTv/uUv/vUP/qhP/xP//pm//ua//sf//ubf/wXv/thv/tif/slv/tjf/smf/yYP/ulf/2R//2Sv/xkP/2av/0gP/ylf/2df/0i//0j//0lP/5cP/7a//1p//5gf/7ev/3o//2sf/5mP/6kv/2vP/3y//+jP///////////////////////////////////////////////////////////////yH5BAEKAH8ALAAAAAAQABAAAAePgH+Cg4SFhoJKPIeHYT+LhVppUTiPg2hrUkKPXWdlb2xHJk9jXoNJQDk9TVtkYCUkOy4wNjdGfy1UXGJYOksnPiwgFwwYg0NubWpmX1ArHREOFYUyWVNIVkxXQSoQhyMoNVUpRU5EixkcMzQaGy8xhwsKHiEfBQkSIg+GBAcUCIIBBDSYYGiAAUMALFR6FAgAOw==') - this._IMG_ERROR = tk.PhotoImage(data='R0lGODlhEAAQAKEBAAAAAP///////////yH5BAEKAAIALAAAAAAQABAAAAIwlBWpeR0AIwwNPRmZuVNJinyWuClhBlZjpm5fqnIAHJPtOd3Hou9mL6NVgj2LplEAADs=') # BBC Mode 5 '?' + this._IMG_KNOWN = tk.PhotoImage(data=IMG_KNOWN_B64) # green circle + this._IMG_UNKNOWN = tk.PhotoImage(data=IMG_UNKNOWN_B64) # red circle + this._IMG_NEW = tk.PhotoImage(data=IMG_NEW_B64) + this._IMG_ERROR = tk.PhotoImage(data=IMG_ERR_B64) # BBC Mode 5 '?' # Migrate old settings if not config.get('edsm_cmdrs'): @@ -136,7 +161,6 @@ def plugin_stop(): def plugin_prefs(parent, cmdr, is_beta): - PADX = 10 BUTTONX = 12 # indent Checkbuttons and Radiobuttons PADY = 2 # close spacing @@ -144,13 +168,31 @@ def plugin_prefs(parent, cmdr, is_beta): frame = nb.Frame(parent) frame.columnconfigure(1, weight=1) - HyperlinkLabel(frame, text='Elite Dangerous Star Map', background=nb.Label().cget('background'), url='https://www.edsm.net/', underline=True).grid(columnspan=2, padx=PADX, sticky=tk.W) # Don't translate + HyperlinkLabel( + frame, + text='Elite Dangerous Star Map', + background=nb.Label().cget('background'), + url='https://www.edsm.net/', + underline=True + ).grid(columnspan=2, padx=PADX, sticky=tk.W) # Don't translate + this.log = tk.IntVar(value=config.getint('edsm_out') and 1) - this.log_button = nb.Checkbutton(frame, text=_('Send flight log and Cmdr status to EDSM'), variable=this.log, command=prefsvarchanged) + this.log_button = nb.Checkbutton( + frame, text=_('Send flight log and Cmdr status to EDSM'), variable=this.log, command=prefsvarchanged + ) + this.log_button.grid(columnspan=2, padx=BUTTONX, pady=(5, 0), sticky=tk.W) nb.Label(frame).grid(sticky=tk.W) # big spacer - this.label = HyperlinkLabel(frame, text=_('Elite Dangerous Star Map credentials'), background=nb.Label().cget('background'), url='https://www.edsm.net/settings/api', underline=True) # Section heading in settings + # Section heading in settings + this.label = HyperlinkLabel( + frame, + text=_('Elite Dangerous Star Map credentials'), + background=nb.Label().cget('background'), + url='https://www.edsm.net/settings/api', + underline=True + ) + this.label.grid(columnspan=2, padx=PADX, sticky=tk.W) this.cmdr_label = nb.Label(frame, text=_('Cmdr')) # Main window @@ -190,11 +232,34 @@ def prefs_cmdr_changed(cmdr, is_beta): else: this.cmdr_text['text'] = _('None') # No hotkey/shortcut currently defined - this.label['state'] = this.cmdr_label['state'] = this.cmdr_text['state'] = this.user_label['state'] = this.user['state'] = this.apikey_label['state'] = this.apikey['state'] = cmdr and not is_beta and this.log.get() and tk.NORMAL or tk.DISABLED + to_set = tk.DISABLED + if cmdr and not is_beta and this.log.get(): + to_set = tk.NORMAL + + set_prefs_ui_states(to_set) def prefsvarchanged(): - this.label['state'] = this.cmdr_label['state'] = this.cmdr_text['state'] = this.user_label['state'] = this.user['state'] = this.apikey_label['state'] = this.apikey['state'] = this.log.get() and this.log_button['state'] or tk.DISABLED + to_set = tk.DISABLED + if this.log.get(): + to_set = this.log_button['state'] + + set_prefs_ui_states(to_set) + + +def set_prefs_ui_states(state: str) -> None: + """ + Set the state of various config UI entries + + :param state: the state to set each entry to + """ + this.label['state'] = state + this.cmdr_label['state'] = state + this.cmdr_text['state'] = state + this.user_label['state'] = state + this.user['state'] = state + this.apikey_label['state'] = state + this.apikey['state'] = state def prefs_changed(cmdr, is_beta): @@ -269,7 +334,15 @@ entry: {entry!r}''' this.station_marketid = None if config.get('station_provider') == 'EDSM': - this.station_link['text'] = this.station or (this.system_population and this.system_population > 0 and STATION_UNDOCKED or '') + to_set = this.station + if not this.station: + if this.system_population and this.system_population > 0: + to_set = STATION_UNDOCKED + + else: + to_set = '' + + this.station_link['text'] = to_set this.station_link['url'] = station_url(this.system, this.station) this.station_link.update_idletasks() @@ -305,7 +378,10 @@ entry: {entry!r}''' this.navbeaconscan = entry['NumBodies'] # Send interesting events to EDSM - if config.getint('edsm_out') and not is_beta and not this.multicrew and credentials(cmdr) and entry['event'] not in this.discardedEvents: + if ( + config.getint('edsm_out') and not is_beta and not this.multicrew and credentials(cmdr) and + entry['event'] not in this.discardedEvents + ): # Introduce transient states into the event transient = { '_systemName': system, @@ -405,8 +481,8 @@ def worker(): this.discardedEvents = set(r.json()) this.discardedEvents.discard('Docked') # should_send() assumes that we send 'Docked' events assert this.discardedEvents # wouldn't expect this to be empty - pending = [x for x in pending if x['event'] - not in this.discardedEvents] # Filter out unwanted events + # Filter out unwanted events + pending = [x for x in pending if x['event'] not in this.discardedEvents] if should_send(pending): if any([p for p in pending if p['event'] in ('CarrierJump', 'FSDJump', 'Location', 'Docked')]): @@ -487,21 +563,24 @@ def should_send(entries): elif this.newgame: pass - elif entry['event'] not in ['CommunityGoal', # Spammed periodically - 'ModuleBuy', 'ModuleSell', 'ModuleSwap', # will be shortly followed by "Loadout" - 'ShipyardBuy', 'ShipyardNew', 'ShipyardSwap']: # " + elif entry['event'] not in [ + 'CommunityGoal', # Spammed periodically + 'ModuleBuy', 'ModuleSell', 'ModuleSwap', # will be shortly followed by "Loadout" + 'ShipyardBuy', 'ShipyardNew', 'ShipyardSwap']: # " return True return False -# Call edsm_notify_system() in this and other interested plugins with EDSM's response to a 'StartUp', 'Location', 'FSDJump' or 'CarrierJump' event +# Call edsm_notify_system() in this and other interested plugins with EDSM's response to a 'StartUp', 'Location', +# 'FSDJump' or 'CarrierJump' event def update_status(event=None): for plugin in plug.provides('edsm_notify_system'): plug.invoke(plugin, None, 'edsm_notify_system', this.lastlookup) -# Called with EDSM's response to a 'StartUp', 'Location', 'FSDJump' or 'CarrierJump' event. https://www.edsm.net/en/api-journal-v1 +# Called with EDSM's response to a 'StartUp', 'Location', 'FSDJump' or 'CarrierJump' event. +# https://www.edsm.net/en/api-journal-v1 # msgnum: 1xx = OK, 2xx = fatal error, 3xx = error, 4xx = ignorable errors. def edsm_notify_system(reply): if not reply: From 81c977d0da729a5ab4f93ce1a448e00d37a2174b Mon Sep 17 00:00:00 2001 From: A_D Date: Tue, 18 Aug 2020 11:08:35 +0200 Subject: [PATCH 06/22] Added type annotations to functions --- plugins/edsm.py | 80 +++++++++++++++++++++++++------------------------ 1 file changed, 41 insertions(+), 39 deletions(-) diff --git a/plugins/edsm.py b/plugins/edsm.py index 4b40d14e..5496d05f 100644 --- a/plugins/edsm.py +++ b/plugins/edsm.py @@ -20,7 +20,7 @@ import urllib.parse import urllib.request from queue import Queue from threading import Thread -from typing import TYPE_CHECKING, Any +from typing import TYPE_CHECKING, Any, List, Mapping, MutableMapping, Optional, Tuple import requests @@ -40,24 +40,24 @@ _TIMEOUT = 20 this: Any = sys.modules[__name__] # For holding module globals -this.session = requests.Session() -this.queue = Queue() # Items to be sent to EDSM by worker thread -this.discardedEvents = [] # List discarded events from EDSM -this.lastlookup = False # whether the last lookup succeeded +this.session: requests.Session = requests.Session() +this.queue: Queue = Queue() # Items to be sent to EDSM by worker thread +this.discardedEvents: List[str] = [] # List discarded events from EDSM +this.lastlookup: bool = False # whether the last lookup succeeded # Game state -this.multicrew = False # don't send captain's ship info to EDSM while on a crew -this.coordinates = None -this.newgame = False # starting up - batch initial burst of events -this.newgame_docked = False # starting up while docked -this.navbeaconscan = 0 # batch up burst of Scan events after NavBeaconScan -this.system_link = None -this.system = None -this.system_address = None # Frontier SystemAddress -this.system_population = None -this.station_link = None -this.station = None -this.station_marketid = None # Frontier MarketID +this.multicrew: bool = False # don't send captain's ship info to EDSM while on a crew +this.coordinates: Optional[Tuple[int, int, int]] = None +this.newgame: bool = False # starting up - batch initial burst of events +this.newgame_docked: bool = False # starting up while docked +this.navbeaconscan: int = 0 # batch up burst of Scan events after NavBeaconScan +this.system_link: tk.Tk = None +this.system: tk.Tk = None +this.system_address: Optional[int] = None # Frontier SystemAddress +this.system_population: Optional[int] = None +this.station_link: tk.Tk = None +this.station: Optional[str] = None +this.station_marketid: Optional[int] = None # Frontier MarketID STATION_UNDOCKED: str = '×' # "Station" name to display when not docked = U+00D7 __cleanup = str.maketrans({' ': None, '\n': None}) IMG_KNOWN_B64 = """ @@ -87,7 +87,7 @@ plEAADs= # Main window clicks -def system_url(system_name): +def system_url(system_name: str) -> str: if this.system_address: return requests.utils.requote_uri(f'https://www.edsm.net/en/system?systemID64={this.system_address}') @@ -97,7 +97,7 @@ def system_url(system_name): return '' -def station_url(system_name, station_name): +def station_url(system_name: str, station_name: str) -> str: if system_name and station_name: return requests.utils.requote_uri(f'https://www.edsm.net/en/system?systemName={system_name}&stationName={station_name}') @@ -110,7 +110,7 @@ def station_url(system_name, station_name): return '' -def plugin_start3(plugin_dir): +def plugin_start3(plugin_dir: str) -> str: # Can't be earlier since can only call PhotoImage after window is created this._IMG_KNOWN = tk.PhotoImage(data=IMG_KNOWN_B64) # green circle this._IMG_UNKNOWN = tk.PhotoImage(data=IMG_UNKNOWN_B64) # red circle @@ -145,13 +145,13 @@ def plugin_start3(plugin_dir): return 'EDSM' -def plugin_app(parent): +def plugin_app(parent: tk.Tk) -> None: this.system_link = parent.children['system'] # system label in main window this.system_link.bind_all('<>', update_status) this.station_link = parent.children['station'] # station label in main window -def plugin_stop(): +def plugin_stop() -> None: # Signal thread to close and wait for it this.queue.put(None) this.thread.join() @@ -160,7 +160,7 @@ def plugin_stop(): this._IMG_KNOWN = this._IMG_UNKNOWN = this._IMG_NEW = this._IMG_ERROR = None -def plugin_prefs(parent, cmdr, is_beta): +def plugin_prefs(parent: tk.Tk, cmdr: str, is_beta: bool) -> tk.Frame: PADX = 10 BUTTONX = 12 # indent Checkbuttons and Radiobuttons PADY = 2 # close spacing @@ -172,7 +172,7 @@ def plugin_prefs(parent, cmdr, is_beta): frame, text='Elite Dangerous Star Map', background=nb.Label().cget('background'), - url='https://www.edsm.net/', + url='https://www.edsm.net/', underline=True ).grid(columnspan=2, padx=PADX, sticky=tk.W) # Don't translate @@ -215,7 +215,7 @@ def plugin_prefs(parent, cmdr, is_beta): return frame -def prefs_cmdr_changed(cmdr, is_beta): +def prefs_cmdr_changed(cmdr: str, is_beta: bool) -> None: this.log_button['state'] = cmdr and not is_beta and tk.NORMAL or tk.DISABLED this.user['state'] = tk.NORMAL this.user.delete(0, tk.END) @@ -239,7 +239,7 @@ def prefs_cmdr_changed(cmdr, is_beta): set_prefs_ui_states(to_set) -def prefsvarchanged(): +def prefsvarchanged() -> None: to_set = tk.DISABLED if this.log.get(): to_set = this.log_button['state'] @@ -262,13 +262,13 @@ def set_prefs_ui_states(state: str) -> None: this.apikey['state'] = state -def prefs_changed(cmdr, is_beta): +def prefs_changed(cmdr: str, is_beta: bool) -> None: config.set('edsm_out', this.log.get()) if cmdr and not is_beta: cmdrs = config.get('edsm_cmdrs') - usernames = config.get('edsm_usernames') or [] - apikeys = config.get('edsm_apikeys') or [] + usernames: List[str] = config.get('edsm_usernames') or [] + apikeys: List[str] = config.get('edsm_apikeys') or [] if cmdr in cmdrs: idx = cmdrs.index(cmdr) usernames.extend([''] * (1 + idx - len(usernames))) @@ -285,7 +285,7 @@ def prefs_changed(cmdr, is_beta): config.set('edsm_apikeys', apikeys) -def credentials(cmdr): +def credentials(cmdr: str) -> Optional[Tuple[str, str]]: # Credentials for cmdr if not cmdr: return None @@ -304,7 +304,9 @@ def credentials(cmdr): return None -def journal_entry(cmdr, is_beta, system, station, entry, state): +def journal_entry( + cmdr: str, is_beta: bool, system: str, station: str, entry: MutableMapping[str, Any], state: Mapping[str, Any] +) -> None: if entry['event'] in ('CarrierJump', 'FSDJump', 'Location', 'Docked'): logger.debug(f'''{entry["event"]} Commander: {cmdr} @@ -313,7 +315,6 @@ Station: {station} state: {state!r} entry: {entry!r}''' ) - # Always update our system address even if we're not currently the provider for system or station, but dont update # on events that contain "future" data, such as FSDTarget if entry['event'] in ('Location', 'Docked', 'CarrierJump', 'FSDJump'): @@ -412,7 +413,7 @@ Queueing: {entry!r}''' # Update system data -def cmdr_data(data, is_beta): +def cmdr_data(data: Mapping[str, Any], is_beta: bool) -> None: system = data['lastSystem']['name'] # Always store initially, even if we're not the *current* system provider. @@ -452,12 +453,12 @@ def cmdr_data(data, is_beta): # Worker thread -def worker(): +def worker() -> None: pending = [] # Unsent events closing = False while True: - item = this.queue.get() + item: Optional[Tuple[str, Mapping[str, Any]]] = this.queue.get() if item: (cmdr, entry) = item else: @@ -466,6 +467,7 @@ def worker(): retrying = 0 while retrying < 3: try: + # TODO: Technically entry can be unbound here. if item and entry['event'] in ('CarrierJump', 'FSDJump', 'Location', 'Docked'): logger.debug(f'{entry["event"]}') @@ -488,7 +490,7 @@ def worker(): if any([p for p in pending if p['event'] in ('CarrierJump', 'FSDJump', 'Location', 'Docked')]): logger.debug('CarrierJump (or FSDJump) in pending and it passed should_send()') - (username, apikey) = credentials(cmdr) + (username, apikey) = credentials(cmdr) # TODO: This raises if credentials returns None data = { 'commanderName': username.encode('utf-8'), 'apiKey': apikey, @@ -540,7 +542,7 @@ def worker(): # Whether any of the entries should be sent immediately -def should_send(entries): +def should_send(entries: List[Mapping[str, Any]]) -> bool: # batch up burst of Scan events after NavBeaconScan if this.navbeaconscan: @@ -574,7 +576,7 @@ def should_send(entries): # Call edsm_notify_system() in this and other interested plugins with EDSM's response to a 'StartUp', 'Location', # 'FSDJump' or 'CarrierJump' event -def update_status(event=None): +def update_status(event=None) -> None: for plugin in plug.provides('edsm_notify_system'): plug.invoke(plugin, None, 'edsm_notify_system', this.lastlookup) @@ -582,7 +584,7 @@ def update_status(event=None): # Called with EDSM's response to a 'StartUp', 'Location', 'FSDJump' or 'CarrierJump' event. # https://www.edsm.net/en/api-journal-v1 # msgnum: 1xx = OK, 2xx = fatal error, 3xx = error, 4xx = ignorable errors. -def edsm_notify_system(reply): +def edsm_notify_system(reply: Mapping[str, Any]) -> None: if not reply: this.system_link['image'] = this._IMG_ERROR plug.show_error(_("Error: Can't connect to EDSM")) From 20357b3debb0314ef19284666951b3e65e58f1e2 Mon Sep 17 00:00:00 2001 From: A_D Date: Wed, 19 Aug 2020 04:39:13 +0200 Subject: [PATCH 07/22] replaced modulo formatting with fstrings --- plugins/edsm.py | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/edsm.py b/plugins/edsm.py index 5496d05f..aca3c623 100644 --- a/plugins/edsm.py +++ b/plugins/edsm.py @@ -543,7 +543,6 @@ def worker() -> None: # Whether any of the entries should be sent immediately def should_send(entries: List[Mapping[str, Any]]) -> bool: - # batch up burst of Scan events after NavBeaconScan if this.navbeaconscan: if entries and entries[-1]['event'] == 'Scan': From 2c2ade05e0fd9bb5d06ea7c66cdd25f94728d8cd Mon Sep 17 00:00:00 2001 From: A_D Date: Wed, 19 Aug 2020 12:25:48 +0200 Subject: [PATCH 08/22] fixed some naming --- plugins/edsm.py | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/plugins/edsm.py b/plugins/edsm.py index aca3c623..766c2dd3 100644 --- a/plugins/edsm.py +++ b/plugins/edsm.py @@ -161,9 +161,9 @@ def plugin_stop() -> None: def plugin_prefs(parent: tk.Tk, cmdr: str, is_beta: bool) -> tk.Frame: - PADX = 10 - BUTTONX = 12 # indent Checkbuttons and Radiobuttons - PADY = 2 # close spacing + PADX = 10 # noqa: N806 + BUTTONX = 12 # indent Checkbuttons and Radiobuttons # noqa: N806 + PADY = 2 # close spacing # noqa: N806 frame = nb.Frame(parent) frame.columnconfigure(1, weight=1) @@ -222,7 +222,7 @@ def prefs_cmdr_changed(cmdr: str, is_beta: bool) -> None: this.apikey['state'] = tk.NORMAL this.apikey.delete(0, tk.END) if cmdr: - this.cmdr_text['text'] = cmdr + (is_beta and ' [Beta]' or '') + this.cmdr_text['text'] = f'{cmdr}{" [Beta]" if is_beta else ""}' cred = credentials(cmdr) if cred: @@ -266,9 +266,10 @@ def prefs_changed(cmdr: str, is_beta: bool) -> None: config.set('edsm_out', this.log.get()) if cmdr and not is_beta: - cmdrs = config.get('edsm_cmdrs') - usernames: List[str] = config.get('edsm_usernames') or [] - apikeys: List[str] = config.get('edsm_apikeys') or [] + # TODO: remove this when config is rewritten. + cmdrs: List[str] = list(config.get('edsm_cmdrs') or []) + usernames: List[str] = list(config.get('edsm_usernames') or []) + apikeys: List[str] = list(config.get('edsm_apikeys') or []) if cmdr in cmdrs: idx = cmdrs.index(cmdr) usernames.extend([''] * (1 + idx - len(usernames))) @@ -344,7 +345,7 @@ entry: {entry!r}''' to_set = '' this.station_link['text'] = to_set - this.station_link['url'] = station_url(this.system, this.station) + this.station_link['url'] = station_url(this.system, str(this.station)) this.station_link.update_idletasks() # Update display of 'EDSM Status' image @@ -506,13 +507,13 @@ def worker() -> None: r = this.session.post('https://www.edsm.net/api-journal-v1', data=data, timeout=_TIMEOUT) r.raise_for_status() reply = r.json() - (msgnum, msg) = reply['msgnum'], reply['msg'] + (msg_num, msg) = reply['msgnum'], reply['msg'] # 1xx = OK # 2xx = fatal error # 3&4xx not generated at top-level # 5xx = error but events saved for later processing - if msgnum // 100 == 2: - logger.warning(f'EDSM\t{msgnum} {msg}\t{json.dumps(pending, separators = (",", ": "))}') + if msg_num // 100 == 2: + logger.warning(f'EDSM\t{msg_num} {msg}\t{json.dumps(pending, separators=(",", ": "))}') plug.show_error(_('Error: EDSM {MSG}').format(MSG=msg)) else: From 25adf297793fdacb8e2294f46a1b3a679702f2b5 Mon Sep 17 00:00:00 2001 From: A_D Date: Wed, 19 Aug 2020 12:27:15 +0200 Subject: [PATCH 09/22] Fixed possible error if credentials is None --- plugins/edsm.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/plugins/edsm.py b/plugins/edsm.py index 766c2dd3..3b12c5ed 100644 --- a/plugins/edsm.py +++ b/plugins/edsm.py @@ -491,7 +491,11 @@ def worker() -> None: if any([p for p in pending if p['event'] in ('CarrierJump', 'FSDJump', 'Location', 'Docked')]): logger.debug('CarrierJump (or FSDJump) in pending and it passed should_send()') - (username, apikey) = credentials(cmdr) # TODO: This raises if credentials returns None + creds = credentials(cmdr) # TODO: possibly unbound + if creds is None: + raise ValueError("Unexpected lack of credentials") + + (username, apikey) = creds data = { 'commanderName': username.encode('utf-8'), 'apiKey': apikey, From 7ab697a80757fa00c9d0612fbb24da7f6a74bd23 Mon Sep 17 00:00:00 2001 From: A_D Date: Tue, 25 Aug 2020 11:56:14 +0200 Subject: [PATCH 10/22] Used default option for .get on dicts --- plugins/edsm.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/edsm.py b/plugins/edsm.py index 3b12c5ed..15999fca 100644 --- a/plugins/edsm.py +++ b/plugins/edsm.py @@ -319,8 +319,8 @@ entry: {entry!r}''' # Always update our system address even if we're not currently the provider for system or station, but dont update # on events that contain "future" data, such as FSDTarget if entry['event'] in ('Location', 'Docked', 'CarrierJump', 'FSDJump'): - this.system_address = entry.get('SystemAddress') or this.system_address - this.system = entry.get('StarSystem') or this.system + this.system_address = entry.get('SystemAddress', this.system_address) + this.system = entry.get('StarSystem', this.system) # We need pop == 0 to set the value so as to clear 'x' in systems with # no stations. @@ -328,8 +328,8 @@ entry: {entry!r}''' if pop is not None: this.system_population = pop - this.station = entry.get('StationName') or this.station - this.station_marketid = entry.get('MarketID') or this.station_marketid + this.station = entry.get('StationName', this.station) + this.station_marketid = entry.get('MarketID', this.station) # We might pick up StationName in DockingRequested, make sure we clear it if leaving if entry['event'] in ('Undocked', 'FSDJump', 'SupercruiseEntry'): this.station = None From 62f3203c3fabbab5729d6548c588e12001d94c30 Mon Sep 17 00:00:00 2001 From: A_D Date: Tue, 25 Aug 2020 12:00:30 +0200 Subject: [PATCH 11/22] Added type checker hint for unbound names Due to the fact that cmdr and entry are only assigned if item exists, a situation can arise where any access to the names will raise an UnboundLocalException, this tells the type checker to ignore that possibility by using a TYPE_CHECKING guarded assignment to those names. This does not fix the issue at runtime, it just tells the type checker that its fine. As this remains a bug, I have left TODOs in to note its existence. --- plugins/edsm.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/plugins/edsm.py b/plugins/edsm.py index 15999fca..f13517a4 100644 --- a/plugins/edsm.py +++ b/plugins/edsm.py @@ -468,13 +468,14 @@ def worker() -> None: retrying = 0 while retrying < 3: try: - # TODO: Technically entry can be unbound here. - if item and entry['event'] in ('CarrierJump', 'FSDJump', 'Location', 'Docked'): - logger.debug(f'{entry["event"]}') + if TYPE_CHECKING: + # Tell the type checker that these two are bound. + # TODO: While this works because of the item check below, these names are still technically unbound + # TODO: in some cases, therefore this should be refactored. + cmdr: str = "" + entry: Mapping[str, Any] = {} - if item and entry['event'] not in this.discardedEvents: - if entry['event'] in ('CarrierJump', 'FSDJump', 'Location', 'Docked'): - logger.debug(f'{entry["event"]} event not in discarded list') + if item and entry['event'] not in this.discardedEvents: # TODO: Technically entry can be unbound here. pending.append(entry) # Get list of events to discard From f2add920c702b83ca377be8d187a456fd6d99a8f Mon Sep 17 00:00:00 2001 From: A_D Date: Tue, 25 Aug 2020 12:06:26 +0200 Subject: [PATCH 12/22] replaced constant contains checks with tuples --- plugins/edsm.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/plugins/edsm.py b/plugins/edsm.py index f13517a4..9868d57f 100644 --- a/plugins/edsm.py +++ b/plugins/edsm.py @@ -361,7 +361,7 @@ entry: {entry!r}''' elif entry['event'] == 'LoadGame': this.coordinates = None - if entry['event'] in ['LoadGame', 'Commander', 'NewCommander']: + if entry['event'] in ('LoadGame', 'Commander', 'NewCommander'): this.newgame = True this.newgame_docked = False this.navbeaconscan = 0 @@ -523,7 +523,7 @@ def worker() -> None: else: for e, r in zip(pending, reply['events']): - if not closing and e['event'] in ['StartUp', 'Location', 'FSDJump', 'CarrierJump']: + if not closing and e['event'] in ('StartUp', 'Location', 'FSDJump', 'CarrierJump'): # Update main window's system status this.lastlookup = r # calls update_status in main thread @@ -558,7 +558,7 @@ def should_send(entries: List[Mapping[str, Any]]) -> bool: else: assert(False) - this.navbeaconscan = 0 + this.navbeaconscan = 0 # TODO: Unreachable code? for entry in entries: if (entry['event'] == 'Cargo' and not this.newgame_docked) or entry['event'] == 'Docked': @@ -570,10 +570,10 @@ def should_send(entries: List[Mapping[str, Any]]) -> bool: elif this.newgame: pass - elif entry['event'] not in [ + elif entry['event'] not in ( 'CommunityGoal', # Spammed periodically 'ModuleBuy', 'ModuleSell', 'ModuleSwap', # will be shortly followed by "Loadout" - 'ShipyardBuy', 'ShipyardNew', 'ShipyardSwap']: # " + 'ShipyardBuy', 'ShipyardNew', 'ShipyardSwap'): # " return True return False From 893cab3c23331ba89eb6365c8f0c16d23a63c869 Mon Sep 17 00:00:00 2001 From: A_D Date: Tue, 25 Aug 2020 12:11:14 +0200 Subject: [PATCH 13/22] cleaned up logic where possible --- plugins/edsm.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/plugins/edsm.py b/plugins/edsm.py index 9868d57f..2f3baa1f 100644 --- a/plugins/edsm.py +++ b/plugins/edsm.py @@ -216,7 +216,7 @@ def plugin_prefs(parent: tk.Tk, cmdr: str, is_beta: bool) -> tk.Frame: def prefs_cmdr_changed(cmdr: str, is_beta: bool) -> None: - this.log_button['state'] = cmdr and not is_beta and tk.NORMAL or tk.DISABLED + this.log_button['state'] = tk.NORMAL if cmdr and not is_beta else tk.DISABLED this.user['state'] = tk.NORMAL this.user.delete(0, tk.END) this.apikey['state'] = tk.NORMAL @@ -350,7 +350,7 @@ entry: {entry!r}''' # Update display of 'EDSM Status' image if this.system_link['text'] != system: - this.system_link['text'] = system or '' + this.system_link['text'] = system if system else '' this.system_link['image'] = '' this.system_link.update_idletasks() @@ -418,12 +418,16 @@ def cmdr_data(data: Mapping[str, Any], is_beta: bool) -> None: system = data['lastSystem']['name'] # Always store initially, even if we're not the *current* system provider. - if not this.station_marketid: - this.station_marketid = data['commander']['docked'] and data['lastStarport']['id'] + if not this.station_marketid and data['commander']['docked']: + this.station_marketid = data['lastStarport']['id'] # Only trust CAPI if these aren't yet set - this.system = this.system or data['lastSystem']['name'] - this.station = this.station or data['commander']['docked'] and data['lastStarport']['name'] + if not this.system: + this.system = data['lastSystem']['name'] + + if not this.station and data['commander']['docked']: + this.station = data['lastStarport']['name'] + # TODO: Fire off the EDSM API call to trigger the callback for the icons if config.get('system_provider') == 'EDSM': @@ -486,7 +490,7 @@ def worker() -> None: this.discardedEvents.discard('Docked') # should_send() assumes that we send 'Docked' events assert this.discardedEvents # wouldn't expect this to be empty # Filter out unwanted events - pending = [x for x in pending if x['event'] not in this.discardedEvents] + pending = list(filter(lambda x: x['event'] not in this.discardedEvents, pending)) if should_send(pending): if any([p for p in pending if p['event'] in ('CarrierJump', 'FSDJump', 'Location', 'Docked')]): From fb080f80807a6a3870f0ab311ae4c3cc80958fac Mon Sep 17 00:00:00 2001 From: A_D Date: Mon, 7 Sep 2020 00:39:39 +0200 Subject: [PATCH 14/22] Removed unused imports --- plugins/edsm.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/plugins/edsm.py b/plugins/edsm.py index 2f3baa1f..edf5f497 100644 --- a/plugins/edsm.py +++ b/plugins/edsm.py @@ -15,9 +15,6 @@ import json import logging import sys import tkinter as tk -import urllib.error -import urllib.parse -import urllib.request from queue import Queue from threading import Thread from typing import TYPE_CHECKING, Any, List, Mapping, MutableMapping, Optional, Tuple From 26be93f92e5220031d88214471a2c4a9307501dd Mon Sep 17 00:00:00 2001 From: A_D Date: Mon, 7 Sep 2020 00:43:43 +0200 Subject: [PATCH 15/22] replaced magic number row with var --- plugins/edsm.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/plugins/edsm.py b/plugins/edsm.py index edf5f497..691ad27a 100644 --- a/plugins/edsm.py +++ b/plugins/edsm.py @@ -107,6 +107,7 @@ def station_url(system_name: str, station_name: str) -> str: return '' + def plugin_start3(plugin_dir: str) -> str: # Can't be earlier since can only call PhotoImage after window is created this._IMG_KNOWN = tk.PhotoImage(data=IMG_KNOWN_B64) # green circle @@ -190,22 +191,28 @@ def plugin_prefs(parent: tk.Tk, cmdr: str, is_beta: bool) -> tk.Frame: underline=True ) + cur_row = 10 + this.label.grid(columnspan=2, padx=PADX, sticky=tk.W) this.cmdr_label = nb.Label(frame, text=_('Cmdr')) # Main window - this.cmdr_label.grid(row=10, padx=PADX, sticky=tk.W) + this.cmdr_label.grid(row=cur_row, padx=PADX, sticky=tk.W) this.cmdr_text = nb.Label(frame) - this.cmdr_text.grid(row=10, column=1, padx=PADX, pady=PADY, sticky=tk.W) + this.cmdr_text.grid(row=cur_row, column=1, padx=PADX, pady=PADY, sticky=tk.W) + + cur_row += 1 this.user_label = nb.Label(frame, text=_('Commander Name')) # EDSM setting - this.user_label.grid(row=11, padx=PADX, sticky=tk.W) + this.user_label.grid(row=cur_row, padx=PADX, sticky=tk.W) this.user = nb.Entry(frame) - this.user.grid(row=11, column=1, padx=PADX, pady=PADY, sticky=tk.EW) + this.user.grid(row=cur_row, column=1, padx=PADX, pady=PADY, sticky=tk.EW) + + cur_row += 1 this.apikey_label = nb.Label(frame, text=_('API Key')) # EDSM setting - this.apikey_label.grid(row=12, padx=PADX, sticky=tk.W) + this.apikey_label.grid(row=cur_row, padx=PADX, sticky=tk.W) this.apikey = nb.Entry(frame) - this.apikey.grid(row=12, column=1, padx=PADX, pady=PADY, sticky=tk.EW) + this.apikey.grid(row=cur_row, column=1, padx=PADX, pady=PADY, sticky=tk.EW) prefs_cmdr_changed(cmdr, is_beta) From 4a7cddc48bf9dba692f5c841aedde7283db42b5a Mon Sep 17 00:00:00 2001 From: A_D Date: Thu, 17 Sep 2020 09:15:12 +0200 Subject: [PATCH 16/22] removed assert False --- plugins/edsm.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/plugins/edsm.py b/plugins/edsm.py index 691ad27a..4a62b5d3 100644 --- a/plugins/edsm.py +++ b/plugins/edsm.py @@ -565,8 +565,11 @@ def should_send(entries: List[Mapping[str, Any]]) -> bool: return False else: - assert(False) - this.navbeaconscan = 0 # TODO: Unreachable code? + logger.error( + 'Invalid state NavBeaconScan exists, but passed entries either ' + "doesn't exist or doesn't have the expected content" + ) + this.navbeaconscan = 0 for entry in entries: if (entry['event'] == 'Cargo' and not this.newgame_docked) or entry['event'] == 'Docked': From 615a36452d855a37109fb3c94ae69e47f403b4fe Mon Sep 17 00:00:00 2001 From: A_D Date: Thu, 17 Sep 2020 09:26:22 +0200 Subject: [PATCH 17/22] Added docstrings --- plugins/edsm.py | 53 +++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 42 insertions(+), 11 deletions(-) diff --git a/plugins/edsm.py b/plugins/edsm.py index 4a62b5d3..e33a9885 100644 --- a/plugins/edsm.py +++ b/plugins/edsm.py @@ -1,6 +1,4 @@ -# -# System display and EDSM lookup -# +"""System display and EDSM lookup.""" # TODO: # 1) Re-factor EDSM API calls out of journal_entry() into own function. @@ -85,6 +83,7 @@ plEAADs= # Main window clicks def system_url(system_name: str) -> str: + """Get a URL for the current system.""" if this.system_address: return requests.utils.requote_uri(f'https://www.edsm.net/en/system?systemID64={this.system_address}') @@ -95,20 +94,28 @@ def system_url(system_name: str) -> str: def station_url(system_name: str, station_name: str) -> str: + """Get a URL for the current station.""" if system_name and station_name: - return requests.utils.requote_uri(f'https://www.edsm.net/en/system?systemName={system_name}&stationName={station_name}') + return requests.utils.requote_uri( + f'https://www.edsm.net/en/system?systemName={system_name}&stationName={station_name}' + ) # monitor state might think these are gone, but we don't yet if this.system and this.station: - return requests.utils.requote_uri(f'https://www.edsm.net/en/system?systemName={this.system}&stationName={this.station}') + return requests.utils.requote_uri( + f'https://www.edsm.net/en/system?systemName={this.system}&stationName={this.station}' + ) if system_name: - return requests.utils.requote_uri(f'https://www.edsm.net/en/system?systemName={system_name}&stationName=ALL') + return requests.utils.requote_uri( + f'https://www.edsm.net/en/system?systemName={system_name}&stationName=ALL' + ) return '' def plugin_start3(plugin_dir: str) -> str: + """Plugin setup hook.""" # Can't be earlier since can only call PhotoImage after window is created this._IMG_KNOWN = tk.PhotoImage(data=IMG_KNOWN_B64) # green circle this._IMG_UNKNOWN = tk.PhotoImage(data=IMG_UNKNOWN_B64) # red circle @@ -144,21 +151,24 @@ def plugin_start3(plugin_dir: str) -> str: def plugin_app(parent: tk.Tk) -> None: + """Plugin UI setup.""" this.system_link = parent.children['system'] # system label in main window this.system_link.bind_all('<>', update_status) this.station_link = parent.children['station'] # station label in main window def plugin_stop() -> None: + """Plugin exit hook.""" # Signal thread to close and wait for it this.queue.put(None) this.thread.join() this.thread = None - # Suppress 'Exception ignored in: ' errors + # Suppress 'Exception ignored in: ' errors # TODO: this is bad. this._IMG_KNOWN = this._IMG_UNKNOWN = this._IMG_NEW = this._IMG_ERROR = None def plugin_prefs(parent: tk.Tk, cmdr: str, is_beta: bool) -> tk.Frame: + """Plugin preferences setup hook.""" PADX = 10 # noqa: N806 BUTTONX = 12 # indent Checkbuttons and Radiobuttons # noqa: N806 PADY = 2 # close spacing # noqa: N806 @@ -220,6 +230,7 @@ def plugin_prefs(parent: tk.Tk, cmdr: str, is_beta: bool) -> tk.Frame: def prefs_cmdr_changed(cmdr: str, is_beta: bool) -> None: + """Commanders changed hook.""" this.log_button['state'] = tk.NORMAL if cmdr and not is_beta else tk.DISABLED this.user['state'] = tk.NORMAL this.user.delete(0, tk.END) @@ -244,6 +255,7 @@ def prefs_cmdr_changed(cmdr: str, is_beta: bool) -> None: def prefsvarchanged() -> None: + """Preferences screen closed hook.""" to_set = tk.DISABLED if this.log.get(): to_set = this.log_button['state'] @@ -253,7 +265,7 @@ def prefsvarchanged() -> None: def set_prefs_ui_states(state: str) -> None: """ - Set the state of various config UI entries + Set the state of various config UI entries. :param state: the state to set each entry to """ @@ -267,6 +279,7 @@ def set_prefs_ui_states(state: str) -> None: def prefs_changed(cmdr: str, is_beta: bool) -> None: + """Preferences changed hook.""" config.set('edsm_out', this.log.get()) if cmdr and not is_beta: @@ -291,6 +304,12 @@ def prefs_changed(cmdr: str, is_beta: bool) -> None: def credentials(cmdr: str) -> Optional[Tuple[str, str]]: + """ + Get credentials for the given commander, if they exist. + + :param cmdr: The commander to get credentials for + :return: The credentials, or None + """ # Credentials for cmdr if not cmdr: return None @@ -312,6 +331,7 @@ def credentials(cmdr: str) -> Optional[Tuple[str, str]]: def journal_entry( cmdr: str, is_beta: bool, system: str, station: str, entry: MutableMapping[str, Any], state: Mapping[str, Any] ) -> None: + """Journal Entry hook.""" if entry['event'] in ('CarrierJump', 'FSDJump', 'Location', 'Docked'): logger.debug(f'''{entry["event"]} Commander: {cmdr} @@ -419,6 +439,7 @@ Queueing: {entry!r}''' # Update system data def cmdr_data(data: Mapping[str, Any], is_beta: bool) -> None: + """CAPI Entry Hook.""" system = data['lastSystem']['name'] # Always store initially, even if we're not the *current* system provider. @@ -463,6 +484,11 @@ def cmdr_data(data: Mapping[str, Any], is_beta: bool) -> None: # Worker thread def worker() -> None: + """ + Upload worker. + + Works based the `this.queue` queue, loops infinitely until the item returned from the queue is None. + """ pending = [] # Unsent events closing = False @@ -555,8 +581,13 @@ def worker() -> None: return -# Whether any of the entries should be sent immediately def should_send(entries: List[Mapping[str, Any]]) -> bool: + """ + Whether or not any of the given entries should be sent immediately. + + :param entries: The entries to check + :return: bool indicating whether or not to send said entries + """ # batch up burst of Scan events after NavBeaconScan if this.navbeaconscan: if entries and entries[-1]['event'] == 'Scan': @@ -590,9 +621,8 @@ def should_send(entries: List[Mapping[str, Any]]) -> bool: return False -# Call edsm_notify_system() in this and other interested plugins with EDSM's response to a 'StartUp', 'Location', -# 'FSDJump' or 'CarrierJump' event def update_status(event=None) -> None: + """Update listening plugins with our response to StartUp, Location, FSDJump, or CarrierJump.""" for plugin in plug.provides('edsm_notify_system'): plug.invoke(plugin, None, 'edsm_notify_system', this.lastlookup) @@ -601,6 +631,7 @@ def update_status(event=None) -> None: # https://www.edsm.net/en/api-journal-v1 # msgnum: 1xx = OK, 2xx = fatal error, 3xx = error, 4xx = ignorable errors. def edsm_notify_system(reply: Mapping[str, Any]) -> None: + """Update the image next to the system link.""" if not reply: this.system_link['image'] = this._IMG_ERROR plug.show_error(_("Error: Can't connect to EDSM")) From 375573c0a8c24b37e7b0b57cbb608aa5a6aae159 Mon Sep 17 00:00:00 2001 From: A_D Date: Fri, 18 Sep 2020 23:17:36 +0200 Subject: [PATCH 18/22] fixed docstrings --- plugins/edsm.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/edsm.py b/plugins/edsm.py index e33a9885..8a2e09c4 100644 --- a/plugins/edsm.py +++ b/plugins/edsm.py @@ -487,7 +487,7 @@ def worker() -> None: """ Upload worker. - Works based the `this.queue` queue, loops infinitely until the item returned from the queue is None. + Processes `this.queue` until the queued item is None. """ pending = [] # Unsent events closing = False @@ -583,7 +583,7 @@ def worker() -> None: def should_send(entries: List[Mapping[str, Any]]) -> bool: """ - Whether or not any of the given entries should be sent immediately. + Whether or not any of the given entries should be sent to EDSM. :param entries: The entries to check :return: bool indicating whether or not to send said entries From 9710a5e9bbc7dd6b6d5f3a50b81f143c30604c30 Mon Sep 17 00:00:00 2001 From: A_D Date: Fri, 18 Sep 2020 23:18:10 +0200 Subject: [PATCH 19/22] repalced assert with log and continue --- plugins/edsm.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/plugins/edsm.py b/plugins/edsm.py index 8a2e09c4..d84696d1 100644 --- a/plugins/edsm.py +++ b/plugins/edsm.py @@ -518,7 +518,13 @@ def worker() -> None: r.raise_for_status() this.discardedEvents = set(r.json()) this.discardedEvents.discard('Docked') # should_send() assumes that we send 'Docked' events - assert this.discardedEvents # wouldn't expect this to be empty + if not this.discardedEvents: + logger.error( + 'Unexpected empty discarded events list from EDSM. Bailing out of send: ' + f'{type(this.discardedEvents)} -- {this.discardedEvents}' + ) + continue + # Filter out unwanted events pending = list(filter(lambda x: x['event'] not in this.discardedEvents, pending)) From e93091141521db4fd760210fa7066b08ff567f89 Mon Sep 17 00:00:00 2001 From: A_D Date: Fri, 18 Sep 2020 23:18:29 +0200 Subject: [PATCH 20/22] remove double assign --- plugins/edsm.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/edsm.py b/plugins/edsm.py index d84696d1..9c3137e9 100644 --- a/plugins/edsm.py +++ b/plugins/edsm.py @@ -552,7 +552,8 @@ def worker() -> None: r = this.session.post('https://www.edsm.net/api-journal-v1', data=data, timeout=_TIMEOUT) r.raise_for_status() reply = r.json() - (msg_num, msg) = reply['msgnum'], reply['msg'] + msg_num = reply['msgnum'] + msg = reply['msg'] # 1xx = OK # 2xx = fatal error # 3&4xx not generated at top-level From f8523e0a9f1e4b57c57fcc0cf540223eee01a966 Mon Sep 17 00:00:00 2001 From: A_D Date: Fri, 18 Sep 2020 23:19:44 +0200 Subject: [PATCH 21/22] removed parens around tuple unpack --- plugins/edsm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/edsm.py b/plugins/edsm.py index 9c3137e9..74127fa5 100644 --- a/plugins/edsm.py +++ b/plugins/edsm.py @@ -536,7 +536,7 @@ def worker() -> None: if creds is None: raise ValueError("Unexpected lack of credentials") - (username, apikey) = creds + username, apikey = creds data = { 'commanderName': username.encode('utf-8'), 'apiKey': apikey, From c02b292f50d9009ddbef0cc8117e2c190eece20d Mon Sep 17 00:00:00 2001 From: A_D Date: Tue, 22 Sep 2020 14:51:45 +0200 Subject: [PATCH 22/22] Removed uneeded list comps --- plugins/edsm.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/plugins/edsm.py b/plugins/edsm.py index 74127fa5..2bc42b4c 100644 --- a/plugins/edsm.py +++ b/plugins/edsm.py @@ -339,7 +339,7 @@ System: {system} Station: {station} state: {state!r} entry: {entry!r}''' - ) + ) # Always update our system address even if we're not currently the provider for system or station, but dont update # on events that contain "future" data, such as FSDTarget if entry['event'] in ('Location', 'Docked', 'CarrierJump', 'FSDJump'): @@ -529,7 +529,7 @@ def worker() -> None: pending = list(filter(lambda x: x['event'] not in this.discardedEvents, pending)) if should_send(pending): - if any([p for p in pending if p['event'] in ('CarrierJump', 'FSDJump', 'Location', 'Docked')]): + if any(p for p in pending if p['event'] in ('CarrierJump', 'FSDJump', 'Location', 'Docked')): logger.debug('CarrierJump (or FSDJump) in pending and it passed should_send()') creds = credentials(cmdr) # TODO: possibly unbound @@ -545,10 +545,11 @@ def worker() -> None: 'message': json.dumps(pending, ensure_ascii=False).encode('utf-8'), } - if any([p for p in pending if p['event'] in ('CarrierJump', 'FSDJump', 'Location', 'Docked')]): + if any(p for p in pending if p['event'] in ('CarrierJump', 'FSDJump', 'Location', 'Docked')): data_elided = data.copy() data_elided['apiKey'] = '' logger.debug(f'CarrierJump (or FSDJump): Attempting API call\ndata: {data_elided!r}') + r = this.session.post('https://www.edsm.net/api-journal-v1', data=data, timeout=_TIMEOUT) r.raise_for_status() reply = r.json()