Exemple #1
0
    def __init__(self, data_fn='static/systems.json'):
        '''Initialize a new EveData object.

        Queries the API for system data on creation.

        Args:
            data_fn (str): Path to JSON file with subset of systems.
        '''

        self.systems_df = pd.read_json(data_fn)
        self.system_ids = set(
            pd.concat([self.systems_df.Entry_ID, self.systems_df.Dest_ID]))

        self.last_query_time = None
        self.map_api = Map()

        tries = 0
        while (self.last_query_time is None):
            try:
                kills_df, jumps_df, sov_df = self.query()
            except Exception as e:
                print 'Error querying API on __init__:', e
                print 'Retrying [tries: {0}]'.format(tries)
                tries += 1

            else:
                self.kills_history = pd.Panel({self.last_query_time: kills_df})
                self.jumps_history = pd.Panel({self.last_query_time: jumps_df})
                self.sov_history = pd.Panel({self.last_query_time: sov_df})
            finally:
                if tries >= EveData.retry:
                    raise RuntimeError('Failed to query API on __init__')
    def __init__(self, data_fn='static/systems.json'):
        '''Initialize a new EveData object.

        Queries the API for system data on creation.

        Args:
            data_fn (str): Path to JSON file with subset of systems.
        '''

        self.systems_df = pd.read_json(data_fn)
        self.system_ids = set(pd.concat([self.systems_df.Entry_ID, 
                                     self.systems_df.Dest_ID]))

        self.last_query_time = None
        self.map_api = Map()
        
        tries = 0
        while(self.last_query_time is None):
            try:
                kills_df, jumps_df, sov_df = self.query()
            except Exception as e:
                print 'Error querying API on __init__:', e
                print 'Retrying [tries: {0}]'.format(tries)
                tries += 1

            else:
                self.kills_history = pd.Panel({self.last_query_time: kills_df})
                self.jumps_history = pd.Panel({self.last_query_time: jumps_df})
                self.sov_history = pd.Panel({self.last_query_time: sov_df})
            finally:
                if tries >= EveData.retry:
                    raise RuntimeError('Failed to query API on __init__')
Exemple #3
0
    def _update_npc_kills(self):
        kills = Map().kills_by_system()
        self.high_deltas = set()

        for system in kills.result[0].values():
            system_id = system['id']

            if system_id in self.npc_kills:
                delta = system['faction'] - self.npc_kills[system_id]
                self.npc_deltas[system_id] = delta

                if delta >= MIN_DELTA:
                    if self.starmap[system_id]['security'] < self.max_security:
                        self.high_deltas.add(system_id)

            self.npc_kills[system_id] = system['faction']

        self.npc_kills_cache_time = kills.expires
Exemple #4
0
class EveData(object):
    '''Manages EVE API access.

    Queries the EVE API for kills, jumps, and sovereignty. Stores
    history in a Pandas panel and writes it to disk on occasion (JK not yet
    actually, but soon (tm)).

    Attributes:
        systems_df (DataFrame): Data for the nullsec entry systems.
        system_ids (Series): Series with all relevant system IDs, for
        convenience.
        last_query_time (Timestamp): Most recent successful query to the API.
        map_api (Map): The evelink Map API object.
    '''

    update_interval = 1200
    retry = 5
    max_frames = 100
    keys = [
        'Dest_ID', 'Entry_ID', 'Dest', 'Dest_Region', 'Dest_TrueSec', 'Entry',
        'Entry_Region', 'Entry_Sec', 'Entry_ShipKills', 'Entry_PodKills',
        'Entry_Jumps', 'Dest_ShipKills', 'Dest_PodKills', 'Dest_Jumps'
    ]

    def __init__(self, data_fn='static/systems.json'):
        '''Initialize a new EveData object.

        Queries the API for system data on creation.

        Args:
            data_fn (str): Path to JSON file with subset of systems.
        '''

        self.systems_df = pd.read_json(data_fn)
        self.system_ids = set(
            pd.concat([self.systems_df.Entry_ID, self.systems_df.Dest_ID]))

        self.last_query_time = None
        self.map_api = Map()

        tries = 0
        while (self.last_query_time is None):
            try:
                kills_df, jumps_df, sov_df = self.query()
            except Exception as e:
                print 'Error querying API on __init__:', e
                print 'Retrying [tries: {0}]'.format(tries)
                tries += 1

            else:
                self.kills_history = pd.Panel({self.last_query_time: kills_df})
                self.jumps_history = pd.Panel({self.last_query_time: jumps_df})
                self.sov_history = pd.Panel({self.last_query_time: sov_df})
            finally:
                if tries >= EveData.retry:
                    raise RuntimeError('Failed to query API on __init__')

    def query(self):
        '''Perform a query for jumps, kills, and sov against the EVE API.

        Notes:
            Raises an exception when the query fails, and does *not* update
            the last_query_time attribute.
        Returns:
            (DataFrame, DataFrame, DataFrame): DataFrames with kills, jumps and
            sov, respectively.
        '''

        try:
            kills_res, _ = self.map_api.kills_by_system().result
            jumps_res, _ = self.map_api.jumps_by_system().result
            sov_res, _ = self.map_api.sov_by_system().result
        except Exception as e:
            print 'Error querying API:', e
            raise
        else:
            self.last_query_time = pd.Timestamp(time.ctime())

            kills_df = pd.DataFrame(kills_res).T.ix[self.system_ids]
            jumps_df = pd.DataFrame({
                'jumps': pd.Series(jumps_res)
            }).ix[self.system_ids]
            sov_df = pd.DataFrame(sov_res).T.ix[self.system_ids]

            return kills_df, jumps_df, sov_df

    def latest(self):
        '''Get the most recent API data being stored.

        Returns:
            (Timestamp, DataFrame): Last update time and the merged result DataFrame.
        '''

        kills = self.kills_history[self.last_query_time]
        jumps = self.jumps_history[self.last_query_time]

        merged = self.systems_df.copy()
        merged = merged.set_index('Entry_ID').sort_index()
        merged['Entry_ShipKills'] = kills.ix[
            self.systems_df.Entry_ID].ship.sort_index()
        merged['Entry_PodKills'] = kills.ix[
            self.systems_df.Entry_ID].pod.sort_index()
        merged['Entry_Jumps'] = jumps.ix[
            self.systems_df.Entry_ID].jumps.sort_index()
        merged.reset_index(inplace=True)

        merged = merged.set_index('Dest_ID').sort_index()
        merged['Dest_ShipKills'] = kills.ix[
            self.systems_df.Dest_ID].ship.sort_index()
        merged['Dest_PodKills'] = kills.ix[
            self.systems_df.Dest_ID].pod.sort_index()
        merged['Dest_Jumps'] = jumps.ix[
            self.systems_df.Dest_ID].jumps.sort_index()
        merged.reset_index(inplace=True)

        merged.sort_values('Dest_Region', inplace=True)
        merged.fillna(0, inplace=True)

        merged['Hotness'] = (merged.Dest_PodKills + merged.Dest_ShipKills) / \
                            (merged.Dest_PodKills + merged.Dest_ShipKills).max()

        merged['Color'] = [
            tuple(c) for c in cm.RdBu_r(merged.Hotness, bytes=True)
        ]

        return self.last_query_time, merged

    def update(self):
        '''Update the API if its been more than 20 minutes since the last query.

        Returns the most recent data, regardless of whether the update succeeds.

        Returns:
            The latest data (see the latest() method)
        '''

        cur_time = pd.Timestamp(time.ctime())
        if (cur_time - self.last_query_time).seconds > EveData.update_interval:
            try:
                kills_df, jumps_df, sov_df = self.query()
            except:
                pass
            else:
                self.kills_history[self.last_query_time] = kills_df
                self.jumps_history[self.last_query_time] = jumps_df
                self.sov_history[self.last_query_time] = sov_df

                if len(self.kills_history) >= EveData.max_frames:
                    del self.kills_history[self.kills_history.index.min()]
                if len(self.jumps_history) >= EveData.max_frames:
                    del self.jumps_history[self.jumps_history.index.min()]
                if len(self.kills_history) >= EveData.max_frames:
                    del self.sov_history[self.sov_history.index.min()]

        return self.latest()

    def dump(self):
        pass
class EveData(object):
    '''Manages EVE API access.

    Queries the EVE API for kills, jumps, and sovereignty. Stores
    history in a Pandas panel and writes it to disk on occasion (JK not yet
    actually, but soon (tm)).

    Attributes:
        systems_df (DataFrame): Data for the nullsec entry systems.
        system_ids (Series): Series with all relevant system IDs, for
        convenience.
        last_query_time (Timestamp): Most recent successful query to the API.
        map_api (Map): The evelink Map API object.
    '''

    update_interval = 1200
    retry = 5
    max_frames = 100
    keys = ['Dest_ID', 'Entry_ID', 'Dest', 'Dest_Region', 
            'Dest_TrueSec', 'Entry', 'Entry_Region', 'Entry_Sec', 
            'Entry_ShipKills', 'Entry_PodKills', 'Entry_Jumps', 
            'Dest_ShipKills', 'Dest_PodKills', 'Dest_Jumps']

    def __init__(self, data_fn='static/systems.json'):
        '''Initialize a new EveData object.

        Queries the API for system data on creation.

        Args:
            data_fn (str): Path to JSON file with subset of systems.
        '''

        self.systems_df = pd.read_json(data_fn)
        self.system_ids = set(pd.concat([self.systems_df.Entry_ID, 
                                     self.systems_df.Dest_ID]))

        self.last_query_time = None
        self.map_api = Map()
        
        tries = 0
        while(self.last_query_time is None):
            try:
                kills_df, jumps_df, sov_df = self.query()
            except Exception as e:
                print 'Error querying API on __init__:', e
                print 'Retrying [tries: {0}]'.format(tries)
                tries += 1

            else:
                self.kills_history = pd.Panel({self.last_query_time: kills_df})
                self.jumps_history = pd.Panel({self.last_query_time: jumps_df})
                self.sov_history = pd.Panel({self.last_query_time: sov_df})
            finally:
                if tries >= EveData.retry:
                    raise RuntimeError('Failed to query API on __init__')

    def query(self):
        '''Perform a query for jumps, kills, and sov against the EVE API.

        Notes:
            Raises an exception when the query fails, and does *not* update
            the last_query_time attribute.
        Returns:
            (DataFrame, DataFrame, DataFrame): DataFrames with kills, jumps and
            sov, respectively.
        '''

        try:
            kills_res, _ = self.map_api.kills_by_system().result
            jumps_res, _ = self.map_api.jumps_by_system().result
            sov_res, _ = self.map_api.sov_by_system().result
        except Exception as e:
            print 'Error querying API:', e
            raise
        else:
            self.last_query_time = pd.Timestamp('now', tz='UTC')

            kills_df = pd.DataFrame(kills_res).T.ix[self.system_ids]
            jumps_df = pd.DataFrame({'jumps': pd.Series(jumps_res)}).ix[self.system_ids]
            sov_df = pd.DataFrame(sov_res).T.ix[self.system_ids]

            return kills_df, jumps_df, sov_df

    def latest(self):
        '''Get the most recent API data being stored.

        Returns:
            (Timestamp, DataFrame): Last update time and the merged result DataFrame.
        '''

        kills = self.kills_history[self.last_query_time]
        jumps = self.jumps_history[self.last_query_time]

        merged = self.systems_df.copy()
        merged = merged.set_index('Entry_ID').sort_index()
        merged['Entry_ShipKills'] = kills.ix[self.systems_df.Entry_ID].ship.sort_index()
        merged['Entry_PodKills'] = kills.ix[self.systems_df.Entry_ID].pod.sort_index()
        merged['Entry_Jumps'] = jumps.ix[self.systems_df.Entry_ID].jumps.sort_index()
        merged.reset_index(inplace=True)

        merged = merged.set_index('Dest_ID').sort_index()
        merged['Dest_ShipKills'] = kills.ix[self.systems_df.Dest_ID].ship.sort_index()
        merged['Dest_PodKills'] = kills.ix[self.systems_df.Dest_ID].pod.sort_index()
        merged['Dest_Jumps'] = jumps.ix[self.systems_df.Dest_ID].jumps.sort_index()
        merged.reset_index(inplace=True)

        merged.sort_values('Dest_Region', inplace=True)
        merged.fillna(0, inplace=True)
        
        merged['Hotness'] = (merged.Dest_PodKills + merged.Dest_ShipKills) / \
                            (merged.Dest_PodKills + merged.Dest_ShipKills).max()

        merged['Color'] = [tuple(c) for c in cm.RdBu_r(merged.Hotness, bytes=True)]

        return self.last_query_time, merged


    def update(self):
        '''Update the API if its been more than 20 minutes since the last query.

        Returns the most recent data, regardless of whether the update succeeds.

        Returns:
            The latest data (see the latest() method)
        '''

        cur_time = pd.Timestamp('now', tz='UTC')
        if (cur_time - self.last_query_time).seconds > EveData.update_interval:
            try:
                kills_df, jumps_df, sov_df = self.query()
            except:
                pass
            else:
                self.kills_history[self.last_query_time] = kills_df
                self.jumps_history[self.last_query_time] = jumps_df
                self.sov_history[self.last_query_time] = sov_df

                if len(self.kills_history) >= EveData.max_frames:
                    del self.kills_history[self.kills_history.index.min()]
                if len(self.jumps_history) >= EveData.max_frames:
                    del self.jumps_history[self.jumps_history.index.min()]
                if len(self.kills_history) >= EveData.max_frames:
                    del self.sov_history[self.sov_history.index.min()]

        return self.latest()

    def dump(self):
        pass
Exemple #6
0
def get_sov_systems(alliance_id):
    _log.debug('Getting sov systems')
    sov = Map().sov_by_system().result[0]
    return dict(filter(lambda (_,v): v['alliance_id'] == alliance_id, sov.iteritems()))
Exemple #7
0
def pull_pos_info(sde, api_key):
    corp = Corp(api_key)

    my_character = Account(api_key).key_info().result['characters'].values()[0]
    my_alliance = my_character['alliance'][
        'id'] if 'alliance' in my_character else None
    logging.info('Fetching info for "%s" corporation' %
                 my_character['corp']['name'])

    sov = Map(api_key).sov_by_system().result[0]

    towerset = TowerSet(sde)
    towerset.add_all(corp.starbases().result)

    def details_cb(item_id):
        try:
            return corp.starbase_details(starbase_id=item_id).result
        except APIError as e:
            if e.code == '114':
                return None
            raise

    towerset.enrich(
        details_cb, lambda solar_id:
        (solar_id in sov and sov[solar_id]['alliance_id'] == my_alliance),
        my_alliance)

    modules = []
    towers = []
    assets = {}

    assets_api = corp.assets()
    assets_result = assets_api.result
    assets_timestamp = datetime.utcfromtimestamp(assets_api.timestamp)

    for location in assets_result:
        if sde.location(location).type != 'system':
            continue
        for item in assets_result[location]['contents']:
            item_id = item['id']
            if item['item_type_id'] in sde.towers:
                assets[item_id] = item
                towers.append(item_id)
            elif item['item_type_id'] in sde.tower_mods:
                assets[item_id] = item
                modules.append(item_id)

    def add_all_mods(locations):
        try:
            r = corp.locations(location_list=locations).result
            towerset.add_mods(r, assets)
        except APIError as e:
            if e.code == '135':
                if len(locations) == 1:
                    logging.warn("strange location: %r" % locations[0])
                else:
                    # recurse until we've got all the locations we *can* get
                    mid = len(locations) // 2
                    add_all_mods(locations[:mid])
                    add_all_mods(locations[mid:])
            else:
                raise

    add_all_mods(towers)
    for chunk in range(0, len(modules), 100):
        add_all_mods(modules[chunk:chunk + 100])

    return my_character, assets_timestamp, towerset