mirror of
https://github.com/EDCD/EDMarketConnector.git
synced 2025-04-13 07:47:14 +03:00
parent
d9d6856ce9
commit
c116aed03c
@ -21,6 +21,7 @@ import bpc
|
||||
import td
|
||||
import eddn
|
||||
import loadout
|
||||
import coriolis
|
||||
import flightlog
|
||||
import stats
|
||||
import chart
|
||||
@ -213,8 +214,10 @@ class AppWindow:
|
||||
chart.export(data)
|
||||
if config.getint('output') & config.OUT_LOG:
|
||||
flightlog.export(data)
|
||||
if config.getint('output') & config.OUT_SHIP:
|
||||
if config.getint('output') & config.OUT_SHIP_EDS:
|
||||
loadout.export(data)
|
||||
if config.getint('output') & config.OUT_SHIP_CORIOLIS:
|
||||
coriolis.export(data)
|
||||
return
|
||||
|
||||
else:
|
||||
@ -230,8 +233,10 @@ class AppWindow:
|
||||
chart.export(data)
|
||||
if config.getint('output') & config.OUT_LOG:
|
||||
flightlog.export(data)
|
||||
if config.getint('output') & config.OUT_SHIP:
|
||||
if config.getint('output') & config.OUT_SHIP_EDS:
|
||||
loadout.export(data)
|
||||
if config.getint('output') & config.OUT_SHIP_CORIOLIS:
|
||||
coriolis.export(data)
|
||||
|
||||
if not (config.getint('output') & (config.OUT_CSV|config.OUT_TD|config.OUT_BPC|config.OUT_EDDN)):
|
||||
# no further output requested
|
||||
|
@ -57,7 +57,7 @@ This app can save a variety of data in a variety of formats:
|
||||
* CSV format - saves commodity market data as files that you can upload to [Thrudd's Trading Tools](http://www.elitetradingtool.co.uk/) or [Inara](http://inara.cz).
|
||||
|
||||
* Ship loadout
|
||||
* After every outfitting change saves a record of your ship loadout as a file that you can open in a text editor and that you can import into [E:D Shipyard](http://www.edshipyard.com).
|
||||
* After every outfitting change saves a record of your ship loadout as a file that you can open in a text editor and that you can import into [E:D Shipyard](http://www.edshipyard.com) or [Coriolis](http://coriolis.io).
|
||||
|
||||
* Flight log
|
||||
* Adds a record of your location, ship and cargo to a file that you can open in a text editor or a spreadsheet program such as Excel. Note: Don't edit, rename or move this file - take a copy if you wish to change it.
|
||||
|
@ -69,9 +69,10 @@ class Config:
|
||||
OUT_BPC = 2
|
||||
OUT_TD = 4
|
||||
OUT_CSV = 8
|
||||
OUT_SHIP = 16
|
||||
OUT_SHIP_EDS = 16
|
||||
OUT_LOG = 32
|
||||
OUT_STAT = 64
|
||||
OUT_SHIP_CORIOLIS = 128
|
||||
|
||||
if platform=='darwin':
|
||||
|
||||
|
164
coriolis.py
Normal file
164
coriolis.py
Normal file
@ -0,0 +1,164 @@
|
||||
# Export ship loadout in Coriolis format
|
||||
|
||||
from collections import OrderedDict
|
||||
import json
|
||||
import os
|
||||
from os.path import join
|
||||
import re
|
||||
import time
|
||||
|
||||
from config import config
|
||||
import outfitting
|
||||
import companion
|
||||
|
||||
|
||||
# Map draft EDDN outfitting to Coriolis
|
||||
# https://raw.githubusercontent.com/jamesremuscat/EDDN/master/schemas/outfitting-v1.0-draft.json
|
||||
# http://cdn.coriolis.io/schemas/ship-loadout/1.json
|
||||
|
||||
ship_map = dict(companion.ship_map)
|
||||
ship_map['Asp'] = 'Asp Explorer'
|
||||
|
||||
category_map = {
|
||||
'standard' : 'standard',
|
||||
'internal' : 'internal',
|
||||
'hardpoint' : 'hardpoints',
|
||||
'utility' : 'utility',
|
||||
}
|
||||
|
||||
slot_map = {
|
||||
'HugeHardpoint' : 'hardpoints',
|
||||
'LargeHardpoint' : 'hardpoints',
|
||||
'MediumHardpoint' : 'hardpoints',
|
||||
'SmallHardpoint' : 'hardpoints',
|
||||
'TinyHardpoint' : 'utility',
|
||||
'Slot' : 'internal',
|
||||
}
|
||||
|
||||
standard_map = OrderedDict([ # in output order
|
||||
('Armour', 'bulkheads'),
|
||||
('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()
|
||||
scanners = [x[0] for x in outfitting.stellar_map.values()]
|
||||
countermeasures = [x[0] for x in outfitting.countermeasure_map.values()]
|
||||
fixup_map = {
|
||||
'Advanced Plasma Accelerator' : ('Plasma Accelerator', 'Advanced'),
|
||||
'Cytoscrambler Burst Laser' : ('Burst Laser', 'Cytoscrambler'),
|
||||
'Enforcer Cannon' : ('Multi-cannon', 'Enforcer'),
|
||||
'Frame Shift Drive Interdictor' : ('FSD Interdictor', None),
|
||||
'Imperial Hammer Rail Gun' : ('Rail Gun', 'Imperial Hammer'),
|
||||
'Impulse Mine Launcher' : ('Mine Launcher', 'Impulse'),
|
||||
'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', 'Distruptor'), # Note sp
|
||||
'Standard Docking Computer' : ('Docking Computer', 'Standard Docking Computer'),
|
||||
}
|
||||
|
||||
|
||||
def export(data):
|
||||
|
||||
querytime = config.getint('querytime') or int(time.time())
|
||||
|
||||
ship = companion.ship_map.get(data['ship']['name'], data['ship']['name'])
|
||||
|
||||
loadout = OrderedDict([ # Mimic Coriolis export ordering
|
||||
('$schema', 'http://cdn.coriolis.io/schemas/ship-loadout/1.json#'),
|
||||
('name', ship_map.get(data['ship']['name'], data['ship']['name'])),
|
||||
('ship', ship_map.get(data['ship']['name'], data['ship']['name'])),
|
||||
('components', OrderedDict([
|
||||
('standard', OrderedDict([(x,None) for x in standard_map.values()])),
|
||||
('hardpoints', []),
|
||||
('utility', []),
|
||||
('internal', []),
|
||||
])),
|
||||
])
|
||||
|
||||
# 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:
|
||||
if not v:
|
||||
# Need to add nulls for empty slots. Assumes that standard slots can't be empty.
|
||||
for s in slot_map:
|
||||
if slot.startswith(s):
|
||||
loadout['components'][slot_map[s]].append(None)
|
||||
break
|
||||
continue
|
||||
|
||||
module = outfitting.lookup(v['module'])
|
||||
if not module: continue
|
||||
|
||||
category = loadout['components'][category_map[module['category']]]
|
||||
thing = OrderedDict([
|
||||
('class', module['class']),
|
||||
('rating', module['rating']),
|
||||
])
|
||||
|
||||
if module['name'] in bulkheads:
|
||||
# Bulkheads are just strings
|
||||
category['bulkheads'] = module['name']
|
||||
elif module['category'] == 'standard':
|
||||
# Standard items are indexed by "group" rather than containing a "group" member
|
||||
category[standard_map[module['name']]] = thing
|
||||
else:
|
||||
# All other items have a "group" member, some also have a "name"
|
||||
if module['name'] in scanners:
|
||||
thing['group'] = 'Scanner'
|
||||
thing['name'] = module['name']
|
||||
elif module['name'] in countermeasures:
|
||||
thing['group'] = 'Countermeasure'
|
||||
thing['name'] = module['name']
|
||||
elif 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
|
||||
|
||||
category.append(thing)
|
||||
|
||||
except AssertionError as e:
|
||||
if __debug__: print 'Loadout: %s' % e
|
||||
continue # Silently skip unrecognized modules
|
||||
except:
|
||||
if __debug__: raise
|
||||
|
||||
# Construct description
|
||||
string = json.dumps(loadout, indent=2)
|
||||
|
||||
# Look for last ship of this type
|
||||
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)
|
22
prefs.py
22
prefs.py
@ -78,7 +78,7 @@ class PreferencesDialog(tk.Toplevel):
|
||||
outframe.grid(padx=10, pady=10, sticky=tk.NSEW)
|
||||
outframe.columnconfigure(0, weight=1)
|
||||
|
||||
output = config.getint('output') or (config.OUT_EDDN | config.OUT_SHIP | config.OUT_STAT)
|
||||
output = config.getint('output') or (config.OUT_EDDN | config.OUT_SHIP_EDS | config.OUT_STAT)
|
||||
ttk.Label(outframe, text="Please choose what data to save").grid(row=0, columnspan=2, padx=5, pady=3, sticky=tk.W)
|
||||
self.out_eddn= tk.IntVar(value = (output & config.OUT_EDDN) and 1 or 0)
|
||||
ttk.Checkbutton(outframe, text="Send station data to the Elite Dangerous Data Network", variable=self.out_eddn).grid(row=1, columnspan=2, padx=5, sticky=tk.W)
|
||||
@ -88,19 +88,21 @@ class PreferencesDialog(tk.Toplevel):
|
||||
ttk.Checkbutton(outframe, text="Market data in Trade Dangerous format", variable=self.out_td, command=self.outvarchanged).grid(row=3, columnspan=2, padx=5, sticky=tk.W)
|
||||
self.out_csv = tk.IntVar(value = (output & config.OUT_CSV ) and 1 or 0)
|
||||
ttk.Checkbutton(outframe, text="Market data in CSV format", variable=self.out_csv, command=self.outvarchanged).grid(row=4, columnspan=2, padx=5, sticky=tk.W)
|
||||
self.out_ship= tk.IntVar(value = (output & config.OUT_SHIP) and 1 or 0)
|
||||
ttk.Checkbutton(outframe, text="Ship loadout in E:D Shipyard format", variable=self.out_ship, command=self.outvarchanged).grid(row=5, columnspan=2, padx=5, sticky=tk.W)
|
||||
self.out_ship_eds= tk.IntVar(value = (output & config.OUT_SHIP_EDS) and 1 or 0)
|
||||
ttk.Checkbutton(outframe, text="Ship loadout in E:D Shipyard format", variable=self.out_ship_eds, command=self.outvarchanged).grid(row=5, columnspan=2, padx=5, sticky=tk.W)
|
||||
self.out_ship_coriolis= tk.IntVar(value = (output & config.OUT_SHIP_CORIOLIS) and 1 or 0)
|
||||
ttk.Checkbutton(outframe, text="Ship loadout in Coriolis format", variable=self.out_ship_coriolis, command=self.outvarchanged).grid(row=6, columnspan=2, padx=5, sticky=tk.W)
|
||||
self.out_log = tk.IntVar(value = (output & config.OUT_LOG ) and 1 or 0)
|
||||
ttk.Checkbutton(outframe, text="Flight log", variable=self.out_log, command=self.outvarchanged).grid(row=6, columnspan=2, padx=5, sticky=tk.W)
|
||||
ttk.Checkbutton(outframe, text="Flight log", variable=self.out_log, command=self.outvarchanged).grid(row=7, columnspan=2, padx=5, sticky=tk.W)
|
||||
self.out_stat= tk.IntVar(value = have_openpyxl and (output & config.OUT_STAT) and 1 or 0)
|
||||
ttk.Checkbutton(outframe, text="Cmdr statistics", variable=self.out_stat, command=self.outvarchanged, state=have_openpyxl and tk.NORMAL or tk.DISABLED).grid(row=7, columnspan=2, padx=5, sticky=tk.W)
|
||||
ttk.Checkbutton(outframe, text="Cmdr statistics", variable=self.out_stat, command=self.outvarchanged, state=have_openpyxl and tk.NORMAL or tk.DISABLED).grid(row=8, columnspan=2, padx=5, sticky=tk.W)
|
||||
|
||||
ttk.Label(outframe, text=(platform=='darwin' and 'Where:' or 'File location:')).grid(row=8, padx=5, pady=(5,0), sticky=tk.NSEW)
|
||||
ttk.Label(outframe, text=(platform=='darwin' and 'Where:' or 'File location:')).grid(row=9, padx=5, pady=(5,0), sticky=tk.NSEW)
|
||||
self.outbutton = ttk.Button(outframe, text=(platform=='darwin' and 'Change...' or 'Browse...'), command=self.outbrowse)
|
||||
self.outbutton.grid(row=8, column=1, padx=5, pady=(5,0), sticky=tk.NSEW)
|
||||
self.outbutton.grid(row=9, column=1, padx=5, pady=(5,0), sticky=tk.NSEW)
|
||||
self.outdir = ttk.Entry(outframe)
|
||||
self.outdir.insert(0, config.get('outdir'))
|
||||
self.outdir.grid(row=9, columnspan=2, padx=5, pady=5, sticky=tk.EW)
|
||||
self.outdir.grid(row=10, columnspan=2, padx=5, pady=5, sticky=tk.EW)
|
||||
self.outvarchanged()
|
||||
|
||||
privacyframe = ttk.LabelFrame(frame, text='Privacy')
|
||||
@ -127,7 +129,7 @@ class PreferencesDialog(tk.Toplevel):
|
||||
#self.wait_window(self) # causes duplicate events on OSX
|
||||
|
||||
def outvarchanged(self):
|
||||
local = self.out_bpc.get() or self.out_td.get() or self.out_csv.get() or self.out_ship.get() or self.out_log.get() or self.out_stat.get()
|
||||
local = self.out_bpc.get() or self.out_td.get() or self.out_csv.get() or self.out_ship_eds.get() or self.out_ship_coriolis.get() or self.out_log.get() or self.out_stat.get()
|
||||
self.outbutton['state'] = local and tk.NORMAL or tk.DISABLED
|
||||
self.outdir['state'] = local and 'readonly' or tk.DISABLED
|
||||
|
||||
@ -166,7 +168,7 @@ class PreferencesDialog(tk.Toplevel):
|
||||
credentials = (config.get('username'), config.get('password'))
|
||||
config.set('username', self.username.get().strip())
|
||||
config.set('password', self.password.get().strip())
|
||||
config.set('output', (self.out_eddn.get() and config.OUT_EDDN or 0) + (self.out_bpc.get() and config.OUT_BPC or 0) + (self.out_td.get() and config.OUT_TD or 0) + (self.out_csv.get() and config.OUT_CSV or 0) + (self.out_ship.get() and config.OUT_SHIP or 0) + (self.out_log.get() and config.OUT_LOG or 0) + (self.out_stat.get() and config.OUT_STAT or 0))
|
||||
config.set('output', (self.out_eddn.get() and config.OUT_EDDN or 0) + (self.out_bpc.get() and config.OUT_BPC or 0) + (self.out_td.get() and config.OUT_TD or 0) + (self.out_csv.get() and config.OUT_CSV or 0) + (self.out_ship_eds.get() and config.OUT_SHIP_EDS or 0) + (self.out_log.get() and config.OUT_LOG or 0) + (self.out_stat.get() and config.OUT_STAT or 0) + (self.out_ship_coriolis.get() and config.OUT_SHIP_CORIOLIS or 0))
|
||||
config.set('outdir', self.outdir.get().strip())
|
||||
config.set('anonymous', self.out_anon.get())
|
||||
self.destroy()
|
||||
|
Loading…
x
Reference in New Issue
Block a user