From 7f47c19d1bb230dfc78cb21364bb29c5022fc77e Mon Sep 17 00:00:00 2001 From: David Sangrey Date: Tue, 24 Sep 2024 19:54:22 -0400 Subject: [PATCH 1/8] [Minor] Spelling is Hard --- ChangeLog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog.md b/ChangeLog.md index 7d289839f..5ff403aea 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -10,7 +10,7 @@ Release 5.12.0 === This release brings a number of performance enhancements and functionality updates requested by the community to EDMC. -Notably, integration with Inara's SLEF notation, custom pugin directories, streamlined logging locations, and +Notably, integration with Inara's SLEF notation, custom plugin directories, streamlined logging locations, and performance enhancements are included. This release also fixes a few administrative issues regarding licenses to ensure compliance with included libraries. From 348ad1d75fcdd15bdcfaba8f75681fc7e87f6c8e Mon Sep 17 00:00:00 2001 From: David Sangrey Date: Sun, 29 Sep 2024 11:03:33 -0400 Subject: [PATCH 2/8] [#2297] Temporary Fix for max() arg empty --- EDMC.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EDMC.py b/EDMC.py index ce0db95b2..743bda5d1 100755 --- a/EDMC.py +++ b/EDMC.py @@ -228,9 +228,9 @@ def main(): # noqa: C901, CCR001 # Get state from latest Journal file logger.debug('Getting state from latest journal file') try: - monitor.currentdir = Path(config.get_str('journaldir', default=config.default_journal_dir)) + monitor.currentdir = config.get_str('journaldir', default=config.default_journal_dir) if not monitor.currentdir: - monitor.currentdir = config.default_journal_dir_path + monitor.currentdir = config.default_journal_dir logger.debug(f'logdir = "{monitor.currentdir}"') logfile = monitor.journal_newest_filename(monitor.currentdir) From 5ad7fcfa622fc4d93f453df7d858c3db4fb194b4 Mon Sep 17 00:00:00 2001 From: David Sangrey Date: Mon, 30 Sep 2024 18:42:09 -0400 Subject: [PATCH 3/8] [2303] Attempt Reversion --- EDMC.py | 7 ++----- EDMCSystemProfiler.py | 17 ++++++++--------- monitor.py | 36 ++++++++++++++++++------------------ prefs.py | 10 +++++----- 4 files changed, 33 insertions(+), 37 deletions(-) diff --git a/EDMC.py b/EDMC.py index 743bda5d1..6b72c7d1c 100755 --- a/EDMC.py +++ b/EDMC.py @@ -14,7 +14,6 @@ import os import queue import sys -from pathlib import Path from time import sleep, time from typing import TYPE_CHECKING, Any @@ -213,16 +212,14 @@ def main(): # noqa: C901, CCR001 # system, chances are its the current locale, and not utf-8. Otherwise if it was copied, its probably # utf8. Either way, try the system FIRST because reading something like cp1251 in UTF-8 results in garbage # but the reverse results in an exception. - json_file = Path(args.j).resolve() + json_file = os.path.abspath(args.j) try: with open(json_file) as file_handle: data = json.load(file_handle) except UnicodeDecodeError: with open(json_file, encoding='utf-8') as file_handle: data = json.load(file_handle) - file_path = Path(args.j) - modification_time = file_path.stat().st_mtime - config.set('querytime', int(modification_time)) + config.set('querytime', int(os.path.getmtime(args.j))) else: # Get state from latest Journal file diff --git a/EDMCSystemProfiler.py b/EDMCSystemProfiler.py index 77212db7a..92502cc8b 100644 --- a/EDMCSystemProfiler.py +++ b/EDMCSystemProfiler.py @@ -11,7 +11,7 @@ import webbrowser import platform import sys -from os import chdir, environ +from os import chdir, environ, path import pathlib import logging from journal_lock import JournalLock @@ -19,10 +19,10 @@ if getattr(sys, "frozen", False): # Under py2exe sys.path[0] is the executable name if sys.platform == "win32": - chdir(pathlib.Path(sys.path[0]).parent) + chdir(path.dirname(sys.path[0])) # Allow executable to be invoked from any cwd - environ['TCL_LIBRARY'] = str(pathlib.Path(sys.path[0]).parent / 'lib' / 'tcl') - environ['TK_LIBRARY'] = str(pathlib.Path(sys.path[0]).parent / 'lib' / 'tk') + environ["TCL_LIBRARY"] = path.join(path.dirname(sys.path[0]), "lib", "tcl") + environ["TK_LIBRARY"] = path.join(path.dirname(sys.path[0]), "lib", "tk") else: # We still want to *try* to have CWD be where the main script is, even if @@ -44,12 +44,11 @@ def get_sys_report(config: config.AbstractConfig) -> str: plt = platform.uname() locale.setlocale(locale.LC_ALL, "") lcl = locale.getlocale() - monitor.currentdir = pathlib.Path(config.get_str( + monitor.currentdir = config.get_str( "journaldir", default=config.default_journal_dir - ) ) if not monitor.currentdir: - monitor.currentdir = config.default_journal_dir_path + monitor.currentdir = config.default_journal_dir try: logfile = monitor.journal_newest_filename(monitor.currentdir) if logfile is None: @@ -116,12 +115,12 @@ def main() -> None: root.withdraw() # Hide the window initially to calculate the dimensions try: icon_image = tk.PhotoImage( - file=cur_config.respath_path / "io.edcd.EDMarketConnector.png" + file=path.join(cur_config.respath_path, "io.edcd.EDMarketConnector.png") ) root.iconphoto(True, icon_image) except tk.TclError: - root.iconbitmap(cur_config.respath_path / "EDMarketConnector.ico") + root.iconbitmap(path.join(cur_config.respath_path, "EDMarketConnector.ico")) sys_report = get_sys_report(cur_config) diff --git a/monitor.py b/monitor.py index ce6b60759..e19d6ad56 100644 --- a/monitor.py +++ b/monitor.py @@ -8,7 +8,7 @@ from __future__ import annotations import json -from pathlib import Path +import pathlib import queue import re import sys @@ -16,6 +16,7 @@ from calendar import timegm from collections import defaultdict from os import SEEK_END, SEEK_SET, listdir +from os.path import basename, expanduser, getctime, isdir, join from time import gmtime, localtime, mktime, sleep, strftime, strptime, time from typing import TYPE_CHECKING, Any, BinaryIO, MutableMapping import psutil @@ -67,7 +68,7 @@ def __init__(self) -> None: # TODO(A_D): A bunch of these should be switched to default values (eg '' for strings) and no longer be Optional FileSystemEventHandler.__init__(self) # futureproofing - not need for current version of watchdog self.root: 'tkinter.Tk' = None # type: ignore # Don't use Optional[] - mypy thinks no methods - self.currentdir: Path | None = None # The actual logdir that we're monitoring + self.currentdir: str | None = None # The actual logdir that we're monitoring self.logfile: str | None = None self.observer: BaseObserver | None = None self.observed = None # a watchdog ObservedWatch, or None if polling @@ -190,9 +191,9 @@ def start(self, root: 'tkinter.Tk') -> bool: # noqa: CCR001 if journal_dir == '' or journal_dir is None: journal_dir = config.default_journal_dir - logdir = Path(journal_dir).expanduser() + logdir = expanduser(journal_dir) - if not logdir or not Path.is_dir(logdir): + if not logdir or not isdir(logdir): logger.error(f'Journal Directory is invalid: "{logdir}"') self.stop() return False @@ -265,10 +266,9 @@ def journal_newest_filename(self, journals_dir) -> str | None: # Odyssey Update 11 has, e.g. Journal.2022-03-15T152503.01.log # Horizons Update 11 equivalent: Journal.220315152335.01.log # So we can no longer use a naive sort. - journals_dir_path = Path(journals_dir) - journal_files = (journals_dir_path / Path(x) for x in journal_files) - latest_file = max(journal_files, key=lambda f: Path(f).stat().st_ctime) - return str(latest_file) + journals_dir_path = pathlib.Path(journals_dir) + journal_files = (journals_dir_path / pathlib.Path(x) for x in journal_files) + return str(max(journal_files, key=getctime)) return None @@ -337,7 +337,7 @@ def running(self) -> bool: def on_created(self, event: 'FileSystemEvent') -> None: """Watchdog callback when, e.g. client (re)started.""" - if not event.is_directory and self._RE_LOGFILE.search(Path(event.src_path).name): + if not event.is_directory and self._RE_LOGFILE.search(basename(event.src_path)): self.logfile = event.src_path @@ -1076,7 +1076,7 @@ def parse_entry(self, line: bytes) -> MutableMapping[str, Any]: # noqa: C901, C self.state['Cargo'] = defaultdict(int) # From 3.3 full Cargo event (after the first one) is written to a separate file if 'Inventory' not in entry: - with open(self.currentdir / 'Cargo.json', 'rb') as h: # type: ignore + with open(join(self.currentdir, 'Cargo.json'), 'rb') as h: # type: ignore entry = json.load(h) self.state['CargoJSON'] = entry @@ -1103,7 +1103,7 @@ def parse_entry(self, line: bytes) -> MutableMapping[str, Any]: # noqa: C901, C # Always attempt loading of this, but if it fails we'll hope this was # a startup/boarding version and thus `entry` contains # the data anyway. - currentdir_path = Path(str(self.currentdir)) + currentdir_path = pathlib.Path(str(self.currentdir)) shiplocker_filename = currentdir_path / 'ShipLocker.json' shiplocker_max_attempts = 5 shiplocker_fail_sleep = 0.01 @@ -1172,7 +1172,7 @@ def parse_entry(self, line: bytes) -> MutableMapping[str, Any]: # noqa: C901, C # TODO: v31 doc says this is`backpack.json` ... but Howard Chalkley # said it's `Backpack.json` - backpack_file = Path(str(self.currentdir)) / 'Backpack.json' + backpack_file = pathlib.Path(str(self.currentdir)) / 'Backpack.json' backpack_data = None if not backpack_file.exists(): @@ -1548,7 +1548,7 @@ def parse_entry(self, line: bytes) -> MutableMapping[str, Any]: # noqa: C901, C entry = fcmaterials elif event_type == 'moduleinfo': - with open(self.currentdir / 'ModulesInfo.json', 'rb') as mf: # type: ignore + with open(join(self.currentdir, 'ModulesInfo.json'), 'rb') as mf: # type: ignore try: entry = json.load(mf) @@ -2259,14 +2259,14 @@ def export_ship(self, filename=None) -> None: # noqa: C901, CCR001 oldfiles = sorted((x for x in listdir(config.get_str('outdir')) if regexp.match(x))) if oldfiles: try: - with open(config.get_str('outdir') / Path(oldfiles[-1]), encoding='utf-8') as h: + with open(join(config.get_str('outdir'), oldfiles[-1]), encoding='utf-8') as h: if h.read() == string: return # same as last time - don't write except UnicodeError: logger.exception("UnicodeError reading old ship loadout with utf-8 encoding, trying without...") try: - with open(config.get_str('outdir') / Path(oldfiles[-1])) as h: + with open(join(config.get_str('outdir'), oldfiles[-1])) as h: if h.read() == string: return # same as last time - don't write @@ -2285,7 +2285,7 @@ def export_ship(self, filename=None) -> None: # noqa: C901, CCR001 # Write ts = strftime('%Y-%m-%dT%H.%M.%S', localtime(time())) - filename = config.get_str('outdir') / Path(f'{ship}.{ts}.txt') + filename = join(config.get_str('outdir'), f'{ship}.{ts}.txt') try: with open(filename, 'wt', encoding='utf-8') as h: @@ -2372,7 +2372,7 @@ def _parse_navroute_file(self) -> dict[str, Any] | None: try: - with open(self.currentdir / 'NavRoute.json') as f: + with open(join(self.currentdir, 'NavRoute.json')) as f: raw = f.read() except Exception as e: @@ -2398,7 +2398,7 @@ def _parse_fcmaterials_file(self) -> dict[str, Any] | None: try: - with open(self.currentdir / 'FCMaterials.json') as f: + with open(join(self.currentdir, 'FCMaterials.json')) as f: raw = f.read() except Exception as e: diff --git a/prefs.py b/prefs.py index 29e1e7b13..95f29e7fc 100644 --- a/prefs.py +++ b/prefs.py @@ -4,7 +4,7 @@ import contextlib import logging -from os.path import expandvars +from os.path import expandvars, join, normpath from pathlib import Path import subprocess import sys @@ -1100,7 +1100,7 @@ def displaypath(self, pathvar: tk.StringVar, entryfield: tk.Entry) -> None: if sys.platform == 'win32': start = len(config.home.split('\\')) if pathvar.get().lower().startswith(config.home.lower()) else 0 display = [] - components = Path(pathvar.get()).resolve().parts + components = normpath(pathvar.get()).split('\\') buf = ctypes.create_unicode_buffer(MAX_PATH) pidsRes = ctypes.c_int() # noqa: N806 # Windows convention for i in range(start, len(components)): @@ -1253,7 +1253,7 @@ def apply(self) -> None: # noqa: CCR001 config.set( 'outdir', - str(config.home_path / self.outdir.get()[2:]) if self.outdir.get().startswith('~') else self.outdir.get() + join(config.home_path, self.outdir.get()[2:]) if self.outdir.get().startswith('~') else self.outdir.get() ) logdir = self.logdir.get() @@ -1296,8 +1296,8 @@ def apply(self) -> None: # noqa: CCR001 if self.plugdir.get() != config.get('plugin_dir'): config.set( 'plugin_dir', - str(Path(config.home_path, self.plugdir.get()[2:])) if self.plugdir.get().startswith('~') else - str(Path(self.plugdir.get())) + join(config.home_path, self.plugdir.get()[2:]) if self.plugdir.get().startswith( + '~') else self.plugdir.get() ) self.req_restart = True From 9db7e9b2dacff1dd757c49ff83de0c7d411e7371 Mon Sep 17 00:00:00 2001 From: David Sangrey Date: Mon, 30 Sep 2024 22:46:05 -0400 Subject: [PATCH 4/8] [PRE-RELEASE] 5.12.1-rc1 --- ChangeLog.md | 23 +++++++++++++++++++++++ config/__init__.py | 2 +- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/ChangeLog.md b/ChangeLog.md index 5ff403aea..1f1d11fdd 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -6,6 +6,29 @@ This is the master changelog for Elite Dangerous Market Connector. Entries are in the source (not distributed with the Windows installer) for the currently used version. --- +Pre-Release 5.12.1-rc1 +=== + +This is a release candidate for 5.12.1. It has been pushed to the "Beta" track for updates! + +This release fixes a pair of widely-reported bugs with EDMC authentication. + +**Changes and Enhancements** +* Fixed a typo in the prior release notes + +**Bug Fixes** +* Fixed a bug where the EDMC System Profiler wouldn't load details properly +* Reverted a number of usages of Pathlib back to os.path for further validation testing +* Fixed a bug where EDMC would error out with a max() ValueError + +**Plugin Developers** +* nb.Entry is deprecated, and is slated for removal in 6.0 or later. Please migrate to nb.EntryMenu +* nb.ColoredButton is deprecated, and is slated for removal in 6.0 or later. Please migrate to tk.Button +* Calling internal translations with `_()` is deprecated, and is slated for removal in 6.0 or later. Please migrate to importing `translations` and calling `translations.translate` or `translations.tl` directly +* `Translations` as the translate system singleton is deprecated, and is slated for removal in 6.0 or later. Please migrate to the `translations` singleton +* `help_open_log_folder()` is deprecated, and is slated for removal in 6.0 or later. Please migrate to open_folder() +* `update_feed` is deprecated, and is slated for removal in 6.0 or later. Please migrate to `get_update_feed()`. + Release 5.12.0 === diff --git a/config/__init__.py b/config/__init__.py index ec5a345c2..798979845 100644 --- a/config/__init__.py +++ b/config/__init__.py @@ -52,7 +52,7 @@ # # Major.Minor.Patch(-prerelease)(+buildmetadata) # NB: Do *not* import this, use the functions appversion() and appversion_nobuild() -_static_appversion = '5.12.0' +_static_appversion = '5.12.1-beta1' _cached_version: semantic_version.Version | None = None copyright = '© 2015-2019 Jonathan Harris, 2020-2024 EDCD' From 0cfc4873c6644d26f12770aa4042be53517754d7 Mon Sep 17 00:00:00 2001 From: David Sangrey Date: Mon, 30 Sep 2024 22:58:16 -0400 Subject: [PATCH 5/8] [RELEASE] 5.12.1-rc2 --- ChangeLog.md | 2 +- config/__init__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index 1f1d11fdd..151d4376c 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -6,7 +6,7 @@ This is the master changelog for Elite Dangerous Market Connector. Entries are in the source (not distributed with the Windows installer) for the currently used version. --- -Pre-Release 5.12.1-rc1 +Pre-Release 5.12.1-rc2 === This is a release candidate for 5.12.1. It has been pushed to the "Beta" track for updates! diff --git a/config/__init__.py b/config/__init__.py index 798979845..d9ff3b796 100644 --- a/config/__init__.py +++ b/config/__init__.py @@ -52,7 +52,7 @@ # # Major.Minor.Patch(-prerelease)(+buildmetadata) # NB: Do *not* import this, use the functions appversion() and appversion_nobuild() -_static_appversion = '5.12.1-beta1' +_static_appversion = '5.12.1-rc2' _cached_version: semantic_version.Version | None = None copyright = '© 2015-2019 Jonathan Harris, 2020-2024 EDCD' From ab02f49aba16808511c1ede676306e54871515bb Mon Sep 17 00:00:00 2001 From: David Sangrey Date: Tue, 1 Oct 2024 17:55:54 -0400 Subject: [PATCH 6/8] [#2303] Revert Prototyping for Protocol --- protocol.py | 75 +++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 56 insertions(+), 19 deletions(-) diff --git a/protocol.py b/protocol.py index a0f02f158..f1c1e0c7b 100644 --- a/protocol.py +++ b/protocol.py @@ -69,11 +69,11 @@ def event(self, url: str) -> None: # This could be false if you use auth_force_edmc_protocol, but then you get to keep the pieces assert sys.platform == 'win32' # spell-checker: words HBRUSH HICON WPARAM wstring WNDCLASS HMENU HGLOBAL - from ctypes import ( - windll, WINFUNCTYPE, Structure, byref, c_long, c_void_p, create_unicode_buffer, wstring_at + from ctypes import ( # type: ignore + windll, POINTER, WINFUNCTYPE, Structure, byref, c_long, c_void_p, create_unicode_buffer, wstring_at ) from ctypes.wintypes import ( - ATOM, HBRUSH, HICON, HINSTANCE, HWND, INT, LPARAM, LPCWSTR, LPWSTR, + ATOM, BOOL, DWORD, HBRUSH, HGLOBAL, HICON, HINSTANCE, HMENU, HWND, INT, LPARAM, LPCWSTR, LPMSG, LPVOID, LPWSTR, MSG, UINT, WPARAM ) import win32gui @@ -101,8 +101,40 @@ class WNDCLASS(Structure): ('lpszClassName', LPCWSTR) ] - TranslateMessage = windll.user32.TranslateMessage + CW_USEDEFAULT = 0x80000000 + + CreateWindowExW = windll.user32.CreateWindowExW + CreateWindowExW.argtypes = [DWORD, LPCWSTR, LPCWSTR, DWORD, INT, INT, INT, INT, HWND, HMENU, HINSTANCE, LPVOID] + CreateWindowExW.restype = HWND + RegisterClassW = windll.user32.RegisterClassW + RegisterClassW.argtypes = [POINTER(WNDCLASS)] + # DefWindowProcW + # Ref: + # LRESULT DefWindowProcW([in] HWND hWnd,[in] UINT Msg,[in] WPARAM wParam,[in] LPARAM lParam); + # As per example at + + prototype = WINFUNCTYPE(c_long, HWND, UINT, WPARAM, LPARAM) + paramflags = (1, "hWnd"), (1, "Msg"), (1, "wParam"), (1, "lParam") + GetParent = windll.user32.GetParent + SetForegroundWindow = windll.user32.SetForegroundWindow + + # + # NB: Despite 'BOOL' return type, it *can* be >0, 0 or -1, so is actually + # c_long + prototype = WINFUNCTYPE(c_long, LPMSG, HWND, UINT, UINT) + paramflags = (1, "lpMsg"), (1, "hWnd"), (1, "wMsgFilterMin"), (1, "wMsgFilterMax") + GetMessageW = prototype(("GetMessageW", windll.user32), paramflags) + + TranslateMessage = windll.user32.TranslateMessage + DispatchMessageW = windll.user32.DispatchMessageW + PostThreadMessageW = windll.user32.PostThreadMessageW + SendMessageW = windll.user32.SendMessageW + SendMessageW.argtypes = [HWND, UINT, WPARAM, LPARAM] + PostMessageW = windll.user32.PostMessageW + PostMessageW.argtypes = [HWND, UINT, WPARAM, LPARAM] + + WM_QUIT = 0x0012 # https://docs.microsoft.com/en-us/windows/win32/dataxchg/wm-dde-initiate WM_DDE_INITIATE = 0x03E0 WM_DDE_TERMINATE = 0x03E1 @@ -118,6 +150,12 @@ class WNDCLASS(Structure): GlobalGetAtomNameW = windll.kernel32.GlobalGetAtomNameW GlobalGetAtomNameW.argtypes = [ATOM, LPWSTR, INT] GlobalGetAtomNameW.restype = UINT + GlobalLock = windll.kernel32.GlobalLock + GlobalLock.argtypes = [HGLOBAL] + GlobalLock.restype = LPVOID + GlobalUnlock = windll.kernel32.GlobalUnlock + GlobalUnlock.argtypes = [HGLOBAL] + GlobalUnlock.restype = BOOL # Windows Message handler stuff (IPC) # https://docs.microsoft.com/en-us/previous-versions/windows/desktop/legacy/ms633573(v=vs.85) @@ -160,7 +198,7 @@ def WndProc(hwnd: HWND, message: UINT, wParam: WPARAM, lParam: LPARAM) -> c_long if target_is_valid and topic_is_valid: # if everything is happy, send an acknowledgement of the DDE request - win32gui.SendMessage( + SendMessageW( wParam, WM_DDE_ACK, hwnd, PackDDElParam(WM_DDE_ACK, GlobalAddAtomW(appname), GlobalAddAtomW('System')) ) @@ -193,7 +231,7 @@ def close(self) -> None: thread = self.thread if thread: self.thread = None - win32api.PostThreadMessage(thread.ident, win32con.WM_QUIT, 0, 0) + PostThreadMessageW(thread.ident, WM_QUIT, 0, 0) thread.join() # Wait for it to quit def worker(self) -> None: @@ -203,25 +241,24 @@ def worker(self) -> None: wndclass.lpfnWndProc = WndProc wndclass.cbClsExtra = 0 wndclass.cbWndExtra = 0 - wndclass.hInstance = win32gui.GetModuleHandle(0) + wndclass.hInstance = windll.kernel32.GetModuleHandleW(0) wndclass.hIcon = None wndclass.hCursor = None wndclass.hbrBackground = None wndclass.lpszMenuName = None wndclass.lpszClassName = 'DDEServer' - if not win32gui.RegisterClass(byref(wndclass)): + if not RegisterClassW(byref(wndclass)): print('Failed to register Dynamic Data Exchange for cAPI') return # https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-createwindowexw - hwnd = win32gui.CreateWindowEx( + hwnd = CreateWindowExW( 0, # dwExStyle wndclass.lpszClassName, # lpClassName "DDE Server", # lpWindowName 0, # dwStyle - # X, Y, nWidth, nHeight - win32con.CW_USEDEFAULT, win32con.CW_USEDEFAULT, win32con.CW_USEDEFAULT, win32con.CW_USEDEFAULT, + CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, # X, Y, nWidth, nHeight self.master.winfo_id(), # hWndParent # Don't use HWND_MESSAGE since the window won't get DDE broadcasts None, # hMenu wndclass.hInstance, # hInstance @@ -241,13 +278,13 @@ def worker(self) -> None: # # But it does actually work. Either getting a non-0 value and # entering the loop, or getting 0 and exiting it. - while win32gui.GetMessage(byref(msg), None, 0, 0) != 0: + while GetMessageW(byref(msg), None, 0, 0) != 0: logger.trace_if('frontier-auth.windows', f'DDE message of type: {msg.message}') if msg.message == WM_DDE_EXECUTE: # GlobalLock does some sort of "please dont move this?" # https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-globallock - args = wstring_at(win32gui.GlobalLock(msg.lParam)).strip() - win32gui.GlobalUnlock(msg.lParam) # Unlocks the GlobalLock-ed object + args = wstring_at(GlobalLock(msg.lParam)).strip() + GlobalUnlock(msg.lParam) # Unlocks the GlobalLock-ed object if args.lower().startswith('open("') and args.endswith('")'): logger.trace_if('frontier-auth.windows', f'args are: {args}') @@ -256,20 +293,20 @@ def worker(self) -> None: logger.debug(f'Message starts with {self.redirect}') self.event(url) - win32gui.SetForegroundWindow(win32gui.GetParent(self.master.winfo_id())) # raise app window + SetForegroundWindow(GetParent(self.master.winfo_id())) # raise app window # Send back a WM_DDE_ACK. this is _required_ with WM_DDE_EXECUTE - win32gui.PostMessage(msg.wParam, WM_DDE_ACK, hwnd, PackDDElParam(WM_DDE_ACK, 0x80, msg.lParam)) + PostMessageW(msg.wParam, WM_DDE_ACK, hwnd, PackDDElParam(WM_DDE_ACK, 0x80, msg.lParam)) else: # Send back a WM_DDE_ACK. this is _required_ with WM_DDE_EXECUTE - win32gui.PostMessage(msg.wParam, WM_DDE_ACK, hwnd, PackDDElParam(WM_DDE_ACK, 0, msg.lParam)) + PostMessageW(msg.wParam, WM_DDE_ACK, hwnd, PackDDElParam(WM_DDE_ACK, 0, msg.lParam)) elif msg.message == WM_DDE_TERMINATE: - win32gui.PostMessage(msg.wParam, WM_DDE_TERMINATE, hwnd, 0) + PostMessageW(msg.wParam, WM_DDE_TERMINATE, hwnd, 0) else: TranslateMessage(byref(msg)) # "Translates virtual key messages into character messages" ??? - win32gui.DispatchMessage(byref(msg)) + DispatchMessageW(byref(msg)) else: # Linux / Run from source From dab510bb213f89cd8d4fcac136e28004c64be283 Mon Sep 17 00:00:00 2001 From: David Sangrey Date: Tue, 1 Oct 2024 18:23:06 -0400 Subject: [PATCH 7/8] [PRE-RELEASE] .12.1-rc4 --- ChangeLog.md | 25 +++++++++++++++++++++++++ config/__init__.py | 2 +- protocol.py | 11 +---------- 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index 151d4376c..14461b1b2 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -6,6 +6,31 @@ This is the master changelog for Elite Dangerous Market Connector. Entries are in the source (not distributed with the Windows installer) for the currently used version. --- +Pre-Release 5.12.1-rc4 +=== + +This is a release candidate for 5.12.1. It has been pushed to the "Beta" track for updates! + +This release continues to refine fixes for with EDMC authentication. + +**Changes and Enhancements** +* Fixed a typo in the prior release notes + +**Bug Fixes** +* Fixed a bug where the EDMC System Profiler wouldn't load details properly +* Reverted a number of usages of Pathlib back to os.path for further validation testing +* Fixed a bug where EDMC would error out with a max() ValueError +* Fixed an issue where the EDMC protocol wouldn't be processed properly via prototyping + +**Plugin Developers** +* nb.Entry is deprecated, and is slated for removal in 6.0 or later. Please migrate to nb.EntryMenu +* nb.ColoredButton is deprecated, and is slated for removal in 6.0 or later. Please migrate to tk.Button +* Calling internal translations with `_()` is deprecated, and is slated for removal in 6.0 or later. Please migrate to importing `translations` and calling `translations.translate` or `translations.tl` directly +* `Translations` as the translate system singleton is deprecated, and is slated for removal in 6.0 or later. Please migrate to the `translations` singleton +* `help_open_log_folder()` is deprecated, and is slated for removal in 6.0 or later. Please migrate to open_folder() +* `update_feed` is deprecated, and is slated for removal in 6.0 or later. Please migrate to `get_update_feed()`. + + Pre-Release 5.12.1-rc2 === diff --git a/config/__init__.py b/config/__init__.py index d9ff3b796..c896b2f88 100644 --- a/config/__init__.py +++ b/config/__init__.py @@ -52,7 +52,7 @@ # # Major.Minor.Patch(-prerelease)(+buildmetadata) # NB: Do *not* import this, use the functions appversion() and appversion_nobuild() -_static_appversion = '5.12.1-rc2' +_static_appversion = '5.12.1-rc4' _cached_version: semantic_version.Version | None = None copyright = '© 2015-2019 Jonathan Harris, 2020-2024 EDCD' diff --git a/protocol.py b/protocol.py index f1c1e0c7b..01be09de8 100644 --- a/protocol.py +++ b/protocol.py @@ -77,8 +77,6 @@ def event(self, url: str) -> None: MSG, UINT, WPARAM ) import win32gui - import win32con - import win32api class WNDCLASS(Structure): """ @@ -108,13 +106,6 @@ class WNDCLASS(Structure): CreateWindowExW.restype = HWND RegisterClassW = windll.user32.RegisterClassW RegisterClassW.argtypes = [POINTER(WNDCLASS)] - # DefWindowProcW - # Ref: - # LRESULT DefWindowProcW([in] HWND hWnd,[in] UINT Msg,[in] WPARAM wParam,[in] LPARAM lParam); - # As per example at - - prototype = WINFUNCTYPE(c_long, HWND, UINT, WPARAM, LPARAM) - paramflags = (1, "hWnd"), (1, "Msg"), (1, "wParam"), (1, "lParam") GetParent = windll.user32.GetParent SetForegroundWindow = windll.user32.SetForegroundWindow @@ -385,7 +376,7 @@ def do_GET(self) -> None: # noqa: N802 # Required to override if self.parse(): self.send_header('Content-Type', 'text/html') self.end_headers() - self.wfile.write(self._generate_auth_response().encode('utf-8')) + self.wfile.write(self._generate_auth_response().encode()) else: self.send_response(404) self.end_headers() From 11d4c0cca1b8a333e8b54b47e8100b85561063ea Mon Sep 17 00:00:00 2001 From: David Sangrey Date: Wed, 2 Oct 2024 19:49:46 -0400 Subject: [PATCH 8/8] [RELEASE] 5.12.1 --- ChangeLog.md | 29 ++--------------------------- config/__init__.py | 2 +- 2 files changed, 3 insertions(+), 28 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index 14461b1b2..d354c6623 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -6,12 +6,10 @@ This is the master changelog for Elite Dangerous Market Connector. Entries are in the source (not distributed with the Windows installer) for the currently used version. --- -Pre-Release 5.12.1-rc4 +Release 5.12.1 === -This is a release candidate for 5.12.1. It has been pushed to the "Beta" track for updates! - -This release continues to refine fixes for with EDMC authentication. +This release fixes a handful of bugs reported with 5.12.0, notably a widely-reported bug with EDMC CAPI Authentication. **Changes and Enhancements** * Fixed a typo in the prior release notes @@ -31,29 +29,6 @@ This release continues to refine fixes for with EDMC authentication. * `update_feed` is deprecated, and is slated for removal in 6.0 or later. Please migrate to `get_update_feed()`. -Pre-Release 5.12.1-rc2 -=== - -This is a release candidate for 5.12.1. It has been pushed to the "Beta" track for updates! - -This release fixes a pair of widely-reported bugs with EDMC authentication. - -**Changes and Enhancements** -* Fixed a typo in the prior release notes - -**Bug Fixes** -* Fixed a bug where the EDMC System Profiler wouldn't load details properly -* Reverted a number of usages of Pathlib back to os.path for further validation testing -* Fixed a bug where EDMC would error out with a max() ValueError - -**Plugin Developers** -* nb.Entry is deprecated, and is slated for removal in 6.0 or later. Please migrate to nb.EntryMenu -* nb.ColoredButton is deprecated, and is slated for removal in 6.0 or later. Please migrate to tk.Button -* Calling internal translations with `_()` is deprecated, and is slated for removal in 6.0 or later. Please migrate to importing `translations` and calling `translations.translate` or `translations.tl` directly -* `Translations` as the translate system singleton is deprecated, and is slated for removal in 6.0 or later. Please migrate to the `translations` singleton -* `help_open_log_folder()` is deprecated, and is slated for removal in 6.0 or later. Please migrate to open_folder() -* `update_feed` is deprecated, and is slated for removal in 6.0 or later. Please migrate to `get_update_feed()`. - Release 5.12.0 === diff --git a/config/__init__.py b/config/__init__.py index c896b2f88..18d3d941d 100644 --- a/config/__init__.py +++ b/config/__init__.py @@ -52,7 +52,7 @@ # # Major.Minor.Patch(-prerelease)(+buildmetadata) # NB: Do *not* import this, use the functions appversion() and appversion_nobuild() -_static_appversion = '5.12.1-rc4' +_static_appversion = '5.12.1' _cached_version: semantic_version.Version | None = None copyright = '© 2015-2019 Jonathan Harris, 2020-2024 EDCD'