1
0
mirror of https://github.com/EDCD/EDMarketConnector.git synced 2025-04-16 09:10:35 +03:00

Merge branch 'releases' into stable

This commit is contained in:
Athanasius 2020-12-15 20:12:50 +00:00
commit 4883c1606b
14 changed files with 397 additions and 73 deletions

View File

@ -12,13 +12,13 @@ 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:
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.

44
.github/workflows/windows-build.yml vendored Normal file
View File

@ -0,0 +1,44 @@
name: Build EDMC for Windows
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
- 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

View File

@ -1,6 +1,62 @@
This is the master changelog for Elite Dangerous Market Connector. Entries are in reverse chronological order (latest first).
---
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](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`.
* 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
===

25
EDMC.py
View File

@ -12,16 +12,20 @@ from os.path import getmtime, join
from time import sleep, time
from typing import TYPE_CHECKING, Any, Optional
# See EDMCLogging.py docs.
# isort: off
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 logging import trace, TRACE # type: ignore # noqa: F401
# isort: on
edmclogger.set_channels_loglevel(logging.INFO)
# workaround for https://github.com/EDCD/EDMarketConnector/issues/568
os.environ["EDMC_NO_UI"] = "1"
# isort: on
import collate
import commodity
@ -169,7 +173,16 @@ 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 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:
data = json.load(open(args.j, encoding='utf-8'))
config.set('querytime', int(getmtime(args.j)))
else:
@ -184,7 +197,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)

View File

@ -284,7 +284,25 @@ class EDMCContextFilter(logging.Filter):
caller_qualname = caller_class_names = ''
if frame:
# <https://stackoverflow.com/questions/2203424/python-how-to-retrieve-class-information-from-a-frame-object#2220759>
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]]

View File

@ -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
@ -947,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):

View File

@ -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";

View File

@ -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
@ -351,7 +358,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

View File

@ -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

1 id symbol category name
215 128924329 Benitoite Minerals Benitoite
216 128924330 Grandidierite Minerals Grandidierite
217 128924331 Alexandrite Minerals Alexandrite
218 128924332 Opal Minerals Void Opals Void Opal
219 128924333 RockforthFertiliser Chemicals Rockforth Fertiliser
220 128924334 AgronomicTreatment Chemicals Agronomic Treatment

View File

@ -13,7 +13,7 @@ appcmdname = 'EDMC'
# appversion **MUST** follow Semantic Versioning rules:
# <https://semver.org/#semantic-versioning-specification-semver>
# 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'

28
docs/Automatic Builds.md Normal file
View File

@ -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 (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
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.**

View File

@ -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 [Automatic Builds](https://github.com/EDCD/EDMarketConnector/blob/main/docs/Automatic%20Builds.md).
# Environment
You will need several pieces of software installed, or the files from their
@ -33,29 +35,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.

View File

@ -168,11 +168,73 @@
<!-- Windows -->
<item>
<title>Release 4.1.4</title>
<title>Release 4.1.5</title>
<description>
<![CDATA[
<style>body { font-family:"Segoe UI","Tahoma"; font-size: 75%; } h2 { font-family:"Segoe UI","Tahoma"; font-size: 105%; }</style>
<h2>Release 4.1.5</h2>
<p>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.</p>
<ul>
<li>
<p>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.</p>
<p>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.</p>
</li>
<li>
<p>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.</p>
<p>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).</p>
<p>If you encounter this shutdown hang then please add a comment to
<a href="https://github.com/EDCD/EDMarketConnector/issues/678">Application can leave a zombie process on shutdown #678</a>
to help us track down the cause and fix it.</p>
</li>
<li>
<p>Cater for 'mangled name' class functions in our logging code. e.g. where
you name a class member with a <code>__</code> prefix in order to 'hide' it from
out-of-class code.</p>
</li>
<li>
<p>To help track down the cause of <a href="https://github.com/EDCD/EDMarketConnector/issues/798">Crashing On Startup #798</a>
we've added some exception catching in our logging code. If this is
triggered you will see <code>??:??</code> in logging output, instead of class and/or
function names.</p>
<p>If you encounter this then please comment on that bug report to aid us in
tracking down the root cause!</p>
</li>
<li>
<p>Fixed logging from EDMC.exe so that the -debug log goes into <code>EDMC-debug.log</code>
not <code>EDMarketConnector-debug.log</code>.</p>
</li>
<li>
<p>Fix <code>EDMC.exe -j</code> handling of file encodings. NB: This command-line
argument isn't listed on <code>EDMC.exe -h</code> as it's intended for developer use
only.</p>
</li>
<li>
<p>Fix the name of 'Void Opal(s)' so that output of market data to files is
correct.</p>
</li>
<li>
<p>Fix URL in PLUGINS.md to refer to <code>main</code>, not <code>master</code> branch.</p>
</li>
<li>
<p>We're able to pull <code>py2exe</code> from PyPi now, so docs/Releasing.md has been
update to reflect this.</p>
</li>
</ul>
<h2>Release 4.1.4</h2>
<p>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,
]]>
</description>
<enclosure
url="https://github.com/EDCD/EDMarketConnector/releases/download/Release/4.1.4/EDMarketConnector_win_4.1.4.msi"
url="https://github.com/EDCD/EDMarketConnector/releases/download/Release/4.1.5/EDMarketConnector_win_4.1.5.msi"
sparkle:os="windows"
sparkle:installerArguments="/passive LAUNCH=yes"
sparkle:version="4.1.4"
length="11341824"
sparkle:version="4.1.5"
length="11362304"
type="application/octet-stream"
/>
</item>

View File

@ -222,36 +222,3 @@ elif sys.platform == 'win32':
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<item>
\t\t\t<title>Release {VERSION}</title>
\t\t\t<description>
\t\t\t\t<![CDATA[
<style>{STYLE}</style>
<h2>Release {VERSION}</h2>
<ul>
</ul>
\t\t\t\t]]>
\t\t\t</description>
\t\t\t<enclosure
\t\t\t\turl="https://github.com/EDCD/EDMarketConnector/releases/download/rel-{VERSION}/{PKG}"
\t\t\t\tsparkle:os="{OS}"
\t\t\t\tsparkle:version="{VERSION}"
\t\t\t\tlength="{LENGTH}"
\t\t\t\ttype="application/octet-stream"
\t\t\t/>
\t\t</item>
'''.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)
)