'''share all plans in an account and generate a CSV of the construction materials''' from __future__ import annotations import collections import csv import sys import typing import httpx import cache def main(): jwt,= sys.argv[1:] with httpx.Client(headers={'Authorization': 'Bearer ' + jwt}) as client: plans: typing.Sequence[Plan] = client.get('https://api.prunplanner.org/baseplanner/').raise_for_status().json() shared: typing.Mapping[str, str] = {s['plan_uuid']: s['shared_uuid'] for s in client.get('https://api.prunplanner.org/shared/list').raise_for_status().json()} for plan in plans: if plan['uuid'] not in shared: print('sharing', plan['uuid'], plan['name']) client.put('https://api.prunplanner.org/shared/baseplanner/' + plan['uuid']).raise_for_status() # refresh shared UUIDs shared: typing.Mapping[str, str] = {s['plan_uuid']: s['shared_uuid'] for s in client.get('https://api.prunplanner.org/shared/list').raise_for_status().json()} buildings: typing.Mapping[str, BuildingData] = {b['Ticker']: b for b in cache.get('https://api.prunplanner.org/data/buildings')} writer = csv.DictWriter(sys.stdout, fieldnames=['plan', 'share', 'PSL', 'TRU', 'MCG', 'BL', 'MGC', 'HSE', 'SEA', 'INS', 'TSH', 'BBH', 'BDE', 'BSE', 'BTA', 'LBH', 'LDE', 'LSE', 'LTA', 'RBH', 'RDE', 'RSE', 'RTA', 'ABH', 'ADE', 'ASE', 'ATA']) writer.writeheader() for plan in plans: shared_uuid = shared[plan['uuid']] planet: Planet = cache.get('https://api.prunplanner.org/data/planet/' + plan['baseplanner_data']['planet']['planetid']) plan_mats = collections.defaultdict(int) for mat in mats(buildings['CM'], planet): plan_mats[mat['CommodityTicker']] += mat['Amount'] for plan_building in plan['baseplanner_data']['buildings']: building_data = buildings[plan_building['name']] for mat in mats(building_data, planet): plan_mats[mat['CommodityTicker']] += mat['Amount'] * plan_building['amount'] for infra_building in plan['baseplanner_data']['infrastructure']: building_data = buildings[infra_building['building']] for mat in mats(building_data, planet): plan_mats[mat['CommodityTicker']] += mat['Amount'] * infra_building['amount'] writer.writerow({'plan': plan['name'], 'share': 'https://prunplanner.org/shared/' + shared_uuid, **plan_mats}) def mats(building: BuildingData, planet: Planet) -> typing.Iterator[BuildingMat]: for mat in building['BuildingCosts']: yield mat if planet['Surface']: # rocky yield {'CommodityTicker': 'MCG', 'Amount': building['AreaCost'] * 4} else: # gaseous yield {'CommodityTicker': 'AEF', 'Amount': math.ceil(building['AreaCost'] / 3)} if planet['Gravity'] > 2.5: yield {'CommodityTicker': 'BL', 'Amount': 1} elif planet['Gravity'] < 0.25: yield {'CommodityTicker': 'MGC', 'Amount': 1} if planet['Pressure'] > 2: yield {'CommodityTicker': 'HSE', 'Amount': 1} elif planet['Pressure'] < 0.25: yield {'CommodityTicker': 'SEA', 'Amount': building['AreaCost']} if planet['Temperature'] < -25: yield {'CommodityTicker': 'INS', 'Amount': building['AreaCost'] * 10} elif planet['Temperature'] > 75: yield {'CommodityTicker': 'TSH', 'Amount': 1} class Plan(typing.TypedDict): uuid: str name: str baseplanner_data: BaseplannerData class BaseplannerData(typing.TypedDict): planet: dict infrastructure: typing.Sequence[InfrastructureBuilding] buildings: typing.Sequence[PlanBuilding] class InfrastructureBuilding(typing.TypedDict): building: str amount: int class PlanBuilding(typing.TypedDict): name: str amount: int class Planet(typing.TypedDict): Surface: bool Pressure: float Temperature: float Gravity: float class BuildingData(typing.TypedDict): Ticker: str AreaCost: int BuildingCosts: list[BuildingMat] class BuildingMat(typing.TypedDict): CommodityTicker: str Amount: int if __name__ == '__main__': main()