planet_bases.py 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. from __future__ import annotations
  2. import collections
  3. import concurrent.futures
  4. import sys
  5. import typing
  6. import tap
  7. import cache
  8. class Args(tap.Tap):
  9. planets: list[str] = []
  10. sector: tuple[str, ...] = ()
  11. def configure(self) -> None:
  12. self.add_argument('planets', nargs='*', metavar='planet') # take planets as positional args instead of flag
  13. def main() -> None:
  14. args = Args().parse_args()
  15. if args.sector:
  16. sectors = []
  17. all_sector_ids, sector_systems = get_sectors()
  18. for sector in args.sector:
  19. if len(sector) == 2:
  20. if len(sector_ids := all_sector_ids[sector]) > 1:
  21. print(sector, 'has multiple sector ids')
  22. for sector_id in sector_ids:
  23. print(f'\t{sector_id}:', ', '.join(system['Name'] for system in sector_systems[sector_id]))
  24. return
  25. else:
  26. (sector_id,) = sector_ids
  27. sectors.append(sector_id)
  28. elif sector.startswith('sector-'):
  29. sectors.append(sector)
  30. else:
  31. sys.exit(f'invalid sector: {sector}')
  32. system_ids = set()
  33. for sector_id in sectors:
  34. system_ids.update(system['SystemId'] for system in sector_systems[sector_id])
  35. all_planets: typing.Sequence[Planet] = cache.get('https://rest.fnar.net/planet/allplanets/full')
  36. for planet in all_planets:
  37. if planet['SystemId'] in system_ids:
  38. args.planets.append(planet['PlanetName'])
  39. with concurrent.futures.ThreadPoolExecutor(max_workers=2) as executor:
  40. for planet, bases in zip(args.planets, executor.map(get_bases, args.planets)):
  41. print(planet)
  42. for base in bases:
  43. if base['OwnerCode'] is None:
  44. continue
  45. print(f'\t{base["OwnerCode"]}\t{base["OwnerName"]}')
  46. def get_sectors() -> tuple[typing.Mapping[str, typing.Collection[str]], typing.Mapping[str, typing.Sequence[System]]]:
  47. systems: typing.Sequence[System] = cache.get('https://rest.fnar.net/systemstars')
  48. sector_ids = collections.defaultdict(set)
  49. sector_systems = collections.defaultdict(list)
  50. for system in systems:
  51. sector_name = system['NaturalId'][:2]
  52. sector_ids[sector_name].add(system['SectorId'])
  53. sector_systems[system['SectorId']].append(system)
  54. return sector_ids, sector_systems
  55. def get_bases(planet: str) -> typing.Sequence[Site]:
  56. return cache.get('https://rest.fnar.net/planet/sites/' + planet)
  57. class System(typing.TypedDict):
  58. SystemId: str
  59. NaturalId: str
  60. Name: str
  61. SectorId: str
  62. class Planet(typing.TypedDict):
  63. PlanetNaturalId: str
  64. PlanetName: str
  65. SystemId: str
  66. class Site(typing.TypedDict):
  67. OwnerId: str
  68. OwnerName: int
  69. OwnerCode: str | None
  70. if __name__ == '__main__':
  71. main()