From aee4114edd4de51a89ca5dd870389fbba65ad6dd Mon Sep 17 00:00:00 2001 From: Athanasius Date: Fri, 9 Oct 2020 09:50:27 +0100 Subject: [PATCH 01/32] Bug Report Template: git/Linux version info --- .github/ISSUE_TEMPLATE/bug_report.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 91943808..1591a7df 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -12,8 +12,8 @@ assignees: '' **Please also check if the issue is covered in our [Troubleshooting Guide](https://github.com/EDCD/EDMarketConnector/wiki/Troubleshooting).** It might be something with a known work around, or where a third party (such as EDSM) is causing logging that is harmless. **Please complete the following information:** - - Version [e.g. 4.0.6 - See 'Help > About E:D Market Connector'] - - OS: [e.g. Windows 10] + - Version [e.g. 4.0.6 - See 'Help > About E:D Market Connector'. If running from source using git then please paste the output of `git log --decorate=full | head -1`] + - OS: [e.g. Windows 10, Linux Debian 10.6, etc.] - OS Locale: [e.g. English, French, Serbian...] - If applicable: Browser [e.g. chrome, safari] - Please attach log files: From 52d39dc5fd9742fc4c1ce940938c5a08d5e8c7ee Mon Sep 17 00:00:00 2001 From: A_D Date: Wed, 2 Dec 2020 15:54:59 +0200 Subject: [PATCH 02/32] Moved os.environ above logging import --- EDMC.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/EDMC.py b/EDMC.py index fac74186..bc5baba2 100755 --- a/EDMC.py +++ b/EDMC.py @@ -12,17 +12,21 @@ from os.path import getmtime, join from time import sleep, time from typing import TYPE_CHECKING, Any, Optional -# See EDMCLogging.py docs. # isort: off -from EDMCLogging import edmclogger, logger, logging -if TYPE_CHECKING: - from logging import trace, TRACE # type: ignore # noqa: F401 -# isort: on -edmclogger.set_channels_loglevel(logging.INFO) +# See EDMCLogging.py docs. # workaround for https://github.com/EDCD/EDMarketConnector/issues/568 os.environ["EDMC_NO_UI"] = "1" +from EDMCLogging import edmclogger, logger, logging + +if TYPE_CHECKING: + from logging import trace, TRACE # type: ignore # noqa: F401 + +edmclogger.set_channels_loglevel(logging.INFO) + +# isort: on + import collate import commodity import companion From 977e62188aa01417ddf2965d04be0f22452f447b Mon Sep 17 00:00:00 2001 From: A_D Date: Wed, 2 Dec 2020 15:57:42 +0200 Subject: [PATCH 03/32] Made sure to handle non-utf8 locales --- EDMC.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/EDMC.py b/EDMC.py index bc5baba2..e3af1879 100755 --- a/EDMC.py +++ b/EDMC.py @@ -173,7 +173,11 @@ sys.path: {sys.path}''' if args.j: logger.debug('Import and collate from JSON dump') # Import and collate from JSON dump - data = json.load(open(args.j)) + try: + data = json.load(open(args.j)) + except UnicodeDecodeError: + data = json.load(open(args.j, encoding='utf-8')) + config.set('querytime', int(getmtime(args.j))) else: @@ -188,7 +192,7 @@ sys.path: {sys.path}''' logfile = join(logdir, logfiles[-1]) logger.debug(f'Using logfile "{logfile}"') - with open(logfile, 'r') as loghandle: + with open(logfile, 'r', encoding='utf-8') as loghandle: for line in loghandle: try: monitor.parse_entry(line) From 9ec03008ced85632890ebf0db9e10e9168302dc7 Mon Sep 17 00:00:00 2001 From: A_D Date: Wed, 2 Dec 2020 16:03:43 +0200 Subject: [PATCH 04/32] Moved comment to correct place --- EDMC.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EDMC.py b/EDMC.py index e3af1879..9552fa4c 100755 --- a/EDMC.py +++ b/EDMC.py @@ -14,10 +14,10 @@ from typing import TYPE_CHECKING, Any, Optional # isort: off -# See EDMCLogging.py docs. -# workaround for https://github.com/EDCD/EDMarketConnector/issues/568 os.environ["EDMC_NO_UI"] = "1" +# See EDMCLogging.py docs. +# workaround for https://github.com/EDCD/EDMarketConnector/issues/568 from EDMCLogging import edmclogger, logger, logging if TYPE_CHECKING: From 8bb9cecfc0a2f11aeb2132c12876720033670bc7 Mon Sep 17 00:00:00 2001 From: A_D Date: Wed, 2 Dec 2020 16:08:06 +0200 Subject: [PATCH 05/32] Explanation comment on try/except --- EDMC.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/EDMC.py b/EDMC.py index 9552fa4c..04701313 100755 --- a/EDMC.py +++ b/EDMC.py @@ -173,6 +173,11 @@ sys.path: {sys.path}''' if args.j: logger.debug('Import and collate from JSON dump') # Import and collate from JSON dump + # + # Try twice, once with the system locale and once enforcing utf-8. If the file was made on the current + # 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. try: data = json.load(open(args.j)) except UnicodeDecodeError: From 859572e8b610a2926978f1c7b2148dbc86ccf128 Mon Sep 17 00:00:00 2001 From: A_D Date: Wed, 2 Dec 2020 17:19:27 +0200 Subject: [PATCH 06/32] Fixed Void Opal name --- commodity.csv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commodity.csv b/commodity.csv index a78111a8..eb7084a3 100644 --- a/commodity.csv +++ b/commodity.csv @@ -215,6 +215,6 @@ id,symbol,category,name 128924329,Benitoite,Minerals,Benitoite 128924330,Grandidierite,Minerals,Grandidierite 128924331,Alexandrite,Minerals,Alexandrite -128924332,Opal,Minerals,Void Opals +128924332,Opal,Minerals,Void Opal 128924333,RockforthFertiliser,Chemicals,Rockforth Fertiliser 128924334,AgronomicTreatment,Chemicals,Agronomic Treatment From 412708b3d1a11e8e97dd4d897ddda5d2dfadc09e Mon Sep 17 00:00:00 2001 From: Athanasius Date: Thu, 3 Dec 2020 12:26:50 +0000 Subject: [PATCH 07/32] Issues: Bugs: Emphasise we want BOTH log files. Also cleans up the wording, as 4.1.4 has been out months so there'll always be the -debug log file now. --- .github/ISSUE_TEMPLATE/bug_report.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 1591a7df..e24f8a60 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -16,9 +16,9 @@ assignees: '' - OS: [e.g. Windows 10, Linux Debian 10.6, etc.] - OS Locale: [e.g. English, French, Serbian...] - If applicable: Browser [e.g. chrome, safari] - - Please attach log files: - 1. Always attach `%TEMP%\EDMarketConnector.log` from *immediately* after the bug occurs (re-running the application overwrites this file). - 1. If running 4.1.0 (including betas) or later: `%TEMP%\EDMarketConnector\EDMarketConnector-debug.log`. See [Debug Log File](https://github.com/EDCD/EDMarketConnector/wiki/Troubleshooting#debug-log-files). + - Please attach **BOTH** log files as follows: + 1. `%TEMP%\EDMarketConnector.log` from *immediately* after the bug occurs (re-running the application overwrites this file). + 1. %TEMP%\EDMarketConnector\EDMarketConnector-debug.log`. See [Debug Log File](https://github.com/EDCD/EDMarketConnector/wiki/Troubleshooting#debug-log-files). NB: If you don't have this log file then you're not running the latest version of the application and should update first to see if we already fixed the bug you're reporting. Use the Icon that looks like `_`, `|` and `^` all in one character towards the right of the toolbar above. From 1c16b5fae6e6108a79c0d528343ca97a4bc02f90 Mon Sep 17 00:00:00 2001 From: Joshua Tyler-Jones Date: Tue, 8 Dec 2020 15:08:27 +0000 Subject: [PATCH 08/32] Fix dead link in PLUGINS.md --- PLUGINS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PLUGINS.md b/PLUGINS.md index 717171f7..2125d117 100644 --- a/PLUGINS.md +++ b/PLUGINS.md @@ -351,7 +351,7 @@ threads - doing so may cause the app to crash intermittently. You can signal back to the main thread using Tkinter's `event_generate()` widget method, generating a user-defined event that you have previously registered with the [`bind_all()`](http://effbot.org/tkinterbook/tkinter-events-and-bindings.htm) -widget method. See the [EDSM plugin](https://github.com/Marginal/EDMarketConnector/blob/master/plugins/edsm.py) +widget method. See the [EDSM plugin](https://github.com/Marginal/EDMarketConnector/blob/main/plugins/edsm.py) for an example of these techniques. #### Journal Entry From 08ac054ccef1b7a8184e4223419e3ef04f05220a Mon Sep 17 00:00:00 2001 From: Athanasius Date: Mon, 26 Oct 2020 13:27:07 +0000 Subject: [PATCH 09/32] requirements: py2exe now available from pypi, so no need for VCS --- requirements-dev.txt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 7f756495..b50ae664 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -20,9 +20,8 @@ autopep8==1.5.4 grip>=4.5.2 # Packaging -# This isn't available via 'pip install', so has to be commented out in order for -# GitHub Action Workflows to not error out -#py2exe==0.9.3.2 +# We only need py2exe on windows. +py2exe==0.10.0.2; sys_platform == 'win32' # All of the normal requirements -r requirements.txt From 7be255b8acfafdf2a06508c28980e625b58f94b0 Mon Sep 17 00:00:00 2001 From: Athanasius Date: Mon, 26 Oct 2020 13:49:13 +0000 Subject: [PATCH 10/32] Releasing: py2exe via pip / requirements-dev.txt now. --- docs/Releasing.md | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/docs/Releasing.md b/docs/Releasing.md index b340e256..fb0623a3 100644 --- a/docs/Releasing.md +++ b/docs/Releasing.md @@ -33,29 +33,16 @@ You will need several pieces of software installed, or the files from their [v3.7.9](https://www.python.org/downloads/release/python-379/) is the most recently tested version. You need the `Windows x86 executable installer` file, for the 32-bit version. -1. [py2exe](https://github.com/albertosottile/py2exe): - 1. Install the python module. There are two options here. - 1. You can use the latest release version [0.9.3.2](https://github.com/albertosottile/py2exe/releases/tag/v0.9.3.2) - and the current Marginal 'python3' branch as-is. This contains a - small hack in `setup.py` to ensure `sqlite3.dll` is packaged. - - pip install py2exe-0.9.3.2-cp37-none-win32.whl - 1. Or you can use a pre-release version, [0.9.4.0](https://bintray.com/alby128/py2exe/download_file?file_path=py2exe-0.9.4.0-cp37-none-win32.whl), see [this py2exe issue](https://github.com/albertosottile/py2exe/issues/23#issuecomment-541359225), - which packages that DLL file correctly. - - pip install py2exe-0.9.4.0-cp37-none-win32.whl - You can then edit out the following line from `setup.py`, but it - does no harm: - - %s/DLLs/sqlite3.dll' % (sys.base_prefix), +1. [py2exe](https://github.com/albertosottile/py2exe) - Now available via PyPi, + so will be picked up with the `pip install` below. Latest tested as per + `requirements-dev.txt`. 1. You'll now need to 'pip install' several python modules. 1. Ensure you have `pip` installed. If needs be see [Installing pip](https://pip.pypa.io/en/stable/installing/) 1. The easiest way is to utilise the `requirements-dev.txt` file: - `python -m pip install -r requirements-dev.txt`. This will install all - dependencies plus anything required for development *other than py2exe, see - above*. + `python -m pip install --user -r requirements-dev.txt`. This will install + all dependencies plus anything required for development. 1. Else check the contents of both `requirements.txt` and `requirements-dev.txt`, and ensure the modules listed there are installed as per the version requirements. From d650db5a1a0c3493ed7c96d68ccc36ac2e667c6e Mon Sep 17 00:00:00 2001 From: A_D Date: Sun, 18 Oct 2020 09:48:23 +0200 Subject: [PATCH 11/32] Added name mangling support to EDMCContextFilter Python name mangling is more about name collisions than actually making things private. This commit adds a check to resolve mangled names to their runtime names, and adds a just-in-case default to fetching the attribute. Fixes #764 --- EDMCLogging.py | 8 ++++++-- EDMarketConnector.py | 4 ++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/EDMCLogging.py b/EDMCLogging.py index 246ee78d..846dba84 100644 --- a/EDMCLogging.py +++ b/EDMCLogging.py @@ -287,11 +287,15 @@ class EDMCContextFilter(logging.Filter): frame_info = inspect.getframeinfo(frame) args, _, _, value_dict = inspect.getargvalues(frame) if len(args) and args[0] in ('self', 'cls'): - frame_class = value_dict[args[0]] + frame_class: 'object' = value_dict[args[0]] if frame_class: + # See https://en.wikipedia.org/wiki/Name_mangling#Python for how name mangling works. + if (name := frame_info.function).startswith("__") and not name.endswith("__"): + name = f'_{frame_class.__class__.__name__}{frame_info.function}' + # Find __qualname__ of the caller - fn = getattr(frame_class, frame_info.function) + fn = getattr(frame_class, name, None) if fn and fn.__qualname__: caller_qualname = fn.__qualname__ diff --git a/EDMarketConnector.py b/EDMarketConnector.py index 90ff631f..63cc2f6f 100755 --- a/EDMarketConnector.py +++ b/EDMarketConnector.py @@ -1165,6 +1165,10 @@ sys.path: {sys.path}''' def __init__(self): logger.debug('A call from A.B.__init__') + self.__test() + + def __test(self): + logger.debug("A call from A.B.__test") # abinit = A.B() From 2b60220365cb723a63907e4eb6840b6c4fa6de70 Mon Sep 17 00:00:00 2001 From: Athanasius Date: Thu, 15 Oct 2020 12:49:30 +0100 Subject: [PATCH 12/32] EDMarketConnector: popup for "already running" * This also refactors code around so that isort and flake8 are happy about the module level imports. --- EDMarketConnector.py | 114 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 113 insertions(+), 1 deletion(-) diff --git a/EDMarketConnector.py b/EDMarketConnector.py index 63cc2f6f..564b35c8 100755 --- a/EDMarketConnector.py +++ b/EDMarketConnector.py @@ -17,8 +17,117 @@ from typing import TYPE_CHECKING from config import applongname, appname, appversion, appversion_nobuild, config, copyright -# TODO: Test: Make *sure* this redirect is working, else py2exe is going to cause an exit popup if __name__ == "__main__": + def no_other_instance_running() -> bool: # noqa: CCR001 + """ + Ensure only one copy of the app is running under this user account. + + OSX does this automatically. + + :returns: True if we are the single instance, else False. + """ + # TODO: Linux implementation + if platform == 'win32': + import ctypes + from ctypes.wintypes import BOOL, HWND, INT, LPARAM, LPCWSTR, LPWSTR + + EnumWindows = ctypes.windll.user32.EnumWindows # noqa: N806 + GetClassName = ctypes.windll.user32.GetClassNameW # noqa: N806 + GetClassName.argtypes = [HWND, LPWSTR, ctypes.c_int] + GetWindowText = ctypes.windll.user32.GetWindowTextW # noqa: N806 + GetWindowText.argtypes = [HWND, LPWSTR, ctypes.c_int] + GetWindowTextLength = ctypes.windll.user32.GetWindowTextLengthW # noqa: N806 + GetProcessHandleFromHwnd = ctypes.windll.oleacc.GetProcessHandleFromHwnd # noqa: N806 + + SW_RESTORE = 9 # noqa: N806 + SetForegroundWindow = ctypes.windll.user32.SetForegroundWindow # noqa: N806 + ShowWindow = ctypes.windll.user32.ShowWindow # noqa: N806 + ShowWindowAsync = ctypes.windll.user32.ShowWindowAsync # noqa: N806 + + COINIT_MULTITHREADED = 0 # noqa: N806,F841 + COINIT_APARTMENTTHREADED = 0x2 # noqa: N806 + COINIT_DISABLE_OLE1DDE = 0x4 # noqa: N806 + CoInitializeEx = ctypes.windll.ole32.CoInitializeEx # noqa: N806 + + ShellExecute = ctypes.windll.shell32.ShellExecuteW # noqa: N806 + ShellExecute.argtypes = [HWND, LPCWSTR, LPCWSTR, LPCWSTR, LPCWSTR, INT] + + def window_title(h): + if h: + text_length = GetWindowTextLength(h) + 1 + buf = ctypes.create_unicode_buffer(text_length) + if GetWindowText(h, buf, text_length): + return buf.value + + return None + + @ctypes.WINFUNCTYPE(BOOL, HWND, LPARAM) + def enumwindowsproc(window_handle, l_param): + # class name limited to 256 - https://msdn.microsoft.com/en-us/library/windows/desktop/ms633576 + cls = ctypes.create_unicode_buffer(257) + if GetClassName(window_handle, cls, 257) \ + and cls.value == 'TkTopLevel' \ + and window_title(window_handle) == applongname \ + and GetProcessHandleFromHwnd(window_handle): + # If GetProcessHandleFromHwnd succeeds then the app is already running as this user + if len(sys.argv) > 1 and sys.argv[1].startswith(protocolhandler.redirect): + CoInitializeEx(0, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE) + # Wait for it to be responsive to avoid ShellExecute recursing + ShowWindow(window_handle, SW_RESTORE) + ShellExecute(0, None, sys.argv[1], None, None, SW_RESTORE) + + else: + ShowWindowAsync(window_handle, SW_RESTORE) + SetForegroundWindow(window_handle) + + return False + + return True + + return EnumWindows(enumwindowsproc, 0) + + return True + + def already_running_popup(): + """Create the "already running" popup.""" + import tkinter as tk + from tkinter import ttk + + root = tk.Tk(className=appname.lower()) + + frame = tk.Frame(root) + frame.grid(row=1, column=0, sticky=tk.NSEW) + + label = tk.Label(frame) + label['text'] = 'An EDMarketConnector.exe process was already running, exiting.' + label.grid(row=1, column=0, sticky=tk.NSEW) + + button = ttk.Button(frame, text='OK', command=lambda: sys.exit(0)) + button.grid(row=2, column=0, sticky=tk.S) + + root.mainloop() + + if not no_other_instance_running(): + # There's a copy already running. We want to inform the user by + # **appending** to the log file, not truncating it. + if getattr(sys, 'frozen', False): + # By default py2exe tries to write log to dirname(sys.executable) which fails when installed + import tempfile + + # unbuffered not allowed for text in python3, so use `1 for line buffering + sys.stdout = sys.stderr = open(join(tempfile.gettempdir(), f'{appname}.log'), mode='a', buffering=1) + + # Logging isn't set up yet. + # We'll keep this print, but it will be over-written by any subsequent + # write by the already-running process. + print("An EDMarketConnector.exe process was already running, exiting.") + + # To be sure the user knows, we need a popup + already_running_popup() + # If the user closes the popup with the 'X', not the 'OK' button we'll + # reach here. + sys.exit(0) + # Keep this as the very first code run to be as sure as possible of no # output until after this redirect is done, if needed. if getattr(sys, 'frozen', False): @@ -36,6 +145,9 @@ if TYPE_CHECKING: from logging import trace, TRACE # type: ignore # noqa: F401 # isort: on + def _(x: str) -> str: + """Fake the l10n translation functions for typing.""" + return x if getattr(sys, 'frozen', False): # Under py2exe sys.path[0] is the executable name From 3ff9bdcc8818faae88aa8fcc3073fd1cb876ef32 Mon Sep 17 00:00:00 2001 From: Athanasius Date: Tue, 8 Dec 2020 16:08:30 +0000 Subject: [PATCH 13/32] Fix Python 3.8 syntax use in backport to 4.1.x/Python 3.7 --- EDMCLogging.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/EDMCLogging.py b/EDMCLogging.py index 846dba84..308e85fc 100644 --- a/EDMCLogging.py +++ b/EDMCLogging.py @@ -291,7 +291,8 @@ class EDMCContextFilter(logging.Filter): if frame_class: # See https://en.wikipedia.org/wiki/Name_mangling#Python for how name mangling works. - if (name := frame_info.function).startswith("__") and not name.endswith("__"): + name = frame_info.function + if name.startswith("__") and not name.endswith("__"): name = f'_{frame_class.__class__.__name__}{frame_info.function}' # Find __qualname__ of the caller From 5cc4a6e80b2c76662569d4b803412b6e7742da26 Mon Sep 17 00:00:00 2001 From: Athanasius Date: Tue, 13 Oct 2020 12:31:12 +0100 Subject: [PATCH 14/32] EDMarketConnector: Add detailed logging to shutdown sequence --- EDMarketConnector.py | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/EDMarketConnector.py b/EDMarketConnector.py index 564b35c8..b1b2a55f 100755 --- a/EDMarketConnector.py +++ b/EDMarketConnector.py @@ -1059,18 +1059,43 @@ class AppWindow(object): if platform != 'darwin' or self.w.winfo_rooty() > 0: x, y = self.w.geometry().split('+')[1:3] # e.g. '212x170+2881+1267' config.set('geometry', f'+{x}+{y}') - self.w.withdraw() # Following items can take a few seconds, so hide the main window while they happen + + # Let the user know we're shutting down. + self.status['text'] = 'Shutting down...' + self.w.update_idletasks() + logger.info('Starting shutdown procedures...') + + logger.info('Closing protocol handler...') protocolhandler.close() + + logger.info('Unregistering hotkey manager...') hotkeymgr.unregister() + + logger.info('Closing dashboard...') dashboard.close() + + logger.info('Closing journal monitor...') monitor.close() + + logger.info('Notifying plugins to stop...') plug.notify_stop() + + logger.info('Closing update checker...') self.updater.close() + + logger.info('Closing Frontier CAPI sessions...') companion.session.close() + + logger.info('Closing config...') config.close() + + logger.info('Destroying app window...') self.w.destroy() - def drag_start(self, event): + logger.info('Done.') + + def drag_start(self, event) -> None: + """Initiate dragging the window.""" self.drag_offset = (event.x_root - self.w.winfo_rootx(), event.y_root - self.w.winfo_rooty()) def drag_continue(self, event): From fa3335d59a9cb9f9a6e81092af8870076af0d32c Mon Sep 17 00:00:00 2001 From: A_D Date: Mon, 7 Dec 2020 17:35:32 +0200 Subject: [PATCH 15/32] Added windows build --- .github/workflows/windows-build.yml | 47 +++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 .github/workflows/windows-build.yml diff --git a/.github/workflows/windows-build.yml b/.github/workflows/windows-build.yml new file mode 100644 index 00000000..e9203a50 --- /dev/null +++ b/.github/workflows/windows-build.yml @@ -0,0 +1,47 @@ +on: + push: + tags: + - "v*" + workflow_dispatch: + +jobs: + test: + name: Build EDMC + runs-on: windows-2019 + + defaults: + run: + shell: powershell + + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-python@v2 + with: + python-version: "3.7.9" + architecture: "x86" + + - name: Install python tools + run: | + pip install wheel + pip install -r requirements-dev.txt + pip install py2exe + ls + + - name: Download winsparkle + run: | + Invoke-Webrequest -UseBasicParsing https://github.com/vslavik/winsparkle/releases/download/v0.7.0/WinSparkle-0.7.0.zip -OutFile out.zip + Expand-Archive out.zip + Move-Item 'out\WinSparkle-0.7.0\Release\*' '.\' + + - name: Build EDMC + run: | + python setup.py py2exe + + - name: Upload build files + uses: actions/upload-artifact@v2 + with: + name: Built files + path: | + EDMarketConnector_win*.msi + dist.win32\EDMarketConnector.exe + appcast_win_*.xml From 87afa69f5351196f96349ed1ac20628812cbeaff Mon Sep 17 00:00:00 2001 From: A_D Date: Mon, 7 Dec 2020 19:01:04 +0200 Subject: [PATCH 16/32] Removed py2exe setup --- .github/workflows/windows-build.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/windows-build.yml b/.github/workflows/windows-build.yml index e9203a50..2e85ecd7 100644 --- a/.github/workflows/windows-build.yml +++ b/.github/workflows/windows-build.yml @@ -24,8 +24,6 @@ jobs: run: | pip install wheel pip install -r requirements-dev.txt - pip install py2exe - ls - name: Download winsparkle run: | From 033a3bb4da1b8b14517588b8bef54594ca982268 Mon Sep 17 00:00:00 2001 From: A_D Date: Tue, 8 Dec 2020 18:51:00 +0200 Subject: [PATCH 17/32] Removed appcast, only upload msi installer --- .github/workflows/windows-build.yml | 5 +---- setup.py | 35 +---------------------------- 2 files changed, 2 insertions(+), 38 deletions(-) diff --git a/.github/workflows/windows-build.yml b/.github/workflows/windows-build.yml index 2e85ecd7..d0013a19 100644 --- a/.github/workflows/windows-build.yml +++ b/.github/workflows/windows-build.yml @@ -39,7 +39,4 @@ jobs: uses: actions/upload-artifact@v2 with: name: Built files - path: | - EDMarketConnector_win*.msi - dist.win32\EDMarketConnector.exe - appcast_win_*.xml + path: EDMarketConnector_win*.msi diff --git a/setup.py b/setup.py index 12953b0f..a10b568d 100755 --- a/setup.py +++ b/setup.py @@ -221,37 +221,4 @@ elif sys.platform == 'win32': os.system(r'"%s\MsiTran.Exe" -g %s\%s_1033.msi %s\%s_%d.msi %s\%d.mst' % (SDKPATH, gettempdir(), APPNAME, gettempdir(), APPNAME, lcid, gettempdir(), lcid)) os.system(r'cscript /nologo "%s\WiSubStg.vbs" %s %s\%d.mst %d' % (SDKPATH, PKG, gettempdir(), lcid, lcid)) else: - raise AssertionError('Unsupported platform') - -if not exists(PKG): - raise AssertionError('No %s found prior to appcast' % (PKG)) -# Make appcast entry -appcast = open('appcast_%s_%s.xml' % (sys.platform=='darwin' and 'mac' or 'win', VERSION), 'w') -appcast.write(''' -\t\t -\t\t\tRelease {VERSION} -\t\t\t -\t\t\t\t{STYLE} -

Release {VERSION}

-
    - -
-\t\t\t\t]]> -\t\t\t
-\t\t\t -\t\t
-'''.format(VERSION=VERSION, - STYLE='{}'.format( - sys.platform=='win32' and 'body { font-family:"Segoe UI","Tahoma"; font-size: 75%; } h2 { font-family:"Segoe UI","Tahoma"; font-size: 105%; }' - or 'h2 { font-size: 105%; }'), - PKG=PKG, - OS=''.format(sys.platform=='win32' and 'windows"\n\t\t\t\tsparkle:installerArguments="/passive LAUNCH=yes' or 'macos'), - LENGTH=os.stat(PKG).st_size) -) + raise AssertionError('Unsupported platform') \ No newline at end of file From 3a0da6dadcf3e9466d665916bc65a230a01f0eda Mon Sep 17 00:00:00 2001 From: A_D Date: Tue, 8 Dec 2020 18:53:23 +0200 Subject: [PATCH 18/32] Added missing newline --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index a10b568d..6d71fb6b 100755 --- a/setup.py +++ b/setup.py @@ -221,4 +221,4 @@ elif sys.platform == 'win32': os.system(r'"%s\MsiTran.Exe" -g %s\%s_1033.msi %s\%s_%d.msi %s\%d.mst' % (SDKPATH, gettempdir(), APPNAME, gettempdir(), APPNAME, lcid, gettempdir(), lcid)) os.system(r'cscript /nologo "%s\WiSubStg.vbs" %s %s\%d.mst %d' % (SDKPATH, PKG, gettempdir(), lcid, lcid)) else: - raise AssertionError('Unsupported platform') \ No newline at end of file + raise AssertionError('Unsupported platform') From bd74aaf0aa7179275c61b14bc0e47be5373fef6e Mon Sep 17 00:00:00 2001 From: A_D Date: Tue, 8 Dec 2020 19:36:26 +0200 Subject: [PATCH 19/32] Add name to windows build action This should make it show up with a more sane name --- .github/workflows/windows-build.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/windows-build.yml b/.github/workflows/windows-build.yml index d0013a19..bd695779 100644 --- a/.github/workflows/windows-build.yml +++ b/.github/workflows/windows-build.yml @@ -1,3 +1,5 @@ +name: Build EDMC for Windows + on: push: tags: From 3a980ef16a1e701f9f4f3275dc4e03dcfc3dd693 Mon Sep 17 00:00:00 2001 From: A_D Date: Tue, 8 Dec 2020 19:59:41 +0200 Subject: [PATCH 20/32] Added docs for windows build action --- docs/Automatic Builds.md | 28 ++++++++++++++++++++++++++++ docs/Releasing.md | 2 ++ 2 files changed, 30 insertions(+) create mode 100644 docs/Automatic Builds.md diff --git a/docs/Automatic Builds.md b/docs/Automatic Builds.md new file mode 100644 index 00000000..a59f7505 --- /dev/null +++ b/docs/Automatic Builds.md @@ -0,0 +1,28 @@ +# Introduction + +Instead of building manually as laid out by [Releasing](https://github.com/EDCD/EDMarketConnector/blob/main/docs/Releasing.md), you can build the EDMC installer using github actions. + +## Initiating a workflow run + +Starting a workflow run is done from the Actions tab at the top of the main GitHub UI + +NB: The branch you want to build must have the workflow file (`.github/workflows/windows-build.yml`), and the version of the file in that branch is the version that will be used for the build (eg for different python versions) + +1. Select the Actions tab at the top of the main github interface +2. Select the `Build EDMC for windows` workflow on the left +3. Click the "Run workflow" button at the right side of the blue banner + 1. Select the branch you want to build + 2. Click the "Run Workflow" + +## Downloading built installer files + +When the workflow is (successfully) completed, it will upload the msi file it built as a "Workflow Artifact". You can find the artifacts as follows: + +1. Select `all workflows` on the left +2. Select the `Build EDMC for Windows` action +3. Select your build (probably the top one) +4. Find the `Built Files` artifact + +Within the `Built Files` zip file is the installer msi + +**Please ensure you test the built msi before creating a release.** diff --git a/docs/Releasing.md b/docs/Releasing.md index fb0623a3..8346d0ff 100644 --- a/docs/Releasing.md +++ b/docs/Releasing.md @@ -10,6 +10,8 @@ This document aims to enable anyone to quickly get up to speed on how to: Note that for Windows only a 32-bit application is supported at this time. This is principally due to the Windows Registry handling in config.py. +Builds can be run automatically from GitHub Actions. For more information on that process, see the [Actions docs](https://github.com/EDCD/EDMarketConnector/blob/main/docs/Releasing.md) + # Environment You will need several pieces of software installed, or the files from their From 77d9eb293e8c849a7863719202b650b6b8782749 Mon Sep 17 00:00:00 2001 From: A_D Date: Tue, 8 Dec 2020 20:07:12 +0200 Subject: [PATCH 21/32] Fixed a few style errors --- docs/Automatic Builds.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/Automatic Builds.md b/docs/Automatic Builds.md index a59f7505..316bc30f 100644 --- a/docs/Automatic Builds.md +++ b/docs/Automatic Builds.md @@ -6,10 +6,10 @@ Instead of building manually as laid out by [Releasing](https://github.com/EDCD/ Starting a workflow run is done from the Actions tab at the top of the main GitHub UI -NB: The branch you want to build must have the workflow file (`.github/workflows/windows-build.yml`), and the version of the file in that branch is the version that will be used for the build (eg for different python versions) +NB: The branch you want to build must have the workflow file (`.github/workflows/windows-build.yml`), and the version of the file in that branch is the version that will be used for the build (e.g. for different python versions) 1. Select the Actions tab at the top of the main github interface -2. Select the `Build EDMC for windows` workflow on the left +2. Select the `Build EDMC for Windows` workflow on the left 3. Click the "Run workflow" button at the right side of the blue banner 1. Select the branch you want to build 2. Click the "Run Workflow" @@ -18,7 +18,7 @@ NB: The branch you want to build must have the workflow file (`.github/workflows When the workflow is (successfully) completed, it will upload the msi file it built as a "Workflow Artifact". You can find the artifacts as follows: -1. Select `all workflows` on the left +1. Select `All workflows` on the left 2. Select the `Build EDMC for Windows` action 3. Select your build (probably the top one) 4. Find the `Built Files` artifact From 20f95460c40cb52df540757fbfc7e8e6f92df4f7 Mon Sep 17 00:00:00 2001 From: A_D Date: Tue, 8 Dec 2020 20:09:36 +0200 Subject: [PATCH 22/32] Fixed actions link in release docs --- docs/Releasing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Releasing.md b/docs/Releasing.md index 8346d0ff..2a29f3b9 100644 --- a/docs/Releasing.md +++ b/docs/Releasing.md @@ -10,7 +10,7 @@ This document aims to enable anyone to quickly get up to speed on how to: Note that for Windows only a 32-bit application is supported at this time. This is principally due to the Windows Registry handling in config.py. -Builds can be run automatically from GitHub Actions. For more information on that process, see the [Actions docs](https://github.com/EDCD/EDMarketConnector/blob/main/docs/Releasing.md) +Builds can be run automatically from GitHub Actions. For more information on that process, see the [Actions Build docs](https://github.com/EDCD/EDMarketConnector/blob/main/docs/Automatic%20Builds.md) # Environment From f468227a6cbf6877b23bfb053e5234404f74853e Mon Sep 17 00:00:00 2001 From: A_D Date: Tue, 8 Dec 2020 20:12:09 +0200 Subject: [PATCH 23/32] Renamed to Automatic builds in link --- docs/Releasing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Releasing.md b/docs/Releasing.md index 2a29f3b9..846324e2 100644 --- a/docs/Releasing.md +++ b/docs/Releasing.md @@ -10,7 +10,7 @@ This document aims to enable anyone to quickly get up to speed on how to: Note that for Windows only a 32-bit application is supported at this time. This is principally due to the Windows Registry handling in config.py. -Builds can be run automatically from GitHub Actions. For more information on that process, see the [Actions Build docs](https://github.com/EDCD/EDMarketConnector/blob/main/docs/Automatic%20Builds.md) +Builds can be run automatically from GitHub Actions. For more information on that process, see [Automatic Builds](https://github.com/EDCD/EDMarketConnector/blob/main/docs/Automatic%20Builds.md). # Environment From 2b038a551b169f5e98d135f2c48d6bc5759fb8ff Mon Sep 17 00:00:00 2001 From: A_D Date: Tue, 8 Dec 2020 20:17:12 +0200 Subject: [PATCH 24/32] Fixed github capitialization --- docs/Automatic Builds.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/Automatic Builds.md b/docs/Automatic Builds.md index 316bc30f..014ecc3c 100644 --- a/docs/Automatic Builds.md +++ b/docs/Automatic Builds.md @@ -1,6 +1,6 @@ # Introduction -Instead of building manually as laid out by [Releasing](https://github.com/EDCD/EDMarketConnector/blob/main/docs/Releasing.md), you can build the EDMC installer using github actions. +Instead of building manually as laid out by [Releasing](https://github.com/EDCD/EDMarketConnector/blob/main/docs/Releasing.md), you can build the EDMC installer using GitHub actions. ## Initiating a workflow run @@ -8,7 +8,7 @@ Starting a workflow run is done from the Actions tab at the top of the main GitH NB: The branch you want to build must have the workflow file (`.github/workflows/windows-build.yml`), and the version of the file in that branch is the version that will be used for the build (e.g. for different python versions) -1. Select the Actions tab at the top of the main github interface +1. Select the Actions tab at the top of the main GitHub interface 2. Select the `Build EDMC for Windows` workflow on the left 3. Click the "Run workflow" button at the right side of the blue banner 1. Select the branch you want to build From a18137966995e6f34603133fdbf210e87044fe1e Mon Sep 17 00:00:00 2001 From: Athanasius Date: Sat, 12 Dec 2020 14:02:11 +0000 Subject: [PATCH 25/32] PLUGINS.md: Point to current Python version information in Releasing.md --- PLUGINS.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/PLUGINS.md b/PLUGINS.md index 2125d117..00d48155 100644 --- a/PLUGINS.md +++ b/PLUGINS.md @@ -21,6 +21,13 @@ Plugins are python files. The plugin folder must have a file named `load.py` that must provide one module level function and optionally provide a few others. +If you're running from source (which allows for debugging with e.g. [PyCharm](https://www.jetbrains.com/pycharm/features/)) +then you'll need to be using an appropriate version of Python. The current +version is listed in the [Environment section of Releasing.md](https://github.com/EDCD/EDMarketConnector/blob/main/docs/Releasing.md#environment). +If you're developing your plugin simply against an install of EDMarketConnector +then you'll be relying on the bundled version of Python (it's baked +into the .exe via the py2exe build process). + --- ### Examples From d903d80410568d3854b8c22bbb761c76284cca36 Mon Sep 17 00:00:00 2001 From: Athanasius Date: Tue, 15 Dec 2020 14:49:22 +0000 Subject: [PATCH 26/32] Make 'Shutting down...' text translatable. --- EDMarketConnector.py | 2 +- L10n/en.template | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/EDMarketConnector.py b/EDMarketConnector.py index b1b2a55f..0607afaa 100755 --- a/EDMarketConnector.py +++ b/EDMarketConnector.py @@ -1061,7 +1061,7 @@ class AppWindow(object): config.set('geometry', f'+{x}+{y}') # Let the user know we're shutting down. - self.status['text'] = 'Shutting down...' + self.status['text'] = _('Shutting down...') self.w.update_idletasks() logger.info('Starting shutdown procedures...') diff --git a/L10n/en.template b/L10n/en.template index cf14aa37..262b36d9 100644 --- a/L10n/en.template +++ b/L10n/en.template @@ -454,6 +454,9 @@ /* Setting to decide which ship outfitting website to link to - either E:D Shipyard or Coriolis. [prefs.py] */ "Shipyard" = "Shipyard"; +/* Status line text that appears when process exit sequence starts [EDMarketConnector.py] */ +"Shutting down..." = "Shutting down..."; + /* Empire rank. [stats.py] */ "Squire" = "Squire"; From f885c2b7698480d6a303154c2da38721453da4ab Mon Sep 17 00:00:00 2001 From: Athanasius Date: Tue, 15 Dec 2020 15:08:36 +0000 Subject: [PATCH 27/32] EDMCLogging: Catch inspect.getframeinfo(frame) not working Maybe with this we'll see something 'here' or later to give a clue as to why this doesn't work on at least two systems. --- EDMCLogging.py | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/EDMCLogging.py b/EDMCLogging.py index 308e85fc..479fa9bc 100644 --- a/EDMCLogging.py +++ b/EDMCLogging.py @@ -284,7 +284,25 @@ class EDMCContextFilter(logging.Filter): caller_qualname = caller_class_names = '' if frame: # - frame_info = inspect.getframeinfo(frame) + try: + frame_info = inspect.getframeinfo(frame) + raise(IndexError) # TODO: Remove, only for testing + + except Exception: + # Separate from the print below to guarantee we see at least this much. + print('EDMCLogging:EDMCContextFilter:caller_attributes(): Failed in `inspect.getframinfo(frame)`') + + # We want to *attempt* to show something about the nature of 'frame', + # but at this point we can't trust it will work. + try: + print(f'frame: {frame}') + + except Exception: + pass + + # We've given up, so just return all '??' to signal we couldn't get the info + return '??', '??', '??' + args, _, _, value_dict = inspect.getargvalues(frame) if len(args) and args[0] in ('self', 'cls'): frame_class: 'object' = value_dict[args[0]] From 286647869b36186aa2aed4eec92ef091abddcc4e Mon Sep 17 00:00:00 2001 From: Athanasius Date: Tue, 15 Dec 2020 19:35:51 +0000 Subject: [PATCH 28/32] EDMCLogging: Comment out a 'testing' raise() call --- EDMCLogging.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EDMCLogging.py b/EDMCLogging.py index 479fa9bc..eae1a222 100644 --- a/EDMCLogging.py +++ b/EDMCLogging.py @@ -286,7 +286,7 @@ class EDMCContextFilter(logging.Filter): # try: frame_info = inspect.getframeinfo(frame) - raise(IndexError) # TODO: Remove, only for testing + # raise(IndexError) # TODO: Remove, only for testing except Exception: # Separate from the print below to guarantee we see at least this much. From a68f5d6e842d6d10d945e34272e817781faeabd4 Mon Sep 17 00:00:00 2001 From: Athanasius Date: Tue, 15 Dec 2020 14:45:50 +0000 Subject: [PATCH 29/32] Initial changelog for 4.1.5. --- ChangeLog.md | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/ChangeLog.md b/ChangeLog.md index e6d07440..b0a8df55 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,6 +1,46 @@ This is the master changelog for Elite Dangerous Market Connector. Entries are in reverse chronological order (latest first). --- +Release 4.1.5 +=== + +* If there is already an EDMarketConnector.exe process running when trying + to run another instance then that new process will no longer exit silently. + Instead you'll get a pop-up telling you it's detected another process, and + you need to close that pop-up in order for this additional process to then + exit. + + This hopefully makes it obvious when you've got a hung EDMarketConnect.exe + process that you need to kill in order to re-run the program. + +* In order to gather more information about how and why EDMarketConnector.exe + sometimes doesn't shutdown properly we've added some extra debug logging to + the sequence of clean-up calls performed during shutdown. + + Also, to make it more obvious if the process has hung during shutdown the + UI window is no longer hidden at the start of this shutdown sequence. It + will instead linger, with "Shutting down..." showing in the status line + (translation for this small phrase will be added in a later release). + +* Cater for 'mangled name' class functions in our logging code. e.g. where + you name a class member with a `__` prefix in order to 'hide' it from + out-of-class code. + +* Fixed logging from EDMC.exe so that the -debug log goes into `EDMC-debug.log` + not `EDMarketConnector-debug.log`. + +* Fix `EDMC.exe -j` handling of file encodings. NB: This command-line + argument isn't listed on `EDMC.exe -h` as it's intended for developer use + only. + +* Fix the name of 'Void Opal(s)' so that output of market data to files is + correct. + +* Fix URL in PLUGINS.md to refer to `main`, not `master` branch. + +* We're able to pull `py2exe` from PyPi now, so docs/Releasing.md has been + update to reflect this. + Release 4.1.4 === From 95becbc49ce83cb23a7cea8ccf5bbc1565e4a739 Mon Sep 17 00:00:00 2001 From: Athanasius Date: Tue, 15 Dec 2020 19:45:17 +0000 Subject: [PATCH 30/32] 4.1.5 Changelog: The '??:??' logging thing, bug linking & preamble. --- ChangeLog.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/ChangeLog.md b/ChangeLog.md index b0a8df55..e0debc15 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -4,6 +4,10 @@ This is the master changelog for Elite Dangerous Market Connector. Entries are Release 4.1.5 === +This is a minor maintenance release, mostly addressing behaviour around +process shutdown and startup, along with a couple of small enhancements that +most users won't notice. + * If there is already an EDMarketConnector.exe process running when trying to run another instance then that new process will no longer exit silently. Instead you'll get a pop-up telling you it's detected another process, and @@ -22,10 +26,22 @@ Release 4.1.5 will instead linger, with "Shutting down..." showing in the status line (translation for this small phrase will be added in a later release). + If you encounter this shutdown hang then please add a comment to + [Application can leave a zombie process on shutdown #678](https://github.com/EDCD/EDMarketConnector/issues/678) + to help us track down the cause and fix it. + * Cater for 'mangled name' class functions in our logging code. e.g. where you name a class member with a `__` prefix in order to 'hide' it from out-of-class code. +* To help track down the cause of [Crashing On Startup #798](https://github.com/EDCD/EDMarketConnector/issues/798) + we've added some exception catching in our logging code. If this is + triggered you will see `??:??` in logging output, instead of class and/or + function names. + + If you encounter this then please comment on that bug report to aid us in + tracking down the root cause! + * Fixed logging from EDMC.exe so that the -debug log goes into `EDMC-debug.log` not `EDMarketConnector-debug.log`. From 741d62c072c04992a390b38178fabbe7ee46edf3 Mon Sep 17 00:00:00 2001 From: Athanasius Date: Tue, 15 Dec 2020 19:57:24 +0000 Subject: [PATCH 31/32] Release 4.1.5: Config.py version bump --- config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.py b/config.py index 880f559d..e60ff1cd 100644 --- a/config.py +++ b/config.py @@ -13,7 +13,7 @@ appcmdname = 'EDMC' # appversion **MUST** follow Semantic Versioning rules: # # Major.Minor.Patch(-prerelease)(+buildmetadata) -appversion = '4.1.4' #-rc1+a872b5f' +appversion = '4.1.5' #-rc1+a872b5f' # For some things we want appversion without (possible) +build metadata appversion_nobuild = str(semantic_version.Version(appversion).truncate('prerelease')) copyright = u'© 2015-2019 Jonathan Harris, 2020 EDCD' From 819bb27997ef2649fac575cfd79113893cc957a6 Mon Sep 17 00:00:00 2001 From: Athanasius Date: Tue, 15 Dec 2020 20:02:24 +0000 Subject: [PATCH 32/32] 4.1.5: appcast file update --- edmarketconnector.xml | 70 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 66 insertions(+), 4 deletions(-) diff --git a/edmarketconnector.xml b/edmarketconnector.xml index 83782562..a696a1e4 100644 --- a/edmarketconnector.xml +++ b/edmarketconnector.xml @@ -168,11 +168,73 @@ - Release 4.1.4 + Release 4.1.5 body { font-family:"Segoe UI","Tahoma"; font-size: 75%; } h2 { font-family:"Segoe UI","Tahoma"; font-size: 105%; } +

Release 4.1.5

+

This is a minor maintenance release, mostly addressing behaviour around +process shutdown and startup, along with a couple of small enhancements that +most users won't notice.

+
    +
  • +

    If there is already an EDMarketConnector.exe process running when trying +to run another instance then that new process will no longer exit silently. +Instead you'll get a pop-up telling you it's detected another process, and +you need to close that pop-up in order for this additional process to then +exit.

    +

    This hopefully makes it obvious when you've got a hung EDMarketConnect.exe +process that you need to kill in order to re-run the program.

    +
  • +
  • +

    In order to gather more information about how and why EDMarketConnector.exe +sometimes doesn't shutdown properly we've added some extra debug logging to +the sequence of clean-up calls performed during shutdown.

    +

    Also, to make it more obvious if the process has hung during shutdown the +UI window is no longer hidden at the start of this shutdown sequence. It +will instead linger, with "Shutting down..." showing in the status line +(translation for this small phrase will be added in a later release).

    +

    If you encounter this shutdown hang then please add a comment to +Application can leave a zombie process on shutdown #678 +to help us track down the cause and fix it.

    +
  • +
  • +

    Cater for 'mangled name' class functions in our logging code. e.g. where +you name a class member with a __ prefix in order to 'hide' it from +out-of-class code.

    +
  • +
  • +

    To help track down the cause of Crashing On Startup #798 +we've added some exception catching in our logging code. If this is +triggered you will see ??:?? in logging output, instead of class and/or +function names.

    +

    If you encounter this then please comment on that bug report to aid us in +tracking down the root cause!

    +
  • +
  • +

    Fixed logging from EDMC.exe so that the -debug log goes into EDMC-debug.log +not EDMarketConnector-debug.log.

    +
  • +
  • +

    Fix EDMC.exe -j handling of file encodings. NB: This command-line +argument isn't listed on EDMC.exe -h as it's intended for developer use +only.

    +
  • +
  • +

    Fix the name of 'Void Opal(s)' so that output of market data to files is +correct.

    +
  • +
  • +

    Fix URL in PLUGINS.md to refer to main, not master branch.

    +
  • +
  • +

    We're able to pull py2exe from PyPi now, so docs/Releasing.md has been +update to reflect this.

    +
  • +
+ +

Release 4.1.4

The only change from 4.1.3 is to insert some Windows version checks before even attempting to set a UTF-8 encoding. We'll now only attempt this if the @@ -824,11 +886,11 @@ If any of your plugins are listed in that section then they will need updating, ]]>