Update main.py, api.py and three other files

This commit is contained in:
Richard Bronkhorst 2023-06-15 21:10:33 +02:00
parent e9815cfca8
commit ffd094df87
5 changed files with 147 additions and 14 deletions

View File

@ -2,7 +2,7 @@ import argparse
from nullptr.commander import Commander
def main(args):
c = Commander(args.store_dir, args.agent)
c = Commander(args.store_dir)
c.run()
# X1-AG74-41076A
@ -11,6 +11,5 @@ def main(args):
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('-s', '--store-dir', default='data')
parser.add_argument('-a', '--agent', default=None)
args = parser.parse_args()
main(args)

View File

@ -3,6 +3,7 @@ from nullptr.models.system import System
from nullptr.models.waypoint import Waypoint
from nullptr.models.marketplace import Marketplace
from nullptr.models.jumpgate import Jumpgate
from nullptr.models.ship import Ship
from .util import *
from time import sleep
class ApiError(Exception):
@ -17,7 +18,9 @@ class Api:
def __init__(self, store, agent):
self.agent = agent
self.store = store
self.requests_sent = 0
self.meta = None
self.last_result = None
self.root = 'https://api.spacetraders.io/v2/'
def token(self):
@ -37,6 +40,7 @@ class Api:
headers = {}
if need_token:
headers['Authorization'] = 'Bearer ' + self.token()
self.requests_sent += 1
if method == 'get':
params['limit'] = 20
r = requests.request(method, self.root+path, json=data, headers=headers, params=params)
@ -93,4 +97,8 @@ class Api:
symbol = str(waypoint)
return self.store.update(Jumpgate, symbol, data)
def list_ships(self):
data = self.request('get', 'my/ships')
return self.store.update_list(Ship, data)

View File

@ -14,11 +14,11 @@ from threading import Thread
from nullptr.atlas_builder import AtlasBuilder
class Commander(CommandLine):
def __init__(self, store_dir='data', agent=None):
def __init__(self, store_dir='data'):
self.store_dir = store_dir
self.store = Store(store_dir)
self.store.load()
self.agent = self.select_agent(agent)
self.agent = self.select_agent()
self.api = Api(self.store, self.agent)
self.atlas_builder = AtlasBuilder(self.store, self.api)
self.analyzer = Analyzer(self.store)
@ -35,16 +35,13 @@ class Commander(CommandLine):
print('not found')
return obj
def select_agent(self, agent_str):
if agent_str is not None:
return self.store.get(Agent, agent_str)
else:
agents = self.store.all(Agent)
agent = next(agents, None)
if agent is None:
symbol = input('agent name: ')
agent = self.store.get(Agent, symbol)
return agent
def select_agent(self):
agents = self.store.all(Agent)
agent = next(agents, None)
if agent is None:
symbol = input('agent name: ')
agent = self.store.get(Agent, symbol)
return agent
def after_cmd(self):
self.store.flush()
@ -94,3 +91,13 @@ class Commander(CommandLine):
# dest = self.store.get(System, 'X1-DA90')
path = self.analyzer.find_path(orig, dest)
pprint(path)
def do_ships(self, arg=''):
if arg.startswith('r'):
r = self.api.list_ships()
else:
r = list(self.store.all('Ship'))
pprint(r)
def do_pp(self):
pprint(self.api.last_result)

111
nullptr/models/ship.py Normal file
View File

@ -0,0 +1,111 @@
from .base import Base
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 = {}
status:str = ''
cargo_capacity:int = 0
cargo_units:int = 0
location_str = ''
cooldown:int = 0
arrival:int = 0
fuel_current:int = 0
fuel_capacity:int = 0
mission:str = None
mission_status:str = 'init'
@classmethod
def ext(self):
return 'shp'
def location(self):
return self.store.get('Waypoint', self.location_str)
def path(self):
agent = self.symbol.split('-')[0]
return f'{agent}/{self.symbol}.{self.ext()}'
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')
self.seta('fuel_current', d,'fuel.current')
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)
def tick(self):
if self.status == 'IN_TRANSIT' and self.arrival < time():
self.status = 'IN_ORBIT'
def is_cooldown(self):
return self.cooldown > time()
def is_travelling(self):
return self.status == 'IN_TRANSIT'
def get_cargo(self, typ):
if typ not in self.cargo:
return 0
return self.cargo[typ].units
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)
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)
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]
garbage = [c for c in cargo if c not in deliveries]
return garbage
def update_timers(self):
if self.status == 'IN_TRANSIT' and self.arrival < time():
self.status = 'IN_ORBIT'
def f(self, detail=1):
self.update_timers()
arrival = int(self.arrival - time())
cooldown = int(self.cooldown - time())
r = self.symbol
if detail > 1:
r += ' ' + self.status
r += f' [{self.fuel_current}/{self.fuel_capacity}]'
r += ' ' + str(self.location())
if self.is_travelling():
r += f' [A: {arrival}]'
if self.is_cooldown():
r += f' [C: {cooldown}]'
return r

View File

@ -6,6 +6,7 @@ from nullptr.models.agent import Agent
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 os.path import isfile, dirname, isdir
import os
from os.path import basename
@ -24,6 +25,7 @@ class Store:
def init_models(self):
self.models = all_subclasses(Base)
self.extensions = {c.ext(): c for c in self.models}
self.model_names = {c.__name__: c for c in self.models}
def dirty(self, obj):
self.dirty_objects.add(obj)
@ -78,6 +80,9 @@ class Store:
return obj
def get(self, typ, symbol, create=False):
if type(typ) == str and typ in self.model_names:
typ = self.model_names[typ]
if typ not in self.data:
return None
if symbol not in self.data[typ]:
@ -96,6 +101,9 @@ class Store:
return [self.update(typ, mg(d, 'symbol'), d) for d in lst]
def all(self, typ):
if type(typ) == str and typ in self.model_names:
typ = self.model_names[typ]
for m in self.data[typ].values():
yield m