1
0
mirror of https://github.com/EDCD/EDMarketConnector.git synced 2025-04-14 16:27:13 +03:00

Drop support for exporting in Coriolis-specific format

This commit is contained in:
Jonathan Harris 2017-08-18 15:35:09 +01:00
parent 7598d5b7b7
commit 66b9699b45
3 changed files with 33 additions and 233 deletions

View File

@ -22,7 +22,6 @@ from commodity import COMMODITY_DEFAULT
import outfitting import outfitting
import loadout import loadout
import edshipyard import edshipyard
import coriolis
import shipyard import shipyard
import eddn import eddn
import stats import stats
@ -43,7 +42,6 @@ try:
parser = argparse.ArgumentParser(prog=appcmdname, description='Prints the current system and station (if docked) to stdout and optionally writes player status, ship locations, ship loadout and/or station data to file. Requires prior setup through the accompanying GUI app.') parser = argparse.ArgumentParser(prog=appcmdname, description='Prints the current system and station (if docked) to stdout and optionally writes player status, ship locations, ship loadout and/or station data to file. Requires prior setup through the accompanying GUI app.')
parser.add_argument('-v', '--version', help='print program version and exit', action='store_const', const=True) parser.add_argument('-v', '--version', help='print program version and exit', action='store_const', const=True)
parser.add_argument('-a', metavar='FILE', help='write ship loadout to FILE in Companion API json format') parser.add_argument('-a', metavar='FILE', help='write ship loadout to FILE in Companion API json format')
parser.add_argument('-c', metavar='FILE', help='write ship loadout to FILE in Coriolis json format')
parser.add_argument('-e', metavar='FILE', help='write ship loadout to FILE in E:D Shipyard plain text format') parser.add_argument('-e', metavar='FILE', help='write ship loadout to FILE in E:D Shipyard plain text format')
parser.add_argument('-l', metavar='FILE', help='write ship locations to FILE in CSV format') parser.add_argument('-l', metavar='FILE', help='write ship locations to FILE in CSV format')
parser.add_argument('-m', metavar='FILE', help='write station commodity market data to FILE in CSV format') parser.add_argument('-m', metavar='FILE', help='write station commodity market data to FILE in CSV format')
@ -118,8 +116,6 @@ try:
h.write(json.dumps(data, ensure_ascii=False, indent=2, sort_keys=True, separators=(',', ': ')).encode('utf-8')) h.write(json.dumps(data, ensure_ascii=False, indent=2, sort_keys=True, separators=(',', ': ')).encode('utf-8'))
if args.a: if args.a:
loadout.export(data, args.a) loadout.export(data, args.a)
if args.c:
coriolis.export(data, args.c)
if args.e: if args.e:
edshipyard.export(data, args.e) edshipyard.export(data, args.e)
if args.l: if args.l:

View File

@ -206,7 +206,6 @@ Arguments:
-h, --help show this help message and exit -h, --help show this help message and exit
-v, --version print program version and exit -v, --version print program version and exit
-a FILE write ship loadout to FILE in Companion API json format -a FILE write ship loadout to FILE in Companion API json format
-c FILE write ship loadout to FILE in Coriolis json format
-e FILE write ship loadout to FILE in E:D Shipyard plain text format -e FILE write ship loadout to FILE in E:D Shipyard plain text format
-l FILE write ship locations to FILE in CSV format -l FILE write ship locations to FILE in CSV format
-m FILE write station commodity market data to FILE in CSV format -m FILE write station commodity market data to FILE in CSV format

View File

@ -7,11 +7,7 @@ import base64
from collections import OrderedDict from collections import OrderedDict
import cPickle import cPickle
import json import json
import os
from os.path import join
import re
import StringIO import StringIO
import time
import gzip import gzip
from config import config from config import config
@ -19,225 +15,6 @@ import outfitting
import companion import companion
# Map API slot names to Coriolis categories
# http://cdn.coriolis.io/schemas/ship-loadout/2.json
slot_map = {
'hugehardpoint' : 'hardpoints',
'largehardpoint' : 'hardpoints',
'mediumhardpoint' : 'hardpoints',
'smallhardpoint' : 'hardpoints',
'tinyhardpoint' : 'utility',
'armour' : 'standard',
'powerplant' : 'standard',
'mainengines' : 'standard',
'frameshiftdrive' : 'standard',
'lifesupport' : 'standard',
'powerdistributor' : 'standard',
'radar' : 'standard',
'fueltank' : 'standard',
'military' : 'internal',
'slot' : 'internal',
}
# Map API ship names to Coriolis names
ship_map = dict(companion.ship_map)
ship_map['cobramkiii'] = 'Cobra Mk III'
ship_map['cobramkiv'] = 'Cobra Mk IV',
ship_map['viper'] = 'Viper'
ship_map['viper_mkiv'] = 'Viper Mk IV'
# Map EDDN outfitting schema / in-game names to Coriolis names
# https://raw.githubusercontent.com/jamesremuscat/EDDN/master/schemas/outfitting-v1.0.json
standard_map = OrderedDict([ # in output order
('Armour', 'bulkheads'),
(None, 'cargoHatch'), # not available in the Companion API data
('Power Plant', 'powerPlant'),
('Thrusters', 'thrusters'),
('Frame Shift Drive', 'frameShiftDrive'),
('Life Support', 'lifeSupport'),
('Power Distributor', 'powerDistributor'),
('Sensors', 'sensors'),
('Fuel Tank', 'fuelTank'),
])
weaponmount_map = {
'Fixed' : 'Fixed',
'Gimballed' : 'Gimballed',
'Turreted' : 'Turret',
}
# Modules that have a name as well as a group
bulkheads = outfitting.armour_map.values()
fixup_map = {}
fixup_map.update({ x[0] : ('Scanner', x[0]) for x in outfitting.misc_internal_map.values() })
fixup_map.update({ x[0] : ('Countermeasure', x[0]) for x in outfitting.countermeasure_map.values() })
fixup_map.update({
'Advanced Plasma Accelerator' : ('Plasma Accelerator', 'Advanced Plasma Accelerator'),
'Corrosion Resistant Cargo Rack': ('Cargo Rack', 'Corrosion Resistant'),
'Cytoscrambler Burst Laser' : ('Burst Laser', 'Cytoscrambler'),
'Enforcer Cannon' : ('Multi-cannon', 'Enforcer'),
'Enhanced Performance Thrusters': ('Thrusters', 'Enhanced Performance'),
'Imperial Hammer Rail Gun' : ('Rail Gun', 'Imperial Hammer'),
'Luxury Class Passenger Cabin' : ('Luxury Passenger Cabin', None),
'Mining Lance Beam Laser' : ('Mining Laser', 'Mining Lance'),
'Multi-Cannon' : ('Multi-cannon', None),
'Pacifier Frag-Cannon' : ('Fragment Cannon', 'Pacifier'),
'Pack-Hound Missile Rack' : ('Missile Rack', 'Pack-Hound'),
'Pulse Disruptor Laser' : ('Pulse Laser', 'Disruptor'),
'Retributor Beam Laser' : ('Beam Laser', 'Retributor'),
'Rocket Propelled FSD Disruptor': ('Missile Rack', 'Rocket Propelled FSD Disruptor'),
'Shock Mine Launcher' : ('Mine Launcher', 'Shock Mine Launcher'),
'Standard Docking Computer' : ('Docking Computer', 'Standard Docking Computer'),
})
# Ship masses
ships = cPickle.load(open(join(config.respath, 'ships.p'), 'rb'))
def export(data, filename=None):
querytime = config.getint('querytime') or int(time.time())
loadout = OrderedDict([ # Mimic Coriolis export ordering
('$schema', 'http://cdn.coriolis.io/schemas/ship-loadout/2.json#'),
('name', ship_map.get(data['ship']['name'].lower(), data['ship']['name'])),
('ship', ship_map.get(data['ship']['name'].lower(), data['ship']['name'])),
('components', OrderedDict([
('standard', OrderedDict([(x,None) for x in standard_map.values()])),
('hardpoints', []),
('utility', []),
('internal', []),
])),
])
maxpri = 0
mass = 0.0
fsd = None
# Correct module ordering relies on the fact that "Slots" in the data are correctly ordered alphabetically.
# Correct hardpoint ordering additionally relies on the fact that "Huge" < "Large" < "Medium" < "Small"
for slot in sorted(data['ship']['modules']):
v = data['ship']['modules'][slot]
try:
for s in slot_map:
if slot.lower().startswith(s):
category = slot_map[s]
break
else:
if __debug__:
for skip in ['bobble', 'decal', 'paintjob', 'planetaryapproachsuite', 'enginecolour', 'shipkit', 'weaponcolour']:
if slot.lower().startswith(skip):
break
else:
print 'Coriolis: Unknown slot %s' % slot
continue
if not v:
# Need to add nulls for empty slots. Assumes that standard slots can't be empty.
loadout['components'][category].append(None)
continue
module = outfitting.lookup(v['module'], ship_map)
if not module:
raise AssertionError('Unknown module %s' % v) # Shouldn't happen
mass += module.get('mass', 0)
thing = OrderedDict([
('class',int(module['class'])),
('rating', module['rating']),
('enabled', module['enabled']),
('priority', module['priority']+1), # make 1-based
])
maxpri = max(maxpri, thing['priority'])
if category == 'standard':
# Standard items are indexed by "group" rather than containing a "group" member
if module['name'] in bulkheads:
loadout['components'][category]['bulkheads'] = module['name'] # Bulkheads are just strings
else:
loadout['components'][category][standard_map[module['name']]] = thing
if module['name'] == 'Frame Shift Drive':
fsd = module # save for range calculation
else:
# All other items have a "group" member, some also have a "name"
if module['name'] in fixup_map:
thing['group'], name = fixup_map[module['name']]
if name: thing['name'] = name
else:
thing['group'] = module['name']
if 'mount' in module:
thing['mount'] = weaponmount_map[module['mount']]
if 'guidance' in module:
thing['missile'] = module['guidance'][0] # not mentioned in schema
loadout['components'][category].append(thing)
except AssertionError as e:
# Silently skip unrecognized modules
if __debug__: print 'Coriolis: %s' % e
if category != 'standard':
loadout['components'][category].append(None)
except:
if __debug__: raise
# Cargo Hatch status is not available in the data - fake something up
loadout['components']['standard']['cargoHatch'] = OrderedDict([
('enabled', True),
('priority', maxpri),
])
# Add mass and range
assert data['ship']['name'].lower() in companion.ship_map, data['ship']['name']
assert companion.ship_map[data['ship']['name'].lower()] in ships, companion.ship_map[data['ship']['name'].lower()]
try:
# https://github.com/cmmcleod/coriolis/blob/master/app/js/shipyard/module-shipyard.js#L184
hullMass = ships[companion.ship_map[data['ship']['name'].lower()]]['hullMass']
mass += hullMass
multiplier = pow(min(data['ship']['fuel']['main']['capacity'], fsd['maxfuel']) / fsd['fuelmul'], 1.0 / fsd['fuelpower']) * fsd['optmass']
loadout['stats'] = OrderedDict([
('hullMass', hullMass),
('fuelCapacity', data['ship']['fuel']['main']['capacity']),
('cargoCapacity', data['ship']['cargo']['capacity']),
('ladenMass', mass + data['ship']['fuel']['main']['capacity'] + data['ship']['cargo']['capacity']),
('unladenMass', mass),
('unladenRange', round(multiplier / (mass + min(data['ship']['fuel']['main']['capacity'], fsd['maxfuel'])), 2)), # fuel for one jump
('fullTankRange', round(multiplier / (mass + data['ship']['fuel']['main']['capacity']), 2)),
('ladenRange', round(multiplier / (mass + data['ship']['fuel']['main']['capacity'] + data['ship']['cargo']['capacity']), 2)),
])
except:
if __debug__: raise
# Construct description
string = json.dumps(loadout, indent=2, separators=(',', ': '))
if filename:
with open(filename, 'wt') as h:
h.write(string)
return
# Look for last ship of this type
ship = companion.ship_map.get(data['ship']['name'].lower(), data['ship']['name']) # Use in-game name
regexp = re.compile(re.escape(ship) + '\.\d\d\d\d\-\d\d\-\d\dT\d\d\.\d\d\.\d\d\.json')
oldfiles = sorted([x for x in os.listdir(config.get('outdir')) if regexp.match(x)])
if oldfiles:
with open(join(config.get('outdir'), oldfiles[-1]), 'rU') as h:
if h.read() == string:
return # same as last time - don't write
# Write
filename = join(config.get('outdir'), '%s.%s.json' % (ship, time.strftime('%Y-%m-%dT%H.%M.%S', time.localtime(querytime))))
with open(filename, 'wt') as h:
h.write(string)
# Return a URL for the current ship # Return a URL for the current ship
def url(data, is_beta): def url(data, is_beta):
@ -246,16 +23,41 @@ def url(data, is_beta):
out = StringIO.StringIO() out = StringIO.StringIO()
with gzip.GzipFile(fileobj=out, mode='w') as f: with gzip.GzipFile(fileobj=out, mode='w') as f:
f.write(string) f.write(string)
return (is_beta and 'http://beta.coriolis.edcd.io/import?data=' or 'https://coriolis.edcd.io/import?data=') + base64.urlsafe_b64encode(out.getvalue()).replace('=', '%3D') return (is_beta and 'https://beta.coriolis.edcd.io/import?data=' or 'https://coriolis.edcd.io/import?data=') + base64.urlsafe_b64encode(out.getvalue()).replace('=', '%3D')
# #
# build ship and module databases from https://github.com/cmmcleod/coriolis-data # build ship and module databases from https://github.com/EDCD/coriolis-data/
# #
if __name__ == "__main__": if __name__ == "__main__":
import json
data = json.load(open('coriolis-data/dist/index.json')) data = json.load(open('coriolis-data/dist/index.json'))
bulkheads = outfitting.armour_map.values()
# Modules that have a name as well as a group
fixup_map = {}
fixup_map.update({ x[0] : ('Scanner', x[0]) for x in outfitting.misc_internal_map.values() })
fixup_map.update({ x[0] : ('Countermeasure', x[0]) for x in outfitting.countermeasure_map.values() })
fixup_map.update({
'Advanced Plasma Accelerator' : ('Plasma Accelerator', 'Advanced Plasma Accelerator'),
'Corrosion Resistant Cargo Rack': ('Cargo Rack', 'Corrosion Resistant'),
'Cytoscrambler Burst Laser' : ('Burst Laser', 'Cytoscrambler'),
'Enforcer Cannon' : ('Multi-cannon', 'Enforcer'),
'Enhanced Performance Thrusters': ('Thrusters', 'Enhanced Performance'),
'Imperial Hammer Rail Gun' : ('Rail Gun', 'Imperial Hammer'),
'Luxury Class Passenger Cabin' : ('Luxury Passenger Cabin', None),
'Mining Lance Beam Laser' : ('Mining Laser', 'Mining Lance'),
'Multi-Cannon' : ('Multi-cannon', None),
'Pacifier Frag-Cannon' : ('Fragment Cannon', 'Pacifier'),
'Pack-Hound Missile Rack' : ('Missile Rack', 'Pack-Hound'),
'Pulse Disruptor Laser' : ('Pulse Laser', 'Disruptor'),
'Retributor Beam Laser' : ('Beam Laser', 'Retributor'),
'Rocket Propelled FSD Disruptor': ('Missile Rack', 'Rocket Propelled FSD Disruptor'),
'Shock Mine Launcher' : ('Mine Launcher', 'Shock Mine Launcher'),
'Standard Docking Computer' : ('Docking Computer', 'Standard Docking Computer'),
})
specials = { v:k for k,v in fixup_map.items() }
# Map Coriolis's names to names displayed in the in-game shipyard # Map Coriolis's names to names displayed in the in-game shipyard
coriolis_ship_map = { coriolis_ship_map = {
'Cobra Mk III' : 'Cobra MkIII', 'Cobra Mk III' : 'Cobra MkIII',
@ -326,8 +128,6 @@ if __name__ == "__main__":
'tp' : 'Torpedo Pylon' 'tp' : 'Torpedo Pylon'
}; };
specials = { v:k for k,v in fixup_map.items() }
ships = {} ships = {}
modules = {} modules = {}
@ -363,5 +163,10 @@ if __name__ == "__main__":
else: else:
modules[key] = { 'mass': m.get('mass', 0) } # Some modules don't have mass modules[key] = { 'mass': m.get('mass', 0) } # Some modules don't have mass
# Repair Limpet Controller not yet present in coriolis-data. Same masses as Prospector
for k in modules.keys():
if k[0] == 'Prospector Limpet Controller':
modules[('Repair Limpet Controller',) + k[1:]] = modules[k]
modules = OrderedDict([(k,modules[k]) for k in sorted(modules)]) # sort for easier diffing modules = OrderedDict([(k,modules[k]) for k in sorted(modules)]) # sort for easier diffing
cPickle.dump(modules, open('modules.p', 'wb')) cPickle.dump(modules, open('modules.p', 'wb'))