Эх сурвалжийг харах

prunplanner/share: generate a CSV of the construction materials

raylu 2 долоо хоног өмнө
parent
commit
49595f0bb0
1 өөрчлөгдсөн 89 нэмэгдсэн , 12 устгасан
  1. 89 12
      prunplanner/share.py

+ 89 - 12
prunplanner/share.py

@@ -1,30 +1,107 @@
+'''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:]
 
-	client = httpx.Client(headers={'Authorization': 'Bearer ' + jwt})
-	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()}
+	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']]
-		print(plan['name'], 'https://prunplanner.org/shared/' + shared_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()