def key_info(self, api_result=None): """Returns the details of the API key being used to auth.""" key = api_result.result.find('key') result = { 'access_mask': int(key.attrib['accessMask']), 'type': constants.APIKey.key_types[key.attrib['type']], 'expire_ts': api.parse_ts(key.attrib['expires']) if key.attrib['expires'] else None, 'characters': {}, } rowset = key.find('rowset') for row in rowset.findall('row'): character = { 'id': int(row.attrib['characterID']), 'name': row.attrib['characterName'], 'corp': { 'id': int(row.attrib['corporationID']), 'name': row.attrib['corporationName'], }, } if 'allianceID' in row.attrib: character['alliance'] = { 'id': int(row.attrib['allianceID']), 'name': row.attrib['allianceName'], } else: character['alliance'] = None result['characters'][character['id']] = character return api.APIResult(result, api_result.timestamp, api_result.expires)
def kills_by_system(self, api_result=None): """Get kill counts for systems in the last hour. Returns a tuple of ({system:{killdata}, timestamp). Each {killdata} is {'faction':count, 'ship':count, 'pod':count}. """ rowset = api_result.result.find('rowset') results = {} for row in rowset.findall('row'): system = int(row.attrib['solarSystemID']) faction_kills = int(row.attrib['factionKills']) ship_kills = int(row.attrib['shipKills']) pod_kills = int(row.attrib['podKills']) results[system] = { 'id': system, 'faction': faction_kills, 'ship': ship_kills, 'pod': pod_kills, } data_time = api.parse_ts(api_result.result.find('dataTime').text) return api.APIResult((results, data_time), api_result.timestamp, api_result.expires)
def assets(self, api_result=None): """Get information about corp assets. Each item is a dict, with keys 'id', 'item_type_id', 'quantity', 'location_id', 'location_flag', and 'packaged'. 'location_flag' denotes additional information about the item's location; see http://wiki.eve-id.net/API_Inventory_Flags for more details. If the item corresponds to a container, it will have a key 'contents', which is itself a list of items in the same format (potentially recursively holding containers of its own). If the contents do not have 'location_id's of their own, they inherit the 'location_id' of their parent container, for convenience. At the top level, the result is a dict mapping location ID (typically a solar system) to a dict containing a 'contents' key, which maps to a list of items. That is, you can think of the top-level values as "containers" with no fields except for "contents" and "location_id". """ return api.APIResult(parse_assets(api_result.result), api_result.timestamp, api_result.expires)
def faction_warfare_stats(self, api_result=None): """Returns FW stats for this character, if enrolled in FW. NOTE: This will return an error instead if the character is not enrolled in Faction Warfare. """ _str, _int, _float, _bool, _ts = api.elem_getters(api_result.result) result = { 'faction': { 'id': _int('factionID'), 'name': _str('factionName'), }, 'enlist_ts': _ts('enlisted'), 'rank': { 'current': _int('currentRank'), 'highest': _int('highestRank'), }, 'kills': { 'yesterday': _int('killsYesterday'), 'week': _int('killsLastWeek'), 'total': _int('killsTotal'), }, 'points': { 'yesterday': _int('victoryPointsYesterday'), 'week': _int('victoryPointsLastWeek'), 'total': _int('victoryPointsTotal'), }, } return api.APIResult(result, api_result.timestamp, api_result.expires)
def standings(self, api_result=None): """Returns the standings towards a character from NPC entities.""" result = {} rowsets = {} for rowset in api_result.result.find('characterNPCStandings').findall( 'rowset'): rowsets[rowset.attrib['name']] = rowset _name_map = { 'agents': 'agents', 'corps': 'NPCCorporations', 'factions': 'factions', } for key, rowset_name in _name_map.items(): result[key] = {} for row in rowsets[rowset_name].findall('row'): a = row.attrib from_id = int(a['fromID']) result[key][from_id] = { 'id': from_id, 'name': a['fromName'], 'standing': float(a['standing']), } return api.APIResult(result, api_result.timestamp, api_result.expires)
def skills(self, api_result=None): """Returns a specific character's skills.""" _str, _int, _float, _bool, _ts = api.elem_getters(api_result.result) result = { 'free_skillpoints': _int('freeSkillPoints'), } rowsets = {} for rowset in api_result.result.findall('rowset'): key = rowset.attrib['name'] rowsets[key] = rowset result['skills'] = {} result['skillpoints'] = 0 for skill in rowsets['skills']: a = skill.attrib skill_id = int(a['typeID']) sp = int(a['skillpoints']) result['skills'][skill_id] = { 'id': skill_id, 'skillpoints': sp, 'level': int(a['level']), 'published': a['published'] == '1', } result['skillpoints'] += sp return api.APIResult(result, api_result.timestamp, api_result.expires)
def permissions(self, api_result=None): """Returns information about corporation member permissions.""" results = {} rowset = api_result.result.find('rowset') for row in rowset.findall('row'): a = row.attrib member = { 'id': int(a['characterID']), 'name': a['name'], 'titles': {}, } rowsets = dict((r.attrib['name'], r) for r in row.findall('rowset')) for title_row in rowsets['titles'].findall('row'): a = title_row.attrib member['titles'][int(a['titleID'])] = a['titleName'] def get_roleset(roles_dict): roles_group = {} for key, rowset_name in roles_dict.items(): roles = {} roles_rowset = rowsets[rowset_name] for role_row in roles_rowset.findall('row'): a = role_row.attrib roles[int(a['roleID'])] = a['roleName'] roles_group[key] = roles return roles_group member['roles'] = get_roleset(constants.Corp.role_types) member['can_grant'] = get_roleset(constants.Corp.grantable_types) results[member['id']] = member return api.APIResult(results, api_result.timestamp, api_result.expires)
def faction_warfare_stats(self, api_result=None): """Returns stats from faction warfare if this corp is enrolled. NOTE: This will raise an APIError if the corp is not enrolled in Faction Warfare. """ _str, _int, _float, _bool, _ts = api.elem_getters(api_result.result) result = { 'faction': { 'id': _int('factionID'), 'name': _str('factionName'), }, 'start_ts': _ts('enlisted'), 'pilots': _int('pilots'), 'kills': { 'yesterday': _int('killsYesterday'), 'week': _int('killsLastWeek'), 'total': _int('killsTotal'), }, 'points': { 'yesterday': _int('victoryPointsYesterday'), 'week': _int('victoryPointsLastWeek'), 'total': _int('victoryPointsTotal'), }, } return api.APIResult(result, api_result.timestamp, api_result.expires)
def character_names_from_ids(self, id_list, api_result=None): """Retrieve a dict mapping character IDs to names. id_list: A list of ids to retrieve names. NOTE: *ALL* character IDs passed to this function must be valid - an invalid character ID will cause the entire call to fail. """ if api_result is None: # The API doesn't actually tell us which character IDs are invalid msg = "One or more of these character IDs are invalid: %r" raise ValueError(msg % id_list) rowset = api_result.result.find('rowset') rows = rowset.findall('row') results = {} for row in rows: name = row.attrib['name'] char_id = int(row.attrib['characterID']) results[char_id] = name return api.APIResult(results, api_result.timestamp, api_result.expires)
def stations(self, api_result=None): """Returns information about the corporation's (non-POS) stations.""" rowset = api_result.result.find('rowset') results = {} for row in rowset.findall('row'): a = row.attrib station = { 'id': int(a['stationID']), 'owner_id': int(a['ownerID']), 'name': a['stationName'], 'system_id': int(a['solarSystemID']), 'docking_fee_per_volume': float(a['dockingCostPerShipVolume']), 'office_fee': int(a['officeRentalCost']), 'type_id': int(a['stationTypeID']), 'reprocessing': { 'efficiency': float(a['reprocessingEfficiency']), 'cut': float(a['reprocessingStationTake']), }, 'standing_owner_id': int(a['standingOwnerID']), 'x': float(a['x']), 'y': float(a['y']), 'z': float(a['z']), } results[station['id']] = station return api.APIResult(results, api_result.timestamp, api_result.expires)
def shareholders(self, api_result=None): """Get information about a corp's shareholders.""" results = { 'char': {}, 'corp': {}, } rowsets = dict( (r.attrib['name'], r) for r in api_result.result.findall('rowset')) for row in rowsets['characters'].findall('row'): a = row.attrib holder = { 'id': int(a['shareholderID']), 'name': a['shareholderName'], 'corp': { 'id': int(a['shareholderCorporationID']), 'name': a['shareholderCorporationName'], }, 'shares': int(a['shares']), } results['char'][holder['id']] = holder for row in rowsets['corporations'].findall('row'): a = row.attrib holder = { 'id': int(a['shareholderID']), 'name': a['shareholderName'], 'shares': int(a['shares']), } results['corp'][holder['id']] = holder return api.APIResult(results, api_result.timestamp, api_result.expires)
def test_event_attendees(self, mock_calendar): mock_calendar.return_value = evelink_api.APIResult( {42: mock.sentinel.attendees}, 12345, 67890) result, current, expires = self.char.event_attendees(42) self.assertEqual(result, mock.sentinel.attendees) self.assertEqual(current, 12345) self.assertEqual(expires, 67890)
def alliances(self, api_result=None): """Return a dict of all alliances in EVE.""" results = {} rowset = api_result.result.find('rowset') for row in rowset.findall('row'): alliance = { 'name': row.attrib['name'], 'ticker': row.attrib['shortName'], 'id': int(row.attrib['allianceID']), 'executor_id': int(row.attrib['executorCorpID']), 'member_count': int(row.attrib['memberCount']), 'timestamp': api.parse_ts(row.attrib['startDate']), 'member_corps': {}, } corp_rowset = row.find('rowset') for corp_row in corp_rowset.findall('row'): corp_id = int(corp_row.attrib['corporationID']) corp_ts = api.parse_ts(corp_row.attrib['startDate']) alliance['member_corps'][corp_id] = { 'id': corp_id, 'timestamp': corp_ts, } results[alliance['id']] = alliance return api.APIResult(results, api_result.timestamp, api_result.expires)
def npc_standings(self, api_result=None): """Returns information about the corporation's standings towards NPCs. NOTE: This is *only* NPC standings. Player standings are accessed via the 'contacts' method. """ container = api_result.result.find('corporationNPCStandings') rowsets = dict( (r.attrib['name'], r) for r in container.findall('rowset')) results = { 'agents': {}, 'corps': {}, 'factions': {}, } _standing_types = { 'agents': 'agents', 'corps': 'NPCCorporations', 'factions': 'factions', } for key, rowset_name in _standing_types.items(): for row in rowsets[rowset_name].findall('row'): a = row.attrib standing = { 'id': int(a['fromID']), 'name': a['fromName'], 'standing': float(a['standing']), } results[key][standing['id']] = standing return api.APIResult(results, api_result.timestamp, api_result.expires)
def messages(self, api_result=None): """Returns a list of headers for a character's mail.""" rowset = api_result.result.find('rowset') results = [] for row in rowset.findall('row'): a = row.attrib message = { 'id': int(a['messageID']), 'sender_id': int(a['senderID']), 'timestamp': api.parse_ts(a['sentDate']), 'title': a['title'], 'to': {}, } org_id = a['toCorpOrAllianceID'] message['to']['org_id'] = int(org_id) if org_id else None char_ids = a['toCharacterIDs'] message['to']['char_ids'] = [int(i) for i in char_ids.split(',') ] if char_ids else None list_ids = a['toListID'] message['to']['list_ids'] = [int(i) for i in list_ids.split(',') ] if list_ids else None results.append(message) return api.APIResult(results, api_result.timestamp, api_result.expires)
def customs_offices(self, api_result=None): rowset = api_result.result.find('rowset') rows = rowset.findall('row') results = {} for row in rows: a = row.attrib results[int(a['itemID'])] = { 'system': { 'id': int(a['solarSystemID']), 'name': a['solarSystemName'], }, 'permissions': { 'alliance': a['allowAlliance'] == 'True', 'standings': a['allowStandings'] == 'True', 'minimum_standing': float(a['standingLevel']), }, 'reinforce_hour': int(a['reinforceHour']), 'tax_rate': { 'alliance': float(a['taxRateAlliance']), 'corp': float(a['taxRateCorp']), 'standings': { 'high': float(a['taxRateStandingHigh']), 'good': float(a['taxRateStandingGood']), 'neutral': float(a['taxRateStandingNeutral']), 'bad': float(a['taxRateStandingBad']), 'horrible': float(a['taxRateStandingHorrible']), }, }, } return api.APIResult(results, api_result.timestamp, api_result.expires)
def type_name_from_id(self, type_id): """Retrieve a type name based on ID. Convenience wrapper around type_names_from_ids(). """ api_result = self.type_names_from_ids([type_id]) return api.APIResult(api_result.result.get(int(type_id)), api_result.timestamp, api_result.expires)
def character_id_from_name(self, name): """Retrieve the named character's ID. Convenience wrapper around character_ids_from_names(). """ api_result = self.character_ids_from_names([name]) return api.APIResult(api_result.result.get(name), api_result.timestamp, api_result.expires)
def kills(self, before_kill=None, api_result=None): """Look up recent kills for a corporation. before_kill: Optional. Only show kills before this kill id. (Used for paging.) """ return api.APIResult(parse_kills(api_result.result), api_result.timestamp, api_result.expires)
def character_name_from_id(self, char_id): """Retrieve the character's name based on ID. Convenience wrapper around character_names_from_ids(). """ api_result = self.character_names_from_ids([char_id]) return api.APIResult(api_result.result.get(char_id), api_result.timestamp, api_result.expires)
def wallet_transactions(self, before_id=None, limit=None, account=None, api_result=None): """Returns wallet transactions for a corporation.""" return api.APIResult(parse_wallet_transactions(api_result.result), api_result.timestamp, api_result.expires)
def clones(self, api_result=None): """Returns jumpclones for a specific character.""" _str, _int, _float, _bool, _ts = api.elem_getters(api_result.result) result = { 'create_ts': _ts('DoB'), 'race': _str('race'), 'bloodline': _str('bloodLine'), 'ancestry': _str('ancestry'), 'remote_station_ts': _ts('remoteStationDate'), 'last_respec_ts': _ts('lastRespecDate'), 'last_timed_respec_ts': _ts('lastTimedRespec'), 'free_respecs': _int('freeRespecs'), 'gender': _str('gender'), 'attributes': {}, 'implants': {}, 'jumpclone': { 'jump_ts': _ts('cloneJumpDate'), }, } for attr in ('intelligence', 'memory', 'charisma', 'perception', 'willpower'): result['attributes'][attr] = {} base = int(api_result.result.findtext('attributes/%s' % attr)) result['attributes'][attr]['base'] = base rowsets = {} for rowset in api_result.result.findall('rowset'): key = rowset.attrib['name'] rowsets[key] = rowset for implant in rowsets['implants']: a = implant.attrib result['implants'][int(a['typeID'])] = a['typeName'] jumpclone_implants = {} for implant in rowsets['jumpCloneImplants']: a = implant.attrib jumpclone_id = int(a['jumpCloneID']) implants = jumpclone_implants.setdefault(jumpclone_id, {}) implants[int(a['typeID'])] = a['typeName'] result['jumpclone']['clones'] = {} for jumpclone in rowsets['jumpClones']: a = jumpclone.attrib jumpclone_id = int(a['jumpCloneID']) location_id = int(a['locationID']) # This is keyed off location_id because it simplifies a # common lookup ("what systems do I have jumpclones in") result['jumpclone']['clones'][location_id] = { 'id': jumpclone_id, 'name': a['cloneName'], 'type_id': int(a['typeID']), 'location_id': location_id, 'implants': jumpclone_implants.get(jumpclone_id, {}) } return api.APIResult(result, api_result.timestamp, api_result.expires)
def server_status(self, api_result=None): """Check the current server status.""" result = { 'online': api.get_bool_value(api_result.result, 'serverOpen'), 'players': api.get_int_value(api_result.result, 'onlinePlayers'), } return api.APIResult(result, api_result.timestamp, api_result.expires)
def affiliations_for_character(self, char_id): """Retrieve the affiliations of a single character Convenience wrapper around owner_ids_from_names(). """ api_result = self.affiliations_for_characters([char_id]) return api.APIResult(api_result.result[char_id], api_result.timestamp, api_result.expires)
def faction_warfare_stats(self, api_result=None): """Return various statistics from Faction Warfare.""" totals = api_result.result.find('totals') rowsets = dict( (r.attrib['name'], r) for r in api_result.result.findall('rowset')) _str, _int, _float, _bool, _ts = api.elem_getters(totals) results = { 'kills': { 'yesterday': _int('killsYesterday'), 'week': _int('killsLastWeek'), 'total': _int('killsTotal'), }, 'points': { 'yesterday': _int('victoryPointsYesterday'), 'week': _int('victoryPointsLastWeek'), 'total': _int('victoryPointsTotal'), }, 'factions': {}, 'wars': [], } for row in rowsets['factions'].findall('row'): a = row.attrib faction = { 'id': int(a['factionID']), 'name': a['factionName'], 'pilots': int(a['pilots']), 'systems': int(a['systemsControlled']), 'kills': { 'yesterday': int(a['killsYesterday']), 'week': int(a['killsLastWeek']), 'total': int(a['killsTotal']), }, 'points': { 'yesterday': int(a['victoryPointsYesterday']), 'week': int(a['victoryPointsLastWeek']), 'total': int(a['victoryPointsTotal']), }, } results['factions'][faction['id']] = faction for row in rowsets['factionWars'].findall('row'): a = row.attrib war = { 'faction': { 'id': int(a['factionID']), 'name': a['factionName'], }, 'against': { 'id': int(a['againstID']), 'name': a['againstName'], }, } results['wars'].append(war) return api.APIResult(results, api_result.timestamp, api_result.expires)
def mailing_lists(self, api_result=None): """Returns the mailing lists to which a character is subscribed.""" rowset = api_result.result.find('rowset') results = {} for row in rowset.findall('row'): a = row.attrib results[int(a['listID'])] = a['displayName'] return api.APIResult(results, api_result.timestamp, api_result.expires)
def type_names_from_ids(self, id_list, api_result=None): """Return a dict containing id -> name mappings for the supplied type ids.""" rowset = api_result.result.find('rowset') results = {} for row in rowset.findall('row'): a = row.attrib results[int(a['typeID'])] = a['typeName'] return api.APIResult(results, api_result.timestamp, api_result.expires)
def faction_warfare_leaderboard(self, api_result=None): """Return top-100 lists from Faction Warfare.""" def parse_top_100(rowset, prefix, attr, attr_name): top100 = [] id_field = '%sID' % prefix name_field = '%sName' % prefix for row in rowset.findall('row'): a = row.attrib top100.append({ 'id': int(a[id_field]), 'name': a[name_field], attr_name: int(a[attr]), }) return top100 def parse_section(section, prefix): section_result = {} rowsets = dict( (r.attrib['name'], r) for r in section.findall('rowset')) section_result['kills'] = { 'yesterday': parse_top_100(rowsets['KillsYesterday'], prefix, 'kills', 'kills'), 'week': parse_top_100(rowsets['KillsLastWeek'], prefix, 'kills', 'kills'), 'total': parse_top_100(rowsets['KillsTotal'], prefix, 'kills', 'kills'), } section_result['points'] = { 'yesterday': parse_top_100(rowsets['VictoryPointsYesterday'], prefix, 'victoryPoints', 'points'), 'week': parse_top_100(rowsets['VictoryPointsLastWeek'], prefix, 'victoryPoints', 'points'), 'total': parse_top_100(rowsets['VictoryPointsTotal'], prefix, 'victoryPoints', 'points'), } return section_result results = { 'char': parse_section(api_result.result.find('characters'), 'character'), 'corp': parse_section(api_result.result.find('corporations'), 'corporation'), 'faction': parse_section(api_result.result.find('factions'), 'faction'), } return api.APIResult(results, api_result.timestamp, api_result.expires)
def wallet_info(self, api_result=None): """Return a given character's wallet.""" rowset = api_result.result.find('rowset') row = rowset.find('row') result = { 'balance': float(row.attrib['balance']), 'id': int(row.attrib['accountID']), 'key': int(row.attrib['accountKey']), } return api.APIResult(result, api_result.timestamp, api_result.expires)
def reference_types(self, api_result=None): """Return a dict containing id -> name reference type mappings.""" rowset = api_result.result.find('rowset') results = {} for row in rowset.findall('row'): a = row.attrib results[int(a['refTypeID'])] = a['refTypeName'] return api.APIResult(results, api_result.timestamp, api_result.expires)