From 93adfff746cc650d236903332abacb7dd96be59e Mon Sep 17 00:00:00 2001 From: Jonathan Harris Date: Wed, 23 Aug 2017 19:36:18 +0100 Subject: [PATCH] Use StationServices to determine whether to retry for shipyard data --- EDMC.py | 14 +++++++++++--- EDMarketConnector.py | 28 ++++++++++++++++------------ monitor.py | 8 +++++++- 3 files changed, 34 insertions(+), 16 deletions(-) diff --git a/EDMC.py b/EDMC.py index 79793787..6fc2c1d8 100755 --- a/EDMC.py +++ b/EDMC.py @@ -198,12 +198,20 @@ try: else: sys.stderr.write("Station doesn't supply outfitting\n") + if (args.s or args.n) and not args.j and not data['lastStarport'].get('ships') and monitor.stationservices and 'Shipyard' in monitor.stationservices: + # Retry for shipyard + sleep(SERVER_RETRY) + data2 = session.query() + if (data2['commander'].get('docked') and # might have undocked while we were waiting for retry in which case station data is unreliable + data2['lastSystem']['name'] == monitor.system and + data2['lastStarport']['name'] == monitor.station): + data = data2 + if args.s: - if not data['lastStarport'].get('ships') and not args.j: - sleep(SERVER_RETRY) - data = session.query() if data['lastStarport'].get('ships'): shipyard.export(data, args.s) + elif not args.j and monitor.stationservices and 'Shipyard' in monitor.stationservices: + sys.stderr.write("Failed to get shipyard data\n") else: sys.stderr.write("Station doesn't have a shipyard\n") diff --git a/EDMarketConnector.py b/EDMarketConnector.py index 23e2ef00..e5fcdd91 100755 --- a/EDMarketConnector.py +++ b/EDMarketConnector.py @@ -483,11 +483,7 @@ class AppWindow: pass elif not data['commander'].get('docked'): - if auto_update and not retrying: - # Silently retry if we got here by 'Automatically update on docking' and the server hasn't caught up - self.w.after(int(SERVER_RETRY * 1000), lambda:self.getandsend(event, True)) - return # early exit to avoid starting cooldown count - elif not self.status['text']: + if not self.status['text']: # Signal as error because the user might actually be docked but the server hosting the Companion API hasn't caught up self.status['text'] = _("You're not docked at a station!") play_bad = True @@ -522,11 +518,14 @@ class AppWindow: self.w.update_idletasks() self.eddn.export_commodities(data, monitor.is_beta) self.eddn.export_outfitting(data, monitor.is_beta) - if monitor.stationtype != 'Outpost' and not data['lastStarport'].get('ships'): - # API is flakey about shipyard info - silently retry if missing (<1s is usually sufficient - 5s for margin). - self.w.after(int(SERVER_RETRY * 1000), self.retry_for_shipyard) - else: + if data['lastStarport'].get('ships'): self.eddn.export_shipyard(data, monitor.is_beta) + elif monitor.stationservices is not None and 'Shipyard' in monitor.stationservices: + # API is flakey about shipyard info - silently retry if missing (<1s is usually sufficient - 5s for margin). + self.w.after(int(SERVER_RETRY * 1000), lambda:self.retry_for_shipyard(2)) + elif monitor.stationservices is None and monitor.stationtype != 'Outpost': + # Pre E:D 2.4 we don't know if we should have shipyard info. Retry once. + self.w.after(int(SERVER_RETRY * 1000), lambda:self.retry_for_shipyard(1)) if not old_status: self.status['text'] = '' @@ -536,7 +535,6 @@ class AppWindow: # Companion API problem except (companion.ServerError, companion.ServerLagging) as e: if retrying: - print 'Lagging: %s,%s != %s,%s' % (data['lastSystem']['name'], data['commander']['docked'] and data['lastStarport']['name'] or 'undocked', monitor.system, monitor.station) self.status['text'] = unicode(e) play_bad = True else: @@ -562,14 +560,20 @@ class AppWindow: self.holdofftime = querytime + companion.holdoff self.cooldown() - def retry_for_shipyard(self): + def retry_for_shipyard(self, tries): # Try again to get shipyard data and send to EDDN. Don't report errors if can't get or send the data. try: data = self.session.query() if __debug__: print 'Retry for shipyard - ' + (data['commander'].get('docked') and (data['lastStarport'].get('ships') and 'Success' or 'Failure') or 'Undocked!') - if data['commander'].get('docked'): # might have undocked while we were waiting for retry in which case station data is unreliable + if not data['commander'].get('docked'): + pass # might have undocked while we were waiting for retry in which case station data is unreliable + elif (data['lastStarport'].get('ships') and + data['lastSystem']['name'] == monitor.system and + data['lastStarport']['name'] == monitor.station): self.eddn.export_shipyard(data, monitor.is_beta) + elif tries > 1: # bogus data - retry + self.w.after(int(SERVER_RETRY * 1000), lambda:self.retry_for_shipyard(tries-1)) except: pass diff --git a/monitor.py b/monitor.py index 6ebad768..5d593062 100644 --- a/monitor.py +++ b/monitor.py @@ -202,7 +202,7 @@ class EDLogs(FileSystemEventHandler): if __debug__: print 'Stopping monitoring Journal' self.currentdir = None - self.version = self.mode = self.group = self.cmdr = self.planet = self.system = self.station = self.stationtype = self.coordinates = None + self.version = self.mode = self.group = self.cmdr = self.planet = self.system = self.station = self.stationtype = self.stationservices = self.coordinates = None self.is_beta = False if self.observed: self.observed = None @@ -311,6 +311,7 @@ class EDLogs(FileSystemEventHandler): self.system = None self.station = None self.stationtype = None + self.stationservices = None self.coordinates = None self.started = None self.state = { @@ -338,6 +339,7 @@ class EDLogs(FileSystemEventHandler): self.system = None self.station = None self.stationtype = None + self.stationservices = None self.coordinates = None self.started = timegm(strptime(entry['timestamp'], '%Y-%m-%dT%H:%M:%SZ')) self.state.update({ @@ -383,6 +385,7 @@ class EDLogs(FileSystemEventHandler): elif entry['event'] in ['Undocked']: self.station = None self.stationtype = None + self.stationservices = None elif entry['event'] in ['Location', 'FSDJump', 'Docked']: if entry['event'] == 'Location': self.planet = entry.get('Body') if entry.get('BodyType') == 'Planet' else None @@ -395,6 +398,7 @@ class EDLogs(FileSystemEventHandler): (self.system, self.station) = (entry['StarSystem'] == 'ProvingGround' and 'CQC' or entry['StarSystem'], entry.get('StationName')) # May be None self.stationtype = entry.get('StationType') # May be None + self.stationservices = entry.get('StationServices') # None under E:D < 2.4 elif entry['event'] == 'SupercruiseExit': self.planet = entry.get('Body') if entry.get('BodyType') == 'Planet' else None elif entry['event'] == 'SupercruiseEntry': @@ -467,6 +471,7 @@ class EDLogs(FileSystemEventHandler): self.system = None self.station = None self.stationtype = None + self.stationservices = None self.coordinates = None elif entry['event'] == 'ChangeCrewRole': self.state['Role'] = entry['Role'] @@ -477,6 +482,7 @@ class EDLogs(FileSystemEventHandler): self.system = None self.station = None self.stationtype = None + self.stationservices = None self.coordinates = None return entry