SatisfactoryPlusCalculator/factorygame/data/fetch.py

78 lines
3.5 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
2024-01-29 17:37:30 +00:00
import click
2024-02-02 16:44:14 +00:00
from sqlalchemy import create_engine, select, delete
2024-01-29 17:37:30 +00:00
from sqlalchemy.orm import Session
2024-01-30 17:07:28 +00:00
from factorygame.data.common import resource_needs_update, chose_resource
from .models import Base, ResourceFlow, Recipe
2024-01-29 17:37:30 +00:00
from .sfp import SatisfactoryPlus
from ..helper import click_prompt
2024-01-29 17:37:30 +00:00
@click.command()
@click.option("--debug", is_flag=True)
@click.option("--refetch", is_flag=True)
@click.option("--ignore-factories", type=list[str], default=["A.I. Fluid Packer", "Craft Bench", "Equipment Workshop"])
2024-01-29 17:37:30 +00:00
@click.argument("search")
def main(debug: bool, refetch: bool, ignore_factories: list[str], search: str):
2024-01-29 17:37:30 +00:00
engine = create_engine("sqlite:///file.db", echo=debug)
Base.metadata.create_all(bind=engine)
2024-02-02 16:44:14 +00:00
if not search:
print("Empty search option. Exiting…")
return
2024-01-29 17:37:30 +00:00
2024-02-02 16:44:14 +00:00
with Session(engine) as session:
resource = chose_resource(session=session, resource_label=search, prompt=click_prompt).result()
exists_in_db = resource is not None
2024-01-29 17:37:30 +00:00
with SatisfactoryPlus(ignore_factories=ignore_factories, debug=debug) as data_provider:
2024-02-02 16:44:14 +00:00
if resource is None:
ret = data_provider.search_for_resource(session=session, search=search)
if ret is None:
return
else:
resource, exists_in_db = ret
2024-01-29 17:37:30 +00:00
2024-02-02 16:44:14 +00:00
refetch |= resource_needs_update(resource)
if refetch:
if exists_in_db:
print("Deleting recipes for", resource.label)
2024-01-29 17:37:30 +00:00
with session.begin_nested():
2024-02-02 16:44:14 +00:00
resource.recipes_populated_at = None
flow_ids_to_delete: list[int] = list()
for flow in session.scalars(
select(ResourceFlow).where(ResourceFlow.resource_id == resource.id)
):
if flow.ingredient_in:
flow_ids_to_delete += map(lambda obj: obj.id, flow.ingredient_in.ingredients)
flow_ids_to_delete += map(lambda obj: obj.id, flow.ingredient_in.results)
session.delete(flow.ingredient_in)
if flow.result_of:
flow_ids_to_delete += map(lambda obj: obj.id, flow.result_of.ingredients)
flow_ids_to_delete += map(lambda obj: obj.id, flow.result_of.results)
session.delete(flow.result_of)
stmt = delete(ResourceFlow).where(ResourceFlow.id.in_(flow_ids_to_delete))
session.execute(stmt)
print("Refetching recipes for", resource.label)
else:
print("Fetching recipes for new resource", resource.label)
2024-01-29 17:37:30 +00:00
2024-02-02 16:44:14 +00:00
with session.begin_nested():
resource = data_provider.update_resource_recipes(session=session, resource=resource)
2024-01-29 17:37:30 +00:00
2024-02-02 16:44:14 +00:00
session.refresh(resource)
assert resource, "Resource must be set at this point"
stmt = select(Recipe).distinct().join(Recipe.ingredients).filter(ResourceFlow.resource_id == resource.id)
for recipe in session.scalars(stmt):
print("Used in recipe", recipe.describe())
stmt = select(Recipe).distinct().join(Recipe.results).filter(ResourceFlow.resource_id == resource.id)
for recipe in session.scalars(stmt):
print("Result of recipe", recipe.describe())
if __name__ == "__main__":
main()