diff --git a/edshipyard.py b/edshipyard.py index ad19d518..4acbee93 100644 --- a/edshipyard.py +++ b/edshipyard.py @@ -1,11 +1,11 @@ -# Export ship loadout in E:D Shipyard plain text format +"""Export ship loadout in ED Shipyard plain text format.""" import os +import pathlib import pickle import re import time from collections import defaultdict -from os.path import join from typing import Dict, List, Union import outfitting @@ -13,6 +13,9 @@ import util_ships from config import config from edmc_data import edshipyard_slot_map as slot_map from edmc_data import ship_name_map +from EDMCLogging import get_main_logger + +logger = get_main_logger() __Module = Dict[str, Union[str, List[str]]] @@ -21,29 +24,44 @@ ship_map = ship_name_map.copy() # Ship masses # TODO: prefer something other than pickle for this storage (dev readability, security) -ships = pickle.load(open(join(config.respath_path, 'ships.p'), 'rb')) +ships = pickle.load(open(pathlib.Path(config.respath_path) / 'ships.p', 'rb')) -# Export ship loadout in E:D Shipyard plain text format -def export(data, filename=None): - def class_rating(module: __Module): +def export(data, filename=None) -> None: # noqa: C901, CCR001 + """ + Export ship loadout in E:D Shipyard plain text format. + + :param data: CAPI data. + :param filename: Override default file name. + """ + def class_rating(module: __Module) -> str: + """ + Return a string representation of the class of the given module. + + :param module: Module data dict. + :return: Rating of the module. + """ mod_class = module['class'] mod_rating = module['rating'] mod_mount = module.get('mount') mod_guidance = module.get('guidance') - ret = '{mod_class}{rating}'.format(mod_class=mod_class, rating=mod_rating) + ret = f'{mod_class}{mod_rating}' if 'guidance' in module: # Missiles - ret += "/{mount}{guidance}".format( - mount=mod_mount[0] if mod_mount is not None else 'F', - guidance=mod_guidance[0], - ) + if mod_mount is not None: + mount = mod_mount[0] + + else: + mount = 'F' + + guidance = mod_guidance[0], + ret += f'/{mount}{guidance}' elif 'mount' in module: # Hardpoints - ret += "/{mount}".format(mount=mod_mount) + ret += f'/{mod_mount}' elif 'Cabin' in module['name']: # Passenger cabins - ret += "/{name}".format(name=module['name'][0]) + ret += f'/{module["name"][0]}' return ret + ' ' @@ -78,11 +96,11 @@ def export(data, filename=None): # Specials if 'Fuel Tank' in module['name']: fuel += 2**int(module['class']) - name = '{} (Capacity: {})'.format(module['name'], 2**int(module['class'])) + name = f'{module["name"]} (Capacity: {2**int(module["class"])})' elif 'Cargo Rack' in module['name']: cargo += 2**int(module['class']) - name = '{} (Capacity: {})'.format(module['name'], 2**int(module['class'])) + name = f'{module["name"]} (Capacity: {2**int(module["class"])})' else: name = module['name'] @@ -107,13 +125,11 @@ def export(data, filename=None): if slot.lower().startswith('slot'): loadout[slot[-1]].append(cr + name) - elif __debug__ and not slot.lower().startswith('planetaryapproachsuite'): - print('EDShipyard: Unknown slot {}'.format(slot)) + elif not slot.lower().startswith('planetaryapproachsuite'): + logger.debug(f'EDShipyard: Unknown slot {slot}') except AssertionError as e: - if __debug__: - print('EDShipyard: {}'.format(e)) - + logger.debug(f'EDShipyard: {e!r}') continue # Silently skip unrecognized modules except Exception: @@ -124,25 +140,26 @@ def export(data, filename=None): ship = ship_map.get(data['ship']['name'].lower(), data['ship']['name']) if data['ship'].get('shipName') is not None: - _ships = '{}, {}'.format(ship, data['ship']['shipName']) + _ships = f'{ship}, {data["ship"]["shipName"]}' + else: _ships = ship - string = '[{}]\n'.format(_ships) + string = f'[{_ships}]\n' - SLOT_TYPES = ( + slot_types = ( 'H', 'L', 'M', 'S', 'U', None, 'BH', 'RB', 'TM', 'FH', 'EC', 'PC', 'SS', 'FS', None, 'MC', None, '9', '8', '7', '6', '5', '4', '3', '2', '1' ) - for slot in SLOT_TYPES: + for slot in slot_types: if not slot: string += '\n' elif slot in loadout: for name in loadout[slot]: - string += '{}: {}\n'.format(slot, name) + string += f'{slot}: {name}\n' - string += '---\nCargo : {} T\nFuel : {} T\n'.format(cargo, fuel) + string += f'---\nCargo : {cargo} T\nFuel : {fuel} T\n' # Add mass and range assert data['ship']['name'].lower() in ship_name_map, data['ship']['name'] @@ -150,14 +167,13 @@ def export(data, filename=None): try: mass += ships[ship_name_map[data['ship']['name'].lower()]]['hullMass'] - string += 'Mass : {:.2f} T empty\n {:.2f} T full\n'.format(mass, mass + fuel + cargo) + string += f'Mass : {mass:.2f} T empty\n {mass + fuel + cargo:.2f} T full\n' multiplier = pow(min(fuel, fsd['maxfuel']) / fsd['fuelmul'], 1.0 / fsd['fuelpower']) * fsd['optmass'] - string += 'Range : {:.2f} LY unladen\n {:.2f} LY laden\n'.format( - multiplier / (mass + fuel) + jumpboost, - multiplier / (mass + fuel + cargo) + jumpboost - ) + range_unladen = multiplier / (mass + fuel) + jumpboost, + range_laden = multiplier / (mass + fuel + cargo) + jumpboost + string += f'Range : {range_unladen:.2f} LY unladen\n {range_laden:.2f} LY laden\n' except Exception: if __debug__: @@ -174,14 +190,13 @@ def export(data, filename=None): regexp = re.compile(re.escape(ship) + r'\.\d{4}-\d\d-\d\dT\d\d\.\d\d\.\d\d\.txt') oldfiles = sorted([x for x in os.listdir(config.get_str('outdir')) if regexp.match(x)]) if oldfiles: - with open(join(config.get_str('outdir'), oldfiles[-1]), 'rU') as h: + with open(pathlib.Path(config.get_str('outdir')) / oldfiles[-1], 'rU') as h: if h.read() == string: return # same as last time - don't write # Write - filename = join(config.get_str('outdir'), '{}.{}.txt'.format( - ship, time.strftime('%Y-%m-%dT%H.%M.%S', time.localtime(querytime))) - ) + timestamp = time.strftime('%Y-%m-%dT%H.%M.%S', time.localtime(querytime)) + filename = pathlib.Path(config.get_str('outdir')) / f'{ship}.{timestamp}.txt' with open(filename, 'wt') as h: h.write(string)