import argparse import json import re import sys import time from . import esi from . import zkill SYSTEM_AND_DATE = re.compile(r"/(\d+)/(\d+)/?$") def expand_hashes(snapshot): """ Expands killmails in *snapshot* IN PLACE by adding their hash based on information from Zkillboard. """ for killmail in snapshot['killmails']: time.sleep(1.05) # Zkillboard is very sensitive. killmail['hash'] = zkill.hash(killmail['killmail_id']) return snapshot def expand_details(snapshot): """ Expands killmails in *snapshot* IN PLACE by adding details from EVE ESI. Some data is dropped in process as e.g., full information on attackers is not important in context of the visualizations. """ for killmail in snapshot['killmails']: details = esi.killmail(killmail['killmail_id'], killmail['hash']) killmail.update(details) return snapshot def get_types(snapshot): ships = {x['victim']['ship_type_id'] for x in snapshot['killmails']} return [esi.type(x) for x in ships] def get_locations(snapshot): solar_system_ids = {x['solar_system_id'] for x in snapshot['killmails']} solar_systems = [esi.system(x) for x in solar_system_ids] constellation_ids = {x['constellation_id'] for x in solar_systems} constellations = {x: esi.constellation(x) for x in constellation_ids} region_ids = {x['region_id'] for x in constellations.values()} regions = {x: esi.region(x) for x in region_ids} for system in solar_systems: constellation = constellations[system['constellation_id']] region_id = constellation['region_id'] system['constellation_name'] = constellation['name'] system['region_name'] = regions[region_id]['name'] system['region_id'] = region_id return solar_systems def get_names(snapshot): fields = ['alliance_id', 'character_id', 'corporation_id', 'faction_id'] misc = set() alliances = set() corporations = set() for km in snapshot['killmails']: victim = km['victim'] for field in fields: if field in victim and victim[field] > 0: misc.add(victim[field]) if 'alliance_id' in victim: alliances.add(victim['alliance_id']) corporations.add(victim['corporation_id']) names = esi.names(json=list(misc)) names += [{'id': x, **esi.corporation(x)} for x in corporations] names += [{'id': x, **esi.alliance(x)} for x in alliances] return names def output_name(args): """ Generates name of the output file based on the CLI *args*. """ if args.output: return args.output match = SYSTEM_AND_DATE.search(args.url) if match: return "{}_{}.json".format(*match.groups()) return "a.json" def main(): parser = argparse.ArgumentParser() parser.add_argument("url") parser.add_argument("-o", "--output") parser.add_argument("--pretty", action='store_true') args = parser.parse_args() snapshot = zkill.parse_battle_report(args.url) expand_hashes(snapshot) expand_details(snapshot) snapshot['types'] = get_types(snapshot) snapshot['locations'] = get_locations(snapshot) snapshot['names'] = get_names(snapshot) filename = output_name(args) with open(filename, 'w') as fd: opts = {'indent': 4} if args.pretty else {} fd.write(json.dumps(snapshot, **opts)) fd.write("\n")