-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
945 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
from Tkinter import DoubleVar | ||
from plotter import Plotter | ||
import pyperclip | ||
import Tkinter as tk | ||
import ttk | ||
|
||
|
||
class Autopath: | ||
|
||
def __init__(self, pointer): | ||
# Pre-Init | ||
self.pointer = pointer | ||
self.plotter = pointer.plotter | ||
self.frame = None | ||
self.label_origin = None | ||
self.separator = None | ||
self.entry_origin = None | ||
self.entry_destination = None | ||
self.label_efficiency = None | ||
self.entry_efficiency = None | ||
self.button_calculate = None | ||
self.label_range = None | ||
self.entry_range = None | ||
self.route = list() | ||
self.route_ready = False | ||
self.label_status = None | ||
self.checkbox_clipboard = None | ||
self.checkbox_status = None | ||
pass | ||
|
||
def update_clipboard(self, arrived_to): | ||
# Check none | ||
if self.checkbox_status is not None or self.checkbox_clipboard is None: | ||
# Check for route ready and checkbox | ||
if self.route_ready and self.checkbox_status.get() == 1: | ||
try: | ||
index = self.route.index(arrived_to) | ||
pyperclip.copy(self.route[index+1]) | ||
self.update_status("Clipboard updated to: ") | ||
self.status_append(self.route[index+1]) | ||
except: | ||
# Ignore errors | ||
pass | ||
|
||
def calculate_path(self): | ||
origin = self.entry_origin.get() | ||
dest = self.entry_destination.get() | ||
eff = -1 | ||
range = -1.0 | ||
|
||
self.update_status("") | ||
|
||
try: | ||
eff = int(self.entry_efficiency.get()) | ||
range = float(self.entry_range.get()) | ||
except ValueError: | ||
pass | ||
|
||
# If origin is empty, use current system | ||
if len(origin) < 1: | ||
origin = self.pointer.current_system | ||
|
||
# Check for data validation | ||
if len(origin) < 1: | ||
self.status_append("ERROR: Origin must not be empty!") | ||
if len(dest) < 1: | ||
self.status_append("ERROR: Destination must not be empty!") | ||
if eff < 1 or eff > 100: | ||
self.status_append("ERROR: Efficiency must be number between 1 and 100!") | ||
if range < 0: | ||
self.status_append("ERROR: Range must be decimal and not empty!") | ||
|
||
# Check for errors | ||
if len(self.label_status["text"]) > 0: | ||
self.route_ready = False | ||
return False | ||
|
||
self.update_status("Calculating..") | ||
|
||
# request calculation | ||
route = self.plotter.request_calculation(origin, dest, eff, range) | ||
|
||
self.update_status("Processing data..") | ||
|
||
# Process json for system names | ||
self.route = list() | ||
for record in route["result"]["system_jumps"]: | ||
self.route.append(record["system"]) | ||
|
||
# Mark as ready | ||
if len(self.route) > 0: | ||
self.update_status("Route calculated..") | ||
self.route_ready = True | ||
# simulate arrive to origin system | ||
self.update_clipboard(self.route[0]) | ||
else: | ||
self.update_status("ERROR: Route has less than one system") | ||
self.route_ready = False | ||
|
||
def status_append(self, status_text): | ||
if self.label_status is not None: | ||
self.label_status["text"] = self.label_status["text"] + "\n" + status_text | ||
self.label_status.update() | ||
|
||
def update_status(self, status_text): | ||
if self.label_status is not None: | ||
self.label_status["text"] = status_text | ||
self.label_status.update() | ||
|
||
def create_gui(self, parrent): | ||
# Unified width | ||
width = 16 | ||
|
||
# Frame | ||
self.frame = tk.Frame(parrent) | ||
|
||
# Label origin | ||
self.label_origin = tk.Label(self.frame, text="Origin: ", justify=tk.LEFT) | ||
self.label_origin.grid(row=0, column=0, sticky=tk.W, pady=(10, 0)) | ||
|
||
# Entry origin | ||
self.entry_origin = tk.Entry(self.frame, width=width) | ||
self.entry_origin.grid(row=0, column=1, sticky=tk.E, pady=(10, 0)) | ||
self.entry_origin.update() | ||
|
||
# Label origin | ||
self.label_origin = tk.Label(self.frame, text="Destination: ", justify=tk.LEFT) | ||
self.label_origin.grid(row=1, column=0, sticky=tk.W, ) | ||
|
||
# Entry destination | ||
self.entry_destination = tk.Entry(self.frame, width=width) | ||
self.entry_destination.grid(row=1, column=1, sticky=tk.E) | ||
self.entry_destination.update() | ||
|
||
# Label range | ||
self.label_range = tk.Label(self.frame, text="Range (LY): ", justify=tk.LEFT) | ||
self.label_range.grid(row=2, column=0, sticky=tk.W) | ||
|
||
# Entry range | ||
range_default = tk.DoubleVar(value=50.0) | ||
self.entry_range = tk.Entry(self.frame, width=width, textvariable=range_default) | ||
self.entry_range.grid(row=2, column=1, sticky=tk.E) | ||
self.entry_range.update() | ||
|
||
# Label efficiency | ||
self.label_efficiency = tk.Label(self.frame, text="Efficiency (%): ", justify=tk.LEFT) | ||
self.label_efficiency.grid(row=3, column=0, sticky=tk.W) | ||
|
||
# Efficiency entry | ||
efficiency_default = tk.IntVar(value=60) | ||
self.entry_efficiency = tk.Spinbox(self.frame, from_=1, to=100, width=width - 2, textvariable=efficiency_default) | ||
self.entry_efficiency.grid(row=3, column=1, sticky=tk.E) | ||
|
||
# Checkbox clipboard | ||
self.checkbox_status = tk.IntVar(value=1) | ||
self.checkbox_clipboard = tk.Checkbutton(self.frame, text="autoclipboard", variable=self.checkbox_status) | ||
self.checkbox_clipboard.grid(row=4, column=0, columnspan=2, sticky=tk.W) | ||
|
||
# Button | ||
self.button_calculate = tk.Button(self.frame, text="Calculate", command=self.calculate_path) | ||
self.button_calculate.grid(row=5, column=0, columnspan=2, pady=(3, 0)) | ||
|
||
# Label Status | ||
self.label_status = tk.Label(self.frame, text="Ready.. ", justify=tk.CENTER) | ||
self.label_status.grid(row=6, column=0, columnspan=2, pady=(0,10)) | ||
|
||
# Frame layout | ||
self.frame.columnconfigure(6, weight=1) | ||
|
||
return self.frame |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
from autopath import Autopath | ||
from plotter import Plotter | ||
import sys | ||
import pprint | ||
|
||
# Plugin name | ||
PLUGIN_NAME = 'Autopath' | ||
# For holding module globals | ||
this = sys.modules[__name__] | ||
|
||
|
||
def plugin_start(plugin_dir): | ||
""" | ||
Load this plugin into EDMC | ||
""" | ||
this.current_system = "" | ||
this.last_system = "" | ||
this.plotter = Plotter() | ||
this.plugin = Autopath(this) | ||
print('{}: PLUGIN STARTED'.format(PLUGIN_NAME)) | ||
|
||
|
||
def plugin_stop(): | ||
""" | ||
EDMC is closing | ||
""" | ||
del this.autopath | ||
print('{}: PLUGIN DISABLED'.format(PLUGIN_NAME)) | ||
|
||
|
||
def plugin_app(parrent): | ||
return this.plugin.create_gui(parrent) | ||
|
||
|
||
def journal_entry(cmdr, is_beta, system, station, entry, state): | ||
if entry is not None and entry["event"].lower() in ("fsdjump","startup"): | ||
if len(this.current_system) < 1: | ||
this.current_system = entry["StarSystem"] | ||
else: | ||
this.last_system = this.current_system | ||
this.current_system = entry["StarSystem"] | ||
this.plugin.update_clipboard(this.current_system) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
import json | ||
import time | ||
from threading import Lock | ||
from threading import Thread | ||
import requests | ||
|
||
# Core API link | ||
API = "https://spansh.co.uk/api/" | ||
# Timeout value | ||
TIMEOUT = 30 | ||
|
||
|
||
class Plotter: | ||
|
||
def __init__(self): | ||
self.origin = None | ||
self.destination = None | ||
self.efficiency = None | ||
self.range = None | ||
# Special data handling | ||
self.route = None | ||
self.job = None | ||
# synchronize | ||
self.lock = Lock() | ||
|
||
def request_calculation(self, origin, destination, efficiency, ship_range): | ||
self.origin = origin | ||
self.destination = destination | ||
self.efficiency = efficiency | ||
self.range = ship_range | ||
|
||
# Prepare link for job queue | ||
link_job = API + "route?from={}&to={}&efficiency={}&range={}".format(origin, destination,efficiency, ship_range) | ||
# API calls for job queue | ||
request = requests.get(link_job).json() | ||
self.job = request["job"] | ||
|
||
thread = Thread(target=self.wait_for_route) | ||
thread.start() | ||
# After timeout we dont care anymore | ||
thread.join(timeout=TIMEOUT+1) | ||
|
||
# synchronize critical path | ||
with self.lock: | ||
return self.route | ||
|
||
def wait_for_route(self,): | ||
if self.job is None or len(self.job) < 1: | ||
return | ||
# Prepare link for route data | ||
link_data = API + "results/{}".format(self.job) | ||
# WAIT for data | ||
data = None | ||
time_start = time.time() | ||
data_request = requests.get(link_data) | ||
while data_request.status_code != 200: | ||
data_request = requests.get(link_data) | ||
time_elapsed = time.time() - time_start | ||
if time_elapsed > TIMEOUT: | ||
break | ||
|
||
# Get json | ||
data = data_request.json() | ||
# Synchronize | ||
with self.lock: | ||
self.route = data | ||
|
||
|
Oops, something went wrong.