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

View File

@ -3,6 +3,7 @@ from nullptr.models.system import System
from nullptr.models.waypoint import Waypoint from nullptr.models.waypoint import Waypoint
from nullptr.models.marketplace import Marketplace from nullptr.models.marketplace import Marketplace
from nullptr.models.jumpgate import Jumpgate from nullptr.models.jumpgate import Jumpgate
from nullptr.models.ship import Ship
from .util import * from .util import *
from time import sleep from time import sleep
class ApiError(Exception): class ApiError(Exception):
@ -17,7 +18,9 @@ class Api:
def __init__(self, store, agent): def __init__(self, store, agent):
self.agent = agent self.agent = agent
self.store = store self.store = store
self.requests_sent = 0
self.meta = None self.meta = None
self.last_result = None
self.root = 'https://api.spacetraders.io/v2/' self.root = 'https://api.spacetraders.io/v2/'
def token(self): def token(self):
@ -37,6 +40,7 @@ class Api:
headers = {} headers = {}
if need_token: if need_token:
headers['Authorization'] = 'Bearer ' + self.token() headers['Authorization'] = 'Bearer ' + self.token()
self.requests_sent += 1
if method == 'get': if method == 'get':
params['limit'] = 20 params['limit'] = 20
r = requests.request(method, self.root+path, json=data, headers=headers, params=params) r = requests.request(method, self.root+path, json=data, headers=headers, params=params)
@ -93,4 +97,8 @@ class Api:
symbol = str(waypoint) symbol = str(waypoint)
return self.store.update(Jumpgate, symbol, data) 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 from nullptr.atlas_builder import AtlasBuilder
class Commander(CommandLine): class Commander(CommandLine):
def __init__(self, store_dir='data', agent=None): def __init__(self, store_dir='data'):
self.store_dir = store_dir self.store_dir = store_dir
self.store = Store(store_dir) self.store = Store(store_dir)
self.store.load() self.store.load()
self.agent = self.select_agent(agent) self.agent = self.select_agent()
self.api = Api(self.store, self.agent) self.api = Api(self.store, self.agent)
self.atlas_builder = AtlasBuilder(self.store, self.api) self.atlas_builder = AtlasBuilder(self.store, self.api)
self.analyzer = Analyzer(self.store) self.analyzer = Analyzer(self.store)
@ -35,16 +35,13 @@ class Commander(CommandLine):
print('not found') print('not found')
return obj return obj
def select_agent(self, agent_str): def select_agent(self):
if agent_str is not None: agents = self.store.all(Agent)
return self.store.get(Agent, agent_str) agent = next(agents, None)
else: if agent is None:
agents = self.store.all(Agent) symbol = input('agent name: ')
agent = next(agents, None) agent = self.store.get(Agent, symbol)
if agent is None: return agent
symbol = input('agent name: ')
agent = self.store.get(Agent, symbol)
return agent
def after_cmd(self): def after_cmd(self):
self.store.flush() self.store.flush()
@ -94,3 +91,13 @@ class Commander(CommandLine):
# dest = self.store.get(System, 'X1-DA90') # dest = self.store.get(System, 'X1-DA90')
path = self.analyzer.find_path(orig, dest) path = self.analyzer.find_path(orig, dest)
pprint(path) 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.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 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
@ -24,6 +25,7 @@ class Store:
def init_models(self): def init_models(self):
self.models = all_subclasses(Base) self.models = all_subclasses(Base)
self.extensions = {c.ext(): c for c in self.models} 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): def dirty(self, obj):
self.dirty_objects.add(obj) self.dirty_objects.add(obj)
@ -78,6 +80,9 @@ class Store:
return obj return obj
def get(self, typ, symbol, create=False): 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: if typ not in self.data:
return None return None
if symbol not in self.data[typ]: 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] return [self.update(typ, mg(d, 'symbol'), d) for d in lst]
def all(self, typ): 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(): for m in self.data[typ].values():
yield m yield m