def shipyard_url(self, shipname=None): self.status['text'] = _('Fetching data...') self.w.update_idletasks() try: data = self.session.query() except companion.VerificationRequired: return prefs.AuthenticationDialog(self.parent, partial(self.verify, self.shipyard_url)) except companion.ServerError as e: self.status['text'] = str(e) return except Exception as e: if __debug__: print_exc() self.status['text'] = str(e) return 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 shipname and shipname != companion.ship_map.get(data['ship']['name'].lower(), data['ship']['name']): self.status['text'] = _('Error: Server is lagging') # Raised when Companion API server is returning old data, e.g. when the servers are too busy else: self.status['text'] = '' if config.getint('shipyard') == config.SHIPYARD_EDSHIPYARD: return edshipyard.url(data) elif config.getint('shipyard') == config.SHIPYARD_CORIOLIS: return coriolis.url(data) else: assert False, config.getint('shipyard') return False
def cmdr_data(data, is_beta): system = data['lastSystem']['name'] if not this.system['text']: this.system['text'] = system this.system['image'] = '' if not system or system in FAKE: this.system['url'] = None this.lastlookup = True else: this.system[ 'url'] = 'https://www.edsm.net/show-system?systemName=%s' % urllib2.quote( system) this.lastlookup = False this.system.update_idletasks() if config.getint( 'edsm_out') and not is_beta and not this.multicrew and credentials( data['commander']['name']): # Send flightlog to EDSM if FSDJump failed to do so if not this.lastlookup: try: this.writelog(data['commander']['name'], int(time.time()), system, None, data['ship']['id']) except Exception as e: if __debug__: print_exc() return unicode(e) # Update credits and ship info and send to EDSM try: if data['commander'].get('credits') is not None: setcredits(data['commander']['name'], data['commander']['credits'], data['commander'].get('debt', 0)) ship = companion.ship(data) if ship != this.lastship: cargo = 0 fuel = 0 for v in data['ship']['modules'].itervalues(): module = outfitting.lookup(v['module'], companion.ship_map) if not module: pass elif 'Fuel Tank' in module['name']: fuel += 2**int(module['class']) elif 'Cargo Rack' in module['name']: cargo += 2**int(module['class']) updateship( data['commander']['name'], data['ship']['id'], data['ship']['name'].lower(), { 'cargoCapacity': cargo, 'fuelMainCapacity': fuel, 'linkToCoriolis': coriolis.url(data, is_beta), 'linkToEDShipyard': edshipyard.url(data, is_beta), }) this.lastship = ship except Exception as e: # Not particularly important so silent on failure if __debug__: print_exc()
def cmdr_data(data, is_beta): system = data['lastSystem']['name'] if not this.system['text']: this.system['text'] = system this.system['image'] = '' if not system or system in FAKE: this.system['url'] = None this.lastlookup = True else: this.system[ 'url'] = 'https://www.edsm.net/show-system?systemName=%s' % urllib2.quote( system) this.lastlookup = False this.system.update_idletasks() if config.getint( 'edsm_out') and not is_beta and not multicrew and credentials( data['commander']['name']): # Send flightlog to EDSM if FSDJump failed to do so if not this.lastlookup: try: this.writelog(data['commander']['name'], int(time.time()), system, None, data['ship']['id']) except Exception as e: if __debug__: print_exc() return unicode(e) # Update credits and ship info and send to EDSM try: if data['commander'].get('credits') is not None: setcredits(data['commander']['name'], data['commander']['credits'], data['commander'].get('debt', 0)) ship = companion.ship(data) if ship != this.lastship: updateship( data['commander']['name'], data['ship']['id'], data['ship']['name'].lower(), [ ('linkToCoriolis', coriolis.url(data, is_beta)), ('linkToEDShipyard', edshipyard.url(data, is_beta)), ]) this.lastship = ship except Exception as e: # Not particularly important so silent on failure if __debug__: print_exc()
def shipyard_url(self, shipname=None): if not monitor.cmdr or not monitor.mode: return False # In CQC - do nothing if config.getint('shipyard') == config.SHIPYARD_EDSHIPYARD: return edshipyard.url(monitor.is_beta) elif config.getint('shipyard') == config.SHIPYARD_CORIOLIS: pass # Fall through else: assert False, config.getint('shipyard') return False self.status['text'] = _('Fetching data...') self.w.update_idletasks() try: data = self.session.profile() except companion.VerificationRequired: return prefs.AuthenticationDialog(self.w, partial(self.verify, self.shipyard_url)) except companion.ServerError as e: self.status['text'] = str(e) return except Exception as e: if __debug__: print_exc() self.status['text'] = str(e) return 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.state['ShipID'] is not None and data['ship']['id'] != monitor.state['ShipID']) or (monitor.state['ShipType'] and data['ship']['name'].lower() != monitor.state['ShipType']): self.status['text'] = _('Error: Frontier server is lagging') # Raised when Companion API server is returning old data, e.g. when the servers are too busy else: self.status['text'] = '' return coriolis.url(data, monitor.is_beta)
def cmdr_data(data, is_beta): system = data['lastSystem']['name'] if not this.system['text']: this.system['text'] = system this.system['image'] = '' if not system or system in FAKE: this.system['url'] = None this.lastlookup = True else: this.system[ 'url'] = 'https://www.edsm.net/show-system?systemName=%s' % urllib2.quote( system) this.lastlookup = False this.system.update_idletasks() # Send ship info to EDSM if config.getint( 'edsm_out') and not is_beta and not this.multicrew and credentials( data['commander']['name']): ship = companion.ship(data) if ship != this.lastship: cmdr = data['commander']['name'] timestamp = time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime()) this.queue.put((cmdr, { 'event': 'Coriolis', 'timestamp': timestamp, '_shipId': data['ship']['id'], 'url': coriolis.url(data, is_beta) })) this.queue.put((cmdr, { 'event': 'EDShipyard', 'timestamp': timestamp, '_shipId': data['ship']['id'], 'url': edshipyard.url(data, is_beta) })) this.lastship = ship
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 journal_entry(cmdr, is_beta, system, station, entry, state): # Update display if this.system['text'] != system: this.system['text'] = system or '' this.system['image'] = '' if not system or system in FAKE: this.system['url'] = None this.lastlookup = True else: this.system[ 'url'] = 'https://www.edsm.net/show-system?systemName=%s' % urllib2.quote( system) this.lastlookup = False this.system.update_idletasks() this.multicrew = bool(state['Role']) if 'StarPos' in entry: this.coordinates = entry['StarPos'] elif entry['event'] == 'LoadGame': this.coordinates = None if entry['event'] in ['LoadGame', 'Commander', 'NewCommander']: 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'] # 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: # Introduce transient states into the event transient = { '_systemName': system, '_systemCoordinates': this.coordinates, '_stationName': station, '_shipId': state['ShipID'], } entry.update(transient) if entry['event'] == 'LoadGame': # Synthesise Materials events on LoadGame since we will have missed it materials = { 'timestamp': entry['timestamp'], 'event': 'Materials', 'Raw': [{ 'Name': k, 'Count': v } for k, v in state['Raw'].iteritems()], 'Manufactured': [{ 'Name': k, 'Count': v } for k, v in state['Manufactured'].iteritems()], 'Encoded': [{ 'Name': k, 'Count': v } for k, v in state['Encoded'].iteritems()], } materials.update(transient) this.queue.put((cmdr, materials)) this.queue.put((cmdr, entry)) if entry[ 'event'] == 'Loadout' and 'EDShipyard' not in this.discardedEvents: url = edshipyard.url(is_beta) if this.lastloadout != url: this.lastloadout = url this.queue.put((cmdr, { 'event': 'EDShipyard', 'timestamp': entry['timestamp'], '_shipId': state['ShipID'], 'url': this.lastloadout }))