edsm-getnearest.py

Now in a usable form with help text and stuff. Bear with me, I literally
picked Python up again about today after having used it like 5y ago on
for completely unrelated things.
This commit is contained in:
alterNERDtive 2019-09-03 21:00:51 +02:00
parent f677b453cd
commit f21e32f653
2 changed files with 132 additions and 83 deletions

21
README.md Normal file
View file

@ -0,0 +1,21 @@
# A collection fo useful scripts around Elite Dangerous #
## edsm-getnearest.py ##
```
usage: edsm-getnearest.py [-h] --system SYSTEM [--short] [--gui | --text]
CMDR [CMDR ...]
Locate your CMDRs using EDSM and find their distance to a given system.
positional arguments:
CMDR a list of CMDR names (must have their location public on
EDSM!)
optional arguments:
-h, --help show this help message and exit
--system SYSTEM the target system (must be in EDDN!)
--short short output (only makes sense with `--text`)
--gui explicitly run the GUI
--text explicitly give text output
```

View file

@ -1,108 +1,136 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import argparse
import math import math
import requests import requests
import sys import sys
import tkinter as tk import tkinter as tk
from tkinter import messagebox # =================================================================================
if len(sys.argv) < 3:
exit(1)
class EdsmApiException(Exception): class EdsmApiException(Exception):
pass pass
def getSystemCoords (system): def getSystemCoords (system):
resp = requests.get('https://www.edsm.net/api-v1/system?systemName={}&showCoordinates=1'.format(system)) resp = requests.get('https://www.edsm.net/api-v1/system?systemName={}&showCoordinates=1'.format(system))
if resp.status_code != 200: if resp.status_code != 200:
raise EdsmApiException('GET /system/ {}'.format(resp.status_code)) raise EdsmApiException('GET /system/ {}'.format(resp.status_code))
try: try:
ret = resp.json()['coords'] ret = resp.json()['coords']
except TypeError: except TypeError:
raise EdsmApiException('System coordinates for {} not found!'.format(system)) raise EdsmApiException('System coordinates for {} not found!'.format(system))
return ret return ret
def getCmdrCoords (cmdr): def getCmdrCoords (cmdr):
resp = requests.get('https://www.edsm.net/api-logs-v1/get-position?commanderName={}&showCoordinates=1'.format(cmdr)) resp = requests.get('https://www.edsm.net/api-logs-v1/get-position?commanderName={}&showCoordinates=1'.format(cmdr))
if resp.status_code != 200: if resp.status_code != 200:
raise EdsmApiException('GET /get-position/ {}'.format(resp.status_code)) raise EdsmApiException('GET /get-position/ {}'.format(resp.status_code))
try: try:
ret = resp.json()['coordinates'] ret = resp.json()['coordinates']
except KeyError: except KeyError:
raise EdsmApiException('Coordinates for CMDR {} not found!'.format(cmdr)) raise EdsmApiException('Coordinates for CMDR {} not found!'.format(cmdr))
return ret return ret
def distance (coords1, coords2): def distance (coords1, coords2):
return math.sqrt( (coords1['x']-coords2['x'])**2 return math.sqrt( (coords1['x']-coords2['x'])**2
+ (coords1['y']-coords2['y'])**2 + (coords1['y']-coords2['y'])**2
+ (coords1['z']-coords2['z'])**2 ) + (coords1['z']-coords2['z'])**2 )
def getDistances (system, cmdrs): def getDistances (system, cmdrs):
systemcoords = getSystemCoords(system) systemcoords = getSystemCoords(system)
distances = {} distances = {}
for cmdr in cmdrs: for cmdr in cmdrs:
cmdrcoords = getCmdrCoords(cmdr) cmdrcoords = getCmdrCoords(cmdr)
distances[cmdr] = round(distance(cmdrcoords, systemcoords)) distances[cmdr] = round(distance(cmdrcoords, systemcoords))
return distances return distances
# =================================================================================
def outputGui(): def outputGui():
def runsearch(event=None): def runsearch(event=None):
for child in frame.winfo_children(): for child in frame.winfo_children():
child.grid_remove() child.grid_remove()
child.destroy() child.destroy()
try: try:
distances = getDistances(systemField.get(), cmdrs) distances = getDistances(systemField.get(), cmdrs)
nearestCmdr = min(distances,key=distances.get) nearestCmdr = min(distances,key=distances.get)
lbl = tk.Label( lbl = tk.Label(
frame, text='nearest CMDR: {} ({}ly from {})'.format(nearestCmdr, frame, text='nearest CMDR: {} ({}ly from {})'.format(nearestCmdr,
distances[nearestCmdr], system)) distances[nearestCmdr], system))
lbl.grid(row=0, columnspan=2) lbl.grid(row=0, columnspan=2)
row = 1 row = 1
for cmdr in distances: for cmdr in distances:
row += 1 row += 1
lbl = tk.Label(frame, text='{}:'.format(cmdr)) lbl = tk.Label(frame, text='{}:'.format(cmdr))
lbl.grid(row=row, column=0) lbl.grid(row=row, column=0)
lbl = tk.Label(frame, text='{}ly'.format(distances[cmdr])) lbl = tk.Label(frame, text='{}ly'.format(distances[cmdr]))
lbl.grid(row=row, column=1) lbl.grid(row=row, column=1)
except EdsmApiException as e: except EdsmApiException as e:
lbl = tk.Label(frame, text=e) lbl = tk.Label(frame, text=e)
lbl.grid(row=0, columnspan=2) lbl.grid(row=0, columnspan=2)
window = tk.Tk() window = tk.Tk()
window.title('EDSM nearest CMDR') window.title('EDSM nearest CMDR')
lbl = tk.Label(window, text='system:') lbl = tk.Label(window, text='system:')
lbl.grid(row=0, column=0) lbl.grid(row=0, column=0)
systemField = tk.Entry(window, width=50) systemField = tk.Entry(window, width=50)
systemField.grid(row=0, column=1) systemField.grid(row=0, column=1)
systemField.insert(tk.END, system) systemField.insert(tk.END, system)
systemField.focus() systemField.focus()
frame = tk.Frame(window) frame = tk.Frame(window)
frame.grid(row=1, columnspan=3) frame.grid(row=1, columnspan=3)
btn = tk.Button(window, text='get distances', command=runsearch) btn = tk.Button(window, text='get distances', command=runsearch)
btn.grid(row=0, column=2) btn.grid(row=0, column=2)
window.geometry('450x200+550+-650') window.bind('<Return>', runsearch)
window.bind('<Return>', runsearch) window.attributes('-topmost', True)
window.attributes('-topmost', True) runsearch()
window.mainloop() window.mainloop()
# =================================================================================
def outputText(): def outputText():
try: try:
distances = getDistances(system, cmdrs) distances = getDistances(system, cmdrs)
except EdsmApiException as e: except EdsmApiException as e:
print(e) print(e)
exit(1) exit(1)
nearestCmdr = min(distances,key=distances.get) nearestCmdr = min(distances,key=distances.get)
if shortOutput:
print('nearest CMDR: {} ({}ly)'.format(nearestCmdr,
distances[nearestCmdr]))
else:
print('nearest CMDR: {} ({}ly from {})'.format(nearestCmdr, print('nearest CMDR: {} ({}ly from {})'.format(nearestCmdr,
distances[nearestCmdr], system)) distances[nearestCmdr], system))
print() print()
for cmdr in distances: for cmdr in distances:
print('{}: {}ly'.format(cmdr, distances[cmdr])) print('{}: {}ly'.format(cmdr, distances[cmdr]))
sys.argv.pop(0) # script name # =================================================================================
system = sys.argv.pop(0)
cmdrs = sys.argv
outputGui() parser = argparse.ArgumentParser(description='Locate your CMDRs using EDSM and '
# try: + 'find their distance to a given system.')
# outputGui() parser.add_argument('cmdrs', metavar='CMDR', nargs='+', help='a list of CMDR names '
# except tk.TclError: + '(must have their location public on EDSM!)')
# outputText() parser.add_argument('--system', nargs=1, help='the target system (must be in '
+ 'EDDN!)', required=True)
parser.add_argument('--short', action='store_true', help='short output (only '
+ 'makes sense with `--text`)')
group = parser.add_mutually_exclusive_group()
group.add_argument('--gui', action='store_true', help='explicitly run the GUI')
group.add_argument('--text', action='store_true', help='explicitly give text output')
args = parser.parse_args()
system = args.system[0]
cmdrs = args.cmdrs
shortOutput = args.short
# =================================================================================
if args.text:
outputText()
elif args.gui:
outputGui()
else:
try:
outputGui()
except tk.TclError:
outputText()