Skip to content

Commit

Permalink
Merge pull request #2099 from HullSeals/enhancement/1490/spansh-URL-p…
Browse files Browse the repository at this point in the history
…rovider

Add spansh as a URL provider
  • Loading branch information
Rixxan authored Nov 17, 2023
2 parents 48644f7 + ed163dd commit 3e1725c
Show file tree
Hide file tree
Showing 3 changed files with 198 additions and 2 deletions.
1 change: 1 addition & 0 deletions build.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ def build() -> None:
"plugins/edsm.py",
"plugins/edsy.py",
"plugins/inara.py",
"plugins/spansh_core.py",
]
options: dict = {
"py2exe": {
Expand Down
4 changes: 2 additions & 2 deletions plugins/edsm.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,13 +199,13 @@ def plugin_start3(plugin_dir: str) -> str:
"""
Start the plugin.
:param plugin_dir: NAme of directory this was loaded from.
:param plugin_dir: Name of directory this was loaded from.
:return: Identifier string for this plugin.
"""
# Can't be earlier since can only call PhotoImage after window is created
this._IMG_KNOWN = tk.PhotoImage(data=IMG_KNOWN_B64) # green circle
this._IMG_UNKNOWN = tk.PhotoImage(data=IMG_UNKNOWN_B64) # red circle
this._IMG_NEW = tk.PhotoImage(data=IMG_NEW_B64)
this._IMG_NEW = tk.PhotoImage(data=IMG_NEW_B64) # yellow star
this._IMG_ERROR = tk.PhotoImage(data=IMG_ERR_B64) # BBC Mode 5 '?'

# Migrate old settings
Expand Down
195 changes: 195 additions & 0 deletions plugins/spansh_core.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
"""
spansh_core.py - Spansh URL provider.
Copyright (c) EDCD, All Rights Reserved
Licensed under the GNU General Public License.
See LICENSE file.
This is an EDMC 'core' plugin.
All EDMC plugins are *dynamically* loaded at run-time.
We build for Windows using `py2exe`.
`py2exe` can't possibly know about anything in the dynamically loaded core plugins.
Thus, you **MUST** check if any imports you add in this file are only
referenced in this file (or only in any other core plugin), and if so...
YOU MUST ENSURE THAT PERTINENT ADJUSTMENTS ARE MADE IN
`build.py` TO ENSURE THE FILES ARE ACTUALLY PRESENT
IN AN END-USER INSTALLATION ON WINDOWS.
"""
from __future__ import annotations

import tkinter as tk
from typing import Any, cast
import requests
from companion import CAPIData
from config import appname, config
from EDMCLogging import get_main_logger

logger = get_main_logger()


class This:
"""Holds module globals."""

def __init__(self):
self.parent: tk.Tk
self.shutting_down = False # Plugin is shutting down.
self.system_link: tk.Widget = None # type: ignore
self.system_name: str | None = None
self.system_address: str | None = None
self.system_population: int | None = None
self.station_link: tk.Widget = None # type: ignore
self.station_name = None
self.station_marketid = None
self.on_foot = False


this = This()
STATION_UNDOCKED: str = '×' # "Station" name to display when not docked = U+00D7


def plugin_start3(plugin_dir: str) -> str:
"""
Start the plugin.
:param plugin_dir: Name of directory this was loaded from.
:return: Identifier string for this plugin.
"""
return 'spansh'


def plugin_app(parent: tk.Tk) -> None:
"""
Construct this plugin's main UI, if any.
:param parent: The tk parent to place our widgets into.
:return: See PLUGINS.md#display
"""
this.parent = parent
this.system_link = parent.nametowidget(f".{appname.lower()}.system")
this.station_link = parent.nametowidget(f".{appname.lower()}.station")


def plugin_stop() -> None:
"""Plugin shutdown hook."""
this.shutting_down = True


def journal_entry(
cmdr: str, is_beta: bool, system: str, station: str, entry: dict[str, Any], state: dict[str, Any]
) -> str:
"""
Handle a new Journal event.
:param cmdr: Name of Commander.
:param is_beta: Whether game beta was detected.
:param system: Name of current tracked system.
:param station: Name of current tracked station location.
:param entry: The journal event.
:param state: `monitor.state`
:return: None if no error, else an error string.
"""
this.on_foot = state['OnFoot']
this.system_address = state['SystemAddress']
this.system_name = state['SystemName']
this.system_population = state['SystemPopulation']
this.station_name = state['StationName']
this.station_marketid = state['MarketID']

# Only actually change URLs if we are current provider.
if config.get_str('system_provider') == 'spansh':
this.system_link['text'] = this.system_name
# Do *NOT* set 'url' here, as it's set to a function that will call
# through correctly. We don't want a static string.
this.system_link.update_idletasks()

if config.get_str('station_provider') == 'spansh':
to_set: str = cast(str, this.station_name)
if not to_set:
if this.system_population is not None and this.system_population > 0:
to_set = STATION_UNDOCKED
else:
to_set = ''

this.station_link['text'] = to_set
# Do *NOT* set 'url' here, as it's set to a function that will call
# through correctly. We don't want a static string.
this.station_link.update_idletasks()

return ''


def cmdr_data(data: CAPIData, is_beta: bool) -> str | None:
"""
Process new CAPI data.
:param data: The latest merged CAPI data.
:param is_beta: Whether game beta was detected.
:return: Optional error string.
"""
# Always store initially, even if we're not the *current* system provider.
if not this.station_marketid and data['commander']['docked']:
this.station_marketid = data['lastStarport']['id']

# Only trust CAPI if these aren't yet set
if not this.system_name:
this.system_name = data['lastSystem']['name']
if not this.station_name and data['commander']['docked']:
this.station_name = data['lastStarport']['name']

# Override standard URL functions
if config.get_str('system_provider') == 'spansh':
this.system_link['text'] = this.system_name
# Do *NOT* set 'url' here, as it's set to a function that will call
# through correctly. We don't want a static string.
this.system_link.update_idletasks()
if config.get_str('station_provider') == 'spansh':
if data['commander']['docked'] or this.on_foot and this.station_name:
this.station_link['text'] = this.station_name
elif data['lastStarport']['name'] and data['lastStarport']['name'] != "":
this.station_link['text'] = STATION_UNDOCKED
else:
this.station_link['text'] = ''
# Do *NOT* set 'url' here, as it's set to a function that will call
# through correctly. We don't want a static string.
this.station_link.update_idletasks()

return ''


def system_url(system_name: str) -> str:
"""
Construct an appropriate spansh URL for the provided system.
:param system_name: Will be overridden with `this.system_address` if that
is set.
:return: The URL, empty if no data was available to construct it.
"""
if this.system_address:
return requests.utils.requote_uri(f'https://www.spansh.co.uk/system/{this.system_address}')

if system_name:
return requests.utils.requote_uri(f'https://www.spansh.co.uk/search/{system_name}')

return ''


def station_url(system_name: str, station_name: str) -> str:
"""
Construct an appropriate spansh URL for a station.
Ignores `station_name` in favour of `this.station_marketid`.
:param system_name: Name of the system the station is in.
:param station_name: **NOT USED**
:return: The URL, empty if no data was available to construct it.
"""
if this.station_marketid:
return requests.utils.requote_uri(f'https://www.spansh.co.uk/station/{this.station_marketid}')

if system_name:
return system_url(system_name)

return ''

0 comments on commit 3e1725c

Please sign in to comment.