mirror of
https://github.com/EDCD/EDMarketConnector.git
synced 2025-04-13 15:57:14 +03:00
Add support for saving a simple flight log.
This commit is contained in:
parent
1af879ffae
commit
050aada1a2
@ -18,6 +18,7 @@ import bpc
|
||||
import td
|
||||
import eddn
|
||||
import loadout
|
||||
import flightlog
|
||||
import stats
|
||||
import prefs
|
||||
from config import appname, applongname, config
|
||||
@ -136,6 +137,15 @@ class AppWindow:
|
||||
try:
|
||||
self.session.login(config.get('username'), config.get('password'))
|
||||
self.status['text'] = ''
|
||||
|
||||
# Try to obtain exclusive lock on flight log ASAP
|
||||
if config.getint('output') & config.OUT_LOG:
|
||||
try:
|
||||
flightlog.openlog()
|
||||
except Exception as e:
|
||||
if __debug__: print_exc()
|
||||
self.status['text'] = str(e)
|
||||
|
||||
except companion.VerificationRequired:
|
||||
# don't worry about authentication now - prompt on query
|
||||
self.status['text'] = ''
|
||||
@ -178,31 +188,38 @@ class AppWindow:
|
||||
|
||||
# Validation
|
||||
if not data.get('commander') or not data['commander'].get('name','').strip():
|
||||
self.status['text'] = "Who are you?!" # Shouldn't happen
|
||||
self.status['text'] = "Who are you?!" # Shouldn't happen
|
||||
elif not data.get('lastSystem') or not data['lastSystem'].get('name','').strip() or not data.get('lastStarport') or not data['lastStarport'].get('name','').strip():
|
||||
self.status['text'] = "Where are you?!" # Shouldn't happen
|
||||
self.status['text'] = "Where are you?!" # Shouldn't happen
|
||||
elif not data.get('ship') or not data['ship'].get('modules') or not data['ship'].get('name','').strip():
|
||||
self.status['text'] = "What are you flying?!" # Shouldn't happen
|
||||
elif not data['commander'].get('docked'):
|
||||
if config.getint('output') & config.OUT_SHIP:
|
||||
loadout.export(data) # do loadout even if not docked
|
||||
self.status['text'] = "You're not docked at a station!"
|
||||
elif not data['lastStarport'].get('commodities'):
|
||||
self.status['text'] = "Station doesn't have a market!"
|
||||
else:
|
||||
# stuff we can do when not docked
|
||||
if config.getint('output') & config.OUT_LOG:
|
||||
flightlog.export(data)
|
||||
if config.getint('output') & config.OUT_SHIP:
|
||||
loadout.export(data)
|
||||
if config.getint('output') & config.OUT_CSV:
|
||||
bpc.export(data, True)
|
||||
if config.getint('output') & config.OUT_TD:
|
||||
td.export(data)
|
||||
if config.getint('output') & config.OUT_BPC:
|
||||
bpc.export(data, False)
|
||||
if config.getint('output') & config.OUT_EDDN:
|
||||
self.status['text'] = 'Sending data to EDDN...'
|
||||
self.w.update_idletasks()
|
||||
eddn.export(data)
|
||||
self.status['text'] = strftime('Last updated at %H:%M:%S', localtime(querytime))
|
||||
|
||||
if not (config.getint('output') & (config.OUT_CSV|config.OUT_TD|config.OUT_BPC|config.OUT_EDDN)):
|
||||
# no further output requested
|
||||
self.status['text'] = strftime('Last updated at %H:%M:%S', localtime(querytime))
|
||||
|
||||
elif not data['commander'].get('docked'):
|
||||
self.status['text'] = "You're not docked at a station!"
|
||||
elif not data['lastStarport'].get('commodities'):
|
||||
self.status['text'] = "Station doesn't have a market!"
|
||||
else:
|
||||
if config.getint('output') & config.OUT_CSV:
|
||||
bpc.export(data, True)
|
||||
if config.getint('output') & config.OUT_TD:
|
||||
td.export(data)
|
||||
if config.getint('output') & config.OUT_BPC:
|
||||
bpc.export(data, False)
|
||||
if config.getint('output') & config.OUT_EDDN:
|
||||
self.status['text'] = 'Sending data to EDDN...'
|
||||
self.w.update_idletasks()
|
||||
eddn.export(data)
|
||||
self.status['text'] = strftime('Last updated at %H:%M:%S', localtime(querytime))
|
||||
|
||||
except companion.VerificationRequired:
|
||||
return prefs.AuthenticationDialog(self.w, self.verify)
|
||||
|
30
README.md
30
README.md
@ -3,10 +3,11 @@ Elite: Dangerous Market Connector
|
||||
|
||||
This app downloads commodity market data from the game [Elite: Dangerous](https://www.elitedangerous.com/) and, at your choice, either:
|
||||
|
||||
* transmits the data to the [Elite Dangerous Data Network](http://eddn.ed-td.space/) ("EDDN") from where you and others can use it via online trading tools such as [eddb](http://eddb.io/).
|
||||
* sends the data to the [Elite Dangerous Data Network](http://eddn.ed-td.space/) ("EDDN") from where you and others can use it via online trading tools such as [eddb](http://eddb.io/) or [Elite Trade Net](http://etn.io/).
|
||||
* saves the data to files on your computer that you can load into trading tools such as [Slopey's BPC Market Tool](https://forums.frontier.co.uk/showthread.php?t=76081), [Trade Dangerous](https://bitbucket.org/kfsone/tradedangerous/wiki/Home) and [Thrudd's Trading Tools](http://www.elitetradingtool.co.uk/).
|
||||
* saves a record of your ship loadout and/or flight log.
|
||||
|
||||
The user-interface is deliberately minimal - when you land at a station just switch to the app and press the "Update" button or press Enter to automatically download and transmit and/or save the station's commodity market data:
|
||||
The user-interface is deliberately minimal - when you land at a station just switch to the app and press the "Update" button or press Enter to automatically download and transmit and/or save your choice of data.
|
||||
|
||||
 
|
||||
|
||||
@ -32,11 +33,9 @@ Windows:
|
||||
Setup
|
||||
--------
|
||||
The first time that you run the app you are prompted for your username and password. This is the same username and password
|
||||
combination that you use to log into the Elite: Dangerous launcher, and is required so that the Frontier servers can send the app the market data for the station that *you* are docked at.
|
||||
combination that you use to log into the Elite: Dangerous launcher, and is required so that the Frontier servers can send the app *your* data and the market data for the station that *you* are docked at.
|
||||
|
||||
You can also choose here whether to send the market data that you download to EDDN or to save it locally,
|
||||
whether to attach your Cmdr name or a [pseudo-anonymized](http://en.wikipedia.org/wiki/Pseudonymity) ID to the data,
|
||||
and whether to save a record of your ship loadout in a form that you can import into [E:D Shipyard](http://www.edshipyard.com) after every outfitting change.
|
||||
You can also choose here what data to save (refer to the next section for details) and whether to attach your Cmdr name or a [pseudo-anonymized](http://en.wikipedia.org/wiki/Pseudonymity) ID to the data.
|
||||
|
||||
You are next prompted to authenticate with a "verification code", which you will shortly receive by email from Frontier.
|
||||
Note that each "verification code" is one-time only - if you enter the code incorrectly or quit the app before
|
||||
@ -45,6 +44,24 @@ authenticating you will need to wait for Frontier to send you a new code.
|
||||
If you are not prompted to authenticate, but instead see the message "Error: Invalid Credentials" then choose the menu
|
||||
option EDMarketConnector → Preferences (Mac) or File → Settings (Windows) and double-check your username and password.
|
||||
|
||||
Output
|
||||
--------
|
||||
This app can save a variety of data in a variety of formats:
|
||||
|
||||
* Market data
|
||||
* Elite Dangerous Data Network - sends the market data to the "[EDDN](http://eddn.ed-td.space/)" from where you and others can use it via online trading tools such as [eddb](http://eddb.io/) or [Elite Trade Net](http://etn.io/).
|
||||
* Slopey's BPC format - saves the market data as files that you can load into [Slopey's BPC Market Tool](https://forums.frontier.co.uk/showthread.php?t=76081).
|
||||
* Trade Dangerous format - saves the market data as files that you can load into [Trade Dangerous](https://bitbucket.org/kfsone/tradedangerous/wiki/Home).
|
||||
* CSV format - saves the market data as files that you can upload to [Thrudd's Trading Tools](http://www.elitetradingtool.co.uk/).
|
||||
|
||||
* 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).
|
||||
|
||||
* 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.
|
||||
|
||||
By default these files will be placed in your Documents folder. Since this app will create a lot of files if you use it for a while you may wish to create a separate folder for the files and tell the app to place them there.
|
||||
|
||||
Statistics
|
||||
--------
|
||||
Choose the "Statistics" item from the menu to view your Cmdrs's statistics. The statistics shown are largely the same
|
||||
@ -61,6 +78,7 @@ Windows:
|
||||
|
||||
* Uninstall **Elite Dangerous Market Connector** from Control Panel → Programs.
|
||||
|
||||
Note: Uninstalling the app does not delete any output files that it has previously written.
|
||||
|
||||
Running from source
|
||||
--------
|
||||
|
@ -70,6 +70,7 @@ class Config:
|
||||
OUT_TD = 4
|
||||
OUT_CSV = 8
|
||||
OUT_SHIP = 16
|
||||
OUT_LOG = 32
|
||||
|
||||
if platform=='darwin':
|
||||
|
||||
|
55
flightlog.py
Normal file
55
flightlog.py
Normal file
@ -0,0 +1,55 @@
|
||||
# Export poor man's flight log
|
||||
|
||||
import errno
|
||||
import os
|
||||
from os.path import join
|
||||
from sys import platform
|
||||
import time
|
||||
|
||||
from config import config
|
||||
from companion import ship_map, commodity_map
|
||||
|
||||
|
||||
logfile = None
|
||||
|
||||
def openlog():
|
||||
|
||||
global logfile
|
||||
if logfile: return
|
||||
|
||||
try:
|
||||
logfile = open(join(config.get('outdir'), 'Flight Log.csv'), 'a+')
|
||||
if platform != 'win32': # open for writing is automatically exclusive on Windows
|
||||
from fcntl import lockf, LOCK_SH, LOCK_NB
|
||||
lockf(logfile, LOCK_SH|LOCK_NB)
|
||||
logfile.seek(0, os.SEEK_END)
|
||||
if not logfile.tell():
|
||||
logfile.write('Date,Time,System,Station,Ship,Cargo\r\n')
|
||||
except EnvironmentError as e:
|
||||
logfile = None
|
||||
if e.errno in [errno.EACCES, errno.EAGAIN]:
|
||||
raise Exception('Can\'t write "Flight Log.csv". Are you editing it in another app?')
|
||||
else:
|
||||
raise
|
||||
except:
|
||||
logfile = None
|
||||
raise
|
||||
|
||||
|
||||
def export(data):
|
||||
|
||||
def elapsed(game_time):
|
||||
return '%3d:%02d:%02d' % ((game_time // 3600) % 3600, (game_time // 60) % 60, game_time % 60)
|
||||
|
||||
querytime = config.getint('querytime') or int(time.time())
|
||||
|
||||
openlog()
|
||||
|
||||
logfile.write('%s,%s,%s,%s,%s,%s\r\n' % (
|
||||
time.strftime('%Y-%m-%d', time.localtime(querytime)),
|
||||
time.strftime('%H:%M:%S', time.localtime(querytime)),
|
||||
data['lastSystem']['name'],
|
||||
data['commander']['docked'] and data['lastStarport']['name'] or '',
|
||||
data['ship']['name'],
|
||||
','.join([('%d %s' % (x['qty'], commodity_map.get(x['commodity'],x['commodity']))) for x in data['ship']['cargo']['items'] if x['commodity']!='drones'])))
|
||||
logfile.flush()
|
26
prefs.py
26
prefs.py
@ -57,7 +57,7 @@ class PreferencesDialog(tk.Toplevel):
|
||||
credframe.grid(padx=10, pady=10, sticky=tk.NSEW)
|
||||
credframe.columnconfigure(1, weight=1)
|
||||
|
||||
ttk.Label(credframe, text="Please log in with your Elite:Dangerous account details").grid(row=0, columnspan=2, sticky=tk.W)
|
||||
ttk.Label(credframe, text="Please log in with your Elite: Dangerous account details").grid(row=0, columnspan=2, sticky=tk.W)
|
||||
ttk.Label(credframe, text="Username (Email)").grid(row=1, sticky=tk.W)
|
||||
ttk.Label(credframe, text="Password").grid(row=2, sticky=tk.W)
|
||||
|
||||
@ -77,23 +77,25 @@ class PreferencesDialog(tk.Toplevel):
|
||||
outframe.columnconfigure(0, weight=1)
|
||||
|
||||
output = config.getint('output') or (config.OUT_EDDN | config.OUT_SHIP)
|
||||
ttk.Label(outframe, text="Please choose how you want the data saved").grid(row=0, columnspan=2, padx=5, pady=3, sticky=tk.W)
|
||||
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="Online to the Elite Dangerous Data Network (EDDN)", variable=self.out_eddn).grid(row=1, columnspan=2, padx=5, sticky=tk.W)
|
||||
ttk.Checkbutton(outframe, text="Send market data to the Elite Dangerous Data Network", variable=self.out_eddn).grid(row=1, columnspan=2, padx=5, sticky=tk.W)
|
||||
self.out_bpc = tk.IntVar(value = (output & config.OUT_BPC ) and 1 or 0)
|
||||
ttk.Checkbutton(outframe, text="Offline in Slopey's BPC format", variable=self.out_bpc, command=self.outvarchanged).grid(row=2, columnspan=2, padx=5, sticky=tk.W)
|
||||
ttk.Checkbutton(outframe, text="Market data in Slopey's BPC format", variable=self.out_bpc, command=self.outvarchanged).grid(row=2, columnspan=2, padx=5, sticky=tk.W)
|
||||
self.out_td = tk.IntVar(value = (output & config.OUT_TD ) and 1 or 0)
|
||||
ttk.Checkbutton(outframe, text="Offline in Trade Dangerous format", variable=self.out_td, command=self.outvarchanged).grid(row=3, columnspan=2, padx=5, sticky=tk.W)
|
||||
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="Offline in CSV format", variable=self.out_csv, command=self.outvarchanged).grid(row=4, columnspan=2, padx=5, sticky=tk.W)
|
||||
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="Offline ship loadout in E:D Shipyard format", variable=self.out_ship, command=self.outvarchanged).grid(row=5, columnspan=2, padx=5, sticky=tk.W)
|
||||
ttk.Label(outframe, text=(platform=='darwin' and 'Where:' or 'File location:')).grid(row=6, padx=5, pady=(5,0), sticky=tk.NSEW)
|
||||
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_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.Label(outframe, text=(platform=='darwin' and 'Where:' or 'File location:')).grid(row=7, 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=6, column=1, padx=5, pady=(5,0), sticky=tk.NSEW)
|
||||
self.outbutton.grid(row=7, 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=7, columnspan=2, padx=5, pady=5, sticky=tk.EW)
|
||||
self.outdir.grid(row=8, columnspan=2, padx=5, pady=5, sticky=tk.EW)
|
||||
self.outvarchanged()
|
||||
|
||||
privacyframe = ttk.LabelFrame(frame, text='Privacy')
|
||||
@ -120,7 +122,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()
|
||||
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()
|
||||
self.outbutton['state'] = local and tk.NORMAL or tk.DISABLED
|
||||
self.outdir['state'] = local and 'readonly' or tk.DISABLED
|
||||
|
||||
@ -159,7 +161,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))
|
||||
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))
|
||||
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