Update api.py, command_line.py and five other files

This commit is contained in:
Richard Bronkhorst 2023-06-16 13:03:19 +02:00
parent 92a5a02180
commit 2c96cbb533
7 changed files with 117 additions and 32 deletions

View File

@ -90,17 +90,27 @@ class Api:
system = waypoint.system()
symbol = str(waypoint)
data = self.request('get', f'systems/{system}/waypoints/{waypoint}/market')
return self.store.update(Marketplace, symbol, data)
return self.store.update(Marketplace, data)
def jumps(self, waypoint):
data = self.request('get', f'systems/{waypoint.system()}/waypoints/{waypoint}/jump-gate')
symbol = str(waypoint)
return self.store.update(Jumpgate, symbol, data)
return self.store.update(Jumpgate, data)
def list_ships(self):
data = self.request('get', 'my/ships')
return self.store.update_list(Ship, data)
def list_contracts(self):
data = self.request('get', 'my/contracts')
return self.store.update_list('Contract', data)
def negotiate(self, ship):
data = self.request('post', f'my/ships/{ship}/negotiate/contract')
if data is not None and 'contract' in data:
contract = self.store.update('Contract', data['contract'])
return contract
def navigate(self, ship, wp):
data = {'waypointSymbol': str(wp)}
response = self.request('post', f'my/ships/{ship}/navigate', data)

View File

@ -41,7 +41,7 @@ class CommandLine:
print(f'command not found; {c}')
def handle_error(self, cmd, args, e):
logging.error(e, exc_info=str(type(e))!='ApiErrorp')
logging.error(e, exc_info=type(e).__name__ !='ApiError')
def handle_empty(self):
pass

View File

@ -81,8 +81,14 @@ class Commander(CommandLine):
system = self.store.get(System, system_str)
r = self.store.all_members(system, 'Waypoint')
for w in r:
traits = ','.join(w.traits)
print(w.symbol, traits)
traits = []
if 'MARKETPLACE' in w.traits:
traits.append('MARKET')
if 'SHIPYARD' in w.traits:
traits.append('SHIPYARD')
if w.type == 'JUMP_GATE':
traits.append('JUMP')
print(w.symbol.split('-')[2], ', '.join(traits))
def do_marketplace(self, waypoint_str):
waypoint = self.store.get(Waypoint, waypoint_str.upper())
@ -119,6 +125,13 @@ class Commander(CommandLine):
r = list(self.store.all('Ship'))
pprint(r)
def do_contracts(self, arg=''):
if arg.startswith('r'):
r = self.api.list_contracts()
else:
r = list(self.store.all('Contract'))
pprint(r)
def do_ship(self, arg=''):
if arg != '':
symbol = f'{self.agent.symbol}-{arg}'
@ -128,7 +141,7 @@ class Commander(CommandLine):
return
else:
self.ship = ship
pprint(ship)
pprint(self.ship)
def do_pp(self):
pprint(self.api.last_result)
@ -151,3 +164,8 @@ class Commander(CommandLine):
self.api.orbit(self.ship)
pprint(self.ship)
def do_negotiate(self):
if not self.has_ship(): return
r = self.api.negotiate(self.ship)
pprint(r)

View File

@ -4,6 +4,7 @@ from nullptr.util import sg
@dataclass
class Base:
identifier = 'symbol'
symbol: str
store: object
@ -17,11 +18,13 @@ class Base:
def __eq__(self, other):
return self.symbol == other.symbol and type(self) == type(other)
def seta(self, attr, d, name=None):
def seta(self, attr, d, name=None, interp=None):
if name is None:
name = attr
val = sg(d, name)
if val is not None:
if interp is not None:
val = interp(val)
setattr(self, attr, val)
def setlst(self, attr, d, name, member):
@ -37,6 +40,9 @@ class Base:
def update(self, d):
pass
def load(self, d):
self.__dict__ = d
def dict(self):
r = {}

View File

@ -0,0 +1,59 @@
from time import time
from nullptr.util import *
from .base import Base
from typing import List
class Contract(Base):
identifier = 'id'
type: str
deliveries: List
accepted: bool
fulfilled: bool
expires: int
expires_str: str
pay: int
@classmethod
def ext(cls):
return 'cnt'
def path(self):
return f'contracts/{self.symbol}.{self.ext()}'
def is_expired(self):
return time() > self.expires
def api_dict(self):
return {
'id': self.symbol,
'expiration': self.expires_str,
}
def update(self, d):
self.seta('expires',d, 'terms.deadline',parse_timestamp)
self.seta('expires_str', d,'terms.deadline')
self.seta('accepted', d, 'accepted')
self.seta('fulfilled', d, 'fulfilled')
self.seta('type', d, 'type')
self.pay = mg(d, 'terms.payment.onAccepted') + mg(d, 'terms.payment.onFulfilled')
deliveries = must_get(d, 'terms.deliver')
self.deliveries = []
for e in deliveries:
delivery = {}
delivery['trade_symbol'] = must_get(e, 'tradeSymbol')
delivery['units_fulfilled'] = must_get(e, 'unitsFulfilled')
delivery['units_required'] = must_get(e, 'unitsRequired')
delivery['destination'] = must_get(e, 'destinationSymbol')
self.deliveries.append(delivery)
def f(self, detail=1):
hours = int(max(0, self.expires - time()) / 3600)
accepted = 'A' if self.accepted else '-'
fulfilled = 'F' if self.fulfilled else '-'
result = f'{self.symbol} {hours}h {accepted}{fulfilled}'
if detail > 1:
result += '\n'
for d in self.deliveries:
result += f"({d['units_fulfilled']} / {d['units_required']}) {d['trade_symbol']} to {d['destination']}"
return result

View File

@ -3,13 +3,6 @@ from time import time
from nullptr.util import *
from dataclasses import dataclass
@dataclass
class InventoryItem:
symbol: str
units: int
def __str__(self):
return self.symbol + ': ' + str(self.units)
class Ship(Base):
cargo:dict = {}
mission_state:dict = {}
@ -38,7 +31,6 @@ class Ship(Base):
def update(self, d):
self.seta('status', d, 'nav.status')
self.seta('location_str', d, 'nav.waypointSymbol')
self.seta('cargo_capacity', d, 'cargo.capacity')
self.seta('cargo_units', d, 'cargo.units')
self.seta('fuel_capacity', d, 'fuel.capacity')
@ -46,13 +38,9 @@ class Ship(Base):
cargo = sg(d, 'cargo.inventory')
if cargo is not None:
self.load_cargo(cargo)
cooldown = sg(d, 'cooldown.expiration')
if cooldown:
self.cooldown = parse_timestamp(cooldown)
arrival = sg(d, 'nav.route.arrival')
if arrival:
self.arrival = parse_timestamp(arrival)
self.seta('cooldown', d, 'cooldown.expiration', parse_timestamp)
self.seta('arrival', d, 'nav.route.arrival', parse_timestamp)
def tick(self):
if self.status == 'IN_TRANSIT' and self.arrival < time():
self.status = 'IN_ORBIT'
@ -66,26 +54,26 @@ class Ship(Base):
def get_cargo(self, typ):
if typ not in self.cargo:
return 0
return self.cargo[typ].units
return self.cargo[typ]
def load_cargo(self, cargo):
result = {}
for i in cargo:
symbol = must_get(i, 'symbol')
units = must_get(i, 'units')
result[symbol] = InventoryItem(symbol, units)
result[symbol] = units
self.cargo = result
def deliverable_cargo(self, contract):
result = []
for d in contract.deliveries:
if self.get_cargo(d.trade_symbol) > 0:
result.append(d.trade_symbol)
if self.get_cargo(d['trade_symbol']) > 0:
result.append(d['trade_symbol'])
return result
def nondeliverable_cargo(self, contract):
cargo = [c.symbol for c in self.cargo.values()]
deliveries = [d.trade_symbol for d in contract.deliveries]
cargo = self.cargo.keys()
deliveries = [d['trade_symbol'] for d in contract.deliveries]
garbage = [c for c in cargo if c not in deliveries]
return garbage

View File

@ -7,6 +7,7 @@ from nullptr.models.marketplace import Marketplace
from nullptr.models.system_member import SystemMember
from nullptr.models.jumpgate import Jumpgate
from nullptr.models.ship import Ship
from nullptr.models.contract import Contract
from os.path import isfile, dirname, isdir
import os
from os.path import basename
@ -46,8 +47,8 @@ class Store:
typ = self.extensions[ext]
obj = self.create(typ, symbol)
data['store'] = self
obj.__dict__ = data
obj.load(data)
obj.store = self
return obj
def load(self):
@ -92,13 +93,16 @@ class Store:
return None
return self.data[typ][symbol]
def update(self, typ, symbol, data):
def update(self, typ, data):
if type(typ) == str and typ in self.model_names:
typ = self.model_names[typ]
symbol = mg(data, typ.identifier)
obj = self.get(typ, symbol, True)
obj.update(data)
return obj
def update_list(self, typ, lst):
return [self.update(typ, mg(d, 'symbol'), d) for d in lst]
return [self.update(typ, d) for d in lst]
def all(self, typ):
if type(typ) == str and typ in self.model_names: