mirror of
https://github.com/EDCD/EDMarketConnector.git
synced 2025-04-14 08:17:13 +03:00
parent
d7aae5dee3
commit
a67eb982d8
5
EDMC.py
5
EDMC.py
@ -82,7 +82,10 @@ try:
|
||||
config.set('querytime', getmtime(args.j))
|
||||
else:
|
||||
session = companion.Session()
|
||||
session.login(config.get('username'), config.get('password'))
|
||||
if config.get('cmdrs'):
|
||||
session.login(config.get('fdev_usernames')[0], config.get('fdev_passwords')[0])
|
||||
else: # <= 2.25 not yet migrated
|
||||
session.login(config.get('username'), config.get('password'))
|
||||
querytime = int(time())
|
||||
data = session.query()
|
||||
config.set('querytime', querytime)
|
||||
|
@ -236,8 +236,6 @@ class AppWindow:
|
||||
theme.register(self.theme_close)
|
||||
theme.register_alternate((self.menubar, self.theme_menubar), {'row':0, 'columnspan':2, 'sticky':tk.NSEW})
|
||||
|
||||
self.set_labels()
|
||||
|
||||
# update geometry
|
||||
if config.get('geometry'):
|
||||
match = re.match('\+([\-\d]+)\+([\-\d]+)', config.get('geometry'))
|
||||
@ -274,17 +272,25 @@ class AppWindow:
|
||||
# Load updater after UI creation (for WinSparkle)
|
||||
import update
|
||||
self.updater = update.Updater(self.w)
|
||||
if not getattr(sys, 'frozen', False):
|
||||
self.updater.checkForUpdates() # Sparkle / WinSparkle does this automatically for packaged apps
|
||||
|
||||
# First run
|
||||
if not config.get('username') or not config.get('password'):
|
||||
prefs.PreferencesDialog(self.w, self.postprefs)
|
||||
else:
|
||||
self.login()
|
||||
self.postprefs() # Companion login happens in callback from monitor
|
||||
|
||||
# Try to obtain exclusive lock on journal cache, even if we don't need it yet
|
||||
if not eddn.load():
|
||||
self.status['text'] = 'Error: Is another copy of this app already running?' # Shouldn't happen - don't bother localizing
|
||||
|
||||
# callback after the Preferences dialog is applied
|
||||
def postprefs(self):
|
||||
self.set_labels() # in case language has changed
|
||||
self.login() # in case credentials gave changed
|
||||
|
||||
# (Re-)install hotkey monitoring
|
||||
hotkeymgr.register(self.w, config.getint('hotkey_code'), config.getint('hotkey_mods'))
|
||||
|
||||
# (Re-)install log monitoring
|
||||
if not monitor.start(self.w):
|
||||
self.status['text'] = 'Error: Check %s' % _('E:D journal file location') # Location of the new Journal file in E:D 2.2
|
||||
|
||||
# set main window labels, e.g. after language change
|
||||
def set_labels(self):
|
||||
@ -321,11 +327,15 @@ class AppWindow:
|
||||
self.edit_menu.entryconfigure(0, label=_('Copy')) # As in Copy and Paste
|
||||
|
||||
def login(self):
|
||||
self.status['text'] = _('Logging in...')
|
||||
if not self.status['text']:
|
||||
self.status['text'] = _('Logging in...')
|
||||
self.button['state'] = self.theme_button['state'] = tk.DISABLED
|
||||
self.w.update_idletasks()
|
||||
try:
|
||||
self.session.login(config.get('username'), config.get('password'))
|
||||
if not monitor.cmdr or monitor.cmdr not in config.get('cmdrs'):
|
||||
raise companion.CredentialsError()
|
||||
idx = config.get('cmdrs').index(monitor.cmdr)
|
||||
self.session.login(config.get('fdev_usernames')[idx], config.get('fdev_passwords')[idx])
|
||||
self.status['text'] = ''
|
||||
except companion.VerificationRequired:
|
||||
return prefs.AuthenticationDialog(self.w, partial(self.verify, self.login))
|
||||
@ -334,21 +344,6 @@ class AppWindow:
|
||||
except Exception as e:
|
||||
if __debug__: print_exc()
|
||||
self.status['text'] = unicode(e)
|
||||
|
||||
if not getattr(sys, 'frozen', False):
|
||||
self.updater.checkForUpdates() # Sparkle / WinSparkle does this automatically for packaged apps
|
||||
|
||||
# Try to obtain exclusive lock on journal cache, even if we don't need it yet
|
||||
if not eddn.load():
|
||||
self.status['text'] = 'Error: Is another copy of this app already running?' # Shouldn't happen - don't bother localizing
|
||||
|
||||
# (Re-)install hotkey monitoring
|
||||
hotkeymgr.register(self.w, config.getint('hotkey_code'), config.getint('hotkey_mods'))
|
||||
|
||||
# (Re-)install log monitoring
|
||||
if not monitor.start(self.w):
|
||||
self.status['text'] = 'Error: Check %s' % _('E:D journal file location') # Location of the new Journal file in E:D 2.2
|
||||
|
||||
self.cooldown()
|
||||
|
||||
# callback after verification code
|
||||
@ -368,7 +363,7 @@ class AppWindow:
|
||||
auto_update = not event
|
||||
play_sound = (auto_update or int(event.type) == self.EVENT_VIRTUAL) and not config.getint('hotkey_mute')
|
||||
|
||||
if (monitor.cmdr and not monitor.mode) or monitor.is_beta:
|
||||
if not monitor.cmdr or not monitor.mode or monitor.is_beta:
|
||||
return # In CQC or Beta - do nothing
|
||||
|
||||
if not retrying:
|
||||
@ -478,7 +473,7 @@ class AppWindow:
|
||||
self.status['text'] = ''
|
||||
|
||||
# Update credits and ship info and send to EDSM
|
||||
if config.getint('output') & config.OUT_SYS_EDSM and not monitor.is_beta:
|
||||
if config.getint('output') & config.OUT_SYS_EDSM:
|
||||
try:
|
||||
if data['commander'].get('credits') is not None:
|
||||
monitor.credits = (data['commander']['credits'], data['commander'].get('debt', 0))
|
||||
@ -568,13 +563,25 @@ class AppWindow:
|
||||
self.edsm.link(monitor.system)
|
||||
self.w.update_idletasks()
|
||||
|
||||
# New Cmdr?
|
||||
if entry['event'] in [None, 'NewCommander', 'LoadGame'] and monitor.cmdr and not monitor.is_beta:
|
||||
prefs.migrate(monitor.cmdr) # migration from <= 2.25
|
||||
if config.get('cmdrs') and monitor.cmdr in config.get('cmdrs'):
|
||||
prefs.make_current(monitor.cmdr)
|
||||
elif config.get('cmdrs') and entry['event'] == 'NewCommander':
|
||||
cmdrs = config.get('cmdrs')
|
||||
cmdrs[0] = monitor.cmdr # New Cmdr uses same credentials as old
|
||||
config.set('cmdrs', cmdrs)
|
||||
else:
|
||||
prefs.PreferencesDialog(self.w, self.postprefs) # First run or new Cmdr
|
||||
|
||||
# Send interesting events to EDSM
|
||||
if config.getint('output') & config.OUT_SYS_EDSM and not monitor.is_beta:
|
||||
self.status['text'] = _('Sending data to EDSM...')
|
||||
self.w.update_idletasks()
|
||||
try:
|
||||
# Update system status on startup
|
||||
if monitor.mode and not entry['event']:
|
||||
if monitor.mode and monitor.system and not entry['event']:
|
||||
self.edsm.lookup(monitor.system)
|
||||
|
||||
# Send credits to EDSM on new game (but not on startup - data might be old)
|
||||
@ -609,6 +616,10 @@ class AppWindow:
|
||||
self.status['text'] = ''
|
||||
self.edsmpoll()
|
||||
|
||||
# Companion login - do this after EDSM so any EDSM errors don't mask login errors
|
||||
if entry['event'] in [None, 'LoadGame'] and monitor.cmdr and not monitor.is_beta:
|
||||
self.login()
|
||||
|
||||
if not entry['event'] or not monitor.mode:
|
||||
return # Startup or in CQC
|
||||
|
||||
@ -688,7 +699,7 @@ class AppWindow:
|
||||
|
||||
def shipyard_url(self, shipname=None):
|
||||
|
||||
if (monitor.cmdr and not monitor.mode) or monitor.is_beta:
|
||||
if not monitor.cmdr or not monitor.mode or monitor.is_beta:
|
||||
return False # In CQC or Beta - do nothing
|
||||
|
||||
self.status['text'] = _('Fetching data...')
|
||||
|
@ -144,6 +144,9 @@ If 2 this problem may or may not resolve itself in time.
|
||||
|
||||
This problem is tracked as [Issue #165](https://github.com/Marginal/EDMarketConnector/issues/165).
|
||||
|
||||
### Credentials settings are greyed out
|
||||
You can't edit your Username/Password or EDSM Commander Name/API Key while Elite: Dangerous is at the Main Menu. You will be able to edit these values once you've entered the game.
|
||||
|
||||
### Error: Can't connect to EDDN
|
||||
EDMC needs to talk to eddn-gateway.elite-markets.net on port 8080. If you consistently receive this error check that your router or VPN configuration allows port 8080 / tcp outbound.
|
||||
|
||||
|
44
companion.py
44
companion.py
@ -1,9 +1,10 @@
|
||||
import requests
|
||||
from collections import defaultdict
|
||||
from cookielib import LWPCookieJar
|
||||
import hashlib
|
||||
import numbers
|
||||
import os
|
||||
from os.path import dirname, join
|
||||
from os.path import dirname, isfile, join
|
||||
import sys
|
||||
from sys import platform
|
||||
import time
|
||||
@ -178,6 +179,7 @@ class Session:
|
||||
def __init__(self):
|
||||
self.state = Session.STATE_INIT
|
||||
self.credentials = None
|
||||
self.session = None
|
||||
|
||||
# yuck suppress InsecurePlatformWarning under Python < 2.7.9 which lacks SNI support
|
||||
try:
|
||||
@ -189,14 +191,6 @@ class Session:
|
||||
if platform=='win32' and getattr(sys, 'frozen', False):
|
||||
os.environ['REQUESTS_CA_BUNDLE'] = join(dirname(sys.executable), 'cacert.pem')
|
||||
|
||||
self.session = requests.Session()
|
||||
self.session.headers['User-Agent'] = 'Mozilla/5.0 (iPhone; CPU iPhone OS 7_1_2 like Mac OS X) AppleWebKit/537.51.2 (KHTML, like Gecko) Mobile/11D257'
|
||||
self.session.cookies = LWPCookieJar(join(config.app_dir, 'cookies.txt'))
|
||||
try:
|
||||
self.session.cookies.load()
|
||||
except IOError:
|
||||
pass
|
||||
|
||||
def login(self, username=None, password=None):
|
||||
if (not username or not password):
|
||||
if not self.credentials:
|
||||
@ -208,8 +202,20 @@ class Session:
|
||||
|
||||
if self.credentials == credentials and self.state == Session.STATE_OK:
|
||||
return # already logged in
|
||||
if self.credentials and self.credentials['email'] != credentials['email']: # changed account
|
||||
self.session.cookies.clear()
|
||||
|
||||
if not self.credentials or self.credentials['email'] != credentials['email']: # changed account
|
||||
self.close()
|
||||
self.session = requests.Session()
|
||||
self.session.headers['User-Agent'] = 'Mozilla/5.0 (iPhone; CPU iPhone OS 7_1_2 like Mac OS X) AppleWebKit/537.51.2 (KHTML, like Gecko) Mobile/11D257'
|
||||
cookiefile = join(config.app_dir, 'cookies-%s.txt' % hashlib.md5(credentials['email']).hexdigest())
|
||||
if not isfile(cookiefile) and isfile(join(config.app_dir, 'cookies.txt')):
|
||||
os.rename(join(config.app_dir, 'cookies.txt'), cookiefile) # migration from <= 2.25
|
||||
self.session.cookies = LWPCookieJar(cookiefile)
|
||||
try:
|
||||
self.session.cookies.load()
|
||||
except IOError:
|
||||
pass
|
||||
|
||||
self.credentials = credentials
|
||||
self.state = Session.STATE_INIT
|
||||
try:
|
||||
@ -237,7 +243,7 @@ class Session:
|
||||
r = self.session.post(URL_CONFIRM, data = {'code' : code}, timeout=timeout)
|
||||
if r.status_code != requests.codes.ok or r.url == URL_CONFIRM: # would have redirected away if success
|
||||
raise VerificationRequired()
|
||||
self.save() # Save cookies now for use by command-line app
|
||||
self.session.cookies.save() # Save cookies now for use by command-line app
|
||||
self.login()
|
||||
|
||||
def query(self):
|
||||
@ -270,16 +276,14 @@ class Session:
|
||||
|
||||
return data
|
||||
|
||||
def save(self):
|
||||
self.session.cookies.save()
|
||||
|
||||
def close(self):
|
||||
self.state = Session.STATE_NONE
|
||||
try:
|
||||
self.session.cookies.save()
|
||||
self.session.close()
|
||||
except:
|
||||
pass
|
||||
if self.session:
|
||||
try:
|
||||
self.session.cookies.save()
|
||||
self.session.close()
|
||||
except:
|
||||
if __debug__: print_exc()
|
||||
self.session = None
|
||||
|
||||
def dump(self, r):
|
||||
|
6
edsm.py
6
edsm.py
@ -7,6 +7,7 @@ import urllib2
|
||||
import Tkinter as tk
|
||||
|
||||
from config import appname, applongname, appversion, config
|
||||
from monitor import monitor
|
||||
|
||||
if __debug__:
|
||||
from traceback import print_exc
|
||||
@ -79,10 +80,11 @@ class EDSM:
|
||||
# Call an EDSM endpoint with args (which should be quoted)
|
||||
def call(self, endpoint, args, check_msgnum=True):
|
||||
try:
|
||||
idx = config.get('cmdrs').index(monitor.cmdr)
|
||||
url = 'https://www.edsm.net/%s?commanderName=%s&apiKey=%s&fromSoftware=%s&fromSoftwareVersion=%s' % (
|
||||
endpoint,
|
||||
urllib2.quote(config.get('edsm_cmdrname').encode('utf-8')),
|
||||
urllib2.quote(config.get('edsm_apikey')),
|
||||
urllib2.quote(config.get('edsm_usernames')[idx].encode('utf-8')),
|
||||
urllib2.quote(config.get('edsm_apikeys')[idx]),
|
||||
urllib2.quote(applongname),
|
||||
urllib2.quote(appversion),
|
||||
) + args
|
||||
|
@ -106,7 +106,7 @@ class EDLogs(FileSystemEventHandler):
|
||||
# Latest pre-existing logfile - e.g. if E:D is already running. Assumes logs sort alphabetically.
|
||||
# Do this before setting up the observer in case the journal directory has gone away
|
||||
try:
|
||||
logfiles = sorted([x for x in listdir(self.currentdir) if x.startswith('Journal.')])
|
||||
logfiles = sorted([x for x in listdir(self.currentdir) if x.startswith('Journal.') and x.endswith('.log')])
|
||||
self.logfile = logfiles and join(self.currentdir, logfiles[-1]) or None
|
||||
except:
|
||||
self.logfile = None
|
||||
@ -129,6 +129,8 @@ class EDLogs(FileSystemEventHandler):
|
||||
print '%s "%s"' % (polling and 'Polling' or 'Monitoring', self.currentdir)
|
||||
print 'Start logfile "%s"' % self.logfile
|
||||
|
||||
self.event_queue.append(None) # Generate null event to signal (re)start
|
||||
|
||||
if not self.running():
|
||||
self.thread = threading.Thread(target = self.worker, name = 'Journal worker')
|
||||
self.thread.daemon = True
|
||||
@ -181,8 +183,6 @@ class EDLogs(FileSystemEventHandler):
|
||||
except:
|
||||
if __debug__:
|
||||
print 'Invalid journal entry "%s"' % repr(line)
|
||||
self.event_queue.append(None) # Generate null event to signal start
|
||||
self.root.event_generate('<<JournalEvent>>', when="tail")
|
||||
else:
|
||||
loghandle = None
|
||||
|
||||
|
156
prefs.py
156
prefs.py
@ -80,12 +80,13 @@ class PreferencesDialog(tk.Toplevel):
|
||||
parent.call('tk::unsupported::MacWindowStyle', 'style', self, 'utility')
|
||||
self.resizable(tk.FALSE, tk.FALSE)
|
||||
|
||||
style = ttk.Style()
|
||||
self.cmdr = None # Note if Cmdr changes in the Journal
|
||||
|
||||
frame = ttk.Frame(self)
|
||||
frame.grid(sticky=tk.NSEW)
|
||||
|
||||
notebook = nb.Notebook(frame)
|
||||
notebook.bind('<<NotebookTabChanged>>', self.outvarchanged) # Recompute on tab change
|
||||
|
||||
PADX = 10
|
||||
BUTTONX = 12 # indent Checkbuttons and Radiobuttons
|
||||
@ -96,17 +97,23 @@ class PreferencesDialog(tk.Toplevel):
|
||||
|
||||
nb.Label(credframe, text=_('Credentials')).grid(padx=PADX, sticky=tk.W) # Section heading in settings
|
||||
ttk.Separator(credframe, orient=tk.HORIZONTAL).grid(columnspan=2, padx=PADX, pady=PADY, sticky=tk.EW)
|
||||
nb.Label(credframe, text=_('Please log in with your Elite: Dangerous account details')).grid(padx=PADX, columnspan=2, sticky=tk.W) # Use same text as E:D Launcher's login dialog
|
||||
nb.Label(credframe, text=_('Username (Email)')).grid(row=10, padx=PADX, sticky=tk.W) # Use same text as E:D Launcher's login dialog
|
||||
nb.Label(credframe, text=_('Password')).grid(row=11, padx=PADX, sticky=tk.W) # Use same text as E:D Launcher's login dialog
|
||||
self.cred_label = nb.Label(credframe, text=_('Please log in with your Elite: Dangerous account details')) # Use same text as E:D Launcher's login dialog
|
||||
self.cred_label.grid(padx=PADX, columnspan=2, sticky=tk.W)
|
||||
self.cmdr_label = nb.Label(credframe, text=_('Cmdr')) # Main window
|
||||
self.cmdr_label.grid(row=10, padx=PADX, sticky=tk.W)
|
||||
self.username_label = nb.Label(credframe, text=_('Username (Email)')) # Use same text as E:D Launcher's login dialog
|
||||
self.username_label.grid(row=11, padx=PADX, sticky=tk.W)
|
||||
self.password_label = nb.Label(credframe, text=_('Password')) # Use same text as E:D Launcher's login dialog
|
||||
self.password_label.grid(row=12, padx=PADX, sticky=tk.W)
|
||||
|
||||
self.cmdr_text = nb.Label(credframe, text=_('None')) # No hotkey/shortcut currently defined
|
||||
self.cmdr_text.grid(row=10, column=1, padx=PADX, pady=PADY, sticky=tk.W)
|
||||
self.username = nb.Entry(credframe)
|
||||
self.username.insert(0, config.get('username') or '')
|
||||
self.username.grid(row=10, column=1, padx=PADX, pady=PADY, sticky=tk.EW)
|
||||
self.username.focus_set()
|
||||
self.username.grid(row=11, column=1, padx=PADX, pady=PADY, sticky=tk.EW)
|
||||
if not monitor.is_beta and monitor.cmdr:
|
||||
self.username.focus_set()
|
||||
self.password = nb.Entry(credframe, show=u'•')
|
||||
self.password.insert(0, config.get('password') or '')
|
||||
self.password.grid(row=11, column=1, padx=PADX, pady=PADY, sticky=tk.EW)
|
||||
self.password.grid(row=12, column=1, padx=PADX, pady=PADY, sticky=tk.EW)
|
||||
|
||||
nb.Label(credframe).grid(sticky=tk.W) # big spacer
|
||||
nb.Label(credframe, text=_('Privacy')).grid(padx=PADX, sticky=tk.W) # Section heading in settings
|
||||
@ -125,13 +132,17 @@ class PreferencesDialog(tk.Toplevel):
|
||||
|
||||
output = config.getint('output') or (config.OUT_MKT_EDDN | config.OUT_SYS_EDDN | config.OUT_SHIP) # default settings
|
||||
|
||||
nb.Label(outframe, text=_('Please choose what data to save')).grid(columnspan=2, padx=PADX, sticky=tk.W)
|
||||
self.out_label = nb.Label(outframe, text=_('Please choose what data to save'))
|
||||
self.out_label.grid(columnspan=2, padx=PADX, sticky=tk.W)
|
||||
self.out_csv = tk.IntVar(value = (output & config.OUT_MKT_CSV ) and 1)
|
||||
nb.Checkbutton(outframe, text=_('Market data in CSV format file'), variable=self.out_csv, command=self.outvarchanged).grid(columnspan=2, padx=BUTTONX, sticky=tk.W)
|
||||
self.out_csv_button = nb.Checkbutton(outframe, text=_('Market data in CSV format file'), variable=self.out_csv, command=self.outvarchanged)
|
||||
self.out_csv_button.grid(columnspan=2, padx=BUTTONX, sticky=tk.W)
|
||||
self.out_td = tk.IntVar(value = (output & config.OUT_MKT_TD ) and 1)
|
||||
nb.Checkbutton(outframe, text=_('Market data in Trade Dangerous format file'), variable=self.out_td, command=self.outvarchanged).grid(columnspan=2, padx=BUTTONX, sticky=tk.W)
|
||||
self.out_td_button = nb.Checkbutton(outframe, text=_('Market data in Trade Dangerous format file'), variable=self.out_td, command=self.outvarchanged)
|
||||
self.out_td_button.grid(columnspan=2, padx=BUTTONX, sticky=tk.W)
|
||||
self.out_ship= tk.IntVar(value = (output & (config.OUT_SHIP|config.OUT_SHIP_EDS|config.OUT_SHIP_CORIOLIS) and 1))
|
||||
nb.Checkbutton(outframe, text=_('Ship loadout'), variable=self.out_ship, command=self.outvarchanged).grid(columnspan=2, padx=BUTTONX, pady=(5,0), sticky=tk.W) # Output setting
|
||||
self.out_ship_button = nb.Checkbutton(outframe, text=_('Ship loadout'), variable=self.out_ship, command=self.outvarchanged) # Output setting
|
||||
self.out_ship_button.grid(columnspan=2, padx=BUTTONX, pady=(5,0), sticky=tk.W)
|
||||
self.out_auto = tk.IntVar(value = 0 if output & config.OUT_MKT_MANUAL else 1) # inverted
|
||||
self.out_auto_button = nb.Checkbutton(outframe, text=_('Automatically update on docking'), variable=self.out_auto, command=self.outvarchanged) # Output setting
|
||||
self.out_auto_button.grid(columnspan=2, padx=BUTTONX, pady=(5,0), sticky=tk.W)
|
||||
@ -155,7 +166,8 @@ class PreferencesDialog(tk.Toplevel):
|
||||
|
||||
HyperlinkLabel(eddnframe, text='Elite Dangerous Data Network', background=nb.Label().cget('background'), url='https://github.com/jamesremuscat/EDDN/wiki', underline=True).grid(padx=PADX, sticky=tk.W) # Don't translate
|
||||
self.eddn_station= tk.IntVar(value = (output & config.OUT_MKT_EDDN) and 1)
|
||||
nb.Checkbutton(eddnframe, text=_('Send station data to the Elite Dangerous Data Network'), variable=self.eddn_station, command=self.outvarchanged).grid(padx=BUTTONX, pady=(5,0), sticky=tk.W) # Output setting
|
||||
self.eddn_station_button = nb.Checkbutton(eddnframe, text=_('Send station data to the Elite Dangerous Data Network'), variable=self.eddn_station, command=self.outvarchanged) # Output setting
|
||||
self.eddn_station_button.grid(padx=BUTTONX, pady=(5,0), sticky=tk.W)
|
||||
self.eddn_auto_button = nb.Checkbutton(eddnframe, text=_('Automatically update on docking'), variable=self.out_auto, command=self.outvarchanged) # Output setting
|
||||
self.eddn_auto_button.grid(padx=BUTTONX, sticky=tk.W)
|
||||
self.eddn_system = tk.IntVar(value = (output & config.OUT_SYS_EDDN) and 1)
|
||||
@ -180,17 +192,20 @@ class PreferencesDialog(tk.Toplevel):
|
||||
self.edsm_label = HyperlinkLabel(edsmframe, text=_('Elite Dangerous Star Map credentials'), background=nb.Label().cget('background'), url='https://www.edsm.net/settings/api', underline=True) # Section heading in settings
|
||||
self.edsm_label.grid(columnspan=2, padx=PADX, sticky=tk.W)
|
||||
|
||||
self.edsm_cmdr_label = nb.Label(edsmframe, text=_('Commander Name')) # EDSM setting
|
||||
self.edsm_cmdr_label = nb.Label(edsmframe, text=_('Cmdr')) # Main window
|
||||
self.edsm_cmdr_label.grid(row=10, padx=PADX, sticky=tk.W)
|
||||
self.edsm_cmdr = nb.Entry(edsmframe)
|
||||
self.edsm_cmdr.insert(0, config.get('edsm_cmdrname') or '')
|
||||
self.edsm_cmdr.grid(row=10, column=1, padx=PADX, pady=PADY, sticky=tk.EW)
|
||||
self.edsm_cmdr_text = nb.Label(edsmframe, text=_('None')) # No hotkey/shortcut currently defined
|
||||
self.edsm_cmdr_text.grid(row=10, column=1, padx=PADX, pady=PADY, sticky=tk.W)
|
||||
|
||||
self.edsm_user_label = nb.Label(edsmframe, text=_('Commander Name')) # EDSM setting
|
||||
self.edsm_user_label.grid(row=11, padx=PADX, sticky=tk.W)
|
||||
self.edsm_user = nb.Entry(edsmframe)
|
||||
self.edsm_user.grid(row=11, column=1, padx=PADX, pady=PADY, sticky=tk.EW)
|
||||
|
||||
self.edsm_apikey_label = nb.Label(edsmframe, text=_('API Key')) # EDSM setting
|
||||
self.edsm_apikey_label.grid(row=11, padx=PADX, sticky=tk.W)
|
||||
self.edsm_apikey_label.grid(row=12, padx=PADX, sticky=tk.W)
|
||||
self.edsm_apikey = nb.Entry(edsmframe)
|
||||
self.edsm_apikey.insert(0, config.get('edsm_apikey') or '')
|
||||
self.edsm_apikey.grid(row=11, column=1, padx=PADX, pady=PADY, sticky=tk.EW)
|
||||
self.edsm_apikey.grid(row=12, column=1, padx=PADX, pady=PADY, sticky=tk.EW)
|
||||
|
||||
notebook.add(edsmframe, text='EDSM') # Not translated
|
||||
|
||||
@ -321,30 +336,57 @@ class PreferencesDialog(tk.Toplevel):
|
||||
0x10000, None, position):
|
||||
self.geometry("+%d+%d" % (position.left, position.top))
|
||||
|
||||
def outvarchanged(self):
|
||||
def outvarchanged(self, event=None):
|
||||
self.cmdr_text['state'] = self.edsm_cmdr_text['state'] = tk.NORMAL # must be writable to update
|
||||
self.cmdr_text['text'] = self.edsm_cmdr_text['text'] = monitor.cmdr and monitor.is_beta and ('%s [Beta]' % monitor.cmdr) or monitor.cmdr or _('None') # No hotkey/shortcut currently defined
|
||||
if self.cmdr != monitor.cmdr:
|
||||
# Cmdr has changed - update settings
|
||||
if not monitor.is_beta:
|
||||
migrate(monitor.cmdr) # migration from <= 2.25
|
||||
if monitor.cmdr and config.get('cmdrs') and monitor.cmdr in config.get('cmdrs'):
|
||||
config_idx = config.get('cmdrs').index(monitor.cmdr)
|
||||
else:
|
||||
config_idx = None
|
||||
self.username['state'] = tk.NORMAL
|
||||
self.username.delete(0, tk.END)
|
||||
self.username.insert(0, config_idx is not None and config.get('fdev_usernames')[config_idx] or '')
|
||||
self.password['state'] = tk.NORMAL
|
||||
self.password.delete(0, tk.END)
|
||||
self.password.insert(0, config_idx is not None and config.get('fdev_passwords')[config_idx] or '')
|
||||
self.edsm_user['state'] = tk.NORMAL
|
||||
self.edsm_user.delete(0, tk.END)
|
||||
self.edsm_user.insert(0, config_idx is not None and config.get('edsm_usernames')[config_idx] or '')
|
||||
self.edsm_apikey['state'] = tk.NORMAL
|
||||
self.edsm_apikey.delete(0, tk.END)
|
||||
self.edsm_apikey.insert(0, config_idx is not None and config.get('edsm_apikeys')[config_idx] or '')
|
||||
self.cmdr = monitor.cmdr
|
||||
|
||||
cmdr_state = not monitor.is_beta and monitor.cmdr and tk.NORMAL or tk.DISABLED
|
||||
self.cred_label['state'] = self.cmdr_label['state'] = self.username_label['state'] = self.password_label['state'] = cmdr_state
|
||||
self.cmdr_text['state'] = self.username['state'] = self.password['state'] = cmdr_state
|
||||
|
||||
self.displaypath(self.outdir, self.outdir_entry)
|
||||
self.displaypath(self.logdir, self.logdir_entry)
|
||||
|
||||
logdir = self.logdir.get()
|
||||
logvalid = logdir and exists(logdir)
|
||||
|
||||
local = self.out_td.get() or self.out_csv.get() or self.out_ship.get()
|
||||
self.out_auto_button['state'] = local and logvalid and not monitor.is_beta and tk.NORMAL or tk.DISABLED
|
||||
self.out_label['state'] = self.out_csv_button['state'] = self.out_td_button['state'] = self.out_ship_button['state'] = not monitor.is_beta and tk.NORMAL or tk.DISABLED
|
||||
local = not monitor.is_beta and (self.out_td.get() or self.out_csv.get() or self.out_ship.get())
|
||||
self.out_auto_button['state'] = local and logvalid and tk.NORMAL or tk.DISABLED
|
||||
self.outdir_label['state'] = local and tk.NORMAL or tk.DISABLED
|
||||
self.outbutton['state'] = local and tk.NORMAL or tk.DISABLED
|
||||
self.outdir_entry['state'] = local and 'readonly' or tk.DISABLED
|
||||
|
||||
self.eddn_station_button['state'] = not monitor.is_beta and tk.NORMAL or tk.DISABLED
|
||||
self.eddn_auto_button['state'] = self.eddn_station.get() and logvalid and not monitor.is_beta and tk.NORMAL or tk.DISABLED
|
||||
self.eddn_system_button['state']= logvalid and tk.NORMAL or tk.DISABLED
|
||||
self.eddn_delay_button['state'] = logvalid and eddn.replayfile and self.eddn_system.get() and tk.NORMAL or tk.DISABLED
|
||||
|
||||
self.edsm_log_button['state'] = logvalid and tk.NORMAL or tk.DISABLED
|
||||
edsm_state = logvalid and self.edsm_log.get() and tk.NORMAL or tk.DISABLED
|
||||
self.edsm_label['state'] = edsm_state
|
||||
self.edsm_cmdr_label['state'] = edsm_state
|
||||
self.edsm_apikey_label['state'] = edsm_state
|
||||
self.edsm_cmdr['state'] = edsm_state
|
||||
self.edsm_apikey['state'] = edsm_state
|
||||
self.edsm_log_button['state'] = logvalid and not monitor.is_beta and tk.NORMAL or tk.DISABLED
|
||||
edsm_state = logvalid and monitor.cmdr and not monitor.is_beta and self.edsm_log.get() and tk.NORMAL or tk.DISABLED
|
||||
self.edsm_label['state'] = self.edsm_cmdr_label['state'] = self.edsm_user_label['state'] = self.edsm_apikey_label['state'] = edsm_state
|
||||
self.edsm_cmdr_text['state'] = self.edsm_user['state'] = self.edsm_apikey['state'] = edsm_state
|
||||
|
||||
def filebrowse(self, title, pathvar):
|
||||
if platform != 'win32':
|
||||
@ -474,9 +516,20 @@ class PreferencesDialog(tk.Toplevel):
|
||||
|
||||
|
||||
def apply(self):
|
||||
credentials = (config.get('username'), config.get('password'))
|
||||
config.set('username', self.username.get().strip())
|
||||
config.set('password', self.password.get().strip())
|
||||
if self.cmdr and not monitor.is_beta:
|
||||
if not config.get('cmdrs'):
|
||||
config.set('cmdrs', [self.cmdr])
|
||||
config.set('fdev_usernames', [self.username.get().strip()])
|
||||
config.set('fdev_passwords', [self.password.get().strip()])
|
||||
config.set('edsm_usernames', [self.edsm_user.get().strip()])
|
||||
config.set('edsm_apikeys', [self.edsm_apikey.get().strip()])
|
||||
else:
|
||||
idx = config.get('cmdrs').index(self.cmdr) if self.cmdr in config.get('cmdrs') else -1
|
||||
_putfirst('cmdrs', idx, self.cmdr)
|
||||
_putfirst('fdev_usernames', idx, self.username.get().strip())
|
||||
_putfirst('fdev_passwords', idx, self.password.get().strip())
|
||||
_putfirst('edsm_usernames', idx, self.edsm_user.get().strip())
|
||||
_putfirst('edsm_apikeys', idx, self.edsm_apikey.get().strip())
|
||||
|
||||
config.set('output',
|
||||
(self.out_td.get() and config.OUT_MKT_TD) +
|
||||
@ -489,9 +542,6 @@ class PreferencesDialog(tk.Toplevel):
|
||||
(self.edsm_log.get() and config.OUT_SYS_EDSM))
|
||||
config.set('outdir', self.outdir.get().startswith('~') and join(config.home, self.outdir.get()[2:]) or self.outdir.get())
|
||||
|
||||
config.set('edsm_cmdrname', self.edsm_cmdr.get().strip())
|
||||
config.set('edsm_apikey', self.edsm_apikey.get().strip())
|
||||
|
||||
logdir = self.logdir.get()
|
||||
if config.default_journal_dir and logdir.lower() == config.default_journal_dir.lower():
|
||||
config.set('journaldir', '') # default location
|
||||
@ -621,3 +671,35 @@ class AuthenticationDialog(tk.Toplevel):
|
||||
self.parent.wm_attributes('-topmost', config.getint('always_ontop') and 1 or 0)
|
||||
self.destroy()
|
||||
if self.callback: self.callback(None)
|
||||
|
||||
# migration from <= 2.25. Assumes current Cmdr corresponds to the saved credentials
|
||||
def migrate(current_cmdr):
|
||||
if current_cmdr and not config.get('cmdrs') and config.get('username') and config.get('password'):
|
||||
config.set('cmdrs', [current_cmdr])
|
||||
config.set('fdev_usernames', [config.get('username')])
|
||||
config.set('fdev_passwords', [config.get('password')])
|
||||
config.set('edsm_usernames', [config.get('edsm_cmdrname') or ''])
|
||||
config.set('edsm_apikeys', [config.get('edsm_apikey') or ''])
|
||||
# XXX to be done for release
|
||||
# config.delete('username')
|
||||
# config.delete('password')
|
||||
# config.delete('edsm_cmdrname')
|
||||
# config.delete('edsm_apikey')
|
||||
|
||||
# Put current Cmdr first in the lists
|
||||
def make_current(current_cmdr):
|
||||
if current_cmdr and config.get('cmdrs') and current_cmdr in config.get('cmdrs'):
|
||||
idx = config.get('cmdrs').index(current_cmdr)
|
||||
_putfirst('cmdrs', idx)
|
||||
_putfirst('fdev_usernames', idx)
|
||||
_putfirst('fdev_passwords', idx)
|
||||
_putfirst('edsm_usernames', idx)
|
||||
_putfirst('edsm_apikeys', idx)
|
||||
|
||||
def _putfirst(setting, config_idx, new_value=None):
|
||||
assert config_idx>=0 or new_value is not None, (setting, config_idx, new_value)
|
||||
values = config.get(setting)
|
||||
values.insert(0, new_value if config_idx<0 else values.pop(config_idx))
|
||||
if new_value is not None:
|
||||
values[0] = new_value
|
||||
config.set(setting, values)
|
||||
|
4
stats.py
4
stats.py
@ -11,6 +11,7 @@ import myNotebook as nb
|
||||
|
||||
import companion
|
||||
from companion import ship_map
|
||||
from monitor import monitor
|
||||
import prefs
|
||||
|
||||
if platform=='win32':
|
||||
@ -175,6 +176,9 @@ class StatsDialog():
|
||||
self.showstats()
|
||||
|
||||
def showstats(self):
|
||||
if not monitor.cmdr or monitor.is_beta:
|
||||
return # In Beta - do nothing
|
||||
|
||||
self.status['text'] = _('Fetching data...')
|
||||
self.parent.update_idletasks()
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user