From 20f9bb2e836cce6585a087fc68f3e18466349e6a Mon Sep 17 00:00:00 2001 From: Jonathan Harris Date: Mon, 24 Jul 2017 15:20:25 +0100 Subject: [PATCH] Option to look up system in EDSM --- README.md | 6 +- img/screenie.png | Bin 25208 -> 26580 bytes load.py | 162 ++++++++++++++++++++++++++++++++++++++--------- 3 files changed, 136 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index 6fc8357..e3eb10d 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,12 @@ # Habitable Zone plugin for [EDMC](https://github.com/Marginal/EDMarketConnector/wiki) -This plugin displays the "habitable-zone" (i.e. the range of distances in which you might find an Earth-Like World) when you scan the primary star in a system with a [Detailed Surface Scanner](http://elite-dangerous.wikia.com/wiki/Detailed_Surface_Scanner). +This plugin helps explorers find high-value planets. It displays the "habitable-zone" (i.e. the range of distances in which you might find an Earth-Like World) when you scan the primary star in a system with a [Detailed Surface Scanner](http://elite-dangerous.wikia.com/wiki/Detailed_Surface_Scanner). ![Screenshot](img/screenie.png) -Optionally, you can choose to display the ranges in which you might find Metal-Rich, Water and/or Ammonia Worlds. +Optionally, you can choose to display the ranges in which you might find other high-value planets - Metal-Rich, Water and/or Ammonia Worlds. + +Optionally, you can choose to display the high-value planets known to [Elite Dangerous Star Map](https://www.edsm.net/). ## Installation diff --git a/img/screenie.png b/img/screenie.png index f2ac25d474196ea796cf09d3d6d593b355402723..7303f87f26cb63502669607ad1ae146972aa7118 100644 GIT binary patch delta 20525 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

J6zwmAEGiuu>^!yn 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 diff --git a/load.py b/load.py index 7abb6a4..89f1ba3 100644 --- a/load.py +++ b/load.py @@ -3,9 +3,14 @@ # Display the "habitable-zone" (i.e. the range of distances in which you might find an Earth-Like World) # +from collections import defaultdict +import requests import sys +import threading +import urllib2 import Tkinter as tk +from ttkHyperlinkLabel import HyperlinkLabel import myNotebook as nb if __debug__: @@ -16,70 +21,90 @@ from l10n import Locale VERSION = '1.00' -SETTING_DEFAULT = 2 # Earth-like +SETTING_DEFAULT = 0x0002 # Earth-like +SETTING_EDSM = 0x1000 SETTING_NONE = 0xffff WORLDS = [ - # Type Black-body temp range - ('Metal-Rich', 0, 1103.0), - ('Earth-Like', 278.0, 227.0), - ('Water', 307.0, 156.0), - ('Ammonia', 193.0, 117.0), + # Type Black-body temp range EDSM description + ('Metal-Rich', 0, 1103.0, 'Metal-rich body'), + ('Earth-Like', 278.0, 227.0, 'Earth-like world'), + ('Water', 307.0, 156.0, 'Water world'), + ('Ammonia', 193.0, 117.0, 'Ammonia world'), ] LS = 300000000.0 # 1 ls in m (approx) this = sys.modules[__name__] # For holding module globals +this.frame = None +this.worlds = [] +this.edsm_session = None +this.edsm_data = None + +# Used during preferences +this.settings = None +this.edsm_setting = None def plugin_start(): + # App isn't initialised at this point so can't do anything interesting return 'HabZone' def plugin_app(parent): - frame = tk.Frame(parent) - frame.columnconfigure(3, weight=1) - this.worlds = [] - for (name, high, low) in WORLDS: - this.worlds.append((tk.Label(frame, text = name + ':'), - tk.Label(frame), - tk.Label(frame), - tk.Label(frame), - tk.Label(frame), + # Create and display widgets + this.frame = tk.Frame(parent) + this.frame.columnconfigure(3, weight=1) + this.frame.bind('<>', edsm_data) # callback when EDSM data received + for (name, high, low, subType) in WORLDS: + this.worlds.append((tk.Label(this.frame, text = name + ':'), + HyperlinkLabel(this.frame), # edsm + tk.Label(this.frame), # near + tk.Label(this.frame), # dash + tk.Label(this.frame), # far + tk.Label(this.frame), # ls )) - this.spacer = tk.Frame(frame) # Main frame can't be empty or it doesn't resize + this.terraformable_label = tk.Label(this.frame, text = 'Terraformable:') + this.terraformable = HyperlinkLabel(this.frame) + this.spacer = tk.Frame(this.frame) # Main frame can't be empty or it doesn't resize update_visibility() - return frame + return this.frame -def plugin_prefs(parent): +def plugin_prefs(parent, cmdr, is_beta): frame = nb.Frame(parent) nb.Label(frame, text = 'Display:').grid(row = 0, padx = 10, pady = (10,0), sticky=tk.W) setting = get_setting() this.settings = [] row = 1 - for (name, high, low) in WORLDS: + for (name, high, low, subType) in WORLDS: var = tk.IntVar(value = (setting & row) and 1) nb.Checkbutton(frame, text = name, variable = var).grid(row = row, padx = 10, pady = 2, sticky=tk.W) this.settings.append(var) row *= 2 + nb.Label(frame, text = 'Elite Dangerous Star Map:').grid(padx = 10, pady = (10,0), sticky=tk.W) + this.edsm_setting = tk.IntVar(value = (setting & SETTING_EDSM) and 1) + nb.Checkbutton(frame, text = 'Look up system in EDSM database', variable = this.edsm_setting).grid(padx = 10, pady = 2, sticky=tk.W) + nb.Label(frame, text = 'Version %s' % VERSION).grid(padx = 10, pady = 10, sticky=tk.W) return frame -def prefs_changed(): +def prefs_changed(cmdr, is_beta): row = 1 setting = 0 for var in this.settings: setting += var.get() and row row *= 2 + setting += this.edsm_setting.get() and SETTING_EDSM config.set('habzone', setting or SETTING_NONE) this.settings = None + this.edsm_setting = None update_visibility() -def journal_entry(cmdr, system, station, entry, state): +def journal_entry(cmdr, is_beta, system, station, entry, state): if entry['event'] == 'Scan': try: @@ -87,8 +112,8 @@ def journal_entry(cmdr, system, station, entry, state): r = float(entry['Radius']) t = float(entry['SurfaceTemperature']) for i in range(len(WORLDS)): - (name, high, low) = WORLDS[i] - (label, near, dash, far, ls) = this.worlds[i] + (name, high, low, subType) = WORLDS[i] + (label, edsm, near, dash, far, ls) = this.worlds[i] far_dist = int(0.5 + dfort(r, t, low)) radius = int(0.5 + r / LS) if far_dist <= radius: @@ -105,24 +130,93 @@ def journal_entry(cmdr, system, station, entry, state): far['text'] = Locale.stringFromNumber(far_dist) ls['text'] = 'ls' except: - for (label, near, dash, far, ls) in this.worlds: + for (label, edsm, near, dash, far, ls) in this.worlds: near['text'] = '' dash['text'] = '' far['text'] = '' ls['text'] = '?' elif entry['event'] == 'FSDJump': - for (label, near, dash, far, ls) in this.worlds: + for (label, edsm, near, dash, far, ls) in this.worlds: + edsm['text'] = '' + edsm['url'] = '' near['text'] = '' dash['text'] = '' far['text'] = '' ls['text'] = '' + if entry['event'] in ['Location', 'FSDJump'] and get_setting() & SETTING_EDSM: + thread = threading.Thread(target = edsm_worker, name = 'EDSM worker', args = (entry['StarSystem'],)) + thread.daemon = True + thread.start() + + +def cmdr_data(data, is_beta): + # Manual Update + if get_setting() & SETTING_EDSM and not data['commander']['docked']: + thread = threading.Thread(target = edsm_worker, name = 'EDSM worker', args = (data['lastSystem']['name'],)) + thread.daemon = True + thread.start() + # Distance for target black-body temperature +# From Jackie Silver's Hab-Zone Calculator https://forums.frontier.co.uk/showthread.php?p=5452081 def dfort(r, t, target): return (((r ** 2) * (t ** 4) / (4 * (target ** 4))) ** 0.5) / LS + +# EDSM lookup +def edsm_worker(systemName): + + if not this.edsm_session: + this.edsm_session = requests.Session() + + r = this.edsm_session.get('https://www.edsm.net/api-system-v1/bodies?systemName=%s' % urllib2.quote(systemName), timeout=10) + if r.status_code != requests.codes.ok: + this.edsm_data = None + else: + try: + this.edsm_data = r.json() + except: + this.edsm_data = None + + # Tk is not thread-safe, so can't access widgets in this thread. + # event_generate() is the only safe way to poke the main thread from this thread. + this.frame.event_generate('<>', when='tail') + + +# EDSM data received +def edsm_data(event): + + if this.edsm_data is None: + # error + for (label, edsm, near, dash, far, ls) in this.worlds: + edsm['text'] = '?' + edsm['url'] = None + this.terraformable['text'] = '?' + this.terraformable['url'] = None + return + + # Collate + bodies = defaultdict(list) + for body in this.edsm_data.get('bodies', []): + if body.get('terraformingState') == 'Candidate for terraforming': + bodies['terraformable'].append(body['name']) + else: + bodies[body['subType']].append(body['name']) + + # Display + systemName = this.edsm_data.get('name', '') + url = 'https://www.edsm.net/show-system?systemName=%s' % urllib2.quote(systemName) + for i in range(len(WORLDS)): + (name, high, low, subType) = WORLDS[i] + (label, edsm, near, dash, far, ls) = this.worlds[i] + edsm['text'] = ' '.join([x[len(systemName):].replace(' ', '') if x.startswith(systemName) else x for x in bodies[subType]]) + edsm['url'] = url + this.terraformable['text'] = ' '.join([x[len(systemName):].replace(' ', '') if x.startswith(systemName) else x for x in bodies['terraformable']]) + this.terraformable['url'] = url + + def get_setting(): setting = config.getint('habzone') if setting == 0: @@ -135,20 +229,28 @@ def get_setting(): def update_visibility(): setting = get_setting() row = 1 - for (label, near, dash, far, ls) in this.worlds: + for (label, edsm, near, dash, far, ls) in this.worlds: if setting & row: label.grid(row = row, column = 0, sticky=tk.W) - near.grid(row = row, column = 1, sticky=tk.E) - dash.grid(row = row, column = 2, sticky=tk.E) - far.grid(row = row, column = 3, sticky=tk.E) - ls.grid(row = row, column = 4, sticky=tk.W) + edsm.grid(row = row, column = 1, sticky=tk.W, padx = (0,10)) + near.grid(row = row, column = 2, sticky=tk.E) + dash.grid(row = row, column = 3, sticky=tk.E) + far.grid(row = row, column = 4, sticky=tk.E) + ls.grid(row = row, column = 5, sticky=tk.W) else: label.grid_remove() + edsm.grid_remove() near.grid_remove() dash.grid_remove() far.grid_remove() ls.grid_remove() row *= 2 + if setting & SETTING_EDSM: + this.terraformable_label.grid(row = row, column = 0, sticky=tk.W) + this.terraformable.grid(row = row, column = 1, sticky=tk.W) + else: + this.terraformable_label.grid_remove() + this.terraformable.grid_remove() if setting: this.spacer.grid_remove() else: