mirror of
https://github.com/EDCD/EDMarketConnector.git
synced 2025-04-13 15:57:14 +03:00
Switch EDSM integration to a plugin
This commit is contained in:
parent
93ff800f90
commit
e810b87dd4
@ -54,7 +54,6 @@ import commodity
|
||||
from commodity import COMMODITY_CSV
|
||||
import td
|
||||
import eddn
|
||||
import edsm
|
||||
import coriolis
|
||||
import edshipyard
|
||||
import loadout
|
||||
@ -68,7 +67,6 @@ from theme import theme
|
||||
|
||||
|
||||
SERVER_RETRY = 5 # retry pause for Companion servers [s]
|
||||
EDSM_POLL = 0.1
|
||||
|
||||
# Limits on local clock drift from EDDN gateway
|
||||
DRIFT_THRESHOLD = 3 * 60
|
||||
@ -87,7 +85,6 @@ class AppWindow:
|
||||
|
||||
self.holdofftime = config.getint('querytime') + companion.holdoff
|
||||
self.session = companion.Session()
|
||||
self.edsm = edsm.EDSM()
|
||||
self.eddn = eddn.EDDN(self)
|
||||
|
||||
self.w = master
|
||||
@ -113,19 +110,15 @@ class AppWindow:
|
||||
|
||||
self.cmdr_label = tk.Label(frame)
|
||||
self.ship_label = tk.Label(frame)
|
||||
self.system_label = tk.Label(frame)
|
||||
|
||||
self.cmdr_label.grid(row=1, column=0, sticky=tk.W)
|
||||
self.ship_label.grid(row=2, column=0, sticky=tk.W)
|
||||
self.system_label.grid(row=3, column=0, sticky=tk.W)
|
||||
|
||||
self.cmdr = tk.Label(frame, anchor=tk.W)
|
||||
self.ship = HyperlinkLabel(frame, url = self.shipyard_url)
|
||||
self.system = HyperlinkLabel(frame, compound=tk.RIGHT, url = self.system_url, popup_copy = True)
|
||||
|
||||
self.cmdr.grid(row=1, column=1, sticky=tk.EW)
|
||||
self.ship.grid(row=2, column=1, sticky=tk.EW)
|
||||
self.system.grid(row=3, column=1, sticky=tk.EW)
|
||||
|
||||
for plugin in plug.PLUGINS:
|
||||
appitem = plugin.get_app(frame)
|
||||
@ -347,7 +340,6 @@ class AppWindow:
|
||||
self.cmdr_label['text'] = _('Cmdr') + ':' # Main window
|
||||
self.ship_label['text'] = (monitor.state['Captain'] and _('Role') or # Multicrew role label in main window
|
||||
_('Ship')) + ':' # Main window
|
||||
self.system_label['text'] = _('System') + ':' # Main window
|
||||
self.button['text'] = self.theme_button['text'] = _('Update') # Update button in main window
|
||||
if platform == 'darwin':
|
||||
self.menubar.entryconfigure(1, label=_('File')) # Menu title
|
||||
@ -434,7 +426,6 @@ class AppWindow:
|
||||
hotkeymgr.play_good()
|
||||
self.status['text'] = _('Fetching data...')
|
||||
self.button['state'] = self.theme_button['state'] = tk.DISABLED
|
||||
self.edit_menu.entryconfigure(0, state=tk.DISABLED) # Copy
|
||||
self.w.update_idletasks()
|
||||
|
||||
try:
|
||||
@ -469,11 +460,10 @@ class AppWindow:
|
||||
self.ship['text'] = companion.ship_map.get(data['ship']['name'].lower(), data['ship']['name'])
|
||||
monitor.state['ShipID'] = data['ship']['id']
|
||||
monitor.state['ShipType'] = data['ship']['name'].lower()
|
||||
if not monitor.system:
|
||||
self.system['text'] = data['lastSystem']['name']
|
||||
self.system['image'] = ''
|
||||
self.status['text'] = ''
|
||||
self.edit_menu.entryconfigure(0, state=tk.NORMAL) # Copy
|
||||
|
||||
if data['commander'].get('credits') is not None:
|
||||
monitor.state['Credits'] = data['commander']['credits']
|
||||
monitor.state['Loan'] = data['commander'].get('debt', 0)
|
||||
|
||||
# stuff we can do when not docked
|
||||
err = plug.notify_newdata(data, monitor.is_beta)
|
||||
@ -484,16 +474,6 @@ class AppWindow:
|
||||
if config.getint('output') & config.OUT_SHIP:
|
||||
loadout.export(data)
|
||||
|
||||
# Send flightlog EDSM if FSDJump failed to do so
|
||||
if config.getint('output') & config.OUT_SYS_EDSM and self.edsm.result['img'] == self.edsm._IMG_ERROR and not monitor.is_beta and not monitor.captain and config.get('cmdrs') and monitor.cmdr in config.get('cmdrs') and config.get('edsm_usernames')[config.get('cmdrs').index(monitor.cmdr)]:
|
||||
try:
|
||||
self.edsm.writelog(querytime, monitor.system, monitor.coordinates, monitor.state['ShipID'])
|
||||
except Exception as e:
|
||||
if __debug__: print_exc()
|
||||
self.status['text'] = unicode(e)
|
||||
play_bad = True
|
||||
self.edsmpoll()
|
||||
|
||||
if not (config.getint('output') & ~config.OUT_SHIP & config.OUT_STATION_ANY):
|
||||
# no station data requested - we're done
|
||||
pass
|
||||
@ -546,27 +526,6 @@ class AppWindow:
|
||||
if not old_status:
|
||||
self.status['text'] = ''
|
||||
|
||||
# Update credits and ship info and send to EDSM
|
||||
if not monitor.is_beta and config.getint('output') & config.OUT_SYS_EDSM:
|
||||
try:
|
||||
if data['commander'].get('credits') is not None:
|
||||
monitor.state['Credits'] = data['commander']['credits']
|
||||
monitor.state['Loan'] = data['commander'].get('debt', 0)
|
||||
self.edsm.setcredits(monitor.state['Credits'], monitor.state['Loan'])
|
||||
ship = companion.ship(data)
|
||||
if ship != self.edsm.lastship:
|
||||
self.edsm.updateship(monitor.state['ShipID'],
|
||||
monitor.state['ShipType'],
|
||||
[
|
||||
('linkToCoriolis', coriolis.url(data, monitor.is_beta)),
|
||||
('linkToEDShipyard', edshipyard.url(data, monitor.is_beta)),
|
||||
])
|
||||
self.edsm.lastship = ship
|
||||
except Exception as e:
|
||||
# Not particularly important so silent on failure
|
||||
if __debug__: print_exc()
|
||||
|
||||
|
||||
except companion.VerificationRequired:
|
||||
return prefs.AuthenticationDialog(self.w, partial(self.verify, self.getandsend))
|
||||
|
||||
@ -627,7 +586,6 @@ class AppWindow:
|
||||
if not entry:
|
||||
return
|
||||
|
||||
system_changed = monitor.system and self.system['text'] != monitor.system
|
||||
|
||||
# Update main window
|
||||
if monitor.cmdr and monitor.state['Captain']:
|
||||
@ -649,63 +607,13 @@ class AppWindow:
|
||||
self.ship_label['text'] = _('Ship') + ':' # Main window
|
||||
self.ship['text'] = ''
|
||||
|
||||
if self.system['text'] != monitor.system:
|
||||
self.system['text'] = monitor.system or ''
|
||||
self.edsm.link(monitor.system)
|
||||
self.edsmpoll()
|
||||
self.edit_menu.entryconfigure(0, state=monitor.system and tk.NORMAL or tk.DISABLED) # Copy
|
||||
|
||||
if entry['event'] in ['Undocked', 'StartJump', 'SetUserShipName', 'ShipyardBuy', 'ShipyardSell', 'ShipyardSwap', 'ModuleBuy', 'ModuleSell', 'MaterialCollected', 'MaterialDiscarded', 'ScientificResearch', 'EngineerCraft', 'Synthesis', 'JoinACrew']:
|
||||
self.status['text'] = '' # Periodically clear any old error
|
||||
self.w.update_idletasks()
|
||||
|
||||
# Send interesting events to EDSM
|
||||
if config.getint('output') & config.OUT_SYS_EDSM and not monitor.is_beta and not monitor.captain and config.get('cmdrs') and monitor.cmdr in config.get('cmdrs') and config.get('edsm_usernames')[config.get('cmdrs').index(monitor.cmdr)]:
|
||||
try:
|
||||
# Update system status on startup
|
||||
if entry['event'] in [None, 'StartUp'] and monitor.mode and monitor.system:
|
||||
self.edsm.lookup(monitor.system)
|
||||
|
||||
# Send credits to EDSM on new game (but not on startup - data might be old)
|
||||
if entry['event'] == 'LoadGame':
|
||||
self.edsm.setcredits(monitor.state['Credits'], monitor.state['Loan'])
|
||||
|
||||
# Send rank info to EDSM on startup or change
|
||||
if entry['event'] in ['StartUp', 'Progress', 'Promotion'] and monitor.state['Rank']:
|
||||
self.edsm.setranks(monitor.state['Rank'])
|
||||
|
||||
# Send ship info to EDSM on startup or change
|
||||
if entry['event'] in ['StartUp', 'Loadout', 'LoadGame', 'SetUserShipName'] and monitor.cmdr and monitor.state['ShipID']:
|
||||
self.edsm.setshipid(monitor.state['ShipID'])
|
||||
props = []
|
||||
if monitor.state['ShipIdent'] is not None:
|
||||
props.append(('shipIdent', monitor.state['ShipIdent']))
|
||||
if monitor.state['ShipName'] is not None:
|
||||
props.append(('shipName', monitor.state['ShipName']))
|
||||
if monitor.state['PaintJob'] is not None:
|
||||
props.append(('paintJob', monitor.state['PaintJob']))
|
||||
self.edsm.updateship(monitor.state['ShipID'], monitor.state['ShipType'], props)
|
||||
elif entry['event'] in ['ShipyardBuy', 'ShipyardSell']:
|
||||
self.edsm.sellship(entry.get('SellShipID'))
|
||||
|
||||
# Send materials info to EDSM on startup or change
|
||||
if entry['event'] in ['StartUp', 'LoadGame', 'MaterialCollected', 'MaterialDiscarded', 'ScientificResearch', 'EngineerCraft', 'Synthesis']:
|
||||
self.edsm.setmaterials(monitor.state['Raw'], monitor.state['Manufactured'], monitor.state['Encoded'])
|
||||
|
||||
# Send paintjob info to EDSM on change
|
||||
if entry['event'] in ['ModuleBuy', 'ModuleSell'] and entry['Slot'] == 'PaintJob':
|
||||
self.edsm.updateship(monitor.state['ShipID'], monitor.state['ShipType'], [('paintJob', monitor.state['PaintJob'])])
|
||||
|
||||
# Write EDSM log on change
|
||||
if monitor.mode and entry['event'] in ['Location', 'FSDJump']:
|
||||
self.edsm.writelog(timegm(strptime(entry['timestamp'], '%Y-%m-%dT%H:%M:%SZ')), monitor.system, monitor.coordinates, monitor.state['ShipID'])
|
||||
|
||||
except Exception as e:
|
||||
if __debug__: print_exc()
|
||||
self.status['text'] = unicode(e)
|
||||
if not config.getint('hotkey_mute'):
|
||||
hotkeymgr.play_bad()
|
||||
self.edsmpoll()
|
||||
|
||||
# Companion login - do this after EDSM so any EDSM errors don't mask login errors
|
||||
# Companion login
|
||||
if entry['event'] in [None, 'StartUp', 'NewCommander', 'LoadGame'] and monitor.cmdr:
|
||||
if config.get('cmdrs') and monitor.cmdr in config.get('cmdrs'):
|
||||
prefs.make_current(monitor.cmdr)
|
||||
@ -737,7 +645,7 @@ class AppWindow:
|
||||
return
|
||||
|
||||
# Plugin backwards compatibility
|
||||
if system_changed:
|
||||
if monitor.mode and entry['event'] in ['StartUp', 'Location', 'FSDJump']:
|
||||
plug.notify_system_changed(timegm(strptime(entry['timestamp'], '%Y-%m-%dT%H:%M:%SZ')), monitor.system, monitor.coordinates)
|
||||
|
||||
# Auto-Update after docking
|
||||
@ -812,13 +720,6 @@ class AppWindow:
|
||||
if not config.getint('hotkey_mute'):
|
||||
hotkeymgr.play_bad()
|
||||
|
||||
def edsmpoll(self):
|
||||
result = self.edsm.result
|
||||
if result['done']:
|
||||
self.system['image'] = result['img']
|
||||
else:
|
||||
self.w.after(int(EDSM_POLL * 1000), self.edsmpoll)
|
||||
|
||||
def shipyard_url(self, shipname=None):
|
||||
|
||||
if not monitor.cmdr or not monitor.mode:
|
||||
@ -856,9 +757,6 @@ class AppWindow:
|
||||
assert False, config.getint('shipyard')
|
||||
return False
|
||||
|
||||
def system_url(self, text):
|
||||
return text and self.edsm.result['url']
|
||||
|
||||
def cooldown(self):
|
||||
if time() < self.holdofftime:
|
||||
self.button['text'] = self.theme_button['text'] = _('cooldown {SS}s').format(SS = int(self.holdofftime - time())) # Update button in main window
|
||||
|
@ -138,6 +138,9 @@
|
||||
<Component Guid="*">
|
||||
<File KeyPath="yes" Source="SourceDir\eddb.py" />
|
||||
</Component>
|
||||
<Component Guid="*">
|
||||
<File KeyPath="yes" Source="SourceDir\edsm.py" />
|
||||
</Component>
|
||||
<Component Guid="*">
|
||||
<File KeyPath="yes" Source="SourceDir\es.strings" />
|
||||
</Component>
|
||||
@ -447,6 +450,7 @@
|
||||
<ComponentRef Id="EDMarketConnector.VisualElementsManifest.xml" />
|
||||
<ComponentRef Id="EDMC.exe" />
|
||||
<ComponentRef Id="eddb.py" />
|
||||
<ComponentRef Id="edsm.py" />
|
||||
<ComponentRef Id="es.strings" />
|
||||
<ComponentRef Id="fi.strings" />
|
||||
<ComponentRef Id="fr.strings" />
|
||||
|
@ -19,7 +19,7 @@
|
||||
/* CQC rank. [stats.py] */
|
||||
"Amateur" = "Amateur";
|
||||
|
||||
/* EDSM setting. [prefs.py] */
|
||||
/* EDSM setting. [edsm.py] */
|
||||
"API Key" = "API Key";
|
||||
|
||||
/* Tab heading in settings. [prefs.py] */
|
||||
@ -70,7 +70,7 @@
|
||||
/* Ranking. [stats.py] */
|
||||
"Combat" = "Combat";
|
||||
|
||||
/* EDSM setting. [prefs.py] */
|
||||
/* EDSM setting. [edsm.py] */
|
||||
"Commander Name" = "Commander Name";
|
||||
|
||||
/* Combat rank. [stats.py] */
|
||||
@ -139,7 +139,7 @@
|
||||
/* Top rank. [stats.py] */
|
||||
"Elite" = "Elite";
|
||||
|
||||
/* Section heading in settings. [prefs.py] */
|
||||
/* Section heading in settings. [edsm.py] */
|
||||
"Elite Dangerous Star Map credentials" = "Elite Dangerous Star Map credentials";
|
||||
|
||||
/* Ranking. [stats.py] */
|
||||
@ -430,7 +430,7 @@
|
||||
/* CQC rank. [stats.py] */
|
||||
"Semi Professional" = "Semi Professional";
|
||||
|
||||
/* [prefs.py] */
|
||||
/* [edsm.py] */
|
||||
"Send flight log to Elite Dangerous Star Map" = "Send flight log to Elite Dangerous Star Map";
|
||||
|
||||
/* Output setting. [prefs.py] */
|
||||
@ -475,7 +475,7 @@
|
||||
/* Explorer rank. [stats.py] */
|
||||
"Surveyor" = "Surveyor";
|
||||
|
||||
/* Main window. [EDMarketConnector.py] */
|
||||
/* Main window. [edsm.py] */
|
||||
"System" = "System";
|
||||
|
||||
/* Appearance setting. [prefs.py] */
|
||||
|
@ -102,7 +102,7 @@ class Config:
|
||||
# OUT_STAT = 64 # No longer available
|
||||
OUT_SHIP_CORIOLIS = 128 # Replaced by OUT_SHIP
|
||||
OUT_STATION_ANY = OUT_MKT_EDDN|OUT_MKT_TD|OUT_MKT_CSV|OUT_SHIP|OUT_SHIP_EDS|OUT_SHIP_CORIOLIS
|
||||
OUT_SYS_EDSM = 256
|
||||
# OUT_SYS_EDSM = 256 # Now a plugin
|
||||
# OUT_SYS_AUTO = 512 # Now always automatic
|
||||
OUT_MKT_MANUAL = 1024
|
||||
OUT_SYS_EDDN = 2048
|
||||
|
233
edsm.py
233
edsm.py
@ -1,233 +0,0 @@
|
||||
import json
|
||||
import threading
|
||||
from sys import platform
|
||||
import time
|
||||
import urllib2
|
||||
|
||||
import Tkinter as tk
|
||||
|
||||
from config import appname, applongname, appversion, config
|
||||
from monitor import monitor
|
||||
|
||||
if __debug__:
|
||||
from traceback import print_exc
|
||||
|
||||
|
||||
if platform=='darwin':
|
||||
# mimimal implementation of requests interface since OpenSSL 0.9.8 on OSX
|
||||
# fails to negotiate with Cloudflare unless cipher is forced
|
||||
|
||||
import ssl
|
||||
|
||||
class Response(object):
|
||||
|
||||
def __init__(self, url, status_code, headers, content):
|
||||
self.url = url
|
||||
self.status_code = status_code
|
||||
self.headers = headers # actually a mimetools.Message instance
|
||||
self.content = content
|
||||
|
||||
def json(self):
|
||||
return json.loads(self.content)
|
||||
|
||||
def raise_for_status(self):
|
||||
if self.status_code >= 400:
|
||||
raise urllib2.HTTPError(self.url, self.status_code, '%d %s' % (self.status_code, self.status_code >= 500 and 'Server Error' or 'Client Error'), self.headers, None)
|
||||
|
||||
class Session(object):
|
||||
|
||||
def __init__(self):
|
||||
self.headers = {}
|
||||
sslcontext = ssl.SSLContext(ssl.PROTOCOL_TLSv1) # Requires Python >= 2.7.9 on OSX >= 10.10
|
||||
sslcontext.set_ciphers("ECCdraft:HIGH:!aNULL")
|
||||
self.opener = urllib2.build_opener(urllib2.HTTPSHandler(context=sslcontext))
|
||||
self.opener.addheaders = [('User-Agent', '%s/%s' % (appname, appversion))]
|
||||
|
||||
def get(self, url, timeout=None, headers={}):
|
||||
try:
|
||||
h = self.opener.open(url, timeout=timeout)
|
||||
r = Response(h.geturl(), h.code, h.info(), h.read())
|
||||
h.close()
|
||||
return r
|
||||
except urllib2.HTTPError, e:
|
||||
return Response(url, e.code, {}, '') # requests doesn't raise exceptions for HTTP errors
|
||||
except:
|
||||
raise
|
||||
|
||||
def close(self):
|
||||
pass
|
||||
else:
|
||||
from requests import Session
|
||||
|
||||
|
||||
class EDSM:
|
||||
|
||||
_TIMEOUT = 10
|
||||
FAKE = ['CQC', 'Training', 'Destination'] # Fake systems that shouldn't be sent to EDSM
|
||||
|
||||
def __init__(self):
|
||||
self.result = { 'img': None, 'url': None, 'done': True }
|
||||
self.syscache = set() # Cache URLs of systems with known coordinates
|
||||
self.session = Session()
|
||||
self.lastship = None # Description of last ship that we sent to EDSM
|
||||
|
||||
# Can't be in class definition since can only call PhotoImage after window is created
|
||||
EDSM._IMG_KNOWN = tk.PhotoImage(data = 'R0lGODlhEAAQAMIEAFWjVVWkVWS/ZGfFZ////////////////yH5BAEKAAQALAAAAAAQABAAAAMvSLrc/lAFIUIkYOgNXt5g14Dk0AQlaC1CuglM6w7wgs7rMpvNV4q932VSuRiPjQQAOw==') # green circle
|
||||
EDSM._IMG_UNKNOWN = tk.PhotoImage(data = 'R0lGODlhEAAQAKEDAGVLJ+ddWO5fW////yH5BAEKAAMALAAAAAAQABAAAAItnI+pywYRQBtA2CtVvTwjDgrJFlreEJRXgKSqwB5keQ6vOKq1E+7IE5kIh4kCADs=') # red circle
|
||||
EDSM._IMG_NEW = tk.PhotoImage(data = 'R0lGODlhEAAQAMZwANKVHtWcIteiHuiqLPCuHOS1MN22ZeW7ROG6Zuu9MOy+K/i8Kf/DAuvCVf/FAP3BNf/JCf/KAPHHSv7ESObHdv/MBv/GRv/LGP/QBPXOPvjPQfjQSvbRSP/UGPLSae7Sfv/YNvLXgPbZhP7dU//iI//mAP/jH//kFv7fU//fV//ebv/iTf/iUv/kTf/iZ/vgiP/hc/vgjv/jbfriiPriiv7ka//if//jd//sJP/oT//tHv/mZv/sLf/rRP/oYv/rUv/paP/mhv/sS//oc//lkf/mif/sUf/uPv/qcv/uTv/uUv/vUP/qhP/xP//pm//ua//sf//ubf/wXv/thv/tif/slv/tjf/smf/yYP/ulf/2R//2Sv/xkP/2av/0gP/ylf/2df/0i//0j//0lP/5cP/7a//1p//5gf/7ev/3o//2sf/5mP/6kv/2vP/3y//+jP///////////////////////////////////////////////////////////////yH5BAEKAH8ALAAAAAAQABAAAAePgH+Cg4SFhoJKPIeHYT+LhVppUTiPg2hrUkKPXWdlb2xHJk9jXoNJQDk9TVtkYCUkOy4wNjdGfy1UXGJYOksnPiwgFwwYg0NubWpmX1ArHREOFYUyWVNIVkxXQSoQhyMoNVUpRU5EixkcMzQaGy8xhwsKHiEfBQkSIg+GBAcUCIIBBDSYYGiAAUMALFR6FAgAOw==')
|
||||
EDSM._IMG_ERROR = tk.PhotoImage(data = 'R0lGODlhEAAQAKEBAAAAAP///////////yH5BAEKAAIALAAAAAAQABAAAAIwlBWpeR0AIwwNPRmZuVNJinyWuClhBlZjpm5fqnIAHJPtOd3Hou9mL6NVgj2LplEAADs=') # BBC Mode 5 '?'
|
||||
|
||||
# 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_usernames')[idx].encode('utf-8')),
|
||||
urllib2.quote(config.get('edsm_apikeys')[idx]),
|
||||
urllib2.quote(applongname),
|
||||
urllib2.quote(appversion),
|
||||
) + args
|
||||
r = self.session.get(url, timeout=EDSM._TIMEOUT)
|
||||
r.raise_for_status()
|
||||
reply = r.json()
|
||||
if not check_msgnum:
|
||||
return reply
|
||||
(msgnum, msg) = reply['msgnum'], reply['msg']
|
||||
except:
|
||||
if __debug__: print_exc()
|
||||
raise Exception(_("Error: Can't connect to EDSM"))
|
||||
|
||||
# Message numbers: 1xx = OK, 2xx = fatal error, 3xx = error (but not generated in practice), 4xx = ignorable errors
|
||||
if msgnum // 100 not in (1,4):
|
||||
raise Exception(_('Error: EDSM {MSG}').format(MSG=msg))
|
||||
else:
|
||||
return reply
|
||||
|
||||
# Just set link without doing a lookup
|
||||
def link(self, system_name):
|
||||
self.cancel_lookup()
|
||||
if not system_name or system_name in self.FAKE:
|
||||
self.result = { 'img': '', 'url': None, 'done': True, 'uncharted': False }
|
||||
else:
|
||||
self.result = { 'img': '', 'url': 'https://www.edsm.net/show-system?systemName=%s' % urllib2.quote(system_name), 'done': True, 'uncharted': False }
|
||||
|
||||
def lookup(self, system_name, known=0):
|
||||
self.cancel_lookup()
|
||||
|
||||
if system_name in self.FAKE:
|
||||
self.result = { 'img': '', 'url': None, 'done': True, 'uncharted': False }
|
||||
elif known or system_name in self.syscache:
|
||||
self.result = { 'img': EDSM._IMG_KNOWN, 'url': 'https://www.edsm.net/show-system?systemName=%s' % urllib2.quote(system_name), 'done': True, 'uncharted': False }
|
||||
else:
|
||||
self.result = { 'img': EDSM._IMG_ERROR, 'url': 'https://www.edsm.net/show-system?systemName=%s' % urllib2.quote(system_name), 'done': True, 'uncharted': False }
|
||||
data = self.call('api-v1/system', '&sysname=%s&coords=1' % urllib2.quote(system_name), check_msgnum=False)
|
||||
|
||||
if data == -1 or not data:
|
||||
# System not present - but don't create it on the assumption that the caller will
|
||||
self.result['img'] = EDSM._IMG_NEW
|
||||
self.result['uncharted'] = True
|
||||
elif data.get('coords'):
|
||||
self.result['img'] = EDSM._IMG_KNOWN
|
||||
self.syscache.add(system_name)
|
||||
else:
|
||||
self.result['img'] = EDSM._IMG_UNKNOWN
|
||||
self.result['uncharted'] = True
|
||||
|
||||
# Asynchronous version of the above
|
||||
def start_lookup(self, system_name, known=0):
|
||||
self.cancel_lookup()
|
||||
|
||||
if system_name in self.FAKE:
|
||||
self.result = { 'img': '', 'url': None, 'done': True, 'uncharted': False }
|
||||
elif known or system_name in self.syscache:
|
||||
self.result = { 'img': EDSM._IMG_KNOWN, 'url': 'https://www.edsm.net/show-system?systemName=%s' % urllib2.quote(system_name), 'done': True, 'uncharted': False }
|
||||
else:
|
||||
self.result = { 'img': '', 'url': 'https://www.edsm.net/show-system?systemName=%s' % urllib2.quote(system_name), 'done': False, 'uncharted': False }
|
||||
self.thread = threading.Thread(target = self.worker, name = 'EDSM worker', args = (system_name, self.result))
|
||||
self.thread.daemon = True
|
||||
self.thread.start()
|
||||
|
||||
def cancel_lookup(self):
|
||||
self.thread = None # orphan any existing thread
|
||||
self.result = { 'img': '', 'url': None, 'done': True } # orphan existing thread's results
|
||||
|
||||
def worker(self, system_name, result):
|
||||
try:
|
||||
data = self.call('api-v1/system', '&sysname=%s&coords=1' % urllib2.quote(system_name), check_msgnum=False)
|
||||
|
||||
if data == -1 or not data:
|
||||
# System not present - create it
|
||||
result['img'] = EDSM._IMG_NEW
|
||||
result['uncharted'] = True
|
||||
elif data.get('coords'):
|
||||
result['img'] = EDSM._IMG_KNOWN
|
||||
self.syscache.add(system_name)
|
||||
else:
|
||||
result['img'] = EDSM._IMG_UNKNOWN
|
||||
result['uncharted'] = True
|
||||
except:
|
||||
if __debug__: print_exc()
|
||||
result['img'] = EDSM._IMG_ERROR
|
||||
result['done'] = True
|
||||
|
||||
|
||||
# Send flight log and also do lookup
|
||||
def writelog(self, timestamp, system_name, coordinates, shipid = None):
|
||||
|
||||
if system_name in self.FAKE:
|
||||
self.result = { 'img': '', 'url': None, 'done': True, 'uncharted': False }
|
||||
return
|
||||
|
||||
self.result = { 'img': EDSM._IMG_ERROR, 'url': 'https://www.edsm.net/show-system?systemName=%s' % urllib2.quote(system_name), 'done': True, 'uncharted': False }
|
||||
|
||||
args = '&systemName=%s&dateVisited=%s' % (
|
||||
urllib2.quote(system_name),
|
||||
urllib2.quote(time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime(timestamp))),
|
||||
)
|
||||
if coordinates:
|
||||
args += '&x=%.3f&y=%.3f&z=%.3f' % coordinates
|
||||
if shipid is not None:
|
||||
args += '&shipId=%d' % shipid
|
||||
reply = self.call('api-logs-v1/set-log', args)
|
||||
|
||||
if reply.get('systemCreated'):
|
||||
self.result['img'] = EDSM._IMG_NEW
|
||||
else:
|
||||
self.result['img'] = EDSM._IMG_KNOWN
|
||||
self.syscache.add(system_name)
|
||||
|
||||
def setranks(self, ranks):
|
||||
args = ''
|
||||
if ranks:
|
||||
for k,v in ranks.iteritems():
|
||||
if v is not None:
|
||||
args += '&%s=%s' % (k, urllib2.quote('%d;%d' % v))
|
||||
if args:
|
||||
self.call('api-commander-v1/set-ranks', args)
|
||||
|
||||
def setcredits(self, balance, loan):
|
||||
if balance is not None:
|
||||
self.call('api-commander-v1/set-credits', '&balance=%d&loan=%d' % (balance, loan))
|
||||
|
||||
def setmaterials(self, raw, manufactured, encoded):
|
||||
self.call('api-commander-v1/set-materials', "&type=data&values=%s" % json.dumps(encoded, separators = (',', ':')))
|
||||
materials = {}
|
||||
materials.update(raw)
|
||||
materials.update(manufactured)
|
||||
self.call('api-commander-v1/set-materials', "&type=materials&values=%s" % json.dumps(materials, separators = (',', ':')))
|
||||
|
||||
def setshipid(self, shipid):
|
||||
if shipid is not None:
|
||||
self.call('api-commander-v1/set-ship-id', '&shipId=%d' % shipid)
|
||||
|
||||
def updateship(self, shipid, shiptype, props=[]):
|
||||
if shipid is not None and shiptype:
|
||||
args = '&shipId=%d&type=%s' % (shipid, shiptype)
|
||||
for (slot, thing) in props:
|
||||
args += '&%s=%s' % (slot, urllib2.quote(unicode(thing)))
|
||||
self.call('api-commander-v1/update-ship', args)
|
||||
|
||||
def sellship(self, shipid):
|
||||
if shipid is not None:
|
||||
self.call('api-commander-v1/sell-ship', '&shipId=%d' % shipid)
|
357
plugins/edsm.py
Normal file
357
plugins/edsm.py
Normal file
@ -0,0 +1,357 @@
|
||||
#
|
||||
# System display and EDSM lookup
|
||||
#
|
||||
|
||||
import json
|
||||
import requests
|
||||
import sys
|
||||
import time
|
||||
import urllib2
|
||||
from calendar import timegm
|
||||
|
||||
import Tkinter as tk
|
||||
from ttkHyperlinkLabel import HyperlinkLabel
|
||||
import myNotebook as nb
|
||||
|
||||
from config import appname, applongname, appversion, config
|
||||
import companion
|
||||
import coriolis
|
||||
import edshipyard
|
||||
|
||||
if __debug__:
|
||||
from traceback import print_exc
|
||||
|
||||
EDSM_POLL = 0.1
|
||||
_TIMEOUT = 10
|
||||
FAKE = ['CQC', 'Training', 'Destination'] # Fake systems that shouldn't be sent to EDSM
|
||||
|
||||
|
||||
this = sys.modules[__name__] # For holding module globals
|
||||
this.syscache = set() # Cache URLs of systems with known coordinates
|
||||
this.session = requests.Session()
|
||||
this.lastship = None # Description of last ship that we sent to EDSM
|
||||
this.lastlookup = False # whether the last lookup succeeded
|
||||
|
||||
# Game state
|
||||
this.multicrew = False # don't send captain's ship info to EDSM while on a crew
|
||||
|
||||
|
||||
def plugin_start():
|
||||
# Can't be earlier since can only call PhotoImage after window is created
|
||||
this._IMG_KNOWN = tk.PhotoImage(data = 'R0lGODlhEAAQAMIEAFWjVVWkVWS/ZGfFZ////////////////yH5BAEKAAQALAAAAAAQABAAAAMvSLrc/lAFIUIkYOgNXt5g14Dk0AQlaC1CuglM6w7wgs7rMpvNV4q932VSuRiPjQQAOw==') # green circle
|
||||
this._IMG_UNKNOWN = tk.PhotoImage(data = 'R0lGODlhEAAQAKEDAGVLJ+ddWO5fW////yH5BAEKAAMALAAAAAAQABAAAAItnI+pywYRQBtA2CtVvTwjDgrJFlreEJRXgKSqwB5keQ6vOKq1E+7IE5kIh4kCADs=') # red circle
|
||||
this._IMG_NEW = tk.PhotoImage(data = 'R0lGODlhEAAQAMZwANKVHtWcIteiHuiqLPCuHOS1MN22ZeW7ROG6Zuu9MOy+K/i8Kf/DAuvCVf/FAP3BNf/JCf/KAPHHSv7ESObHdv/MBv/GRv/LGP/QBPXOPvjPQfjQSvbRSP/UGPLSae7Sfv/YNvLXgPbZhP7dU//iI//mAP/jH//kFv7fU//fV//ebv/iTf/iUv/kTf/iZ/vgiP/hc/vgjv/jbfriiPriiv7ka//if//jd//sJP/oT//tHv/mZv/sLf/rRP/oYv/rUv/paP/mhv/sS//oc//lkf/mif/sUf/uPv/qcv/uTv/uUv/vUP/qhP/xP//pm//ua//sf//ubf/wXv/thv/tif/slv/tjf/smf/yYP/ulf/2R//2Sv/xkP/2av/0gP/ylf/2df/0i//0j//0lP/5cP/7a//1p//5gf/7ev/3o//2sf/5mP/6kv/2vP/3y//+jP///////////////////////////////////////////////////////////////yH5BAEKAH8ALAAAAAAQABAAAAePgH+Cg4SFhoJKPIeHYT+LhVppUTiPg2hrUkKPXWdlb2xHJk9jXoNJQDk9TVtkYCUkOy4wNjdGfy1UXGJYOksnPiwgFwwYg0NubWpmX1ArHREOFYUyWVNIVkxXQSoQhyMoNVUpRU5EixkcMzQaGy8xhwsKHiEfBQkSIg+GBAcUCIIBBDSYYGiAAUMALFR6FAgAOw==')
|
||||
this._IMG_ERROR = tk.PhotoImage(data = 'R0lGODlhEAAQAKEBAAAAAP///////////yH5BAEKAAIALAAAAAAQABAAAAIwlBWpeR0AIwwNPRmZuVNJinyWuClhBlZjpm5fqnIAHJPtOd3Hou9mL6NVgj2LplEAADs=') # BBC Mode 5 '?'
|
||||
|
||||
# Migrate old settings
|
||||
if not config.get('edsm_cmdrs'):
|
||||
if isinstance(config.get('cmdrs'), list) and config.get('edsm_usernames') and config.get('edsm_apikeys'):
|
||||
# Migrate <= 2.34 settings
|
||||
config.set('edsm_cmdrs', config.get('cmdrs'))
|
||||
elif config.get('edsm_cmdrname'):
|
||||
# Migrate <= 2.25 settings. edsm_cmdrs is unknown at this time
|
||||
config.set('edsm_usernames', [config.get('edsm_cmdrname') or ''])
|
||||
config.set('edsm_apikeys', [config.get('edsm_apikey') or ''])
|
||||
config.delete('edsm_cmdrname')
|
||||
config.delete('edsm_apikey')
|
||||
if config.getint('output') & 256:
|
||||
# Migrate <= 2.34 setting
|
||||
config.set('edsm_out', 1)
|
||||
config.delete('edsm_autoopen')
|
||||
config.delete('edsm_historical')
|
||||
|
||||
return 'EDSM'
|
||||
|
||||
def plugin_app(parent):
|
||||
this.system_label = tk.Label(parent, text = _('System') + ':') # Main window
|
||||
this.system = HyperlinkLabel(parent, compound=tk.RIGHT, url = None, popup_copy = True)
|
||||
return (this.system_label, this.system)
|
||||
|
||||
def plugin_prefs(parent, cmdr, is_beta):
|
||||
|
||||
PADX = 10
|
||||
BUTTONX = 12 # indent Checkbuttons and Radiobuttons
|
||||
PADY = 2 # close spacing
|
||||
|
||||
frame = nb.Frame(parent)
|
||||
frame.columnconfigure(1, weight=1)
|
||||
|
||||
HyperlinkLabel(frame, text='Elite Dangerous Star Map', background=nb.Label().cget('background'), url='https://www.edsm.net/', underline=True).grid(columnspan=2, padx=PADX, sticky=tk.W) # Don't translate
|
||||
this.log = tk.IntVar(value = config.getint('edsm_out') and 1)
|
||||
this.log_button = nb.Checkbutton(frame, text=_('Send flight log to Elite Dangerous Star Map'), variable=this.log, command=prefsvarchanged)
|
||||
this.log_button.grid(columnspan=2, padx=BUTTONX, pady=(5,0), sticky=tk.W)
|
||||
|
||||
nb.Label(frame).grid(sticky=tk.W) # big spacer
|
||||
this.label = HyperlinkLabel(frame, text=_('Elite Dangerous Star Map credentials'), background=nb.Label().cget('background'), url='https://www.edsm.net/settings/api', underline=True) # Section heading in settings
|
||||
this.label.grid(columnspan=2, padx=PADX, sticky=tk.W)
|
||||
|
||||
this.cmdr_label = nb.Label(frame, text=_('Cmdr')) # Main window
|
||||
this.cmdr_label.grid(row=10, padx=PADX, sticky=tk.W)
|
||||
this.cmdr_text = nb.Label(frame)
|
||||
this.cmdr_text.grid(row=10, column=1, padx=PADX, pady=PADY, sticky=tk.W)
|
||||
|
||||
this.user_label = nb.Label(frame, text=_('Commander Name')) # EDSM setting
|
||||
this.user_label.grid(row=11, padx=PADX, sticky=tk.W)
|
||||
this.user = nb.Entry(frame)
|
||||
this.user.grid(row=11, column=1, padx=PADX, pady=PADY, sticky=tk.EW)
|
||||
|
||||
this.apikey_label = nb.Label(frame, text=_('API Key')) # EDSM setting
|
||||
this.apikey_label.grid(row=12, padx=PADX, sticky=tk.W)
|
||||
this.apikey = nb.Entry(frame)
|
||||
this.apikey.grid(row=12, column=1, padx=PADX, pady=PADY, sticky=tk.EW)
|
||||
|
||||
prefs_cmdr_changed(cmdr, is_beta)
|
||||
|
||||
return frame
|
||||
|
||||
def prefs_cmdr_changed(cmdr, is_beta):
|
||||
this.log_button['state'] = cmdr and not is_beta and tk.NORMAL or tk.DISABLED
|
||||
this.user['state'] = tk.NORMAL
|
||||
this.user.delete(0, tk.END)
|
||||
this.apikey['state'] = tk.NORMAL
|
||||
this.apikey.delete(0, tk.END)
|
||||
if cmdr:
|
||||
this.cmdr_text['text'] = cmdr + (is_beta and ' [Beta]' or '')
|
||||
cred = credentials(cmdr)
|
||||
if cred:
|
||||
this.user.insert(0, cred[0])
|
||||
this.apikey.insert(0, cred[1])
|
||||
else:
|
||||
this.cmdr_text['text'] = _('None') # No hotkey/shortcut currently defined
|
||||
this.label['state'] = this.cmdr_label['state'] = this.cmdr_text['state'] = this.user_label['state'] = this.user['state'] = this.apikey_label['state'] = this.apikey['state'] = cmdr and not is_beta and this.log.get() and tk.NORMAL or tk.DISABLED
|
||||
|
||||
def prefsvarchanged():
|
||||
this.user_label['state'] = this.user['state'] = this.apikey_label['state'] = this.log.get() and tk.NORMAL or tk.DISABLED
|
||||
|
||||
def prefs_changed(cmdr, is_beta):
|
||||
this.system_label['text'] = _('System') + ':' # Main window
|
||||
config.set('edsm_out', this.log.get())
|
||||
|
||||
if cmdr and not is_beta:
|
||||
cmdrs = config.get('edsm_cmdrs')
|
||||
usernames = config.get('edsm_usernames')
|
||||
apikeys = config.get('edsm_apikeys')
|
||||
if cmdr in cmdrs:
|
||||
idx = cmdrs.index(cmdr)
|
||||
usernames[idx] = this.user.get().strip()
|
||||
apikeys[idx] = this.apikey.get().strip()
|
||||
else:
|
||||
config.set('edsm_cmdrs', cmdrs + [cmdr])
|
||||
usernames.append(this.user.get().strip())
|
||||
apikeys.append(this.apikey.get().strip())
|
||||
config.set('edsm_usernames', usernames)
|
||||
config.set('edsm_apikeys', apikeys)
|
||||
|
||||
|
||||
def credentials(cmdr):
|
||||
# Credentials for cmdr
|
||||
if not cmdr:
|
||||
return None
|
||||
|
||||
cmdrs = config.get('edsm_cmdrs')
|
||||
if not cmdrs:
|
||||
# Migrate from <= 2.25
|
||||
cmdrs = [cmdr]
|
||||
config.set('edsm_cmdrs', cmdrs)
|
||||
|
||||
if cmdr in cmdrs:
|
||||
idx = cmdrs.index(cmdr)
|
||||
return (config.get('edsm_usernames')[idx], config.get('edsm_apikeys')[idx])
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
def journal_entry(cmdr, is_beta, system, station, entry, state):
|
||||
|
||||
# Update display
|
||||
if this.system['text'] != system:
|
||||
this.system['text'] = system or ''
|
||||
this.system['image'] = ''
|
||||
if not system or system in FAKE:
|
||||
this.system['url'] = None
|
||||
this.lastlookup = True
|
||||
else:
|
||||
this.system['url'] = 'https://www.edsm.net/show-system?systemName=%s' % urllib2.quote(system)
|
||||
this.lastlookup = False
|
||||
this.system.update_idletasks()
|
||||
|
||||
this.multicrew = bool(state['Role'])
|
||||
|
||||
# Send interesting events to EDSM
|
||||
if config.getint('edsm_out') and not is_beta and not multicrew and credentials(cmdr):
|
||||
try:
|
||||
# Send credits to EDSM on new game (but not on startup - data might be old)
|
||||
if entry['event'] == 'LoadGame':
|
||||
setcredits(cmdr, state['Credits'], state['Loan'])
|
||||
|
||||
# Send rank info to EDSM on startup or change
|
||||
if entry['event'] in ['StartUp', 'Progress', 'Promotion'] and state['Rank']:
|
||||
setranks(cmdr, state['Rank'])
|
||||
|
||||
# Send ship info to EDSM on startup or change
|
||||
if entry['event'] in ['StartUp', 'Loadout', 'LoadGame', 'SetUserShipName'] and cmdr and state['ShipID']:
|
||||
setshipid(cmdr, state['ShipID'])
|
||||
props = []
|
||||
if state['ShipIdent'] is not None:
|
||||
props.append(('shipIdent', state['ShipIdent']))
|
||||
if state['ShipName'] is not None:
|
||||
props.append(('shipName', state['ShipName']))
|
||||
if state['PaintJob'] is not None:
|
||||
props.append(('paintJob', state['PaintJob']))
|
||||
updateship(cmdr, state['ShipID'], state['ShipType'], props)
|
||||
elif entry['event'] in ['ShipyardBuy', 'ShipyardSell']:
|
||||
sellship(cmdr, entry.get('SellShipID'))
|
||||
|
||||
# Send materials info to EDSM on startup or change
|
||||
if entry['event'] in ['StartUp', 'LoadGame', 'MaterialCollected', 'MaterialDiscarded', 'ScientificResearch', 'EngineerCraft', 'Synthesis']:
|
||||
setmaterials(cmdr, state['Raw'], state['Manufactured'], state['Encoded'])
|
||||
|
||||
# Send paintjob info to EDSM on change
|
||||
if entry['event'] in ['ModuleBuy', 'ModuleSell'] and entry['Slot'] == 'PaintJob':
|
||||
updateship(cmdr, state['ShipID'], state['ShipType'], [('paintJob', state['PaintJob'])])
|
||||
|
||||
# Write EDSM log on startup and change
|
||||
if system and entry['event'] in ['Location', 'FSDJump']:
|
||||
this.lastlookup = False
|
||||
writelog(cmdr, timegm(time.strptime(entry['timestamp'], '%Y-%m-%dT%H:%M:%SZ')), system, 'StarPos' in entry and tuple(entry['StarPos']), state['ShipID'])
|
||||
this.lastlookup = True
|
||||
this.system.update_idletasks()
|
||||
|
||||
except Exception as e:
|
||||
if __debug__: print_exc()
|
||||
return unicode(e)
|
||||
|
||||
|
||||
def cmdr_data(data, is_beta):
|
||||
|
||||
system = data['lastSystem']['name']
|
||||
|
||||
if not this.system['text']:
|
||||
this.system['text'] = system
|
||||
this.system['image'] = ''
|
||||
if not system or system in FAKE:
|
||||
this.system['url'] = None
|
||||
this.lastlookup = True
|
||||
else:
|
||||
this.system['url'] = 'https://www.edsm.net/show-system?systemName=%s' % urllib2.quote(system)
|
||||
this.lastlookup = False
|
||||
this.system.update_idletasks()
|
||||
|
||||
if config.getint('edsm_out') and not is_beta and not multicrew and credentials(data['commander']['name']):
|
||||
# Send flightlog to EDSM if FSDJump failed to do so
|
||||
if not this.lastlookup:
|
||||
try:
|
||||
this.lastlookup = False
|
||||
this.writelog(data['commander']['name'], int(time.time()), system, None, data['ship']['id'])
|
||||
this.lastlookup = True
|
||||
this.system.update_idletasks()
|
||||
except Exception as e:
|
||||
if __debug__: print_exc()
|
||||
return unicode(e)
|
||||
|
||||
# Update credits and ship info and send to EDSM
|
||||
try:
|
||||
if data['commander'].get('credits') is not None:
|
||||
setcredits(data['commander']['name'], data['commander']['credits'], data['commander'].get('debt', 0))
|
||||
ship = companion.ship(data)
|
||||
if ship != this.lastship:
|
||||
updateship(data['commander']['name'],
|
||||
data['ship']['id'],
|
||||
data['ship']['name'].lower(),
|
||||
[
|
||||
('linkToCoriolis', coriolis.url(data, is_beta)),
|
||||
('linkToEDShipyard', edshipyard.url(data, is_beta)),
|
||||
])
|
||||
this.lastship = ship
|
||||
except Exception as e:
|
||||
# Not particularly important so silent on failure
|
||||
if __debug__: print_exc()
|
||||
|
||||
|
||||
# Call an EDSM endpoint with args (which should be quoted)
|
||||
def call(cmdr, endpoint, args, check_msgnum=True):
|
||||
try:
|
||||
(username, apikey) = credentials(cmdr)
|
||||
url = 'https://www.edsm.net/%s?commanderName=%s&apiKey=%s&fromSoftware=%s&fromSoftwareVersion=%s' % (
|
||||
endpoint,
|
||||
urllib2.quote(username.encode('utf-8')),
|
||||
urllib2.quote(apikey),
|
||||
urllib2.quote(applongname),
|
||||
urllib2.quote(appversion),
|
||||
) + args
|
||||
r = this.session.get(url, timeout=_TIMEOUT)
|
||||
r.raise_for_status()
|
||||
reply = r.json()
|
||||
if not check_msgnum:
|
||||
return reply
|
||||
(msgnum, msg) = reply['msgnum'], reply['msg']
|
||||
except:
|
||||
if __debug__: print_exc()
|
||||
raise Exception(_("Error: Can't connect to EDSM"))
|
||||
|
||||
# Message numbers: 1xx = OK, 2xx = fatal error, 3xx = error (but not generated in practice), 4xx = ignorable errors
|
||||
if msgnum // 100 not in (1,4):
|
||||
raise Exception(_('Error: EDSM {MSG}').format(MSG=msg))
|
||||
else:
|
||||
return reply
|
||||
|
||||
|
||||
# Send flight log and also do lookup
|
||||
def writelog(cmdr, timestamp, system_name, coordinates, shipid = None):
|
||||
|
||||
if system_name in FAKE:
|
||||
return
|
||||
|
||||
args = '&systemName=%s&dateVisited=%s' % (
|
||||
urllib2.quote(system_name),
|
||||
urllib2.quote(time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime(timestamp))),
|
||||
)
|
||||
if coordinates:
|
||||
args += '&x=%.3f&y=%.3f&z=%.3f' % coordinates
|
||||
if shipid is not None:
|
||||
args += '&shipId=%d' % shipid
|
||||
try:
|
||||
reply = call(cmdr, 'api-logs-v1/set-log', args)
|
||||
if reply.get('systemCreated'):
|
||||
this.system['image'] = this._IMG_NEW
|
||||
else:
|
||||
this.system['image'] = this._IMG_KNOWN
|
||||
this.syscache.add(system_name)
|
||||
except:
|
||||
this.system['image'] = this._IMG_ERROR
|
||||
raise
|
||||
|
||||
def setranks(cmdr, ranks):
|
||||
args = ''
|
||||
if ranks:
|
||||
for k,v in ranks.iteritems():
|
||||
if v is not None:
|
||||
args += '&%s=%s' % (k, urllib2.quote('%d;%d' % v))
|
||||
if args:
|
||||
call(cmdr, 'api-commander-v1/set-ranks', args)
|
||||
|
||||
def setcredits(cmdr, balance, loan):
|
||||
if balance is not None:
|
||||
call(cmdr, 'api-commander-v1/set-credits', '&balance=%d&loan=%d' % (balance, loan))
|
||||
|
||||
def setmaterials(cmdr, raw, manufactured, encoded):
|
||||
call(cmdr, 'api-commander-v1/set-materials', "&type=data&values=%s" % json.dumps(encoded, separators = (',', ':')))
|
||||
materials = {}
|
||||
materials.update(raw)
|
||||
materials.update(manufactured)
|
||||
call(cmdr, 'api-commander-v1/set-materials', "&type=materials&values=%s" % json.dumps(materials, separators = (',', ':')))
|
||||
|
||||
def setshipid(cmdr, shipid):
|
||||
if shipid is not None:
|
||||
call(cmdr, 'api-commander-v1/set-ship-id', '&shipId=%d' % shipid)
|
||||
|
||||
def updateship(cmdr, shipid, shiptype, props=[]):
|
||||
if shipid is not None and shiptype:
|
||||
args = '&shipId=%d&type=%s' % (shipid, shiptype)
|
||||
for (slot, thing) in props:
|
||||
args += '&%s=%s' % (slot, urllib2.quote(unicode(thing)))
|
||||
call(cmdr, 'api-commander-v1/update-ship', args)
|
||||
|
||||
def sellship(cmdr, shipid):
|
||||
if shipid is not None:
|
||||
call(cmdr, 'api-commander-v1/sell-ship', '&shipId=%d' % shipid)
|
56
prefs.py
56
prefs.py
@ -182,36 +182,6 @@ class PreferencesDialog(tk.Toplevel):
|
||||
|
||||
notebook.add(eddnframe, text='EDDN') # Not translated
|
||||
|
||||
|
||||
edsmframe = nb.Frame(notebook)
|
||||
edsmframe.columnconfigure(1, weight=1)
|
||||
|
||||
HyperlinkLabel(edsmframe, text='Elite Dangerous Star Map', background=nb.Label().cget('background'), url='https://www.edsm.net/', underline=True).grid(columnspan=2, padx=PADX, sticky=tk.W) # Don't translate
|
||||
self.edsm_log = tk.IntVar(value = (output & config.OUT_SYS_EDSM) and 1)
|
||||
self.edsm_log_button = nb.Checkbutton(edsmframe, text=_('Send flight log to Elite Dangerous Star Map'), variable=self.edsm_log, command=self.outvarchanged)
|
||||
self.edsm_log_button.grid(columnspan=2, padx=BUTTONX, pady=(5,0), sticky=tk.W)
|
||||
|
||||
nb.Label(edsmframe).grid(sticky=tk.W) # big spacer
|
||||
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=_('Cmdr')) # Main window
|
||||
self.edsm_cmdr_label.grid(row=10, padx=PADX, sticky=tk.W)
|
||||
self.edsm_cmdr_text = nb.Label(edsmframe)
|
||||
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=12, padx=PADX, sticky=tk.W)
|
||||
self.edsm_apikey = nb.Entry(edsmframe)
|
||||
self.edsm_apikey.grid(row=12, column=1, padx=PADX, pady=PADY, sticky=tk.EW)
|
||||
|
||||
notebook.add(edsmframe, text='EDSM') # Not translated
|
||||
|
||||
# build plugin prefs tabs
|
||||
for plugin in plug.PLUGINS:
|
||||
plugframe = plugin.get_prefs(notebook, monitor.cmdr, monitor.is_beta)
|
||||
@ -406,22 +376,14 @@ class PreferencesDialog(tk.Toplevel):
|
||||
self.username.delete(0, tk.END)
|
||||
self.password['state'] = tk.NORMAL
|
||||
self.password.delete(0, tk.END)
|
||||
self.edsm_user['state'] = tk.NORMAL
|
||||
self.edsm_user.delete(0, tk.END)
|
||||
self.edsm_apikey['state'] = tk.NORMAL
|
||||
self.edsm_apikey.delete(0, tk.END)
|
||||
if monitor.cmdr and config.get('cmdrs') and monitor.cmdr in config.get('cmdrs'):
|
||||
config_idx = config.get('cmdrs').index(monitor.cmdr)
|
||||
self.username.insert(0, config.get('fdev_usernames')[config_idx] or '')
|
||||
self.password.insert(0, config.get_password(config.get('fdev_usernames')[config_idx]) or '')
|
||||
self.edsm_user.insert(0, config.get('edsm_usernames')[config_idx] or '')
|
||||
self.edsm_apikey.insert(0, config.get('edsm_apikeys')[config_idx] or '')
|
||||
elif monitor.cmdr and not config.get('cmdrs') and config.get('username') and config.get('password'):
|
||||
# migration from <= 2.25
|
||||
self.username.insert(0, config.get('username') or '')
|
||||
self.password.insert(0, config.get('password') or '')
|
||||
self.edsm_user.insert(0,config.get('edsm_cmdrname') or '')
|
||||
self.edsm_apikey.insert(0, config.get('edsm_apikey') or '')
|
||||
if self.cmdr is not False: # Don't notify on first run
|
||||
plug.notify_prefs_cmdr_changed(monitor.cmdr, monitor.is_beta)
|
||||
self.cmdr = monitor.cmdr
|
||||
@ -452,11 +414,6 @@ class PreferencesDialog(tk.Toplevel):
|
||||
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 monitor.cmdr 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':
|
||||
import tkFileDialog
|
||||
@ -598,14 +555,10 @@ class PreferencesDialog(tk.Toplevel):
|
||||
if not config.get('cmdrs'):
|
||||
config.set('cmdrs', [self.cmdr])
|
||||
config.set('fdev_usernames', [self.username.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('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) +
|
||||
@ -614,8 +567,7 @@ class PreferencesDialog(tk.Toplevel):
|
||||
(self.out_ship.get() and config.OUT_SHIP) +
|
||||
(self.eddn_station.get() and config.OUT_MKT_EDDN) +
|
||||
(self.eddn_system.get() and config.OUT_SYS_EDDN) +
|
||||
(self.eddn_delay.get() and config.OUT_SYS_DELAY) +
|
||||
(self.edsm_log.get() and config.OUT_SYS_EDSM))
|
||||
(self.eddn_delay.get() and config.OUT_SYS_DELAY))
|
||||
config.set('outdir', self.outdir.get().startswith('~') and join(config.home, self.outdir.get()[2:]) or self.outdir.get())
|
||||
|
||||
logdir = self.logdir.get()
|
||||
@ -764,12 +716,8 @@ def migrate(current_cmdr):
|
||||
config.set_password(config.get('username'), config.get('password')) # Can fail on Linux
|
||||
config.set('cmdrs', [current_cmdr])
|
||||
config.set('fdev_usernames', [config.get('username')])
|
||||
config.set('edsm_usernames', [config.get('edsm_cmdrname') or ''])
|
||||
config.set('edsm_apikeys', [config.get('edsm_apikey') or ''])
|
||||
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):
|
||||
@ -777,8 +725,6 @@ def make_current(current_cmdr):
|
||||
idx = config.get('cmdrs').index(current_cmdr)
|
||||
_putfirst('cmdrs', idx)
|
||||
_putfirst('fdev_usernames', 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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user