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

This commit is contained in:
Richard Bronkhorst 2023-06-12 10:51:01 +02:00
parent 415d0e98c1
commit 80badca912
9 changed files with 79 additions and 26 deletions

View File

@ -6,6 +6,7 @@ def main(args):
c.run() c.run()
# X1-AG74-41076A # X1-AG74-41076A
# X1-KS52-51429E
if __name__ == '__main__': if __name__ == '__main__':
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()

View File

@ -2,6 +2,7 @@ import requests
from nullptr.models.system import System 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 .util import * from .util import *
class ApiError(Exception): class ApiError(Exception):
@ -71,6 +72,13 @@ class Api:
def marketplace(self, waypoint): def marketplace(self, waypoint):
system = waypoint.system() system = waypoint.system()
symbol = f'{waypoint}-market' 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, symbol, 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)

View File

@ -35,7 +35,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=str(type(e))!='ApiErrorp')
def handle_empty(self): def handle_empty(self):
pass pass

View File

@ -44,12 +44,12 @@ class Commander(CommandLine):
self.stop_auto = True self.stop_auto = True
print('stopping...') print('stopping...')
def do_universe(self): def do_universe(self, page=1):
print('universe mode. hit enter to stop') print('universe mode. hit enter to stop')
t = Thread(target=self.wait_for_stop) t = Thread(target=self.wait_for_stop)
t.daemon = True t.daemon = True
t.start() t.start()
self.all_systems() self.all_systems(int(page))
print('manual mode') print('manual mode')
def all_specials(self, waypoints): def all_specials(self, waypoints):
@ -60,26 +60,30 @@ class Commander(CommandLine):
self.api.marketplace(w) self.api.marketplace(w)
print(f'marketplace at {w}') print(f'marketplace at {w}')
sleep(0.5) sleep(0.5)
if w.type == 'JUMP_GATE':
self.api.jumps(w)
print(f'jumpgate at {w}')
def all_waypoints(self, systems): def all_waypoints(self, systems):
for s in systems: for s in systems:
if self.stop_auto: if self.stop_auto:
break break
r = self.api.list_waypoints(s) r = self.api.list_waypoints(s)
print(f'system {s}: {len(r)} waypoints')
self.all_specials(r) self.all_specials(r)
self.store.flush()
sleep(0.5) sleep(0.5)
def all_systems(self):
def all_systems(self, start_page):
self.stop_auto = False self.stop_auto = False
data = self.api.list_systems(1) data = self.api.list_systems(start_page)
pages = total_pages(self.api.last_meta) pages = total_pages(self.api.last_meta)
print(f'{pages} pages of systems') print(f'{pages} pages of systems')
print(f'page {1}: {len(data)} results') print(f'page {1}: {len(data)} results')
self.all_waypoints(data) self.all_waypoints(data)
self.store.flush()
for p in range(start_page+1, pages):
for p in range(2, pages):
if self.stop_auto: if self.stop_auto:
break break
data = self.api.list_systems(p) data = self.api.list_systems(p)
@ -101,3 +105,8 @@ class Commander(CommandLine):
waypoint = self.store.get(Waypoint, waypoint_str.upper()) waypoint = self.store.get(Waypoint, waypoint_str.upper())
r = self.api.marketplace(waypoint) r = self.api.marketplace(waypoint)
def do_jumps(self, waypoint_str):
waypoint = self.store.get(Waypoint, waypoint_str.upper())
r = self.api.jumps(waypoint)
pprint(r)

View File

@ -1,15 +1,18 @@
from copy import deepcopy from copy import deepcopy
from dataclasses import dataclass from dataclasses import dataclass
from nullptr.util import sg from nullptr.util import sg
@dataclass @dataclass
class Base: class Base:
symbol: str symbol: str
dirty: bool store: object
def __init__(self, symbol, store): def __init__(self, symbol, store):
self.symbol = symbol
self.store = store self.store = store
self.dirty = True self.symbol = symbol
def __hash__(self):
return hash(self.symbol)
def seta(self, attr, d, name=None): def seta(self, attr, d, name=None):
if name is None: if name is None:
@ -25,17 +28,19 @@ class Base:
setattr(self, attr, lst) setattr(self, attr, lst)
def __setattr__(self, name, value): def __setattr__(self, name, value):
if name != 'dirty': if name not in ['symbol','store']:
self.dirty = True self.store.dirty(self)
super().__setattr__(name, value) super().__setattr__(name, value)
def update(self, d): def update(self, d):
pass pass
def dict(self): def dict(self):
r = deepcopy(self.__dict__) r = {}
del r['store'] for k,v in self.__dict__.items():
del r['dirty'] if k == 'store':
continue
r[k] = deepcopy(v)
return r return r
def path(self): def path(self):

View File

@ -0,0 +1,20 @@
from .base import Base
from typing import List
class Jumpgate(Base):
range: int
faction: str
systems:List[str] = []
def update(self, d):
self.setlst('systems', d, 'connectedSystems', 'symbol')
self.seta('faction', d, 'factionSymbol')
self.seta('range', d, 'jumpRange')
@classmethod
def ext(self):
return 'jmp'
def path(self):
sector, system, symbol = self.symbol.split('-')
return f'atlas/{sector}/{system[0:1]}/{system}/{symbol}.{self.ext()}'

View File

@ -17,5 +17,5 @@ class Marketplace(Base):
return 'mkt' return 'mkt'
def path(self): def path(self):
sector, system, symbol, _ = self.symbol.split('-') sector, system, symbol = self.symbol.split('-')
return f'atlas/{sector}/{system[0:1]}/{system}/{symbol}.{self.ext()}' return f'atlas/{sector}/{system[0:1]}/{system}/{symbol}.{self.ext()}'

View File

@ -14,8 +14,7 @@ class Waypoint(Base):
self.seta('y', d) self.seta('y', d)
self.seta('type', d) self.seta('type', d)
self.seta('faction', d, 'faction.symbol') self.seta('faction', d, 'faction.symbol')
if 'traits' in d: self.setlst('traits', d, 'traits', 'symbol')
self.traits = [mg(t, 'symbol') for t in d['traits'] ]
@classmethod @classmethod
def ext(self): def ext(self):

View File

@ -7,11 +7,16 @@ from os.path import isfile, dirname, isdir
import os import os
import json import json
from .util import * from .util import *
from time import time
class Store: class Store:
def __init__(self, data_dir): def __init__(self, data_dir):
self.data_dir = data_dir self.data_dir = data_dir
self.data = {} self.data = {}
self.dirty_objects = set()
def dirty(self, obj):
self.dirty_objects.add(obj)
def path(self, obj): def path(self, obj):
return os.path.join(self.data_dir, obj.path()) return os.path.join(self.data_dir, obj.path())
@ -23,7 +28,6 @@ class Store:
with open(path) as f: with open(path) as f:
data = json.load(f) data = json.load(f)
data['store'] = self data['store'] = self
data['dirty'] = False
obj.__dict__ = data obj.__dict__ = data
def store(self, obj): def store(self, obj):
@ -34,12 +38,14 @@ class Store:
os.makedirs(path_dir, exist_ok=True) os.makedirs(path_dir, exist_ok=True)
with open(path, 'w') as f: with open(path, 'w') as f:
json.dump(data, f, indent=2) json.dump(data, f, indent=2)
obj.dirty = False
def get(self, typ, symbol): def get(self, typ, symbol):
oid = f'{symbol}.{typ.ext()}'
if oid in self.data:
return self.data[oid]
obj = typ(symbol, self) obj = typ(symbol, self)
self.load(obj) self.load(obj)
self.data[symbol] = obj self.data[oid] = obj
return obj return obj
def update(self, typ, symbol, data): def update(self, typ, symbol, data):
@ -68,6 +74,11 @@ class Store:
def flush(self): def flush(self):
for obj in self.data.values(): it = 0
if obj.dirty: start_time = time()
self.store(obj) for obj in self.dirty_objects:
it += 1
self.store(obj)
self.dirty_objects = set()
dur = time() - start_time
print(f'flush done {it} items {dur:.2f}')