mirror of
https://github.com/EDCD/EDMarketConnector.git
synced 2025-04-17 01:22:19 +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
|
||||
####################################################################
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version-file: '.python-version'
|
||||
- name: Install dependencies
|
||||
|
2
.github/workflows/push-checks.yml
vendored
2
.github/workflows/push-checks.yml
vendored
@ -26,7 +26,7 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version-file: '.python-version'
|
||||
- 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
|
||||
name: Build EDMC for Windows
|
||||
name: Build EDMC
|
||||
|
||||
on:
|
||||
push:
|
||||
@ -11,7 +11,7 @@ jobs:
|
||||
variables:
|
||||
outputs:
|
||||
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"
|
||||
steps:
|
||||
- name: Setting global variables
|
||||
@ -20,6 +20,7 @@ jobs:
|
||||
with:
|
||||
script: |
|
||||
core.setOutput('sem_ver', '${{ github.ref_name }}'.replaceAll('Release\/', ''))
|
||||
core.setOutput('short_sha', '${{ github.sha }}'.substring(0, 8))
|
||||
|
||||
linux_build:
|
||||
needs: [variables]
|
||||
@ -29,6 +30,9 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
- name: Create .gitversion
|
||||
run: |
|
||||
echo "${{ needs.variables.outputs.short_sha }}" > .gitversion
|
||||
|
||||
- name: Make tar archive
|
||||
run: |
|
||||
@ -40,7 +44,11 @@ jobs:
|
||||
--exclude=EDMarketConnector-release-*.* \
|
||||
--exclude=.editorconfig \
|
||||
--exclude=.flake8 \
|
||||
--exclude=.git* \
|
||||
--exclude=.gitattributes \
|
||||
--exclude=.gitignore \
|
||||
--exclude=.gitmodules \
|
||||
--exclude=.git \
|
||||
--exclude=.github \
|
||||
--exclude=.mypy.ini \
|
||||
--exclude=.pre-commit-config.yaml \
|
||||
--exclude=build.py \
|
||||
@ -93,7 +101,7 @@ jobs:
|
||||
# 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/'
|
||||
|
||||
- uses: actions/setup-python@v4
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version-file: '.python-version'
|
||||
architecture: "x86"
|
||||
@ -105,9 +113,9 @@ jobs:
|
||||
|
||||
- name: Download winsparkle
|
||||
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
|
||||
Move-Item 'out\WinSparkle-0.8.0\Release\*' '.\'
|
||||
Move-Item 'out\WinSparkle-0.8.1\Release\*' '.\'
|
||||
|
||||
- name: Build EDMC
|
||||
run: |
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -52,6 +52,7 @@ htmlcov/
|
||||
.coverage
|
||||
pylintrc
|
||||
pylint.txt
|
||||
.pylintrc
|
||||
|
||||
# Ignore Submodule data directory
|
||||
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.
|
||||
This is due to
|
||||
@ -33,6 +33,35 @@ produce the Windows executables and installer.
|
||||
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
|
||||
===
|
||||
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():
|
||||
"""Create the "already running" popup."""
|
||||
import tkinter as tk
|
||||
from tkinter import ttk
|
||||
# Check for CL arg that suppresses this popup.
|
||||
if args.suppress_dupe_process_popup:
|
||||
sys.exit(0)
|
||||
@ -1547,7 +1549,7 @@ class AppWindow:
|
||||
self.w.update_idletasks()
|
||||
|
||||
# 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'):
|
||||
config.set('cmdrs', config.get_list('cmdrs', default=[]) + [monitor.cmdr])
|
||||
self.login()
|
||||
@ -1565,7 +1567,7 @@ class AppWindow:
|
||||
logger.trace_if('journal.queue', 'Startup, returning')
|
||||
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')
|
||||
|
||||
# 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_bad.wav",
|
||||
"modules.p", # TODO: Remove in 6.0
|
||||
"resources/modules.json",
|
||||
"resources/ships.json",
|
||||
"modules.json",
|
||||
"ships.json",
|
||||
"ships.p", # TODO: Remove in 6.0
|
||||
f"{app_name}.VisualElementsManifest.xml",
|
||||
f"{app_name}.ico",
|
||||
|
@ -54,7 +54,7 @@ appcmdname = 'EDMC'
|
||||
# <https://semver.org/#semantic-versioning-specification-semver>
|
||||
# Major.Minor.Patch(-prerelease)(+buildmetadata)
|
||||
# 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
|
||||
copyright = '© 2015-2019 Jonathan Harris, 2020-2023 EDCD'
|
||||
@ -81,15 +81,15 @@ else:
|
||||
_T = TypeVar('_T')
|
||||
|
||||
|
||||
def git_shorthash_from_head() -> str:
|
||||
def git_shorthash_from_head() -> str | None:
|
||||
"""
|
||||
Determine short hash for current git 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:
|
||||
git_cmd = subprocess.Popen(
|
||||
@ -99,14 +99,14 @@ def git_shorthash_from_head() -> str:
|
||||
)
|
||||
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}")
|
||||
|
||||
else:
|
||||
shorthash = out.decode().rstrip('\n')
|
||||
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")
|
||||
shorthash = None # type: ignore
|
||||
shorthash = None
|
||||
|
||||
if shorthash is not None:
|
||||
with contextlib.suppress(Exception):
|
||||
@ -134,13 +134,19 @@ def appversion() -> semantic_version.Version:
|
||||
# Running frozen, so we should have a .gitversion file
|
||||
# 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:
|
||||
shorthash = gitv.read()
|
||||
shorthash: str | None = gitv.read()
|
||||
|
||||
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()
|
||||
if shorthash is None:
|
||||
shorthash = 'UNKNOWN'
|
||||
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'
|
||||
|
||||
_cached_version = semantic_version.Version(f'{_static_appversion}+{shorthash}')
|
||||
return _cached_version
|
||||
|
@ -57,7 +57,7 @@ if __name__ == "__main__":
|
||||
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
|
||||
with open("resources/ships.json", "w") as ships_file:
|
||||
with open("ships.json", "w") as ships_file:
|
||||
json.dump(ships, ships_file, indent=4)
|
||||
|
||||
# Module masses
|
||||
@ -92,5 +92,5 @@ if __name__ == "__main__":
|
||||
add(modules, 'hpt_multicannon_fixed_medium_advanced', {'mass': 4})
|
||||
|
||||
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)
|
||||
|
@ -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 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:
|
||||
ships = json.load(ships_file_handle)
|
||||
|
||||
|
@ -211,12 +211,12 @@ class MacHotkeyMgr(AbstractHotkeyMgr):
|
||||
return False
|
||||
|
||||
# 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
|
||||
return None
|
||||
|
||||
# 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()
|
||||
self.acquire_state = MacHotkeyMgr.ACQUIRE_INACTIVE
|
||||
return None
|
||||
|
@ -284,23 +284,23 @@ class WindowsHotkeyMgr(AbstractHotkeyMgr):
|
||||
| ((GetKeyState(VK_RWIN) & 0x8000) and MOD_WIN)
|
||||
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
|
||||
|
||||
if not modifiers:
|
||||
if keycode == VK_ESCAPE: # Esc = retain previous
|
||||
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
|
||||
|
||||
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
|
||||
winsound.MessageBeep()
|
||||
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
|
||||
return 0, modifiers
|
||||
|
||||
|
2
l10n.py
2
l10n.py
@ -25,7 +25,7 @@ from config import config
|
||||
from EDMCLogging import get_main_logger
|
||||
|
||||
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
|
||||
try:
|
||||
|
@ -57,7 +57,7 @@ def lookup(module, ship_map, entitled=False) -> dict | None: # noqa: C901, CCR0
|
||||
"""
|
||||
# Lazily populate
|
||||
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()))
|
||||
|
||||
if not module.get('name'):
|
||||
@ -79,7 +79,7 @@ def lookup(module, ship_map, entitled=False) -> dict | None: # noqa: C901, CCR0
|
||||
new['rating'] = 'I'
|
||||
|
||||
# Skip uninteresting stuff - some no longer present in ED 3.1 cAPI data
|
||||
elif (name[0] in [
|
||||
elif (name[0] in (
|
||||
'bobble',
|
||||
'decal',
|
||||
'nameplate',
|
||||
@ -87,7 +87,7 @@ def lookup(module, ship_map, entitled=False) -> dict | None: # noqa: C901, CCR0
|
||||
'enginecustomisation',
|
||||
'voicepack',
|
||||
'weaponcustomisation'
|
||||
]
|
||||
)
|
||||
or name[1].startswith('shipkit')):
|
||||
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.
|
||||
(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')
|
||||
|
||||
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')
|
||||
|
||||
else:
|
||||
|
4
plug.py
4
plug.py
@ -165,7 +165,7 @@ def load_plugins(master: tk.Tk) -> None:
|
||||
def _load_internal_plugins():
|
||||
internal = []
|
||||
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:
|
||||
plugin = Plugin(name[:-3], os.path.join(config.internal_plugin_dir_path, name), logger)
|
||||
plugin.folder = None
|
||||
@ -184,7 +184,7 @@ def _load_found_plugins():
|
||||
|
||||
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())):
|
||||
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
|
||||
elif name.endswith('.disabled'):
|
||||
name, discard = name.rsplit('.', 1)
|
||||
|
@ -918,7 +918,7 @@ def journal_entry( # noqa: C901, CCR001
|
||||
])
|
||||
|
||||
# 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
|
||||
('starsystemNameTarget', 'DestinationSystem'),
|
||||
('stationNameTarget', 'DestinationStation'),
|
||||
@ -932,7 +932,7 @@ def journal_entry( # noqa: C901, CCR001
|
||||
('passengerCount', 'PassengerCount'),
|
||||
('passengerIsVIP', 'PassengerVIPs'),
|
||||
('passengerIsWanted', 'PassengerWanted'),
|
||||
]:
|
||||
):
|
||||
|
||||
if prop in entry:
|
||||
data[iprop] = entry[prop]
|
||||
@ -1295,7 +1295,7 @@ def journal_entry( # noqa: C901, CCR001
|
||||
|
||||
# Friends
|
||||
if event_name == 'Friends':
|
||||
if entry['Status'] in ['Added', 'Online']:
|
||||
if entry['Status'] in ('Added', 'Online'):
|
||||
new_add_event(
|
||||
'addCommanderFriend',
|
||||
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(
|
||||
'delCommanderFriend',
|
||||
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', {})
|
||||
if not config.shutting_down:
|
||||
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', {})
|
||||
if not config.shutting_down:
|
||||
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),
|
||||
# or venv-init-time version. Specify here so that dependabot will prod us
|
||||
# about new versions.
|
||||
setuptools==69.0.2
|
||||
setuptools==69.0.3
|
||||
|
||||
# Static analysis tools
|
||||
flake8==6.1.0
|
||||
@ -18,17 +18,17 @@ flake8-noqa==1.3.2
|
||||
flake8-polyfill==1.0.2
|
||||
flake8-use-fstring==1.4
|
||||
|
||||
mypy==1.7.1
|
||||
mypy==1.8.0
|
||||
pep8-naming==0.13.3
|
||||
safety==2.3.5
|
||||
types-requests==2.31.0.10
|
||||
types-requests==2.31.0.20231231
|
||||
types-pkg-resources==0.1.3
|
||||
|
||||
# Code formatting tools
|
||||
autopep8==2.0.4
|
||||
|
||||
# Git pre-commit checking
|
||||
pre-commit==3.5.0
|
||||
pre-commit==3.6.0
|
||||
|
||||
# HTML changelogs
|
||||
grip==4.6.2
|
||||
@ -40,7 +40,7 @@ py2exe==0.13.0.1; sys_platform == 'win32'
|
||||
# Testing
|
||||
pytest==7.4.3
|
||||
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
|
||||
# For manipulating folder permissions and the like.
|
||||
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.
|
||||
See LICENSE file.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import csv
|
||||
import json
|
||||
import sys
|
||||
@ -22,7 +24,7 @@ from monitor import monitor
|
||||
logger = EDMCLogging.get_main_logger()
|
||||
|
||||
if TYPE_CHECKING:
|
||||
def _(x: str) -> str: ...
|
||||
def _(x: str) -> str: return x
|
||||
|
||||
if sys.platform == 'win32':
|
||||
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:
|
||||
# Format described here: https://github.com/eyeonus/Trade-Dangerous/wiki/Price-Data
|
||||
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()
|
||||
h.write(
|
||||
f'# Created by {applongname} {appversion()} on {this_platform} for Cmdr {cmdr_name}.\n'.encode('utf-8')
|
||||
|
@ -296,7 +296,7 @@ class OldConfig:
|
||||
None,
|
||||
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
|
||||
|
||||
|
@ -22,20 +22,21 @@ from __future__ import annotations
|
||||
|
||||
import sys
|
||||
import tkinter as tk
|
||||
import warnings
|
||||
import webbrowser
|
||||
from tkinter import font as tk_font
|
||||
from tkinter import ttk
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
if TYPE_CHECKING:
|
||||
def _(x: str) -> str: ...
|
||||
def _(x: str) -> str: return x
|
||||
|
||||
|
||||
# FIXME: Split this into multi-file module to separate the platforms
|
||||
class HyperlinkLabel(sys.platform == 'darwin' and tk.Label or ttk.Label): # type: ignore
|
||||
"""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.
|
||||
|
||||
@ -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:
|
||||
"""Change cursor and appearance depending on state and text."""
|
||||
# This class' state
|
||||
for thing in ['url', 'popup_copy', 'underline']:
|
||||
for thing in ('url', 'popup_copy', 'underline'):
|
||||
if thing in kw:
|
||||
setattr(self, thing, kw.pop(thing))
|
||||
for thing in ['foreground', 'disabledforeground']:
|
||||
for thing in ('foreground', 'disabledforeground'):
|
||||
if thing in kw:
|
||||
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
|
||||
if url:
|
||||
self._leave(event) # Remove underline before we change window to browser
|
||||
openurl(url)
|
||||
webbrowser.open(url)
|
||||
|
||||
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):
|
||||
@ -183,4 +184,6 @@ def openurl(url: str) -> None:
|
||||
ended up using `webbrowser.open()` *anyway*.
|
||||
:param url: URL to open.
|
||||
"""
|
||||
warnings.warn("This function is deprecated. "
|
||||
"Please use `webbrowser.open() instead.", DeprecationWarning, stacklevel=2)
|
||||
webbrowser.open(url)
|
||||
|
Loading…
x
Reference in New Issue
Block a user