mirror of
https://github.com/EDCD/EDMarketConnector.git
synced 2025-06-09 03:42:16 +03:00
Merge branch 'stable' into releases
This commit is contained in:
commit
0e0096771e
2
.github/workflows/pr-checks.yml
vendored
2
.github/workflows/pr-checks.yml
vendored
@ -53,7 +53,7 @@ jobs:
|
|||||||
# Get Python set up
|
# Get Python set up
|
||||||
####################################################################
|
####################################################################
|
||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@v4
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version-file: '.python-version'
|
python-version-file: '.python-version'
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
|
2
.github/workflows/push-checks.yml
vendored
2
.github/workflows/push-checks.yml
vendored
@ -26,7 +26,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@v4
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version-file: '.python-version'
|
python-version-file: '.python-version'
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
|
20
.github/workflows/windows-build.yml
vendored
20
.github/workflows/windows-build.yml
vendored
@ -1,5 +1,5 @@
|
|||||||
# vim: tabstop=2 shiftwidth=2
|
# vim: tabstop=2 shiftwidth=2
|
||||||
name: Build EDMC for Windows
|
name: Build EDMC
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
@ -11,7 +11,7 @@ jobs:
|
|||||||
variables:
|
variables:
|
||||||
outputs:
|
outputs:
|
||||||
sem_ver: ${{ steps.var.outputs.sem_ver }}
|
sem_ver: ${{ steps.var.outputs.sem_ver }}
|
||||||
archive_exclusions: ${{ steps.var.outputs.archive_exclusions }}
|
short_sha: ${{ steps.var.outputs.short_sha }}
|
||||||
runs-on: "ubuntu-latest"
|
runs-on: "ubuntu-latest"
|
||||||
steps:
|
steps:
|
||||||
- name: Setting global variables
|
- name: Setting global variables
|
||||||
@ -20,6 +20,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
script: |
|
script: |
|
||||||
core.setOutput('sem_ver', '${{ github.ref_name }}'.replaceAll('Release\/', ''))
|
core.setOutput('sem_ver', '${{ github.ref_name }}'.replaceAll('Release\/', ''))
|
||||||
|
core.setOutput('short_sha', '${{ github.sha }}'.substring(0, 8))
|
||||||
|
|
||||||
linux_build:
|
linux_build:
|
||||||
needs: [variables]
|
needs: [variables]
|
||||||
@ -29,6 +30,9 @@ jobs:
|
|||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
|
- name: Create .gitversion
|
||||||
|
run: |
|
||||||
|
echo "${{ needs.variables.outputs.short_sha }}" > .gitversion
|
||||||
|
|
||||||
- name: Make tar archive
|
- name: Make tar archive
|
||||||
run: |
|
run: |
|
||||||
@ -40,7 +44,11 @@ jobs:
|
|||||||
--exclude=EDMarketConnector-release-*.* \
|
--exclude=EDMarketConnector-release-*.* \
|
||||||
--exclude=.editorconfig \
|
--exclude=.editorconfig \
|
||||||
--exclude=.flake8 \
|
--exclude=.flake8 \
|
||||||
--exclude=.git* \
|
--exclude=.gitattributes \
|
||||||
|
--exclude=.gitignore \
|
||||||
|
--exclude=.gitmodules \
|
||||||
|
--exclude=.git \
|
||||||
|
--exclude=.github \
|
||||||
--exclude=.mypy.ini \
|
--exclude=.mypy.ini \
|
||||||
--exclude=.pre-commit-config.yaml \
|
--exclude=.pre-commit-config.yaml \
|
||||||
--exclude=build.py \
|
--exclude=build.py \
|
||||||
@ -93,7 +101,7 @@ jobs:
|
|||||||
# presumably due to a Windows CL length limit.
|
# presumably due to a Windows CL length limit.
|
||||||
exclusions: 'EDMarketConnector/EDMarketConnector-release-*.* EDMarketConnector/.editorconfig EDMarketConnector/.flake8 EDMarketConnector/.git* EDMarketConnector/.mypy.ini EDMarketConnector/.pre-commit-config.yaml EDMarketConnector/build.py EDMarketConnector/*.manifest EDMarketConnector/coriolis-data/ EDMarketConnector/img/ EDMarketConnector/pyproject.toml EDMarketConnector/scripts/ EDMarketConnector/tests/'
|
exclusions: 'EDMarketConnector/EDMarketConnector-release-*.* EDMarketConnector/.editorconfig EDMarketConnector/.flake8 EDMarketConnector/.git* EDMarketConnector/.mypy.ini EDMarketConnector/.pre-commit-config.yaml EDMarketConnector/build.py EDMarketConnector/*.manifest EDMarketConnector/coriolis-data/ EDMarketConnector/img/ EDMarketConnector/pyproject.toml EDMarketConnector/scripts/ EDMarketConnector/tests/'
|
||||||
|
|
||||||
- uses: actions/setup-python@v4
|
- uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version-file: '.python-version'
|
python-version-file: '.python-version'
|
||||||
architecture: "x86"
|
architecture: "x86"
|
||||||
@ -105,9 +113,9 @@ jobs:
|
|||||||
|
|
||||||
- name: Download winsparkle
|
- name: Download winsparkle
|
||||||
run: |
|
run: |
|
||||||
Invoke-Webrequest -UseBasicParsing https://github.com/vslavik/winsparkle/releases/download/v0.8.0/WinSparkle-0.8.0.zip -OutFile out.zip
|
Invoke-Webrequest -UseBasicParsing https://github.com/vslavik/winsparkle/releases/download/v0.8.1/WinSparkle-0.8.1.zip -OutFile out.zip
|
||||||
Expand-Archive out.zip
|
Expand-Archive out.zip
|
||||||
Move-Item 'out\WinSparkle-0.8.0\Release\*' '.\'
|
Move-Item 'out\WinSparkle-0.8.1\Release\*' '.\'
|
||||||
|
|
||||||
- name: Build EDMC
|
- name: Build EDMC
|
||||||
run: |
|
run: |
|
||||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -52,6 +52,7 @@ htmlcov/
|
|||||||
.coverage
|
.coverage
|
||||||
pylintrc
|
pylintrc
|
||||||
pylint.txt
|
pylint.txt
|
||||||
|
.pylintrc
|
||||||
|
|
||||||
# Ignore Submodule data directory
|
# Ignore Submodule data directory
|
||||||
coriolis-data/
|
coriolis-data/
|
||||||
|
@ -1 +1 @@
|
|||||||
3.11.1
|
3.11.7
|
||||||
|
31
ChangeLog.md
31
ChangeLog.md
@ -9,7 +9,7 @@ produce the Windows executables and installer.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
* We now test against, and package with, Python 3.11.1, 32-bit.
|
* We now test against, and package with, Python 3.11.7, 32-bit.
|
||||||
|
|
||||||
**As a consequence of this we no longer support Windows 7.
|
**As a consequence of this we no longer support Windows 7.
|
||||||
This is due to
|
This is due to
|
||||||
@ -33,6 +33,35 @@ produce the Windows executables and installer.
|
|||||||
currently used version in a given branch.
|
currently used version in a given branch.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
Release 5.10.1
|
||||||
|
===
|
||||||
|
This release contains a number of bugfixes, minor performance enhancements,
|
||||||
|
workflow and dependency updates, and a function deprecation.
|
||||||
|
|
||||||
|
Note to plugin developers: modules.p and ships.p are deprecated, and slated
|
||||||
|
for removal in the next major release! Please look for that change coming soon.
|
||||||
|
|
||||||
|
Note to plugin developers: The `openurl()` function in ttkHyperlinkLabel has been deprecated,
|
||||||
|
and slated for removal in the next major release! Please migrate to `webbrowser.open()`.
|
||||||
|
|
||||||
|
**Changes and Enhancements**
|
||||||
|
* Deprecated `openurl()`. Please migrate to `webbrowser.open()`
|
||||||
|
* Updated a number of list comparisons to use more efficient tuple comparisons
|
||||||
|
* Updated a few type hints
|
||||||
|
* Updated a few binary comparitors to be more efficient
|
||||||
|
* Moved `resources.json` and `modules.json` back to the top level for all users
|
||||||
|
* Updated several dependencies
|
||||||
|
* Updated Python version to 3.11.7
|
||||||
|
|
||||||
|
**Bug Fixes**
|
||||||
|
* Fixed an issue where resources files could be in different locations for different users.
|
||||||
|
* These files are now in the same location (top level) for all users on all distributions.
|
||||||
|
* Fixed an issue where CMDRs without the Git application installed would crash on start if running from Source.
|
||||||
|
* Thanks to the Flatpak team for pointing this one out!
|
||||||
|
* Fixed a bug where CMDRs running from source would have their git hash version displayed as UNKNOWN.
|
||||||
|
* We're now more failure tolerant and use the bundled .gitversion if no true git hash is provided.
|
||||||
|
* Fixed a bug where starting two copies of EDMC with a valid install would not generate a duplicate warning.
|
||||||
|
|
||||||
Release 5.10.0
|
Release 5.10.0
|
||||||
===
|
===
|
||||||
This release contains a number of under-the-hood changes to EDMC designed to improve performance, code
|
This release contains a number of under-the-hood changes to EDMC designed to improve performance, code
|
||||||
|
@ -336,6 +336,8 @@ if __name__ == '__main__': # noqa: C901
|
|||||||
|
|
||||||
def already_running_popup():
|
def already_running_popup():
|
||||||
"""Create the "already running" popup."""
|
"""Create the "already running" popup."""
|
||||||
|
import tkinter as tk
|
||||||
|
from tkinter import ttk
|
||||||
# Check for CL arg that suppresses this popup.
|
# Check for CL arg that suppresses this popup.
|
||||||
if args.suppress_dupe_process_popup:
|
if args.suppress_dupe_process_popup:
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
@ -1547,7 +1549,7 @@ class AppWindow:
|
|||||||
self.w.update_idletasks()
|
self.w.update_idletasks()
|
||||||
|
|
||||||
# Companion login
|
# Companion login
|
||||||
if entry['event'] in [None, 'StartUp', 'NewCommander', 'LoadGame'] and monitor.cmdr:
|
if entry['event'] in (None, 'StartUp', 'NewCommander', 'LoadGame') and monitor.cmdr:
|
||||||
if not config.get_list('cmdrs') or monitor.cmdr not in config.get_list('cmdrs'):
|
if not config.get_list('cmdrs') or monitor.cmdr not in config.get_list('cmdrs'):
|
||||||
config.set('cmdrs', config.get_list('cmdrs', default=[]) + [monitor.cmdr])
|
config.set('cmdrs', config.get_list('cmdrs', default=[]) + [monitor.cmdr])
|
||||||
self.login()
|
self.login()
|
||||||
@ -1565,7 +1567,7 @@ class AppWindow:
|
|||||||
logger.trace_if('journal.queue', 'Startup, returning')
|
logger.trace_if('journal.queue', 'Startup, returning')
|
||||||
return # Startup
|
return # Startup
|
||||||
|
|
||||||
if entry['event'] in ['StartUp', 'LoadGame'] and monitor.started:
|
if entry['event'] in ('StartUp', 'LoadGame') and monitor.started:
|
||||||
logger.info('StartUp or LoadGame event')
|
logger.info('StartUp or LoadGame event')
|
||||||
|
|
||||||
# Disable WinSparkle automatic update checks, IFF configured to do so when in-game
|
# Disable WinSparkle automatic update checks, IFF configured to do so when in-game
|
||||||
|
4
build.py
4
build.py
@ -77,8 +77,8 @@ def generate_data_files(
|
|||||||
"snd_good.wav",
|
"snd_good.wav",
|
||||||
"snd_bad.wav",
|
"snd_bad.wav",
|
||||||
"modules.p", # TODO: Remove in 6.0
|
"modules.p", # TODO: Remove in 6.0
|
||||||
"resources/modules.json",
|
"modules.json",
|
||||||
"resources/ships.json",
|
"ships.json",
|
||||||
"ships.p", # TODO: Remove in 6.0
|
"ships.p", # TODO: Remove in 6.0
|
||||||
f"{app_name}.VisualElementsManifest.xml",
|
f"{app_name}.VisualElementsManifest.xml",
|
||||||
f"{app_name}.ico",
|
f"{app_name}.ico",
|
||||||
|
@ -54,7 +54,7 @@ appcmdname = 'EDMC'
|
|||||||
# <https://semver.org/#semantic-versioning-specification-semver>
|
# <https://semver.org/#semantic-versioning-specification-semver>
|
||||||
# Major.Minor.Patch(-prerelease)(+buildmetadata)
|
# Major.Minor.Patch(-prerelease)(+buildmetadata)
|
||||||
# NB: Do *not* import this, use the functions appversion() and appversion_nobuild()
|
# NB: Do *not* import this, use the functions appversion() and appversion_nobuild()
|
||||||
_static_appversion = '5.10.0'
|
_static_appversion = '5.10.1'
|
||||||
|
|
||||||
_cached_version: semantic_version.Version | None = None
|
_cached_version: semantic_version.Version | None = None
|
||||||
copyright = '© 2015-2019 Jonathan Harris, 2020-2023 EDCD'
|
copyright = '© 2015-2019 Jonathan Harris, 2020-2023 EDCD'
|
||||||
@ -81,15 +81,15 @@ else:
|
|||||||
_T = TypeVar('_T')
|
_T = TypeVar('_T')
|
||||||
|
|
||||||
|
|
||||||
def git_shorthash_from_head() -> str:
|
def git_shorthash_from_head() -> str | None:
|
||||||
"""
|
"""
|
||||||
Determine short hash for current git HEAD.
|
Determine short hash for current git HEAD.
|
||||||
|
|
||||||
Includes `.DIRTY` if any changes have been made from HEAD
|
Includes `.DIRTY` if any changes have been made from HEAD
|
||||||
|
|
||||||
:return: str - None if we couldn't determine the short hash.
|
:return: str | None: None if we couldn't determine the short hash.
|
||||||
"""
|
"""
|
||||||
shorthash: str = None # type: ignore
|
shorthash: str | None = None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
git_cmd = subprocess.Popen(
|
git_cmd = subprocess.Popen(
|
||||||
@ -99,14 +99,14 @@ def git_shorthash_from_head() -> str:
|
|||||||
)
|
)
|
||||||
out, err = git_cmd.communicate()
|
out, err = git_cmd.communicate()
|
||||||
|
|
||||||
except subprocess.CalledProcessError as e:
|
except (subprocess.CalledProcessError, FileNotFoundError) as e:
|
||||||
logger.info(f"Couldn't run git command for short hash: {e!r}")
|
logger.info(f"Couldn't run git command for short hash: {e!r}")
|
||||||
|
|
||||||
else:
|
else:
|
||||||
shorthash = out.decode().rstrip('\n')
|
shorthash = out.decode().rstrip('\n')
|
||||||
if re.match(r'^[0-9a-f]{7,}$', shorthash) is None:
|
if re.match(r'^[0-9a-f]{7,}$', shorthash) is None:
|
||||||
logger.error(f"'{shorthash}' doesn't look like a valid git short hash, forcing to None")
|
logger.error(f"'{shorthash}' doesn't look like a valid git short hash, forcing to None")
|
||||||
shorthash = None # type: ignore
|
shorthash = None
|
||||||
|
|
||||||
if shorthash is not None:
|
if shorthash is not None:
|
||||||
with contextlib.suppress(Exception):
|
with contextlib.suppress(Exception):
|
||||||
@ -134,12 +134,18 @@ def appversion() -> semantic_version.Version:
|
|||||||
# Running frozen, so we should have a .gitversion file
|
# Running frozen, so we should have a .gitversion file
|
||||||
# Yes, .parent because if frozen we're inside library.zip
|
# Yes, .parent because if frozen we're inside library.zip
|
||||||
with open(pathlib.Path(sys.path[0]).parent / GITVERSION_FILE, encoding='utf-8') as gitv:
|
with open(pathlib.Path(sys.path[0]).parent / GITVERSION_FILE, encoding='utf-8') as gitv:
|
||||||
shorthash = gitv.read()
|
shorthash: str | None = gitv.read()
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# Running from source
|
# Running from source. Use git rev-parse --short HEAD
|
||||||
|
# or fall back to .gitversion file if it exists.
|
||||||
|
# This is also required for the Flatpak
|
||||||
shorthash = git_shorthash_from_head()
|
shorthash = git_shorthash_from_head()
|
||||||
if shorthash is None:
|
if shorthash is None:
|
||||||
|
if pathlib.Path(sys.path[0] + "/" + GITVERSION_FILE).exists():
|
||||||
|
with open(pathlib.Path(sys.path[0] + "/" + GITVERSION_FILE), encoding='utf-8') as gitv:
|
||||||
|
shorthash = gitv.read()
|
||||||
|
else:
|
||||||
shorthash = 'UNKNOWN'
|
shorthash = 'UNKNOWN'
|
||||||
|
|
||||||
_cached_version = semantic_version.Version(f'{_static_appversion}+{shorthash}')
|
_cached_version = semantic_version.Version(f'{_static_appversion}+{shorthash}')
|
||||||
|
@ -57,7 +57,7 @@ if __name__ == "__main__":
|
|||||||
modules['_'.join([reverse_ship_map[name], 'armour', bulkhead])] = {'mass': m['bulkheads'][i]['mass']}
|
modules['_'.join([reverse_ship_map[name], 'armour', bulkhead])] = {'mass': m['bulkheads'][i]['mass']}
|
||||||
|
|
||||||
ships = OrderedDict([(k, ships[k]) for k in sorted(ships)]) # sort for easier diffing
|
ships = OrderedDict([(k, ships[k]) for k in sorted(ships)]) # sort for easier diffing
|
||||||
with open("resources/ships.json", "w") as ships_file:
|
with open("ships.json", "w") as ships_file:
|
||||||
json.dump(ships, ships_file, indent=4)
|
json.dump(ships, ships_file, indent=4)
|
||||||
|
|
||||||
# Module masses
|
# Module masses
|
||||||
@ -92,5 +92,5 @@ if __name__ == "__main__":
|
|||||||
add(modules, 'hpt_multicannon_fixed_medium_advanced', {'mass': 4})
|
add(modules, 'hpt_multicannon_fixed_medium_advanced', {'mass': 4})
|
||||||
|
|
||||||
modules = OrderedDict([(k, modules[k]) for k in sorted(modules)]) # sort for easier diffing
|
modules = OrderedDict([(k, modules[k]) for k in sorted(modules)]) # sort for easier diffing
|
||||||
with open("resources/modules.json", "w") as modules_file:
|
with open("modules.json", "w") as modules_file:
|
||||||
json.dump(modules, modules_file, indent=4)
|
json.dump(modules, modules_file, indent=4)
|
||||||
|
@ -24,7 +24,7 @@ __Module = dict[str, Union[str, list[str]]] # Have to keep old-style here for c
|
|||||||
ship_map = ship_name_map.copy()
|
ship_map = ship_name_map.copy()
|
||||||
|
|
||||||
# Ship masses
|
# Ship masses
|
||||||
ships_file = config.respath_path / "resources" / "ships.json"
|
ships_file = config.respath_path / "ships.json"
|
||||||
with open(ships_file, encoding="utf-8") as ships_file_handle:
|
with open(ships_file, encoding="utf-8") as ships_file_handle:
|
||||||
ships = json.load(ships_file_handle)
|
ships = json.load(ships_file_handle)
|
||||||
|
|
||||||
|
@ -211,12 +211,12 @@ class MacHotkeyMgr(AbstractHotkeyMgr):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
# BkSp, Del, Clear = clear hotkey
|
# BkSp, Del, Clear = clear hotkey
|
||||||
if keycode in [0x7f, ord(NSDeleteFunctionKey), ord(NSClearLineFunctionKey)]:
|
if keycode in (0x7f, ord(NSDeleteFunctionKey), ord(NSClearLineFunctionKey)):
|
||||||
self.acquire_state = MacHotkeyMgr.ACQUIRE_INACTIVE
|
self.acquire_state = MacHotkeyMgr.ACQUIRE_INACTIVE
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# don't allow keys needed for typing in System Map
|
# don't allow keys needed for typing in System Map
|
||||||
if keycode in [0x13, 0x20, 0x2d] or 0x61 <= keycode <= 0x7a:
|
if keycode in (0x13, 0x20, 0x2d) or 0x61 <= keycode <= 0x7a:
|
||||||
NSBeep()
|
NSBeep()
|
||||||
self.acquire_state = MacHotkeyMgr.ACQUIRE_INACTIVE
|
self.acquire_state = MacHotkeyMgr.ACQUIRE_INACTIVE
|
||||||
return None
|
return None
|
||||||
|
@ -284,23 +284,23 @@ class WindowsHotkeyMgr(AbstractHotkeyMgr):
|
|||||||
| ((GetKeyState(VK_RWIN) & 0x8000) and MOD_WIN)
|
| ((GetKeyState(VK_RWIN) & 0x8000) and MOD_WIN)
|
||||||
keycode = event.keycode
|
keycode = event.keycode
|
||||||
|
|
||||||
if keycode in [VK_SHIFT, VK_CONTROL, VK_MENU, VK_LWIN, VK_RWIN]:
|
if keycode in (VK_SHIFT, VK_CONTROL, VK_MENU, VK_LWIN, VK_RWIN):
|
||||||
return 0, modifiers
|
return 0, modifiers
|
||||||
|
|
||||||
if not modifiers:
|
if not modifiers:
|
||||||
if keycode == VK_ESCAPE: # Esc = retain previous
|
if keycode == VK_ESCAPE: # Esc = retain previous
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if keycode in [VK_BACK, VK_DELETE, VK_CLEAR, VK_OEM_CLEAR]: # BkSp, Del, Clear = clear hotkey
|
if keycode in (VK_BACK, VK_DELETE, VK_CLEAR, VK_OEM_CLEAR): # BkSp, Del, Clear = clear hotkey
|
||||||
return None
|
return None
|
||||||
|
|
||||||
if (
|
if (
|
||||||
keycode in [VK_RETURN, VK_SPACE, VK_OEM_MINUS] or ord('A') <= keycode <= ord('Z')
|
keycode in (VK_RETURN, VK_SPACE, VK_OEM_MINUS) or ord('A') <= keycode <= ord('Z')
|
||||||
): # don't allow keys needed for typing in System Map
|
): # don't allow keys needed for typing in System Map
|
||||||
winsound.MessageBeep()
|
winsound.MessageBeep()
|
||||||
return None
|
return None
|
||||||
|
|
||||||
if (keycode in [VK_NUMLOCK, VK_SCROLL, VK_PROCESSKEY]
|
if (keycode in (VK_NUMLOCK, VK_SCROLL, VK_PROCESSKEY)
|
||||||
or VK_CAPITAL <= keycode <= VK_MODECHANGE): # ignore unmodified mode switch keys
|
or VK_CAPITAL <= keycode <= VK_MODECHANGE): # ignore unmodified mode switch keys
|
||||||
return 0, modifiers
|
return 0, modifiers
|
||||||
|
|
||||||
|
2
l10n.py
2
l10n.py
@ -25,7 +25,7 @@ from config import config
|
|||||||
from EDMCLogging import get_main_logger
|
from EDMCLogging import get_main_logger
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
def _(x: str) -> str: ...
|
def _(x: str) -> str: return x
|
||||||
|
|
||||||
# Note that this is also done in EDMarketConnector.py, and thus removing this here may not have a desired effect
|
# Note that this is also done in EDMarketConnector.py, and thus removing this here may not have a desired effect
|
||||||
try:
|
try:
|
||||||
|
@ -57,7 +57,7 @@ def lookup(module, ship_map, entitled=False) -> dict | None: # noqa: C901, CCR0
|
|||||||
"""
|
"""
|
||||||
# Lazily populate
|
# Lazily populate
|
||||||
if not moduledata:
|
if not moduledata:
|
||||||
modules_path = config.respath_path / "resources" / "modules.json"
|
modules_path = config.respath_path / "modules.json"
|
||||||
moduledata.update(json.loads(modules_path.read_text()))
|
moduledata.update(json.loads(modules_path.read_text()))
|
||||||
|
|
||||||
if not module.get('name'):
|
if not module.get('name'):
|
||||||
@ -79,7 +79,7 @@ def lookup(module, ship_map, entitled=False) -> dict | None: # noqa: C901, CCR0
|
|||||||
new['rating'] = 'I'
|
new['rating'] = 'I'
|
||||||
|
|
||||||
# Skip uninteresting stuff - some no longer present in ED 3.1 cAPI data
|
# Skip uninteresting stuff - some no longer present in ED 3.1 cAPI data
|
||||||
elif (name[0] in [
|
elif (name[0] in (
|
||||||
'bobble',
|
'bobble',
|
||||||
'decal',
|
'decal',
|
||||||
'nameplate',
|
'nameplate',
|
||||||
@ -87,7 +87,7 @@ def lookup(module, ship_map, entitled=False) -> dict | None: # noqa: C901, CCR0
|
|||||||
'enginecustomisation',
|
'enginecustomisation',
|
||||||
'voicepack',
|
'voicepack',
|
||||||
'weaponcustomisation'
|
'weaponcustomisation'
|
||||||
]
|
)
|
||||||
or name[1].startswith('shipkit')):
|
or name[1].startswith('shipkit')):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@ -205,10 +205,10 @@ def lookup(module, ship_map, entitled=False) -> dict | None: # noqa: C901, CCR0
|
|||||||
elif len(name) < 4 and name[1] == 'resourcesiphon': # Hack! 128066402 has no size or class.
|
elif len(name) < 4 and name[1] == 'resourcesiphon': # Hack! 128066402 has no size or class.
|
||||||
(new['class'], new['rating']) = ('1', 'I')
|
(new['class'], new['rating']) = ('1', 'I')
|
||||||
|
|
||||||
elif len(name) < 4 and name[1] in ['guardianpowerdistributor', 'guardianpowerplant']: # Hack! No class.
|
elif len(name) < 4 and name[1] in ('guardianpowerdistributor', 'guardianpowerplant'): # Hack! No class.
|
||||||
(new['class'], new['rating']) = (str(name[2][4:]), 'A')
|
(new['class'], new['rating']) = (str(name[2][4:]), 'A')
|
||||||
|
|
||||||
elif len(name) < 4 and name[1] in ['guardianfsdbooster']: # Hack! No class.
|
elif len(name) < 4 and name[1] == 'guardianfsdbooster': # Hack! No class.
|
||||||
(new['class'], new['rating']) = (str(name[2][4:]), 'H')
|
(new['class'], new['rating']) = (str(name[2][4:]), 'H')
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
4
plug.py
4
plug.py
@ -165,7 +165,7 @@ def load_plugins(master: tk.Tk) -> None:
|
|||||||
def _load_internal_plugins():
|
def _load_internal_plugins():
|
||||||
internal = []
|
internal = []
|
||||||
for name in sorted(os.listdir(config.internal_plugin_dir_path)):
|
for name in sorted(os.listdir(config.internal_plugin_dir_path)):
|
||||||
if name.endswith('.py') and name[0] not in ['.', '_']:
|
if name.endswith('.py') and name[0] not in ('.', '_'):
|
||||||
try:
|
try:
|
||||||
plugin = Plugin(name[:-3], os.path.join(config.internal_plugin_dir_path, name), logger)
|
plugin = Plugin(name[:-3], os.path.join(config.internal_plugin_dir_path, name), logger)
|
||||||
plugin.folder = None
|
plugin.folder = None
|
||||||
@ -184,7 +184,7 @@ def _load_found_plugins():
|
|||||||
|
|
||||||
for name in sorted(os.listdir(config.plugin_dir_path), key=lambda n: (
|
for name in sorted(os.listdir(config.plugin_dir_path), key=lambda n: (
|
||||||
not os.path.isfile(os.path.join(config.plugin_dir_path, n, '__init__.py')), n.lower())):
|
not os.path.isfile(os.path.join(config.plugin_dir_path, n, '__init__.py')), n.lower())):
|
||||||
if not os.path.isdir(os.path.join(config.plugin_dir_path, name)) or name[0] in ['.', '_']:
|
if not os.path.isdir(os.path.join(config.plugin_dir_path, name)) or name[0] in ('.', '_'):
|
||||||
pass
|
pass
|
||||||
elif name.endswith('.disabled'):
|
elif name.endswith('.disabled'):
|
||||||
name, discard = name.rsplit('.', 1)
|
name, discard = name.rsplit('.', 1)
|
||||||
|
@ -918,7 +918,7 @@ def journal_entry( # noqa: C901, CCR001
|
|||||||
])
|
])
|
||||||
|
|
||||||
# optional mission-specific properties
|
# optional mission-specific properties
|
||||||
for (iprop, prop) in [
|
for (iprop, prop) in (
|
||||||
('missionExpiry', 'Expiry'), # Listed as optional in the docs, but always seems to be present
|
('missionExpiry', 'Expiry'), # Listed as optional in the docs, but always seems to be present
|
||||||
('starsystemNameTarget', 'DestinationSystem'),
|
('starsystemNameTarget', 'DestinationSystem'),
|
||||||
('stationNameTarget', 'DestinationStation'),
|
('stationNameTarget', 'DestinationStation'),
|
||||||
@ -932,7 +932,7 @@ def journal_entry( # noqa: C901, CCR001
|
|||||||
('passengerCount', 'PassengerCount'),
|
('passengerCount', 'PassengerCount'),
|
||||||
('passengerIsVIP', 'PassengerVIPs'),
|
('passengerIsVIP', 'PassengerVIPs'),
|
||||||
('passengerIsWanted', 'PassengerWanted'),
|
('passengerIsWanted', 'PassengerWanted'),
|
||||||
]:
|
):
|
||||||
|
|
||||||
if prop in entry:
|
if prop in entry:
|
||||||
data[iprop] = entry[prop]
|
data[iprop] = entry[prop]
|
||||||
@ -1295,7 +1295,7 @@ def journal_entry( # noqa: C901, CCR001
|
|||||||
|
|
||||||
# Friends
|
# Friends
|
||||||
if event_name == 'Friends':
|
if event_name == 'Friends':
|
||||||
if entry['Status'] in ['Added', 'Online']:
|
if entry['Status'] in ('Added', 'Online'):
|
||||||
new_add_event(
|
new_add_event(
|
||||||
'addCommanderFriend',
|
'addCommanderFriend',
|
||||||
entry['timestamp'],
|
entry['timestamp'],
|
||||||
@ -1305,7 +1305,7 @@ def journal_entry( # noqa: C901, CCR001
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
elif entry['Status'] in ['Declined', 'Lost']:
|
elif entry['Status'] in ('Declined', 'Lost'):
|
||||||
new_add_event(
|
new_add_event(
|
||||||
'delCommanderFriend',
|
'delCommanderFriend',
|
||||||
entry['timestamp'],
|
entry['timestamp'],
|
||||||
@ -1666,7 +1666,7 @@ def handle_special_events(data_event: dict[str, Any], reply_event: dict[str, Any
|
|||||||
this.lastlocation = reply_event.get('eventData', {})
|
this.lastlocation = reply_event.get('eventData', {})
|
||||||
if not config.shutting_down:
|
if not config.shutting_down:
|
||||||
this.system_link.event_generate('<<InaraLocation>>', when="tail")
|
this.system_link.event_generate('<<InaraLocation>>', when="tail")
|
||||||
elif data_event['eventName'] in ['addCommanderShip', 'setCommanderShip']:
|
elif data_event['eventName'] in ('addCommanderShip', 'setCommanderShip'):
|
||||||
this.lastship = reply_event.get('eventData', {})
|
this.lastship = reply_event.get('eventData', {})
|
||||||
if not config.shutting_down:
|
if not config.shutting_down:
|
||||||
this.system_link.event_generate('<<InaraShip>>', when="tail")
|
this.system_link.event_generate('<<InaraShip>>', when="tail")
|
||||||
|
@ -5,7 +5,7 @@ wheel
|
|||||||
# We can't rely on just picking this up from either the base (not venv),
|
# We can't rely on just picking this up from either the base (not venv),
|
||||||
# or venv-init-time version. Specify here so that dependabot will prod us
|
# or venv-init-time version. Specify here so that dependabot will prod us
|
||||||
# about new versions.
|
# about new versions.
|
||||||
setuptools==69.0.2
|
setuptools==69.0.3
|
||||||
|
|
||||||
# Static analysis tools
|
# Static analysis tools
|
||||||
flake8==6.1.0
|
flake8==6.1.0
|
||||||
@ -18,17 +18,17 @@ flake8-noqa==1.3.2
|
|||||||
flake8-polyfill==1.0.2
|
flake8-polyfill==1.0.2
|
||||||
flake8-use-fstring==1.4
|
flake8-use-fstring==1.4
|
||||||
|
|
||||||
mypy==1.7.1
|
mypy==1.8.0
|
||||||
pep8-naming==0.13.3
|
pep8-naming==0.13.3
|
||||||
safety==2.3.5
|
safety==2.3.5
|
||||||
types-requests==2.31.0.10
|
types-requests==2.31.0.20231231
|
||||||
types-pkg-resources==0.1.3
|
types-pkg-resources==0.1.3
|
||||||
|
|
||||||
# Code formatting tools
|
# Code formatting tools
|
||||||
autopep8==2.0.4
|
autopep8==2.0.4
|
||||||
|
|
||||||
# Git pre-commit checking
|
# Git pre-commit checking
|
||||||
pre-commit==3.5.0
|
pre-commit==3.6.0
|
||||||
|
|
||||||
# HTML changelogs
|
# HTML changelogs
|
||||||
grip==4.6.2
|
grip==4.6.2
|
||||||
@ -40,7 +40,7 @@ py2exe==0.13.0.1; sys_platform == 'win32'
|
|||||||
# Testing
|
# Testing
|
||||||
pytest==7.4.3
|
pytest==7.4.3
|
||||||
pytest-cov==4.1.0 # Pytest code coverage support
|
pytest-cov==4.1.0 # Pytest code coverage support
|
||||||
coverage[toml]==7.3.2 # pytest-cov dep. This is here to ensure that it includes TOML support for pyproject.toml configs
|
coverage[toml]==7.3.4 # pytest-cov dep. This is here to ensure that it includes TOML support for pyproject.toml configs
|
||||||
coverage-conditional-plugin==0.9.0
|
coverage-conditional-plugin==0.9.0
|
||||||
# For manipulating folder permissions and the like.
|
# For manipulating folder permissions and the like.
|
||||||
pywin32==306; sys_platform == 'win32'
|
pywin32==306; sys_platform == 'win32'
|
||||||
|
4
stats.py
4
stats.py
@ -5,6 +5,8 @@ Copyright (c) EDCD, All Rights Reserved
|
|||||||
Licensed under the GNU General Public License.
|
Licensed under the GNU General Public License.
|
||||||
See LICENSE file.
|
See LICENSE file.
|
||||||
"""
|
"""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import csv
|
import csv
|
||||||
import json
|
import json
|
||||||
import sys
|
import sys
|
||||||
@ -22,7 +24,7 @@ from monitor import monitor
|
|||||||
logger = EDMCLogging.get_main_logger()
|
logger = EDMCLogging.get_main_logger()
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
def _(x: str) -> str: ...
|
def _(x: str) -> str: return x
|
||||||
|
|
||||||
if sys.platform == 'win32':
|
if sys.platform == 'win32':
|
||||||
import ctypes
|
import ctypes
|
||||||
|
2
td.py
2
td.py
@ -32,7 +32,7 @@ def export(data: CAPIData) -> None:
|
|||||||
with open(data_path / data_filename, 'wb') as h:
|
with open(data_path / data_filename, 'wb') as h:
|
||||||
# Format described here: https://github.com/eyeonus/Trade-Dangerous/wiki/Price-Data
|
# Format described here: https://github.com/eyeonus/Trade-Dangerous/wiki/Price-Data
|
||||||
h.write('#! trade.py import -\n'.encode('utf-8'))
|
h.write('#! trade.py import -\n'.encode('utf-8'))
|
||||||
this_platform = sys.platform == 'darwin' and "Mac OS" or system()
|
this_platform = "Mac OS" if sys.platform == 'darwin' else system()
|
||||||
cmdr_name = data['commander']['name'].strip()
|
cmdr_name = data['commander']['name'].strip()
|
||||||
h.write(
|
h.write(
|
||||||
f'# Created by {applongname} {appversion()} on {this_platform} for Cmdr {cmdr_name}.\n'.encode('utf-8')
|
f'# Created by {applongname} {appversion()} on {this_platform} for Cmdr {cmdr_name}.\n'.encode('utf-8')
|
||||||
|
@ -296,7 +296,7 @@ class OldConfig:
|
|||||||
None,
|
None,
|
||||||
ctypes.byref(key_size)
|
ctypes.byref(key_size)
|
||||||
)
|
)
|
||||||
or key_type.value not in [REG_SZ, REG_MULTI_SZ]
|
or key_type.value not in (REG_SZ, REG_MULTI_SZ)
|
||||||
):
|
):
|
||||||
return default
|
return default
|
||||||
|
|
||||||
|
@ -22,20 +22,21 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import sys
|
import sys
|
||||||
import tkinter as tk
|
import tkinter as tk
|
||||||
|
import warnings
|
||||||
import webbrowser
|
import webbrowser
|
||||||
from tkinter import font as tk_font
|
from tkinter import font as tk_font
|
||||||
from tkinter import ttk
|
from tkinter import ttk
|
||||||
from typing import TYPE_CHECKING, Any
|
from typing import TYPE_CHECKING, Any
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
def _(x: str) -> str: ...
|
def _(x: str) -> str: return x
|
||||||
|
|
||||||
|
|
||||||
# FIXME: Split this into multi-file module to separate the platforms
|
# FIXME: Split this into multi-file module to separate the platforms
|
||||||
class HyperlinkLabel(sys.platform == 'darwin' and tk.Label or ttk.Label): # type: ignore
|
class HyperlinkLabel(sys.platform == 'darwin' and tk.Label or ttk.Label): # type: ignore
|
||||||
"""Clickable label for HTTP links."""
|
"""Clickable label for HTTP links."""
|
||||||
|
|
||||||
def __init__(self, master: tk.Frame | None = None, **kw: Any) -> None:
|
def __init__(self, master: ttk.Frame | tk.Frame | None = None, **kw: Any) -> None:
|
||||||
"""
|
"""
|
||||||
Initialize the HyperlinkLabel.
|
Initialize the HyperlinkLabel.
|
||||||
|
|
||||||
@ -80,10 +81,10 @@ class HyperlinkLabel(sys.platform == 'darwin' and tk.Label or ttk.Label): # typ
|
|||||||
) -> dict[str, tuple[str, str, str, Any, Any]] | None:
|
) -> dict[str, tuple[str, str, str, Any, Any]] | None:
|
||||||
"""Change cursor and appearance depending on state and text."""
|
"""Change cursor and appearance depending on state and text."""
|
||||||
# This class' state
|
# This class' state
|
||||||
for thing in ['url', 'popup_copy', 'underline']:
|
for thing in ('url', 'popup_copy', 'underline'):
|
||||||
if thing in kw:
|
if thing in kw:
|
||||||
setattr(self, thing, kw.pop(thing))
|
setattr(self, thing, kw.pop(thing))
|
||||||
for thing in ['foreground', 'disabledforeground']:
|
for thing in ('foreground', 'disabledforeground'):
|
||||||
if thing in kw:
|
if thing in kw:
|
||||||
setattr(self, thing, kw[thing])
|
setattr(self, thing, kw[thing])
|
||||||
|
|
||||||
@ -135,7 +136,7 @@ class HyperlinkLabel(sys.platform == 'darwin' and tk.Label or ttk.Label): # typ
|
|||||||
url = self.url(self['text']) if callable(self.url) else self.url
|
url = self.url(self['text']) if callable(self.url) else self.url
|
||||||
if url:
|
if url:
|
||||||
self._leave(event) # Remove underline before we change window to browser
|
self._leave(event) # Remove underline before we change window to browser
|
||||||
openurl(url)
|
webbrowser.open(url)
|
||||||
|
|
||||||
def _contextmenu(self, event: tk.Event) -> None:
|
def _contextmenu(self, event: tk.Event) -> None:
|
||||||
if self['text'] and (self.popup_copy(self['text']) if callable(self.popup_copy) else self.popup_copy):
|
if self['text'] and (self.popup_copy(self['text']) if callable(self.popup_copy) else self.popup_copy):
|
||||||
@ -183,4 +184,6 @@ def openurl(url: str) -> None:
|
|||||||
ended up using `webbrowser.open()` *anyway*.
|
ended up using `webbrowser.open()` *anyway*.
|
||||||
:param url: URL to open.
|
:param url: URL to open.
|
||||||
"""
|
"""
|
||||||
|
warnings.warn("This function is deprecated. "
|
||||||
|
"Please use `webbrowser.open() instead.", DeprecationWarning, stacklevel=2)
|
||||||
webbrowser.open(url)
|
webbrowser.open(url)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user