def getandsend(self, event=None, retrying=False): play_sound = event and event.type == '35' and not config.getint( 'hotkey_mute') if not retrying: if time( ) < self.holdofftime: # Was invoked by key while in cooldown self.status['text'] = '' if play_sound and (self.holdofftime - time()) < companion.holdoff * 0.75: hotkeymgr.play_bad( ) # Don't play sound in first few seconds to prevent repeats return elif play_sound: hotkeymgr.play_good() self.cmdr['text'] = self.system['text'] = self.station['text'] = '' self.system['image'] = '' self.status['text'] = _('Fetching data...') self.button['state'] = tk.DISABLED self.edit_menu.entryconfigure(_('Copy'), state=tk.DISABLED) self.w.update_idletasks() try: querytime = int(time()) data = self.session.query() config.set('querytime', querytime) # Validation if not data.get('commander') or not data['commander'].get( 'name', '').strip(): self.status['text'] = _("Who are you?!") # Shouldn't happen elif not data.get('lastSystem') or not data['lastSystem'].get( 'name', '').strip() or not data.get( 'lastStarport') or not data['lastStarport'].get( 'name', '').strip(): self.status['text'] = _("Where are you?!") # Shouldn't happen elif not data.get('ship') or not data['ship'].get( 'modules') or not data['ship'].get('name', '').strip(): self.status['text'] = _( "What are you flying?!") # Shouldn't happen else: if __debug__: # Recording with open( '%s%s.%s.json' % (data['lastSystem']['name'], data['commander'].get('docked') and '.' + data['lastStarport']['name'] or '', strftime('%Y-%m-%dT%H.%M.%S', localtime())), 'wt') as h: h.write( json.dumps(data, ensure_ascii=False, indent=2, sort_keys=True).encode('utf-8')) self.cmdr['text'] = data.get('commander') and data.get( 'commander').get('name') or '' self.system['text'] = data.get('lastSystem') and data.get( 'lastSystem').get('name') or '' self.station['text'] = data.get('commander') and data.get( 'commander').get('docked') and data.get( 'lastStarport') and data.get('lastStarport').get( 'name') or (EDDB.system(self.system['text']) and self.STATION_UNDOCKED or '') self.status['text'] = '' self.edit_menu.entryconfigure(_('Copy'), state=tk.NORMAL) self.view_menu.entryconfigure(_('Status'), state=tk.NORMAL) # stuff we can do when not docked if config.getint('output') & config.OUT_SHIP_EDS: loadout.export(data) if config.getint('output') & config.OUT_SHIP_CORIOLIS: coriolis.export(data) if config.getint('output') & config.OUT_LOG_FILE: flightlog.export(data) if config.getint('output') & config.OUT_LOG_EDSM: # Catch any EDSM errors here so that they don't prevent station update try: self.status['text'] = _('Sending data to EDSM...') self.w.update_idletasks() edsm.export(data, lambda: self.edsm.lookup( self.system['text'], EDDB.system(self.system['text'])) ) # Do EDSM lookup during EDSM export self.status['text'] = '' except Exception as e: if __debug__: print_exc() self.status['text'] = unicode(e) else: self.edsm.link(self.system['text']) self.edsmpoll() if not (config.getint('output') & (config.OUT_CSV | config.OUT_TD | config.OUT_BPC | config.OUT_EDDN)): # no station data requested - we're done pass elif not data['commander'].get('docked'): # signal as error because the user might actually be docked but the server hosting the Companion API hasn't caught up if not self.status['text']: self.status['text'] = _( "You're not docked at a station!") else: # Finally - the data looks sane and we're docked at a station (station_id, has_market, has_outfitting, has_shipyard) = EDDB.station(self.system['text'], self.station['text']) # No EDDN output at known station? if (config.getint('output') & config.OUT_EDDN) and station_id and not ( has_market or has_outfitting or has_shipyard): if not self.status['text']: self.status['text'] = _( "Station doesn't have anything!") # No EDDN output at unknown station? elif ( config.getint('output') & config.OUT_EDDN ) and not station_id and not ( data['lastStarport'].get('commodities') or data['lastStarport'].get('modules') ): # Ignore usually spurious shipyard at unknown stations if not self.status['text']: self.status['text'] = _( "Station doesn't have anything!") # No market output at known station? elif not (config.getint('output') & config.OUT_EDDN ) and station_id and not has_market: if not self.status['text']: self.status['text'] = _( "Station doesn't have a market!") # No market output at unknown station? elif not (config.getint('output') & config.OUT_EDDN) and not station_id and not data[ 'lastStarport'].get('commodities'): if not self.status['text']: self.status['text'] = _( "Station doesn't have a market!") else: if data['lastStarport'].get('commodities'): # Fixup anomalies in the commodity data self.session.fixup( data['lastStarport']['commodities']) if config.getint('output') & config.OUT_CSV: bpc.export(data, True) if config.getint('output') & config.OUT_TD: td.export(data) if config.getint('output') & config.OUT_BPC: bpc.export(data, False) elif has_market and ( config.getint('output') & (config.OUT_CSV | config.OUT_TD | config.OUT_BPC | config.OUT_EDDN)): # Overwrite any previous error message self.status['text'] = _( "Error: Can't get market data!") if config.getint('output') & config.OUT_EDDN: old_status = self.status['text'] if not old_status: self.status['text'] = _( 'Sending data to EDDN...') self.w.update_idletasks() eddn.export_commodities(data) if has_outfitting or not station_id: # Only send if eddb says that the station provides outfitting, or unknown station eddn.export_outfitting(data) elif __debug__ and data['lastStarport'].get( 'modules'): print 'Spurious outfitting!' if has_shipyard: # Only send if eddb says that the station has a shipyard - # https://github.com/Marginal/EDMarketConnector/issues/16 if data['lastStarport'].get('ships'): eddn.export_shipyard(data) else: # 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) elif __debug__ and data['lastStarport'].get( 'ships'): print 'Spurious shipyard!' if not old_status: self.status['text'] = '' except companion.VerificationRequired: return prefs.AuthenticationDialog(self.w, self.verify) # Companion API problem except companion.ServerError as e: if retrying: self.status['text'] = unicode(e) else: # Retry once if Companion server is unresponsive self.w.after(int(SERVER_RETRY * 1000), lambda: self.getandsend(event, True)) return # early exit to avoid starting cooldown count except requests.exceptions.ConnectionError as e: if __debug__: print_exc() self.status['text'] = _("Error: Can't connect to EDDN") except requests.exceptions.Timeout as e: if __debug__: print_exc() self.status['text'] = _("Error: Connection to EDDN timed out") except Exception as e: if __debug__: print_exc() self.status['text'] = unicode(e) if not self.status['text']: # no errors self.status['text'] = strftime( _('Last updated at {HH}:{MM}:{SS}').format( HH='%H', MM='%M', SS='%S').encode('utf-8'), localtime(querytime)).decode('utf-8') elif play_sound: hotkeymgr.play_bad() self.holdofftime = querytime + companion.holdoff self.cooldown()
if not data.get('commander') or not data['commander'].get('name','').strip(): sys.stderr.write('Who are you?!\n') sys.exit(EXIT_SERVER) elif not data.get('lastSystem') or not data['lastSystem'].get('name','').strip() or not data.get('lastStarport') or not data['lastStarport'].get('name','').strip(): sys.stderr.write('Where are you?!\n') # Shouldn't happen sys.exit(EXIT_SERVER) elif not data.get('ship') or not data['ship'].get('modules') or not data['ship'].get('name','').strip(): sys.stderr.write('What are you flying?!\n') # Shouldn't happen sys.exit(EXIT_SERVER) # stuff we can do when not docked if args.d: with open(args.d, 'wt') as h: h.write(json.dumps(data, ensure_ascii=False, indent=2, sort_keys=True, separators=(',', ': ')).encode('utf-8')) if args.a: loadout.export(data, args.a) if args.c: coriolis.export(data, args.c) if args.e: edshipyard.export(data, args.e) if args.l: stats.export_ships(data, args.l) if args.t: stats.export_status(data, args.t) if not data['commander'].get('docked'): print data['lastSystem']['name'] if (args.m or args.o or args.s): sys.stderr.write("You're not docked at a station!\n") sys.exit(EXIT_NOT_DOCKED) else:
def getandsend(self, event=None, retrying=False): auto_update = not event play_sound = (auto_update or int(event.type) == self.EVENT_VIRTUAL ) and not config.getint('hotkey_mute') if (monitor.cmdr and not monitor.mode) or monitor.is_beta: return # In CQC - do nothing if not retrying: if time( ) < self.holdofftime: # Was invoked by key while in cooldown self.status['text'] = '' if play_sound and (self.holdofftime - time()) < companion.holdoff * 0.75: hotkeymgr.play_bad( ) # Don't play sound in first few seconds to prevent repeats return elif play_sound: hotkeymgr.play_good() self.status['text'] = _('Fetching data...') self.button['state'] = self.theme_button['state'] = tk.DISABLED self.edit_menu.entryconfigure(0, state=tk.DISABLED) # Copy self.w.update_idletasks() try: querytime = int(time()) data = self.session.query() config.set('querytime', querytime) # Validation if not data.get('commander') or not data['commander'].get( 'name', '').strip(): self.status['text'] = _("Who are you?!") # Shouldn't happen elif not data.get('lastSystem') or not data['lastSystem'].get( 'name', '').strip() or not data.get( 'lastStarport') or not data['lastStarport'].get( 'name', '').strip(): self.status['text'] = _("Where are you?!") # Shouldn't happen elif not data.get('ship') or not data['ship'].get( 'modules') or not data['ship'].get('name', '').strip(): self.status['text'] = _( "What are you flying?!") # Shouldn't happen elif monitor.cmdr and data['commander']['name'] != monitor.cmdr: raise companion.CredentialsError( ) # Companion API credentials don't match Journal elif (auto_update and not data['commander'].get('docked')) or ( monitor.system and data['lastSystem']['name'] != monitor.system ) or (monitor.shipid and data['ship']['id'] != monitor.shipid) or ( monitor.shiptype and data['ship']['name'].lower() != monitor.shiptype): raise companion.ServerLagging() else: if __debug__: # Recording if not isdir('dump'): mkdir('dump') with open( 'dump/%s%s.%s.json' % (data['lastSystem']['name'], data['commander'].get('docked') and '.' + data['lastStarport']['name'] or '', strftime('%Y-%m-%dT%H.%M.%S', localtime())), 'wt') as h: h.write( json.dumps(data, ensure_ascii=False, indent=2, sort_keys=True, separators=(',', ': ')).encode('utf-8')) self.cmdr['text'] = data['commander']['name'] self.ship['text'] = companion.ship_map.get( data['ship']['name'].lower(), data['ship']['name']) if not monitor.system: self.system['text'] = data['lastSystem']['name'] self.system['image'] = '' self.station['text'] = data['commander'].get( 'docked') and data.get('lastStarport') and data[ 'lastStarport'].get('name') or (EDDB.system( self.system['text']) and self.STATION_UNDOCKED or '') self.status['text'] = '' self.edit_menu.entryconfigure(0, state=tk.NORMAL) # Copy # stuff we can do when not docked plug.notify_newdata(data) if config.getint('output') & config.OUT_SHIP_EDS: loadout.export(data) if config.getint('output') & config.OUT_SHIP_CORIOLIS: coriolis.export(data) if not (config.getint('output') & (config.OUT_MKT_CSV | config.OUT_MKT_TD | config.OUT_MKT_BPC | config.OUT_MKT_EDDN)): # no station data requested - we're done pass elif not data['commander'].get('docked'): if not event 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 else: # Signal as error because the user might actually be docked but the server hosting the Companion API hasn't caught up if not self.status['text']: self.status['text'] = _( "You're not docked at a station!") else: # Finally - the data looks sane and we're docked at a station (station_id, has_market, has_outfitting, has_shipyard) = EDDB.station(self.system['text'], self.station['text']) # No EDDN output? if (config.getint('output') & config.OUT_MKT_EDDN ) and not (data['lastStarport'].get('commodities') or data['lastStarport'].get('modules') ): # Ignore possibly missing shipyard info if not self.status['text']: self.status['text'] = _( "Station doesn't have anything!") # No market output? elif not ( config.getint('output') & config.OUT_MKT_EDDN ) and not data['lastStarport'].get('commodities'): if not self.status['text']: self.status['text'] = _( "Station doesn't have a market!") else: if data['lastStarport'].get( 'commodities') and config.getint('output') & ( config.OUT_MKT_CSV | config.OUT_MKT_TD | config.OUT_MKT_BPC): # Fixup anomalies in the commodity data fixed = companion.fixup(data) if config.getint('output') & config.OUT_MKT_CSV: commodity.export(fixed, COMMODITY_CSV) if config.getint('output') & config.OUT_MKT_TD: td.export(fixed) if config.getint('output') & config.OUT_MKT_BPC: commodity.export(fixed, COMMODITY_BPC) if config.getint('output') & config.OUT_MKT_EDDN: old_status = self.status['text'] if not old_status: self.status['text'] = _( 'Sending data to EDDN...') self.w.update_idletasks() eddn.export_commodities(data) eddn.export_outfitting(data) if has_shipyard 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: eddn.export_shipyard(data) if not old_status: self.status['text'] = '' # Update credits and ship info and send to EDSM if config.getint( 'output' ) & config.OUT_SYS_EDSM and not monitor.is_beta: try: if data['commander'].get('credits') is not None: monitor.credits = ( data['commander']['credits'], data['commander'].get('debt', 0)) self.edsm.setcredits(monitor.credits) ship = companion.ship(data) if ship == self.edsm.lastship: props = [] else: props = [ ('cargoCapacity', ship['cargo']['capacity']), ('fuelMainCapacity', ship['fuel']['main']['capacity']), ('linkToCoriolis', coriolis.url(data)), ('linkToEDShipyard', edshipyard.url(data)), ] if monitor.shippaint is None: # Companion API server can lag, so prefer Journal. But paintjob only reported in Journal on change. monitor.shipid = data['ship']['id'] monitor.shiptype = data['ship']['name'].lower() monitor.shippaint = data['ship']['modules'][ 'PaintJob'] and data['ship']['modules'][ 'PaintJob']['module']['name'].lower( ) or '' props.append(('paintJob', monitor.shippaint)) if props: self.edsm.updateship(monitor.shipid, monitor.shiptype, props) self.edsm.lastship = ship except Exception as e: # Not particularly important so silent on failure if __debug__: print_exc() except companion.VerificationRequired: return prefs.AuthenticationDialog( self.w, partial(self.verify, self.getandsend)) # Companion API problem except (companion.ServerError, companion.ServerLagging) as e: if retrying: self.status['text'] = unicode(e) else: # Retry once if Companion server is unresponsive self.w.after(int(SERVER_RETRY * 1000), lambda: self.getandsend(event, True)) return # early exit to avoid starting cooldown count except requests.RequestException as e: if __debug__: print_exc() self.status['text'] = _("Error: Can't connect to EDDN") except Exception as e: if __debug__: print_exc() self.status['text'] = unicode(e) if not self.status['text']: # no errors self.status['text'] = strftime( _('Last updated at {HH}:{MM}:{SS}').format( HH='%H', MM='%M', SS='%S').encode('utf-8'), localtime(querytime)).decode('utf-8') elif play_sound: hotkeymgr.play_bad() self.holdofftime = querytime + companion.holdoff self.cooldown()
def getandsend(self, event=None, retrying=False): play_sound = event and event.type=='35' and not config.getint('hotkey_mute') if not retrying: if time() < self.holdofftime: # Was invoked by key while in cooldown self.status['text'] = '' if play_sound and (self.holdofftime-time()) < companion.holdoff*0.75: hotkeymgr.play_bad() # Don't play sound in first few seconds to prevent repeats return elif play_sound: hotkeymgr.play_good() self.cmdr['text'] = self.system['text'] = self.station['text'] = '' self.system['image'] = '' self.status['text'] = _('Fetching data...') self.button['state'] = tk.DISABLED self.edit_menu.entryconfigure(_('Copy'), state=tk.DISABLED) self.w.update_idletasks() try: querytime = int(time()) data = self.session.query() config.set('querytime', querytime) # Validation if not data.get('commander') or not data['commander'].get('name','').strip(): self.status['text'] = _("Who are you?!") # Shouldn't happen elif not data.get('lastSystem') or not data['lastSystem'].get('name','').strip() or not data.get('lastStarport') or not data['lastStarport'].get('name','').strip(): self.status['text'] = _("Where are you?!") # Shouldn't happen elif not data.get('ship') or not data['ship'].get('modules') or not data['ship'].get('name','').strip(): self.status['text'] = _("What are you flying?!") # Shouldn't happen else: if __debug__: # Recording with open('%s%s.%s.json' % (data['lastSystem']['name'], data['commander'].get('docked') and '.'+data['lastStarport']['name'] or '', strftime('%Y-%m-%dT%H.%M.%S', localtime())), 'wt') as h: h.write(json.dumps(data, ensure_ascii=False, indent=2, sort_keys=True).encode('utf-8')) self.cmdr['text'] = data.get('commander') and data.get('commander').get('name') or '' self.system['text'] = data.get('lastSystem') and data.get('lastSystem').get('name') or '' self.station['text'] = data.get('commander') and data.get('commander').get('docked') and data.get('lastStarport') and data.get('lastStarport').get('name') or (EDDB.system(self.system['text']) and self.STATION_UNDOCKED or '') self.status['text'] = '' self.edit_menu.entryconfigure(_('Copy'), state=tk.NORMAL) self.view_menu.entryconfigure(_('Status'), state=tk.NORMAL) # stuff we can do when not docked if config.getint('output') & config.OUT_SHIP_EDS: loadout.export(data) if config.getint('output') & config.OUT_SHIP_CORIOLIS: coriolis.export(data) if config.getint('output') & config.OUT_LOG_FILE: flightlog.export(data) if config.getint('output') & config.OUT_LOG_EDSM: # Catch any EDSM errors here so that they don't prevent station update try: self.status['text'] = _('Sending data to EDSM...') self.w.update_idletasks() edsm.export(data, lambda:self.edsm.lookup(self.system['text'], EDDB.system(self.system['text']))) # Do EDSM lookup during EDSM export self.status['text'] = '' except Exception as e: if __debug__: print_exc() self.status['text'] = unicode(e) else: self.edsm.link(self.system['text']) self.edsmpoll() if not (config.getint('output') & (config.OUT_CSV|config.OUT_TD|config.OUT_BPC|config.OUT_EDDN)): # no station data requested - we're done pass elif not data['commander'].get('docked'): # signal as error because the user might actually be docked but the server hosting the Companion API hasn't caught up if not self.status['text']: self.status['text'] = _("You're not docked at a station!") else: # Finally - the data looks sane and we're docked at a station (station_id, has_market, has_outfitting, has_shipyard) = EDDB.station(self.system['text'], self.station['text']) # No EDDN output at known station? if (config.getint('output') & config.OUT_EDDN) and station_id and not (has_market or has_outfitting or has_shipyard): if not self.status['text']: self.status['text'] = _("Station doesn't have anything!") # No EDDN output at unknown station? elif (config.getint('output') & config.OUT_EDDN) and not station_id and not (data['lastStarport'].get('commodities') or data['lastStarport'].get('modules')): # Ignore usually spurious shipyard at unknown stations if not self.status['text']: self.status['text'] = _("Station doesn't have anything!") # No market output at known station? elif not (config.getint('output') & config.OUT_EDDN) and station_id and not has_market: if not self.status['text']: self.status['text'] = _("Station doesn't have a market!") # No market output at unknown station? elif not (config.getint('output') & config.OUT_EDDN) and not station_id and not data['lastStarport'].get('commodities'): if not self.status['text']: self.status['text'] = _("Station doesn't have a market!") else: if data['lastStarport'].get('commodities'): # Fixup anomalies in the commodity data self.session.fixup(data['lastStarport']['commodities']) if config.getint('output') & config.OUT_CSV: bpc.export(data, True) if config.getint('output') & config.OUT_TD: td.export(data) if config.getint('output') & config.OUT_BPC: bpc.export(data, False) elif has_market and (config.getint('output') & (config.OUT_CSV|config.OUT_TD|config.OUT_BPC|config.OUT_EDDN)): # Overwrite any previous error message self.status['text'] = _("Error: Can't get market data!") if config.getint('output') & config.OUT_EDDN: old_status = self.status['text'] if not old_status: self.status['text'] = _('Sending data to EDDN...') self.w.update_idletasks() eddn.export_commodities(data) if has_outfitting or not station_id: # Only send if eddb says that the station provides outfitting, or unknown station eddn.export_outfitting(data) elif __debug__ and data['lastStarport'].get('modules'): print 'Spurious outfitting!' if has_shipyard: # Only send if eddb says that the station has a shipyard - # https://github.com/Marginal/EDMarketConnector/issues/16 if data['lastStarport'].get('ships'): eddn.export_shipyard(data) else: # 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) elif __debug__ and data['lastStarport'].get('ships'): print 'Spurious shipyard!' if not old_status: self.status['text'] = '' except companion.VerificationRequired: return prefs.AuthenticationDialog(self.w, self.verify) # Companion API problem except companion.ServerError as e: if retrying: self.status['text'] = unicode(e) else: # Retry once if Companion server is unresponsive self.w.after(int(SERVER_RETRY * 1000), lambda:self.getandsend(event, True)) return # early exit to avoid starting cooldown count except requests.exceptions.ConnectionError as e: if __debug__: print_exc() self.status['text'] = _("Error: Can't connect to EDDN") except requests.exceptions.Timeout as e: if __debug__: print_exc() self.status['text'] = _("Error: Connection to EDDN timed out") except Exception as e: if __debug__: print_exc() self.status['text'] = unicode(e) if not self.status['text']: # no errors self.status['text'] = strftime(_('Last updated at {HH}:{MM}:{SS}').format(HH='%H', MM='%M', SS='%S').encode('utf-8'), localtime(querytime)).decode('utf-8') elif play_sound: hotkeymgr.play_bad() self.holdofftime = querytime + companion.holdoff self.cooldown()
def getandsend(self, event=None, retrying=False): if not retrying: if time() < self.holdofftime: return # Was invoked by Return key while in cooldown self.cmdr['text'] = self.system['text'] = self.station['text'] = '' self.status['text'] = 'Fetching station data...' self.button['state'] = tk.DISABLED self.w.update_idletasks() try: querytime = int(time()) data = self.session.query() self.cmdr['text'] = data.get('commander') and data.get('commander').get('name') or '' self.system['text'] = data.get('lastSystem') and data.get('lastSystem').get('name') or '' self.station['text'] = data.get('commander') and data.get('commander').get('docked') and data.get('lastStarport') and data.get('lastStarport').get('name') or '-' config.set('querytime', querytime) self.holdofftime = querytime + companion.holdoff # Validation if not data.get('commander') or not data['commander'].get('name','').strip(): self.status['text'] = "Who are you?!" # Shouldn't happen elif not data.get('lastSystem') or not data['lastSystem'].get('name','').strip() or not data.get('lastStarport') or not data['lastStarport'].get('name','').strip(): self.status['text'] = "Where are you?!" # Shouldn't happen elif not data.get('ship') or not data['ship'].get('modules') or not data['ship'].get('name','').strip(): self.status['text'] = "What are you flying?!" # Shouldn't happen elif (config.getint('output') & config.OUT_EDDN) and not data['lastStarport'].get('ships') and not retrying: # API is flakey about shipyard info - retry if missing (<1s is usually sufficient - 2.5s for margin). self.w.after(2500, lambda:self.getandsend(retrying=True)) return else: if __debug__ and retrying: print data['lastStarport'].get('ships') and 'Retry for shipyard - Success' or 'Retry for shipyard - Fail' # stuff we can do when not docked if __debug__: # Recording with open('%s%s.%s.json' % (data['lastSystem']['name'], data['commander'].get('docked') and '.'+data['lastStarport']['name'] or '', strftime('%Y-%m-%dT%H.%M.%S', localtime())), 'wt') as h: h.write(json.dumps(data, indent=2, sort_keys=True)) if config.getint('output') & config.OUT_LOG: flightlog.export(data) if config.getint('output') & config.OUT_SHIP: loadout.export(data) if not (config.getint('output') & (config.OUT_CSV|config.OUT_TD|config.OUT_BPC|config.OUT_EDDN)): # no further output requested self.status['text'] = strftime('Last updated at %H:%M:%S', localtime(querytime)) elif not data['commander'].get('docked'): self.status['text'] = "You're not docked at a station!" else: if data['lastStarport'].get('commodities'): # Fixup anomalies in the commodity data self.session.fixup(data['lastStarport']['commodities']) if config.getint('output') & config.OUT_CSV: bpc.export(data, True) if config.getint('output') & config.OUT_TD: td.export(data) if config.getint('output') & config.OUT_BPC: bpc.export(data, False) if config.getint('output') & config.OUT_EDDN: if data['lastStarport'].get('commodities') or data['lastStarport'].get('modules') or data['lastStarport'].get('ships'): self.status['text'] = 'Sending data to EDDN...' self.w.update_idletasks() eddn.export(data) self.status['text'] = strftime('Last updated at %H:%M:%S', localtime(querytime)) else: self.status['text'] = "Station doesn't have anything!" elif not data['lastStarport'].get('commodities'): self.status['text'] = "Station doesn't have a market!" else: self.status['text'] = strftime('Last updated at %H:%M:%S', localtime(querytime)) except companion.VerificationRequired: return prefs.AuthenticationDialog(self.w, self.verify) # Companion API problem except companion.ServerError as e: self.status['text'] = str(e) except requests.exceptions.ConnectionError as e: if __debug__: print_exc() self.status['text'] = "Error: Can't connect to EDDN" except requests.exceptions.Timeout as e: if __debug__: print_exc() self.status['text'] = "Error: Connection to EDDN timed out" except Exception as e: if __debug__: print_exc() self.status['text'] = str(e) self.cooldown()
def getandsend(self, event=None): if time() < self.holdofftime: return # Was invoked by Return key while in cooldown self.cmdr['text'] = self.system['text'] = self.station['text'] = '' self.status['text'] = 'Fetching market data...' self.button['state'] = tk.DISABLED self.w.update_idletasks() try: querytime = int(time()) data = self.session.query() self.cmdr['text'] = data.get('commander') and data.get('commander').get('name') or '' self.system['text'] = data.get('lastSystem') and data.get('lastSystem').get('name') or '' self.station['text'] = data.get('commander') and data.get('commander').get('docked') and data.get('lastStarport') and data.get('lastStarport').get('name') or '-' config.set('querytime', querytime) self.holdofftime = querytime + companion.holdoff # Validation if not data.get('commander') or not data['commander'].get('name','').strip(): self.status['text'] = "Who are you?!" # Shouldn't happen elif not data.get('lastSystem') or not data['lastSystem'].get('name','').strip() or not data.get('lastStarport') or not data['lastStarport'].get('name','').strip(): self.status['text'] = "Where are you?!" # Shouldn't happen elif not data.get('ship') or not data['ship'].get('modules') or not data['ship'].get('name','').strip(): self.status['text'] = "What are you flying?!" # Shouldn't happen else: # stuff we can do when not docked if config.getint('output') & config.OUT_LOG: flightlog.export(data) if config.getint('output') & config.OUT_SHIP: loadout.export(data) if not (config.getint('output') & (config.OUT_CSV|config.OUT_TD|config.OUT_BPC|config.OUT_EDDN)): # no further output requested self.status['text'] = strftime('Last updated at %H:%M:%S', localtime(querytime)) elif not data['commander'].get('docked'): self.status['text'] = "You're not docked at a station!" elif not data['lastStarport'].get('commodities'): self.status['text'] = "Station doesn't have a market!" else: if config.getint('output') & config.OUT_CSV: bpc.export(data, True) if config.getint('output') & config.OUT_TD: td.export(data) if config.getint('output') & config.OUT_BPC: bpc.export(data, False) if config.getint('output') & config.OUT_EDDN: self.status['text'] = 'Sending data to EDDN...' self.w.update_idletasks() eddn.export(data) self.status['text'] = strftime('Last updated at %H:%M:%S', localtime(querytime)) except companion.VerificationRequired: return prefs.AuthenticationDialog(self.w, self.verify) except companion.ServerError as e: self.status['text'] = str(e) except Exception as e: if __debug__: print_exc() self.status['text'] = str(e) self.cooldown()
def send(self, event=None): data = self.data try: if True: # validation now done in get part # stuff we can do when not docked if config.getint('output') & config.OUT_SHIP_EDS: loadout.export(data) if config.getint('output') & config.OUT_SHIP_CORIOLIS: coriolis.export(data) if config.getint('output') & config.OUT_LOG_FILE: flightlog.export(data) if config.getint('output') & config.OUT_LOG_EDSM: # Catch any EDSM errors here so that they don't prevent station update try: self.status['text'] = _('Sending data to EDSM...') self.w.update_idletasks() edsm.export(data, lambda: self.edsm.lookup( self.system['text'], EDDB.system(self.system['text'])) ) # Do EDSM lookup during EDSM export self.status['text'] = '' except Exception as e: if __debug__: print_exc() self.status['text'] = unicode(e) else: self.edsm.link(self.system['text']) self.edsmpoll() if not (config.getint('output') & (config.OUT_CSV | config.OUT_TD | config.OUT_BPC | config.OUT_EDDN)): # no station data requested - we're done pass elif not data['commander'].get('docked'): # signal as error because the user might actually be docked but the server hosting the Companion API hasn't caught up if not self.status['text']: self.status['text'] = _( "You're not docked at a station!") else: # Finally - the data looks sane and we're docked at a station (station_id, has_market, has_outfitting, has_shipyard) = EDDB.station(self.system['text'], self.station['text']) # No EDDN output at known station? if ( config.getint('output') & config.OUT_EDDN ) and station_id and not has_market and not has_outfitting and not has_shipyard: if not self.status['text']: self.status['text'] = _( "Station doesn't have anything!") # No EDDN output at unknown station? elif ( config.getint('output') & config.OUT_EDDN ) and not station_id and not data['lastStarport'].get( 'commodities') and not data['lastStarport'].get( 'modules') and not data['lastStarport'].get( 'ships'): if not self.status['text']: self.status['text'] = _( "Station doesn't have anything!") # No market output at known station? elif not (config.getint('output') & config.OUT_EDDN ) and station_id and not has_market: if not self.status['text']: self.status['text'] = _( "Station doesn't have a market!") # No market output at unknown station? elif not (config.getint('output') & config.OUT_EDDN) and not station_id and not data[ 'lastStarport'].get('commodities'): if not self.status['text']: self.status['text'] = _( "Station doesn't have a market!") else: if data['lastStarport'].get('commodities'): # Fixup anomalies in the commodity data self.session.fixup( data['lastStarport']['commodities']) if config.getint('output') & config.OUT_CSV: bpc.export(data, True) if config.getint('output') & config.OUT_TD: td.export(data) if config.getint('output') & config.OUT_BPC: bpc.export(data, False) elif has_market and ( config.getint('output') & (config.OUT_CSV | config.OUT_TD | config.OUT_BPC | config.OUT_EDDN)): # Overwrite any previous error message self.status['text'] = _( "Error: Can't get market data!") if config.getint('output') & config.OUT_EDDN: old_status = self.status['text'] if not old_status: self.status['text'] = _( 'Sending data to EDDN...') self.w.update_idletasks() eddn.export_commodities(data) if has_outfitting or not station_id: # Only send if eddb says that the station provides outfitting eddn.export_outfitting(data) elif __debug__ and data['lastStarport'].get( 'modules'): print 'Spurious outfitting!' if has_shipyard or not station_id: # Only send if eddb says that the station has a shipyard - # https://github.com/Marginal/EDMarketConnector/issues/16 if data['lastStarport'].get('ships'): eddn.export_shipyard(data) else: # 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) elif __debug__ and data['lastStarport'].get( 'ships'): print 'Spurious shipyard!' if not old_status: self.status['text'] = '' except requests.exceptions.ConnectionError as e: if __debug__: print_exc() self.status['text'] = _("Error: Can't connect to EDDN") except requests.exceptions.Timeout as e: if __debug__: print_exc() self.status['text'] = _("Error: Connection to EDDN timed out") except Exception as e: if __debug__: print_exc() self.status['text'] = unicode(e) if not self.status['text']: # no errors self.status['text'] = strftime( _('Last updated at {HH}:{MM}:{SS}').format( HH='%H', MM='%M', SS='%S').encode('utf-8'), localtime(self.querytime)).decode('utf-8') elif play_sound: hotkeymgr.play_bad() self.holdofftime = self.querytime + companion.holdoff self.cooldown()
def getandsend(self, event=None, retrying=False): auto_update = not event play_sound = (auto_update or int(event.type) == self.EVENT_VIRTUAL) and not config.getint('hotkey_mute') play_bad = False if not monitor.cmdr or not monitor.mode or monitor.state['Captain'] or not monitor.system: return # In CQC or on crew - do nothing if not retrying: if time() < self.holdofftime: # Was invoked by key while in cooldown self.status['text'] = '' if play_sound and (self.holdofftime-time()) < companion.holdoff*0.75: hotkeymgr.play_bad() # Don't play sound in first few seconds to prevent repeats return elif play_sound: hotkeymgr.play_good() self.status['text'] = _('Fetching data...') self.button['state'] = self.theme_button['state'] = tk.DISABLED self.w.update_idletasks() try: querytime = int(time()) data = self.session.station() config.set('querytime', querytime) # Validation if not data.get('commander', {}).get('name'): self.status['text'] = _("Who are you?!") # Shouldn't happen elif (not data.get('lastSystem', {}).get('name') or (data['commander'].get('docked') and not data.get('lastStarport', {}).get('name'))): # Only care if docked self.status['text'] = _("Where are you?!") # Shouldn't happen elif not data.get('ship', {}).get('name') or not data.get('ship', {}).get('modules'): self.status['text'] = _("What are you flying?!") # Shouldn't happen elif monitor.cmdr and data['commander']['name'] != monitor.cmdr: raise companion.CmdrError() # Companion API return doesn't match Journal elif ((auto_update and not data['commander'].get('docked')) or (data['lastSystem']['name'] != monitor.system) or ((data['commander']['docked'] and data['lastStarport']['name'] or None) != monitor.station) or (data['ship']['id'] != monitor.state['ShipID']) or (data['ship']['name'].lower() != monitor.state['ShipType'])): raise companion.ServerLagging() else: if __debug__: # Recording if isdir('dump'): with open('dump/%s%s.%s.json' % (data['lastSystem']['name'], data['commander'].get('docked') and '.'+data['lastStarport']['name'] or '', strftime('%Y-%m-%dT%H.%M.%S', localtime())), 'wt') as h: h.write(json.dumps(data, ensure_ascii=False, indent=2, sort_keys=True, separators=(',', ': ')).encode('utf-8')) if not monitor.state['ShipType']: # Started game in SRV or fighter self.ship['text'] = companion.ship_map.get(data['ship']['name'].lower(), data['ship']['name']) monitor.state['ShipID'] = data['ship']['id'] monitor.state['ShipType'] = data['ship']['name'].lower() if data['commander'].get('credits') is not None: monitor.state['Credits'] = data['commander']['credits'] monitor.state['Loan'] = data['commander'].get('debt', 0) # stuff we can do when not docked err = plug.notify_newdata(data, monitor.is_beta) self.status['text'] = err and err or '' if err: play_bad = True if config.getint('output') & config.OUT_SHIP: loadout.export(data) if not (config.getint('output') & ~config.OUT_SHIP & config.OUT_STATION_ANY): # no station data requested - we're done pass elif not data['commander'].get('docked'): 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 else: # Finally - the data looks sane and we're docked at a station # No EDDN output? if (config.getint('output') & config.OUT_MKT_EDDN) and not (data['lastStarport'].get('commodities') or data['lastStarport'].get('modules')): # Ignore possibly missing shipyard info if not self.status['text']: self.status['text'] = _("Station doesn't have anything!") # No market output? elif not (config.getint('output') & config.OUT_MKT_EDDN) and not data['lastStarport'].get('commodities'): if not self.status['text']: self.status['text'] = _("Station doesn't have a market!") else: if data['lastStarport'].get('commodities') and config.getint('output') & (config.OUT_MKT_CSV|config.OUT_MKT_TD): # Fixup anomalies in the commodity data fixed = companion.fixup(data) if config.getint('output') & config.OUT_MKT_CSV: commodity.export(fixed, COMMODITY_CSV) if config.getint('output') & config.OUT_MKT_TD: td.export(fixed) if config.getint('output') & config.OUT_MKT_EDDN: old_status = self.status['text'] if not old_status: self.status['text'] = _('Sending data to EDDN...') self.w.update_idletasks() self.eddn.export_commodities(data, monitor.is_beta) self.eddn.export_outfitting(data, monitor.is_beta) if data['lastStarport'].get('ships'): self.eddn.export_shipyard(data, monitor.is_beta) elif data['lastStarport'].get('services', {}).get('shipyard'): # 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)) if not old_status: self.status['text'] = '' except companion.VerificationRequired: return prefs.AuthenticationDialog(self.w, partial(self.verify, self.getandsend)) # Companion API problem except (companion.ServerError, companion.ServerLagging) as e: if retrying: self.status['text'] = unicode(e) play_bad = True else: # Retry once if Companion server is unresponsive self.w.after(int(SERVER_RETRY * 1000), lambda:self.getandsend(event, True)) return # early exit to avoid starting cooldown count except requests.RequestException as e: if __debug__: print_exc() self.status['text'] = _("Error: Can't connect to EDDN") play_bad = True except Exception as e: if __debug__: print_exc() self.status['text'] = unicode(e) play_bad = True if not self.status['text']: # no errors self.status['text'] = strftime(_('Last updated at {HH}:{MM}:{SS}').format(HH='%H', MM='%M', SS='%S').encode('utf-8'), localtime(querytime)).decode('utf-8') if play_sound and play_bad: hotkeymgr.play_bad() self.holdofftime = querytime + companion.holdoff self.cooldown()
def main(): """Run the main code of the program.""" try: # arg parsing parser = argparse.ArgumentParser( prog=appcmdname, description='Prints the current system and station (if docked) to stdout and optionally writes player ' 'status, ship locations, ship loadout and/or station data to file. ' 'Requires prior setup through the accompanying GUI app.' ) parser.add_argument('-v', '--version', help='print program version and exit', action='store_const', const=True) group_loglevel = parser.add_mutually_exclusive_group() group_loglevel.add_argument('--loglevel', metavar='loglevel', help='Set the logging loglevel to one of: ' 'CRITICAL, ERROR, WARNING, INFO, DEBUG, TRACE', ) group_loglevel.add_argument('--trace', help='Set the Debug logging loglevel to TRACE', action='store_true', ) parser.add_argument('-a', metavar='FILE', help='write ship loadout to FILE in Companion API json format') parser.add_argument('-e', metavar='FILE', help='write ship loadout to FILE in E:D Shipyard plain text format') parser.add_argument('-l', metavar='FILE', help='write ship locations to FILE in CSV format') parser.add_argument('-m', metavar='FILE', help='write station commodity market data to FILE in CSV format') parser.add_argument('-o', metavar='FILE', help='write station outfitting data to FILE in CSV format') parser.add_argument('-s', metavar='FILE', help='write station shipyard data to FILE in CSV format') parser.add_argument('-t', metavar='FILE', help='write player status to FILE in CSV format') parser.add_argument('-d', metavar='FILE', help='write raw JSON data to FILE') parser.add_argument('-n', action='store_true', help='send data to EDDN') parser.add_argument('-p', metavar='CMDR', help='Returns data from the specified player account') parser.add_argument('-j', help=argparse.SUPPRESS) # Import JSON dump args = parser.parse_args() if args.version: updater = Updater(provider='internal') newversion: Optional[EDMCVersion] = updater.check_appcast() if newversion: print(f'{appversion} ({newversion.title!r} is available)') else: print(appversion) return if args.trace: edmclogger.set_channels_loglevel(logging.TRACE) elif args.loglevel: if args.loglevel not in ('CRITICAL', 'ERROR', 'WARNING', 'INFO', 'DEBUG', 'TRACE'): print('loglevel must be one of: CRITICAL, ERROR, WARNING, INFO, DEBUG, TRACE', file=sys.stderr) sys.exit(EXIT_ARGS) edmclogger.set_channels_loglevel(args.loglevel) logger.debug(f'Startup v{appversion} : Running on Python v{sys.version}') logger.debug(f'''Platform: {sys.platform} argv[0]: {sys.argv[0]} exec_prefix: {sys.exec_prefix} executable: {sys.executable} sys.path: {sys.path}''' ) log_locale('Initial Locale') if args.j: logger.debug('Import and collate from JSON dump') # Import and collate from JSON dump data = json.load(open(args.j)) config.set('querytime', int(getmtime(args.j))) else: # Get state from latest Journal file logger.debug('Getting state from latest journal file') try: logdir = config.get('journaldir') or config.default_journal_dir logger.debug(f'logdir = "{logdir}"') logfiles = sorted((x for x in os.listdir(logdir) if JOURNAL_RE.search(x)), key=lambda x: x.split('.')[1:]) logfile = join(logdir, logfiles[-1]) logger.debug(f'Using logfile "{logfile}"') with open(logfile, 'r') as loghandle: for line in loghandle: try: monitor.parse_entry(line) except Exception: logger.debug(f'Invalid journal entry {line!r}') except Exception: logger.exception("Can't read Journal file") sys.exit(EXIT_SYS_ERR) if not monitor.cmdr: logger.error('Not available while E:D is at the main menu') sys.exit(EXIT_SYS_ERR) # Get data from Companion API if args.p: logger.debug(f'Attempting to use commander "{args.p}"') cmdrs = config.get('cmdrs') or [] if args.p in cmdrs: idx = cmdrs.index(args.p) else: for idx, cmdr in enumerate(cmdrs): if cmdr.lower() == args.p.lower(): break else: raise companion.CredentialsError() companion.session.login(cmdrs[idx], monitor.is_beta) else: logger.debug(f'Attempting to use commander "{monitor.cmdr}" from Journal File') cmdrs = config.get('cmdrs') or [] if monitor.cmdr not in cmdrs: raise companion.CredentialsError() companion.session.login(monitor.cmdr, monitor.is_beta) querytime = int(time()) data = companion.session.station() config.set('querytime', querytime) # Validation if not deep_get(data, 'commander', 'name', default='').strip(): logger.error("No data['command']['name'] from CAPI") sys.exit(EXIT_SERVER) elif not deep_get(data, 'lastSystem', 'name') or \ data['commander'].get('docked') and not \ deep_get(data, 'lastStarport', 'name'): # Only care if docked logger.error("No data['lastSystem']['name'] from CAPI") sys.exit(EXIT_SERVER) elif not deep_get(data, 'ship', 'modules') or not deep_get(data, 'ship', 'name', default=''): logger.error("No data['ship']['modules'] from CAPI") sys.exit(EXIT_SERVER) elif args.j: pass # Skip further validation elif data['commander']['name'] != monitor.cmdr: logger.error(f'Commander "{data["commander"]["name"]}" from CAPI doesn\'t match "{monitor.cmdr}" from Journal') # noqa: E501 sys.exit(EXIT_CREDENTIALS) elif data['lastSystem']['name'] != monitor.system or \ ((data['commander']['docked'] and data['lastStarport']['name'] or None) != monitor.station) or \ data['ship']['id'] != monitor.state['ShipID'] or \ data['ship']['name'].lower() != monitor.state['ShipType']: logger.error('Mismatch(es) between CAPI and Journal for at least one of: StarSystem, Last Star Port, Ship ID or Ship Name/Type') # noqa: E501 sys.exit(EXIT_LAGGING) # stuff we can do when not docked if args.d: logger.debug(f'Writing raw JSON data to "{args.d}"') out = json.dumps(data, ensure_ascii=False, indent=2, sort_keys=True, separators=(',', ': ')) with open(args.d, 'wb') as f: f.write(out.encode("utf-8")) if args.a: logger.debug(f'Writing Ship Loadout in Companion API JSON format to "{args.a}"') loadout.export(data, args.a) if args.e: logger.debug(f'Writing Ship Loadout in ED Shipyard plain text format to "{args.e}"') edshipyard.export(data, args.e) if args.l: logger.debug(f'Writing Ship Locations in CSV format to "{args.l}"') stats.export_ships(data, args.l) if args.t: logger.debug(f'Writing Player Status in CSV format to "{args.t}"') stats.export_status(data, args.t) if data['commander'].get('docked'): print(f'{deep_get(data, "lastSystem", "name", default="Unknown")},' f'{deep_get(data, "lastStarport", "name", default="Unknown")}' ) else: print(deep_get(data, 'lastSystem', 'name', default='Unknown')) if (args.m or args.o or args.s or args.n or args.j): if not data['commander'].get('docked'): logger.error("Can't use -m, -o, -s, -n or -j because you're not currently docked!") return elif not deep_get(data, 'lastStarport', 'name'): logger.error("No data['lastStarport']['name'] from CAPI") sys.exit(EXIT_LAGGING) # Ignore possibly missing shipyard info elif not (data['lastStarport'].get('commodities') or data['lastStarport'].get('modules')): logger.error("No commodities or outfitting (modules) in CAPI data") return else: return # Finally - the data looks sane and we're docked at a station if args.j: logger.debug('Importing data from the CAPI return...') # Collate from JSON dump collate.addcommodities(data) collate.addmodules(data) collate.addships(data) if args.m: logger.debug(f'Writing Station Commodity Market Data in CSV format to "{args.m}"') if data['lastStarport'].get('commodities'): # Fixup anomalies in the commodity data fixed = companion.fixup(data) commodity.export(fixed, COMMODITY_DEFAULT, args.m) else: logger.error("Station doesn't have a market") if args.o: if data['lastStarport'].get('modules'): logger.debug(f'Writing Station Outfitting in CSV format to "{args.o}"') outfitting.export(data, args.o) else: logger.error("Station doesn't supply outfitting") if (args.s or args.n) and not args.j and not \ data['lastStarport'].get('ships') and data['lastStarport']['services'].get('shipyard'): # Retry for shipyard sleep(SERVER_RETRY) new_data = companion.session.station() # might have undocked while we were waiting for retry in which case station data is unreliable if new_data['commander'].get('docked') and \ deep_get(new_data, 'lastSystem', 'name') == monitor.system and \ deep_get(new_data, 'lastStarport', 'name') == monitor.station: data = new_data if args.s: if deep_get(data, 'lastStarport', 'ships', 'shipyard_list'): logger.debug(f'Writing Station Shipyard in CSV format to "{args.s}"') shipyard.export(data, args.s) elif not args.j and monitor.stationservices and 'Shipyard' in monitor.stationservices: logger.error('Failed to get shipyard data') else: logger.error("Station doesn't have a shipyard") if args.n: try: eddn_sender = eddn.EDDN(None) logger.debug('Sending Market, Outfitting and Shipyard data to EDDN...') eddn_sender.export_commodities(data, monitor.is_beta) eddn_sender.export_outfitting(data, monitor.is_beta) eddn_sender.export_shipyard(data, monitor.is_beta) except Exception: logger.exception('Failed to send data to EDDN') except companion.ServerError: logger.error('Frontier CAPI Server returned an error') sys.exit(EXIT_SERVER) except companion.SKUError: logger.error('Frontier CAPI Server SKU problem') sys.exit(EXIT_SERVER) except companion.CredentialsError: logger.error('Frontier CAPI Server: Invalid Credentials') sys.exit(EXIT_CREDENTIALS)
# Validation if not data.get('commander') or not data['commander'].get('name','').strip(): sys.stderr.write('Who are you?!\n') sys.exit(EXIT_SERVER) elif not data.get('lastSystem') or not data['lastSystem'].get('name','').strip() or not data.get('lastStarport') or not data['lastStarport'].get('name','').strip(): sys.stderr.write('Where are you?!\n') # Shouldn't happen sys.exit(EXIT_SERVER) elif not data.get('ship') or not data['ship'].get('modules') or not data['ship'].get('name','').strip(): sys.stderr.write('What are you flying?!\n') # Shouldn't happen sys.exit(EXIT_SERVER) # stuff we can do when not docked if args.c: coriolis.export(data, args.c) if args.e: loadout.export(data, args.e) if args.l: stats.export_ships(data, args.l) if args.t: stats.export_status(data, args.t) if not data['commander'].get('docked'): print data['lastSystem']['name'] if (args.m or args.o or args.s): sys.stderr.write("You're not docked at a station!\n") sys.exit(EXIT_NOT_DOCKED) else: sys.exit(EXIT_SUCCESS) # Finally - the data looks sane and we're docked at a station print '%s,%s' % (data['lastSystem']['name'], data['lastStarport']['name'])
def getandsend(self, event=None, retrying=False): if not retrying: if time() < self.holdofftime: return # Was invoked by Return key while in cooldown self.cmdr['text'] = self.system['text'] = self.station['text'] = '' self.status['text'] = 'Fetching station data...' self.button['state'] = tk.DISABLED self.w.update_idletasks() try: querytime = int(time()) data = self.session.query() self.cmdr['text'] = data.get('commander') and data.get( 'commander').get('name') or '' self.system['text'] = data.get('lastSystem') and data.get( 'lastSystem').get('name') or '' self.station['text'] = data.get('commander') and data.get( 'commander').get('docked') and data.get( 'lastStarport') and data.get('lastStarport').get( 'name') or '-' config.set('querytime', querytime) self.holdofftime = querytime + companion.holdoff # Validation if not data.get('commander') or not data['commander'].get( 'name', '').strip(): self.status['text'] = "Who are you?!" # Shouldn't happen elif not data.get('lastSystem') or not data['lastSystem'].get( 'name', '').strip() or not data.get( 'lastStarport') or not data['lastStarport'].get( 'name', '').strip(): self.status['text'] = "Where are you?!" # Shouldn't happen elif not data.get('ship') or not data['ship'].get( 'modules') or not data['ship'].get('name', '').strip(): self.status[ 'text'] = "What are you flying?!" # Shouldn't happen elif (config.getint('output') & config.OUT_EDDN ) and not data['lastStarport'].get('ships') and not retrying: # API is flakey about shipyard info - retry if missing (<1s is usually sufficient - 2.5s for margin). self.w.after(2500, lambda: self.getandsend(retrying=True)) return else: if __debug__ and retrying: print data['lastStarport'].get( 'ships' ) and 'Retry for shipyard - Success' or 'Retry for shipyard - Fail' # stuff we can do when not docked if __debug__: # Recording with open( '%s%s.%s.json' % (data['lastSystem']['name'], data['commander'].get('docked') and '.' + data['lastStarport']['name'] or '', strftime('%Y-%m-%dT%H.%M.%S', localtime())), 'wt') as h: h.write(json.dumps(data, indent=2, sort_keys=True)) if config.getint('output') & config.OUT_LOG: flightlog.export(data) if config.getint('output') & config.OUT_SHIP: loadout.export(data) if not (config.getint('output') & (config.OUT_CSV | config.OUT_TD | config.OUT_BPC | config.OUT_EDDN)): # no further output requested self.status['text'] = strftime('Last updated at %H:%M:%S', localtime(querytime)) elif not data['commander'].get('docked'): self.status['text'] = "You're not docked at a station!" else: if data['lastStarport'].get('commodities'): # Fixup anomalies in the commodity data self.session.fixup(data['lastStarport']['commodities']) if config.getint('output') & config.OUT_CSV: bpc.export(data, True) if config.getint('output') & config.OUT_TD: td.export(data) if config.getint('output') & config.OUT_BPC: bpc.export(data, False) if config.getint('output') & config.OUT_EDDN: if data['lastStarport'].get( 'commodities') or data['lastStarport'].get( 'modules') or data['lastStarport'].get( 'ships'): self.status['text'] = 'Sending data to EDDN...' self.w.update_idletasks() eddn.export(data) self.status['text'] = strftime( 'Last updated at %H:%M:%S', localtime(querytime)) else: self.status[ 'text'] = "Station doesn't have anything!" elif not data['lastStarport'].get('commodities'): self.status['text'] = "Station doesn't have a market!" else: self.status['text'] = strftime( 'Last updated at %H:%M:%S', localtime(querytime)) except companion.VerificationRequired: return prefs.AuthenticationDialog(self.w, self.verify) # Companion API problem except companion.ServerError as e: self.status['text'] = str(e) except requests.exceptions.ConnectionError as e: if __debug__: print_exc() self.status['text'] = "Error: Can't connect to EDDN" except requests.exceptions.Timeout as e: if __debug__: print_exc() self.status['text'] = "Error: Connection to EDDN timed out" except Exception as e: if __debug__: print_exc() self.status['text'] = str(e) self.cooldown()