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
Exemple #2
0
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()
Exemple #3
0
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()
Exemple #4
0
    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)
Exemple #5
0
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()
Exemple #7
0
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
                }))