Update api.py, command_line.py and five other files
This commit is contained in:
parent
92a5a02180
commit
2c96cbb533
@ -90,17 +90,27 @@ class Api:
|
|||||||
system = waypoint.system()
|
system = waypoint.system()
|
||||||
symbol = str(waypoint)
|
symbol = str(waypoint)
|
||||||
data = self.request('get', f'systems/{system}/waypoints/{waypoint}/market')
|
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):
|
def jumps(self, waypoint):
|
||||||
data = self.request('get', f'systems/{waypoint.system()}/waypoints/{waypoint}/jump-gate')
|
data = self.request('get', f'systems/{waypoint.system()}/waypoints/{waypoint}/jump-gate')
|
||||||
symbol = str(waypoint)
|
symbol = str(waypoint)
|
||||||
return self.store.update(Jumpgate, symbol, data)
|
return self.store.update(Jumpgate, data)
|
||||||
|
|
||||||
def list_ships(self):
|
def list_ships(self):
|
||||||
data = self.request('get', 'my/ships')
|
data = self.request('get', 'my/ships')
|
||||||
return self.store.update_list(Ship, data)
|
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):
|
def navigate(self, ship, wp):
|
||||||
data = {'waypointSymbol': str(wp)}
|
data = {'waypointSymbol': str(wp)}
|
||||||
response = self.request('post', f'my/ships/{ship}/navigate', data)
|
response = self.request('post', f'my/ships/{ship}/navigate', data)
|
||||||
|
@ -41,7 +41,7 @@ class CommandLine:
|
|||||||
print(f'command not found; {c}')
|
print(f'command not found; {c}')
|
||||||
|
|
||||||
def handle_error(self, cmd, args, e):
|
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):
|
def handle_empty(self):
|
||||||
pass
|
pass
|
||||||
|
@ -81,8 +81,14 @@ class Commander(CommandLine):
|
|||||||
system = self.store.get(System, system_str)
|
system = self.store.get(System, system_str)
|
||||||
r = self.store.all_members(system, 'Waypoint')
|
r = self.store.all_members(system, 'Waypoint')
|
||||||
for w in r:
|
for w in r:
|
||||||
traits = ','.join(w.traits)
|
traits = []
|
||||||
print(w.symbol, 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):
|
def do_marketplace(self, waypoint_str):
|
||||||
waypoint = self.store.get(Waypoint, waypoint_str.upper())
|
waypoint = self.store.get(Waypoint, waypoint_str.upper())
|
||||||
@ -119,6 +125,13 @@ class Commander(CommandLine):
|
|||||||
r = list(self.store.all('Ship'))
|
r = list(self.store.all('Ship'))
|
||||||
pprint(r)
|
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=''):
|
def do_ship(self, arg=''):
|
||||||
if arg != '':
|
if arg != '':
|
||||||
symbol = f'{self.agent.symbol}-{arg}'
|
symbol = f'{self.agent.symbol}-{arg}'
|
||||||
@ -128,7 +141,7 @@ class Commander(CommandLine):
|
|||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
self.ship = ship
|
self.ship = ship
|
||||||
pprint(ship)
|
pprint(self.ship)
|
||||||
|
|
||||||
def do_pp(self):
|
def do_pp(self):
|
||||||
pprint(self.api.last_result)
|
pprint(self.api.last_result)
|
||||||
@ -151,3 +164,8 @@ class Commander(CommandLine):
|
|||||||
self.api.orbit(self.ship)
|
self.api.orbit(self.ship)
|
||||||
pprint(self.ship)
|
pprint(self.ship)
|
||||||
|
|
||||||
|
def do_negotiate(self):
|
||||||
|
if not self.has_ship(): return
|
||||||
|
r = self.api.negotiate(self.ship)
|
||||||
|
pprint(r)
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ from nullptr.util import sg
|
|||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class Base:
|
class Base:
|
||||||
|
identifier = 'symbol'
|
||||||
symbol: str
|
symbol: str
|
||||||
store: object
|
store: object
|
||||||
|
|
||||||
@ -17,11 +18,13 @@ class Base:
|
|||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
return self.symbol == other.symbol and type(self) == type(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:
|
if name is None:
|
||||||
name = attr
|
name = attr
|
||||||
val = sg(d, name)
|
val = sg(d, name)
|
||||||
if val is not None:
|
if val is not None:
|
||||||
|
if interp is not None:
|
||||||
|
val = interp(val)
|
||||||
setattr(self, attr, val)
|
setattr(self, attr, val)
|
||||||
|
|
||||||
def setlst(self, attr, d, name, member):
|
def setlst(self, attr, d, name, member):
|
||||||
@ -37,6 +40,9 @@ class Base:
|
|||||||
|
|
||||||
def update(self, d):
|
def update(self, d):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def load(self, d):
|
||||||
|
self.__dict__ = d
|
||||||
|
|
||||||
def dict(self):
|
def dict(self):
|
||||||
r = {}
|
r = {}
|
||||||
|
59
nullptr/models/contract.py
Normal file
59
nullptr/models/contract.py
Normal 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
|
@ -3,13 +3,6 @@ from time import time
|
|||||||
from nullptr.util import *
|
from nullptr.util import *
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class InventoryItem:
|
|
||||||
symbol: str
|
|
||||||
units: int
|
|
||||||
def __str__(self):
|
|
||||||
return self.symbol + ': ' + str(self.units)
|
|
||||||
|
|
||||||
class Ship(Base):
|
class Ship(Base):
|
||||||
cargo:dict = {}
|
cargo:dict = {}
|
||||||
mission_state:dict = {}
|
mission_state:dict = {}
|
||||||
@ -38,7 +31,6 @@ class Ship(Base):
|
|||||||
def update(self, d):
|
def update(self, d):
|
||||||
self.seta('status', d, 'nav.status')
|
self.seta('status', d, 'nav.status')
|
||||||
self.seta('location_str', d, 'nav.waypointSymbol')
|
self.seta('location_str', d, 'nav.waypointSymbol')
|
||||||
|
|
||||||
self.seta('cargo_capacity', d, 'cargo.capacity')
|
self.seta('cargo_capacity', d, 'cargo.capacity')
|
||||||
self.seta('cargo_units', d, 'cargo.units')
|
self.seta('cargo_units', d, 'cargo.units')
|
||||||
self.seta('fuel_capacity', d, 'fuel.capacity')
|
self.seta('fuel_capacity', d, 'fuel.capacity')
|
||||||
@ -46,13 +38,9 @@ class Ship(Base):
|
|||||||
cargo = sg(d, 'cargo.inventory')
|
cargo = sg(d, 'cargo.inventory')
|
||||||
if cargo is not None:
|
if cargo is not None:
|
||||||
self.load_cargo(cargo)
|
self.load_cargo(cargo)
|
||||||
cooldown = sg(d, 'cooldown.expiration')
|
self.seta('cooldown', d, 'cooldown.expiration', parse_timestamp)
|
||||||
if cooldown:
|
self.seta('arrival', d, 'nav.route.arrival', parse_timestamp)
|
||||||
self.cooldown = parse_timestamp(cooldown)
|
|
||||||
arrival = sg(d, 'nav.route.arrival')
|
|
||||||
if arrival:
|
|
||||||
self.arrival = parse_timestamp(arrival)
|
|
||||||
|
|
||||||
def tick(self):
|
def tick(self):
|
||||||
if self.status == 'IN_TRANSIT' and self.arrival < time():
|
if self.status == 'IN_TRANSIT' and self.arrival < time():
|
||||||
self.status = 'IN_ORBIT'
|
self.status = 'IN_ORBIT'
|
||||||
@ -66,26 +54,26 @@ class Ship(Base):
|
|||||||
def get_cargo(self, typ):
|
def get_cargo(self, typ):
|
||||||
if typ not in self.cargo:
|
if typ not in self.cargo:
|
||||||
return 0
|
return 0
|
||||||
return self.cargo[typ].units
|
return self.cargo[typ]
|
||||||
|
|
||||||
def load_cargo(self, cargo):
|
def load_cargo(self, cargo):
|
||||||
result = {}
|
result = {}
|
||||||
for i in cargo:
|
for i in cargo:
|
||||||
symbol = must_get(i, 'symbol')
|
symbol = must_get(i, 'symbol')
|
||||||
units = must_get(i, 'units')
|
units = must_get(i, 'units')
|
||||||
result[symbol] = InventoryItem(symbol, units)
|
result[symbol] = units
|
||||||
self.cargo = result
|
self.cargo = result
|
||||||
|
|
||||||
def deliverable_cargo(self, contract):
|
def deliverable_cargo(self, contract):
|
||||||
result = []
|
result = []
|
||||||
for d in contract.deliveries:
|
for d in contract.deliveries:
|
||||||
if self.get_cargo(d.trade_symbol) > 0:
|
if self.get_cargo(d['trade_symbol']) > 0:
|
||||||
result.append(d.trade_symbol)
|
result.append(d['trade_symbol'])
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def nondeliverable_cargo(self, contract):
|
def nondeliverable_cargo(self, contract):
|
||||||
cargo = [c.symbol for c in self.cargo.values()]
|
cargo = self.cargo.keys()
|
||||||
deliveries = [d.trade_symbol for d in contract.deliveries]
|
deliveries = [d['trade_symbol'] for d in contract.deliveries]
|
||||||
garbage = [c for c in cargo if c not in deliveries]
|
garbage = [c for c in cargo if c not in deliveries]
|
||||||
return garbage
|
return garbage
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ from nullptr.models.marketplace import Marketplace
|
|||||||
from nullptr.models.system_member import SystemMember
|
from nullptr.models.system_member import SystemMember
|
||||||
from nullptr.models.jumpgate import Jumpgate
|
from nullptr.models.jumpgate import Jumpgate
|
||||||
from nullptr.models.ship import Ship
|
from nullptr.models.ship import Ship
|
||||||
|
from nullptr.models.contract import Contract
|
||||||
from os.path import isfile, dirname, isdir
|
from os.path import isfile, dirname, isdir
|
||||||
import os
|
import os
|
||||||
from os.path import basename
|
from os.path import basename
|
||||||
@ -46,8 +47,8 @@ class Store:
|
|||||||
|
|
||||||
typ = self.extensions[ext]
|
typ = self.extensions[ext]
|
||||||
obj = self.create(typ, symbol)
|
obj = self.create(typ, symbol)
|
||||||
data['store'] = self
|
obj.load(data)
|
||||||
obj.__dict__ = data
|
obj.store = self
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
def load(self):
|
def load(self):
|
||||||
@ -92,13 +93,16 @@ class Store:
|
|||||||
return None
|
return None
|
||||||
return self.data[typ][symbol]
|
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 = self.get(typ, symbol, True)
|
||||||
obj.update(data)
|
obj.update(data)
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
def update_list(self, typ, lst):
|
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):
|
def all(self, typ):
|
||||||
if type(typ) == str and typ in self.model_names:
|
if type(typ) == str and typ in self.model_names:
|
||||||
|
Loading…
Reference in New Issue
Block a user