Files
PuGa/puga/contracts.py
dodoxandClaude Sonnet 5 c660559f74 Add tools/lmscan.py: live Local Market hauling-ad scan
Pulls real player-posted freight jobs from FIO's /localmarket/shipping
endpoints (public, no auth - distinct from the CONTD player-contract
system, which isn't exposed via any API). Ranks by margin after real
one-way fuel cost (puga.shipping.leg_cost), flagging ads that exceed the
account's ship hold or route through an unmeasured gateway.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-09 13:33:04 +02:00

36 lines
2.1 KiB
Python

"""Local Market hauling-ad scan: live ads from FIO's /localmarket/shipping/{source,destination}
(public, no auth - real player-posted freight-for-hire jobs, NOT the CONTD player-to-player
custom contract system). Evaluates each against the real fuel model (puga.shipping).
SHIP_CARGO is this account's actual ship hold (both AVI-07JFB/AVI-07JFC: 500 t, 500 m3 - confirmed
via FIO /storage/{user} SHIP_STORE). A contract whose cargo exceeds this needs multiple round
trips to fulfil in one hull; that case is flagged, not computed.
One-way cost only: this does NOT add a return trip home, because the realistic loop is picking
up the NEXT ad near the destination, not flying back empty. That makes the margin reported here
optimistic for a one-off job with nothing lined up on the return leg.
"""
from . import fio, shipping
SHIP_CARGO = 500.0 # t and m3, both ships
def scan(planet: str, direction: str, sf_price: float, ff_price: float, v0: float = 1.0, v1: float = 1.0):
"""direction: 'source' (ads picking up AT `planet`) or 'destination' (ads dropping off there).
Returns a list of ads enriched with cost/margin, deduplicated by ContractNaturalId."""
ads = fio.lm_shipping_source(planet) if direction == "source" else fio.lm_shipping_destination(planet)
seen, rows = set(), []
for ad in ads:
cid = ad["ContractNaturalId"]
if cid in seen:
continue
seen.add(cid)
over_capacity = ad["CargoWeight"] > SHIP_CARGO or ad["CargoVolume"] > SHIP_CARGO
cost = None if over_capacity else shipping.leg_cost(ad["OriginPlanetNaturalId"], ad["DestinationPlanetNaturalId"],
sf_price, ff_price, v0, v1)
payout = ad["PayoutPrice"] if ad["PayoutCurrency"] == "AIC" else None # non-AIC payout not priced here
margin = (payout - cost["aic"]) if (cost and payout is not None) else None
rows.append({**ad, "over_capacity": over_capacity, "cost": cost, "margin_aic": margin,
"margin_per_day": margin / max(ad["DeliveryTime"], 1) if margin is not None else None})
return rows