Ejemplo n.º 1
0
 def Music(cls, system, cmdr, timestamp, client):
     if cls.state == 2:
         debug("Hyperdiction Detected")
         cls.show()
         x, y, z = Systems.edsmGetSystem(system)
         dx, dy, dz = Systems.edsmGetSystem(cls.target_system)
         canonn.emitter.post(
             "https://europe-west1-canonn-api-236217.cloudfunctions.net/postHDDetected",
             {
                 "cmdr": cmdr,
                 "system": system,
                 "timestamp": timestamp,
                 "x": x,
                 "y": y,
                 "z": z,
                 "destination": cls.target_system,
                 "dx": dx,
                 "dy": dy,
                 "dz": dz,
                 "client": client
             })
         plug.show_error("Hyperdiction: Exit to main menu")
     else:
         debug("FSDJUMP resetting state back")
         cls.hide()
         cls.state == 0
Ejemplo n.º 2
0
def worker():
    while True:
        item = this.queue.get()
        if not item:
            return  # Closing
        else:
            (url, data, callback) = item

        retrying = 0
        while retrying < 3:
            try:
                r = this.session.post(url, data=data, timeout=_TIMEOUT)
                r.raise_for_status()
                reply = r.json()
                (msgnum, msg) = reply['msgnum'], reply['msg']
                if callback:
                    callback(reply)
                elif msgnum // 100 != 1:  # 1xx = OK, 2xx = fatal error
                    plug.show_error(_('Error: EDSM {MSG}').format(MSG=msg))
                break
            except:
                retrying += 1
        else:
            if callback:
                callback(None)
            else:
                plug.show_error(_("Error: Can't connect to EDSM"))
Ejemplo n.º 3
0
def find_overlay_binary() -> Path:
    our_directory = Path(__file__).resolve().parent
    overlay_binary = our_directory / "overlay"
    if not overlay_binary.exists():
        plug.show_error("edmcoverlay2 unable to find overlay binary")
        raise RuntimeError("edmcoverlay2 unable to find overlay binary")
    return overlay_binary
Ejemplo n.º 4
0
def edsm_notify_system(reply):
    if not reply:
        this.system['image'] = this._IMG_ERROR
        plug.show_error(_("Error: Can't connect to EDSM"))
    elif reply['msgnum'] // 100 not in (1,4):
        this.system['image'] = this._IMG_ERROR
        plug.show_error(_('Error: EDSM {MSG}').format(MSG=reply['msg']))
    elif reply.get('systemCreated'):
        this.system['image'] = this._IMG_NEW
    else:
        this.system['image'] = this._IMG_KNOWN
Ejemplo n.º 5
0
def edsm_notify_system(reply):
    if not reply:
        this.system['image'] = this._IMG_ERROR
        plug.show_error(_("Error: Can't connect to EDSM"))
    elif reply['msgnum'] // 100 not in (1, 4):
        this.system['image'] = this._IMG_ERROR
        plug.show_error(_('Error: EDSM {MSG}').format(MSG=reply['msg']))
    elif reply.get('systemCreated'):
        this.system['image'] = this._IMG_NEW
    else:
        this.system['image'] = this._IMG_KNOWN
Ejemplo n.º 6
0
def post_traffic(system, entry):
    debug("posting traffic {} ".format(system))
    try:
        emitter.post(
            "https://europe-west1-canonn-api-236217.cloudfunctions.net/postTraffic",
            {
                "system": system,
                "timestamp": entry.get("timestamp")
            })
    except:
        plug.show_error("Failed to post traffic")
        debug("Failed to post traffic for {}".format(system))
Ejemplo n.º 7
0
 def openLocalDatabase(self):
     try:
         self.localDbConnection = sqlite3.connect(
             os.path.join(self.pluginDir, "cache.sqlite"))
         self.localDbCursor = self.localDbConnection.cursor()
     except Exception as e:
         if __debug__:
             print("Local cache database could not be opened")
         plug.show_error(
             "EDSM-RSE: Local cache database could not be opened")
         sys.stderr.write(
             "EDSM-RSE: Local cache database could not be opened\n")
Ejemplo n.º 8
0
 def open_local_database(self):
     try:
         self.local_db_connection = sqlite3.connect(os.path.join(
             self.plugin_dir, "cache.sqlite"),
                                                    timeout=10)
         self.local_db_cursor = self.local_db_connection.cursor()
     except Exception as e:
         error_message = "Local cache database could not be opened"
         logger.exception(error_message)
         plug.show_error(
             plug.show_error(
                 f"{RseData.PLUGIN_NAME}-{RseData.VERSION}: {error_message}"
             ))
Ejemplo n.º 9
0
def update_status(event=None):
    reply = this.lastlookup
    # Message numbers: 1xx = OK, 2xx = fatal error, 3xx = error (but not generated in practice), 4xx = ignorable errors
    if not reply:
        this.system['image'] = this._IMG_ERROR
        plug.show_error(_("Error: Can't connect to EDSM"))
    elif reply['msgnum'] // 100 not in (1, 4):
        this.system['image'] = this._IMG_ERROR
        plug.show_error(_('Error: EDSM {MSG}').format(MSG=reply['msg']))
    elif reply.get('systemCreated'):
        this.system['image'] = this._IMG_NEW
    else:
        this.system['image'] = this._IMG_KNOWN
Ejemplo n.º 10
0
 def openDatabase(self):
     try:
         self.conn = psycopg2.connect(
             host="cyberlord.de",
             port=5432,
             dbname="edmc_rse_db",
             user="******",
             password="******",
             application_name="EDSM-RSE {}".format(VERSION),
             connect_timeout=10)
         self.c = self.conn.cursor()
     except Exception as e:
         plug.show_error("EDSM-RSE: Database could not be opened")
         sys.stderr.write("EDSM-RSE: Database could not be opened\n")
Ejemplo n.º 11
0
def edsm_notify_system(reply: Mapping[str, Any]) -> None:
    """Update the image next to the system link."""
    if not reply:
        this.system_link['image'] = this._IMG_ERROR
        plug.show_error(_("Error: Can't connect to EDSM"))

    elif reply['msgnum'] // 100 not in (1, 4):
        this.system_link['image'] = this._IMG_ERROR
        plug.show_error(_('Error: EDSM {MSG}').format(MSG=reply['msg']))

    elif reply.get('systemCreated'):
        this.system_link['image'] = this._IMG_NEW

    else:
        this.system_link['image'] = this._IMG_KNOWN
Ejemplo n.º 12
0
 def openRemoteDatabase(self):
     try:
         self.remoteDbConnection = psycopg2.connect(
             host="cyberlord.de",
             port=5432,
             dbname="edmc_rse_db",
             user="******",
             password="******",
             application_name="EDSM-RSE {}".format(RseData.VERSION),
             connect_timeout=10)
         self.remoteDbCursor = self.remoteDbConnection.cursor()
     except Exception as e:
         if __debug__:
             print("Remote database could not be opened")
         plug.show_error("EDSM-RSE: Remote database could not be opened")
         sys.stderr.write("EDSM-RSE: Remote database could not be opened\n")
Ejemplo n.º 13
0
def send_data(url: str, data: Mapping[str, Any]) -> bool:
    """
    Write a set of events to the inara API.

    :param url: the target URL to post to
    :param data: the data to POST
    :return: success state
    """
    r = this.session.post(url, data=json.dumps(data, separators=(',', ':')), timeout=_TIMEOUT)
    r.raise_for_status()
    reply = r.json()
    status = reply['header']['eventStatus']

    if status // 100 != 2:  # 2xx == OK (maybe with warnings)
        # Log fatal errors
        logger.warning(f'Inara\t{status} {reply["header"].get("eventStatusText", "")}')
        logger.debug(f'JSON data:\n{json.dumps(data, indent=2, separators = (",", ": "))}')
        plug.show_error(_('Error: Inara {MSG}').format(MSG=reply['header'].get('eventStatusText', status)))

    else:
        # Log individual errors and warnings
        for data_event, reply_event in zip(data['events'], reply['events']):
            if reply_event['eventStatus'] != 200:
                logger.warning(f'Inara\t{status} {reply_event.get("eventStatusText", "")}')
                logger.debug(f'JSON data:\n{json.dumps(data_event)}')
                if reply_event['eventStatus'] // 100 != 2:
                    plug.show_error(_('Error: Inara {MSG}').format(
                        MSG=f'{data_event["eventName"]},'
                            f'{reply_event.get("eventStatusText", reply_event["eventStatus"])}'
                    ))

            if data_event['eventName'] in (
                'addCommanderTravelCarrierJump',
                'addCommanderTravelDock',
                'addCommanderTravelFSDJump',
                'setCommanderTravelLocation'
            ):
                this.lastlocation = reply_event.get('eventData', {})
                # calls update_location in main thread
                this.system_link.event_generate('<<InaraLocation>>', when="tail")

            elif data_event['eventName'] in ['addCommanderShip', 'setCommanderShip']:
                this.lastship = reply_event.get('eventData', {})
                # calls update_ship in main thread
                this.system_link.event_generate('<<InaraShip>>', when="tail")

    return True  # regardless of errors above, we DID manage to send it, therefore inform our caller as such
Ejemplo n.º 14
0
def shipyard_url(loadout, is_beta, data=None):

    # Ignore supplied loadout (except for validation) until Coriolis updates to 3.0. Use cAPI instead.
    if not data:
        try:
            data = companion.session.profile()
        except Exception as e:
            if __debug__: print_exc()
            plug.show_error(str(e))
            return

    if not data.get('commander', {}).get('name'):
        plug.show_error(_("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
        plug.show_error(_("Where are you?!"))  # Shouldn't happen
    elif not data.get('ship', {}).get('name') or not data.get(
            'ship', {}).get('modules'):
        plug.show_error(_("What are you flying?!"))  # Shouldn't happen
    elif (loadout.get('ShipID') is not None
          and data['ship']['id'] != loadout['ShipID']) or (
              loadout.get('Ship')
              and data['ship']['name'].lower() != loadout['Ship']):
        plug.show_error(
            _('Error: Frontier server is lagging')
        )  # Raised when Companion API server is returning old data, e.g. when the servers are too busy
    else:
        string = json.dumps(companion.ship(data),
                            ensure_ascii=False,
                            sort_keys=True,
                            separators=(',', ':')).encode(
                                'utf-8')  # most compact representation
        out = StringIO.StringIO()
        with gzip.GzipFile(fileobj=out, mode='w') as f:
            f.write(string)
        return (is_beta and 'https://beta.coriolis.edcd.io/import?data='
                or 'https://coriolis.edcd.io/import?data='
                ) + base64.urlsafe_b64encode(out.getvalue()).replace(
                    '=', '%3D')
Ejemplo n.º 15
0
    def initialize(self):
        # initialize local cache
        self.open_local_database()
        if self.is_local_database_accessible():
            self.local_db_cursor.execute(
                """CREATE TABLE IF NOT EXISTS `CachedSystems` (
                                            `id64`	          INTEGER,
                                            `expirationDate`  REAL NOT NULL,
                                            `cacheType`	      INTEGER NOT NULL,
                                            PRIMARY KEY(`id64`));""")
            self.local_db_connection.commit()
            self.remove_expired_systems_from_caches(handle_db_connection=False)

            # read cached systems
            self.local_db_cursor.execute(
                "SELECT id64, cacheType FROM CachedSystems")
            for row in self.local_db_cursor.fetchall():
                id64, cacheType = row
                self.get_cached_set(cacheType).add(id64)
            self.close_local_database()

        # initialize dictionaries
        if len(self.projects_dict) == 0:
            response = self._query_rse_api(
                "https://cyberlord.de/rse/projects.py")
            if not response:
                errorMessage = "Could not get information about projects."
                logger.error(errorMessage)
                plug.show_error("{plugin_name}-{version}: {msg}".format(
                    plugin_name=RseData.PLUGIN_NAME,
                    version=RseData.VERSION,
                    msg=errorMessage))
            else:
                for _row in response:
                    rseProject = RseProject(_row["id"], _row["action_text"],
                                            _row["project_name"],
                                            _row["explanation"],
                                            _row["enabled"])
                    self.projects_dict[rseProject.project_id] = rseProject
Ejemplo n.º 16
0
    def installer(self):
        # need to add some defensive code around this
        tag_name = self.latest.get("tag_name")

        debug("Installing {}".format(tag_name))

        new_plugin_dir = os.path.join(os.path.dirname(Release.plugin_dir),
                                      "EDMC-Canonn-{}".format(tag_name))

        debug("Checking for pre-existence")
        if os.path.isdir(new_plugin_dir):
            error("Download already exists: {}".format(new_plugin_dir))
            plug.show_error("Canonn upgrade failed")
            return False

        try:
            debug("Downloading new version")
            download = requests.get(
                "https://github.com/canonn-science/EDMC-Canonn/archive/{}.zip".
                format(tag_name),
                stream=True)

            try:
                z = zipfile.ZipFile(BytesIO(download.content))
                z.extractall(os.path.dirname(Release.plugin_dir))
            except:
                z = zipfile.ZipFile(StringIO.StringIO(download.content))
                z.extractall(os.path.dirname(Release.plugin_dir))
        except:
            error("Download failed: {}".format(new_plugin_dir))
            plug.show_error("Canonn upgrade failed")

            return False

        # If we got this far then we have a new plugin so any failures and we will need to delete it

        debug("disable the current plugin")
        try:
            os.rename(Release.plugin_dir,
                      "{}.disabled".format(Release.plugin_dir))
            debug("Renamed {} to {}".format(
                Release.plugin_dir, "{}.disabled".format(Release.plugin_dir)))
        except:
            error("Upgrade failed reverting: {}".format(new_plugin_dir))
            plug.show_error("Canonn upgrade failed")
            shutil.rmtree(new_plugin_dir)
            return False

        if self.rmbackup.get() == 1:
            config.set('Canonn:RemoveBackup',
                       "{}.disabled".format(Release.plugin_dir))

        debug("Upgrade complete")

        Release.plugin_dir = new_plugin_dir
        self.installed = True

        return True
Ejemplo n.º 17
0
def worker():
    while True:
        item = this.queue.get()
        if not item:
            return  # Closing
        else:
            (url, data, callback) = item

        retrying = 0
        while retrying < 3:
            try:
                r = this.session.post(url,
                                      data=json.dumps(data,
                                                      separators=(',', ':')),
                                      timeout=_TIMEOUT)
                r.raise_for_status()
                reply = r.json()
                status = reply['header']['eventStatus']
                if callback:
                    callback(reply)
                elif status // 100 != 2:  # 2xx == OK (maybe with warnings)
                    # Log fatal errors
                    print 'Inara\t%s %s' % (reply['header']['eventStatus'],
                                            reply['header'].get(
                                                'eventStatusText', ''))
                    print json.dumps(data, indent=2, separators=(',', ': '))
                    plug.show_error(
                        _('Error: Inara {MSG}').format(MSG=reply['header'].get(
                            'eventStatusText', status)))
                else:
                    # Log individual errors and warnings
                    for data_event, reply_event in zip(data['events'],
                                                       reply['events']):
                        if reply_event['eventStatus'] != 200:
                            print 'Inara\t%s %s\t%s' % (
                                reply_event['eventStatus'],
                                reply_event.get('eventStatusText', ''),
                                json.dumps(data_event, separators=(',', ': ')))
                            if reply_event['eventStatus'] // 100 != 2:
                                plug.show_error(
                                    _('Error: Inara {MSG}').format(
                                        MSG='%s, %s' %
                                        (data_event['eventName'],
                                         reply_event.get(
                                             'eventStatusText',
                                             reply_event['eventStatus']))))
                break
            except:
                if __debug__: print_exc()
                retrying += 1
        else:
            if callback:
                callback(None)
            else:
                plug.show_error(_("Error: Can't connect to Inara"))
Ejemplo n.º 18
0
def worker():
    while True:
        item = this.queue.get()
        if not item:
            return	# Closing
        else:
            (url, data, callback) = item

        retrying = 0
        while retrying < 3:
            try:
                r = this.session.post(url, data=json.dumps(data, separators = (',', ':')), timeout=_TIMEOUT)
                r.raise_for_status()
                reply = r.json()
                status = reply['header']['eventStatus']
                if callback:
                    callback(reply)
                elif status // 100 != 2:	# 2xx == OK (maybe with warnings)
                    # Log fatal errors
                    print 'Inara\t%s %s' % (reply['header']['eventStatus'], reply['header'].get('eventStatusText', ''))
                    print json.dumps(data, indent=2, separators = (',', ': '))
                    plug.show_error(_('Error: Inara {MSG}').format(MSG = reply['header'].get('eventStatusText', status)))
                else:
                    # Log individual errors and warnings
                    for data_event, reply_event in zip(data['events'], reply['events']):
                        if reply_event['eventStatus'] != 200:
                            print 'Inara\t%s %s\t%s' % (reply_event['eventStatus'], reply_event.get('eventStatusText', ''), json.dumps(data_event))
                            if reply_event['eventStatus'] // 100 != 2:
                                plug.show_error(_('Error: Inara {MSG}').format(MSG = '%s, %s' % (data_event['eventName'], reply_event.get('eventStatusText', reply_event['eventStatus']))))
                        if data_event['eventName'] in ['addCommanderTravelDock', 'addCommanderTravelFSDJump', 'setCommanderTravelLocation']:
                            eventData = reply_event.get('eventData', {})
                            this.system  = eventData.get('starsystemInaraURL')
                            if config.get('system_provider') == 'Inara':
                                this.system_link['url'] = this.system	# Override standard URL function
                            this.station = eventData.get('stationInaraURL')
                            if config.get('station_provider') == 'Inara':
                                this.station_link['url'] = this.station or this.system	# Override standard URL function
                break
            except:
                if __debug__: print_exc()
                retrying += 1
        else:
            if callback:
                callback(None)
            else:
                plug.show_error(_("Error: Can't connect to Inara"))
Ejemplo n.º 19
0
def null_callback(reply):
    if not reply:
        plug.show_error(_("Error: Can't connect to EDSM"))
Ejemplo n.º 20
0
def worker():

    pending = []  # Unsent events
    closing = False

    while True:
        item = this.queue.get()
        if item:
            (cmdr, entry) = item
        else:
            closing = True  # Try to send any unsent events before we close

        retrying = 0
        while retrying < 3:
            try:
                if item and entry['event'] not in this.discardedEvents:
                    pending.append(entry)

                # Get list of events to discard
                if not this.discardedEvents:
                    r = this.session.get(
                        'https://www.edsm.net/api-journal-v1/discard',
                        timeout=_TIMEOUT)
                    r.raise_for_status()
                    this.discardedEvents = set(r.json())
                    this.discardedEvents.discard(
                        'Docked'
                    )  # should_send() assumes that we send 'Docked' events
                    assert this.discardedEvents  # wouldn't expect this to be empty
                    pending = [
                        x for x in pending
                        if x['event'] not in this.discardedEvents
                    ]  # Filter out unwanted events

                if should_send(pending):
                    (username, apikey) = credentials(cmdr)
                    data = {
                        'commanderName':
                        username.encode('utf-8'),
                        'apiKey':
                        apikey,
                        'fromSoftware':
                        applongname,
                        'fromSoftwareVersion':
                        appversion,
                        'message':
                        json.dumps(pending,
                                   ensure_ascii=False).encode('utf-8'),
                    }
                    r = this.session.post(
                        'https://www.edsm.net/api-journal-v1',
                        data=data,
                        timeout=_TIMEOUT)
                    r.raise_for_status()
                    reply = r.json()
                    (msgnum, msg) = reply['msgnum'], reply['msg']
                    # 1xx = OK, 2xx = fatal error, 3&4xx not generated at top-level, 5xx = error but events saved for later processing
                    if msgnum // 100 == 2:
                        print('EDSM\t%s %s\t%s' %
                              (msgnum, msg,
                               json.dumps(pending, separators=(',', ': '))))
                        plug.show_error(_('Error: EDSM {MSG}').format(MSG=msg))
                    else:
                        for e, r in zip(pending, reply['events']):
                            if not closing and e['event'] in [
                                    'StartUp', 'Location', 'FSDJump'
                            ]:
                                # Update main window's system status
                                this.lastlookup = r
                                this.system.event_generate(
                                    '<<EDSMStatus>>', when="tail"
                                )  # calls update_status in main thread
                            elif r['msgnum'] // 100 != 1:
                                print('EDSM\t%s %s\t%s' %
                                      (r['msgnum'], r['msg'],
                                       json.dumps(e, separators=(',', ': '))))
                        pending = []

                break
            except:
                if __debug__: print_exc()
                retrying += 1
        else:
            plug.show_error(_("Error: Can't connect to EDSM"))

        if closing:
            return
Ejemplo n.º 21
0
def worker():

    pending = []	# Unsent events
    closing = False

    while True:
        item = this.queue.get()
        if item:
            (cmdr, entry) = item
        else:
            closing = True	# Try to send any unsent events before we close

        retrying = 0
        while retrying < 3:
            try:
                if item and entry['event'] not in this.discardedEvents:
                    pending.append(entry)

                # Get list of events to discard
                if not this.discardedEvents:
                    r = this.session.get('https://www.edsm.net/api-journal-v1/discard', timeout=_TIMEOUT)
                    r.raise_for_status()
                    this.discardedEvents = set(r.json())
                    this.discardedEvents.discard('Docked')	# should_send() assumes that we send 'Docked' events
                    assert this.discardedEvents			# wouldn't expect this to be empty
                    pending = [x for x in pending if x['event'] not in this.discardedEvents]	# Filter out unwanted events

                if should_send(pending):
                    (username, apikey) = credentials(cmdr)
                    data = {
                        'commanderName': username.encode('utf-8'),
                        'apiKey': apikey,
                        'fromSoftware': applongname,
                        'fromSoftwareVersion': appversion,
                        'message': json.dumps(pending, ensure_ascii=False).encode('utf-8'),
                    }
                    r = this.session.post('https://www.edsm.net/api-journal-v1', data=data, timeout=_TIMEOUT)
                    r.raise_for_status()
                    reply = r.json()
                    (msgnum, msg) = reply['msgnum'], reply['msg']
                    # 1xx = OK, 2xx = fatal error, 3&4xx not generated at top-level, 5xx = error but events saved for later processing
                    if msgnum // 100 == 2:
                        print('EDSM\t%s %s\t%s' % (msgnum, msg, json.dumps(pending, separators = (',', ': '))))
                        plug.show_error(_('Error: EDSM {MSG}').format(MSG=msg))
                    else:
                        for e, r in zip(pending, reply['events']):
                            if not closing and e['event'] in ['StartUp', 'Location', 'FSDJump']:
                                # Update main window's system status
                                this.lastlookup = r
                                this.system.event_generate('<<EDSMStatus>>', when="tail")	# calls update_status in main thread
                            elif r['msgnum'] // 100 != 1:
                                print('EDSM\t%s %s\t%s' % (r['msgnum'], r['msg'], json.dumps(e, separators = (',', ': '))))
                        pending = []

                break
            except:
                if __debug__: print_exc()
                retrying += 1
        else:
            plug.show_error(_("Error: Can't connect to EDSM"))

        if closing:
            return
Ejemplo n.º 22
0
def worker():
    while True:
        item = this.queue.get()
        if not item:
            return  # Closing
        else:
            (url, data, callback) = item

        retrying = 0
        while retrying < 3:
            try:
                r = this.session.post(url,
                                      headers=API_HEADERS,
                                      data=json.dumps(data,
                                                      separators=(',', ':')),
                                      timeout=_TIMEOUT)
                r.raise_for_status()
                reply = r.json()
                status = reply['header']['eventStatus']
                if callback:
                    callback(reply)
                elif status // 100 != 2:  # 2xx == OK (maybe with warnings)
                    # Log fatal errors
                    print(
                        ('SFR\t%s %s' %
                         (reply['header']['eventStatus'], reply['header'].get(
                             'eventStatusText', ''))))
                    print((json.dumps(data, indent=2, separators=(',', ': '))))
                    plug.show_error(
                        _('Error: SFR {MSG}').format(MSG=reply['header'].get(
                            'eventStatusText', status)))
                    this.status["text"] = "ERROR"
                else:
                    # Log individual errors and warnings
                    for data_event, reply_event in zip(data['events'],
                                                       reply['events']):
                        if reply_event['eventStatus'] != 200:
                            print(('SFR\t%s %s\t%s' %
                                   (reply_event['eventStatus'],
                                    reply_event.get('eventStatusText', ''),
                                    json.dumps(data_event))))
                            if reply_event['eventStatus'] // 100 != 2:
                                plug.show_error(
                                    _('Error: SFR {MSG}').format(
                                        MSG='%s, %s' %
                                        (data_event['eventName'],
                                         reply_event.get(
                                             'eventStatusText',
                                             reply_event['eventStatus']))))
                        if data_event['eventName'] in [
                                'addCommanderTravelDock',
                                'addCommanderTravelFSDJump',
                                'setCommanderTravelLocation'
                        ]:
                            this.lastlocation = reply_event.get(
                                'eventData', {})
                            this.system_link.event_generate(
                                '<<SFRLocation>>', when="tail"
                            )  # calls update_location in main thread
                        elif data_event['eventName'] in [
                                'addCommanderShip', 'setCommanderShip'
                        ]:
                            this.lastship = reply_event.get('eventData', {})
                            this.system_link.event_generate(
                                '<<SFRShip>>', when="tail"
                            )  # calls update_ship in main thread

                break
            except:
                print_exc()
                retrying += 1
        else:
            if callback:
                callback(None)
            else:
                plug.show_error(_("Error: Can't connect to SFR"))
                this.status["text"] = "ERROR"
Ejemplo n.º 23
0
def worker():
    while True:
        item = this.queue.get()
        if not item:
            return  # Closing
        else:
            (url, data, callback) = item

        retrying = 0
        while retrying < 3:
            try:
                r = this.session.post(url,
                                      data=json.dumps(data,
                                                      separators=(',', ':')),
                                      timeout=_TIMEOUT)
                r.raise_for_status()
                reply = r.json()
                status = reply['header']['eventStatus']
                if callback:
                    callback(reply)
                elif status // 100 != 2:  # 2xx == OK (maybe with warnings)
                    # Log fatal errors
                    print 'Inara\t%s %s' % (reply['header']['eventStatus'],
                                            reply['header'].get(
                                                'eventStatusText', ''))
                    print json.dumps(data, indent=2, separators=(',', ': '))
                    plug.show_error(
                        _('Error: Inara {MSG}').format(MSG=reply['header'].get(
                            'eventStatusText', status)))
                else:
                    # Log individual errors and warnings
                    for data_event, reply_event in zip(data['events'],
                                                       reply['events']):
                        if reply_event['eventStatus'] != 200:
                            print 'Inara\t%s %s\t%s' % (
                                reply_event['eventStatus'],
                                reply_event.get('eventStatusText',
                                                ''), json.dumps(data_event))
                            if reply_event['eventStatus'] // 100 != 2:
                                plug.show_error(
                                    _('Error: Inara {MSG}').format(
                                        MSG='%s, %s' %
                                        (data_event['eventName'],
                                         reply_event.get(
                                             'eventStatusText',
                                             reply_event['eventStatus']))))
                        if data_event['eventName'] in [
                                'addCommanderTravelDock',
                                'addCommanderTravelFSDJump',
                                'setCommanderTravelLocation'
                        ]:
                            eventData = reply_event.get('eventData', {})
                            this.system = eventData.get('starsystemInaraURL')
                            if config.get('system_provider') == 'Inara':
                                this.system_link[
                                    'url'] = this.system  # Override standard URL function
                            this.station = eventData.get('stationInaraURL')
                            if config.get('station_provider') == 'Inara':
                                this.station_link[
                                    'url'] = this.station or this.system  # Override standard URL function
                break
            except:
                if __debug__: print_exc()
                retrying += 1
        else:
            if callback:
                callback(None)
            else:
                plug.show_error(_("Error: Can't connect to Inara"))
Ejemplo n.º 24
0
def worker() -> None:
    """
    Upload worker.

    Processes `this.queue` until the queued item is None.
    """
    pending = []  # Unsent events
    closing = False

    while True:
        item: Optional[Tuple[str, Mapping[str, Any]]] = this.queue.get()
        if item:
            (cmdr, entry) = item
        else:
            closing = True  # Try to send any unsent events before we close

        retrying = 0
        while retrying < 3:
            try:
                if TYPE_CHECKING:
                    # Tell the type checker that these two are bound.
                    # TODO: While this works because of the item check below, these names are still technically unbound
                    # TODO: in some cases, therefore this should be refactored.
                    cmdr: str = ""
                    entry: Mapping[str, Any] = {}

                if item and entry[
                        'event'] not in this.discardedEvents:  # TODO: Technically entry can be unbound here.
                    pending.append(entry)

                # Get list of events to discard
                if not this.discardedEvents:
                    r = this.session.get(
                        'https://www.edsm.net/api-journal-v1/discard',
                        timeout=_TIMEOUT)
                    r.raise_for_status()
                    this.discardedEvents = set(r.json())
                    this.discardedEvents.discard(
                        'Docked'
                    )  # should_send() assumes that we send 'Docked' events
                    if not this.discardedEvents:
                        logger.error(
                            'Unexpected empty discarded events list from EDSM. Bailing out of send: '
                            f'{type(this.discardedEvents)} -- {this.discardedEvents}'
                        )
                        continue

                    # Filter out unwanted events
                    pending = list(
                        filter(
                            lambda x: x['event'] not in this.discardedEvents,
                            pending))

                if should_send(pending):
                    if any(p for p in pending
                           if p['event'] in ('CarrierJump', 'FSDJump',
                                             'Location', 'Docked')):
                        logger.trace(
                            "pending has at least one of "
                            "('CarrierJump', 'FSDJump', 'Location', 'Docked')"
                            " and it passed should_send()")
                        for p in pending:
                            if p['event'] in ('Location'):
                                logger.trace(
                                    '"Location" event in pending passed should_send(), '
                                    f'timestamp: {p["timestamp"]}')

                    creds = credentials(cmdr)  # TODO: possibly unbound
                    if creds is None:
                        raise ValueError("Unexpected lack of credentials")

                    username, apikey = creds
                    data = {
                        'commanderName':
                        username.encode('utf-8'),
                        'apiKey':
                        apikey,
                        'fromSoftware':
                        applongname,
                        'fromSoftwareVersion':
                        appversion,
                        'message':
                        json.dumps(pending,
                                   ensure_ascii=False).encode('utf-8'),
                    }

                    if any(p for p in pending
                           if p['event'] in ('CarrierJump', 'FSDJump',
                                             'Location', 'Docked')):
                        data_elided = data.copy()
                        data_elided['apiKey'] = '<elided>'
                        logger.trace(
                            "pending has at least one of "
                            "('CarrierJump', 'FSDJump', 'Location', 'Docked')"
                            " Attempting API call with the following events:")

                        for p in pending:
                            logger.trace(f"Event: {p!r}")
                            if p['event'] in ('Location'):
                                logger.trace(
                                    'Attempting API call for "Location" event with timestamp: '
                                    f'{p["timestamp"]}')

                        logger.trace(
                            f'Overall POST data (elided) is:\n{data_elided}')

                    r = this.session.post(
                        'https://www.edsm.net/api-journal-v1',
                        data=data,
                        timeout=_TIMEOUT)
                    logger.trace(f'API response content: {r.content}')
                    r.raise_for_status()
                    reply = r.json()
                    msg_num = reply['msgnum']
                    msg = reply['msg']
                    # 1xx = OK
                    # 2xx = fatal error
                    # 3&4xx not generated at top-level
                    # 5xx = error but events saved for later processing

                    if msg_num // 100 == 2:
                        logger.warning(
                            f'EDSM\t{msg_num} {msg}\t{json.dumps(pending, separators=(",", ": "))}'
                        )
                        plug.show_error(_('Error: EDSM {MSG}').format(MSG=msg))

                    else:

                        if msg_num // 100 == 1:
                            logger.trace('Overall OK')

                        elif msg_num // 100 == 5:
                            logger.trace(
                                'Event(s) not currently processed, but saved for later'
                            )

                        else:
                            logger.warning(
                                f'EDSM API call status not 1XX, 2XX or 5XX: {msg.num}'
                            )

                        for e, r in zip(pending, reply['events']):
                            if not closing and e['event'] in ('StartUp',
                                                              'Location',
                                                              'FSDJump',
                                                              'CarrierJump'):
                                # Update main window's system status
                                this.lastlookup = r
                                # calls update_status in main thread
                                this.system_link.event_generate(
                                    '<<EDSMStatus>>', when="tail")

                            if r['msgnum'] // 100 != 1:
                                logger.warning(
                                    f'EDSM event with not-1xx status:\n{r["msgnum"]}\n{r["msg"]}\n'
                                    f'{json.dumps(e, separators = (",", ": "))}'
                                )

                        pending = []

                break  # No exception, so assume success
            except Exception as e:
                logger.debug(
                    f'Attempt to send API events: retrying == {retrying}',
                    exc_info=e)
                retrying += 1

        else:
            plug.show_error(_("Error: Can't connect to EDSM"))

        if closing:
            return