1
0
mirror of https://github.com/EDCD/EDMarketConnector.git synced 2025-05-20 17:11:32 +03:00

Merge branch 'stable' into releases

This commit is contained in:
Athanasius 2022-02-21 12:37:30 +00:00
commit 3019cea52e
No known key found for this signature in database
GPG Key ID: AE3E527847057C7D
6 changed files with 187 additions and 56 deletions

View File

@ -27,6 +27,51 @@ produce the Windows executables and installer.
---
Release 5.3.1
===
This release addresses some issues with newer EDDN code which could cause
erroneous alerts to the player, or sending of bad messages.
* EDDN: Cope with `ApproachSettlement` on login occurring before `Location`,
such that we don't yet know the name of the star system the player is in.
Closes [#1484](https://github.com/EDCD/EDMarketConnector/pull/1484)
* EDDN: Cope with `ApproachSettlement` missing planetary coordinates on login
at/near a settlement in Horizons.
Closes [#1476](https://github.com/EDCD/EDMarketConnector/pull/1476)
* EDDN: Change the `CodexEntry` "empty string" checks to only apply to those
values where the schema enforces "must be at least one character".
This prevents the big 'CodexEntry had empty string, PLEASE ALERT THE EDMC
DEVELOPERS' message from triggering on, e.g. `NearestDestination` being
empty, which the schema allows.
Closes [#1481](https://github.com/EDCD/EDMarketConnector/issues/1481)
Plugin Developers
---
* If you use a sub-class for a widget the core code will no longer break if
your code raises an exception. e.g. a plugin was failing due to Python
3.10 using `collections.abc` instead of `collections`, and the plugin's
custom widget had a `configure()` method which was called by the core
theme code on startup or theme change. This then caused the whole
application UI to never show up on startup.
This also applies if you set up a button such that enter/leave on it, i.e.
mouse in/out, causes the `theme.py` code for that to trigger.
So, now in such cases the main UI should actually show up, although your
plugin's UI might look weird due to theming not being properly applied.
The plugin exception **WILL** be logged, at ERROR level.
---
Release 5.3.0
===

View File

@ -38,6 +38,8 @@ Please be sure to read the [Avoiding potential pitfalls](#avoiding-potential-pit
section, else you might inadvertently cause issues for the core
EDMarketConnector code including whole application crashes.
## Being aware of core application changes
It is highly advisable to ensure you are aware of all EDMarketConnector
releases, including the pre-releases. The -beta and -rc changelogs will
contain valuable information about any forthcoming changes that affect plugins.
@ -55,6 +57,11 @@ The easiest way is:
And, of course, either ensure you check your GitHub messages regularly, or
have it set up to email you such notifications.
You should also keep an eye on [our GitHub Discussions](https://github.com/EDCD/EDMarketConnector/discussions)
in case there are any proposed changes to EDMC plugin functionality. You can
do this by ensuring 'Discussions' is also ticked when following the steps
above to set up a 'Custom' watch on this repository.
---
## Examples

View File

@ -52,7 +52,7 @@ appcmdname = 'EDMC'
# <https://semver.org/#semantic-versioning-specification-semver>
# Major.Minor.Patch(-prerelease)(+buildmetadata)
# NB: Do *not* import this, use the functions appversion() and appversion_nobuild()
_static_appversion = '5.3.0'
_static_appversion = '5.3.1'
_cached_version: Optional[semantic_version.Version] = None
copyright = '© 2015-2019 Jonathan Harris, 2020-2022 EDCD'

View File

@ -829,7 +829,7 @@ class EDDN:
else:
logger.warning("Neither this_coordinates or this.coordinates set, can't add StarPos")
return 'No source for adding StarPos to approachsettlement/1 !'
return 'No source for adding StarPos to EDDN message !'
return entry
@ -970,7 +970,9 @@ class EDDN:
logger.warning(f'this.body_id was not set properly: "{this.body_id}" ({type(this.body_id)})')
#######################################################################
for k, v in entry.items():
# Check just the top-level strings with minLength=1 in the schema
for k in ('System', 'Name', 'Region', 'Category', 'SubCategory'):
v = entry[k]
if v is None or isinstance(v, str) and v == '':
logger.warning(f'post-processing entry contains entry["{k}"] = {v} {(type(v))}')
# We should drop this message and VERY LOUDLY inform the
@ -978,6 +980,13 @@ class EDDN:
# raw Journal event that caused this.
return 'CodexEntry had empty string, PLEASE ALERT THE EDMC DEVELOPERS'
# Also check traits
if 'Traits' in entry:
for v in entry['Traits']:
if v is None or isinstance(v, str) and v == '':
logger.warning(f'post-processing entry[\'Traits\'] contains {v} {(type(v))}\n{entry["Traits"]}\n')
return 'CodexEntry Trait had empty string, PLEASE ALERT THE EDMC DEVELOPERS'
msg = {
'$schemaRef': f'https://eddn.edcd.io/schemas/codexentry/1{"/test" if is_beta else ""}',
'message': entry
@ -1126,6 +1135,27 @@ class EDDN:
# "event": "ApproachSettlement",
# "timestamp": "2021-10-14T12:37:54Z"
# }
#######################################################################
# Bugs
#######################################################################
# WORKAROUND 3.8.0.404 | 2022-02-18: ApproachSettlement missing coords
# As of Horizons ("gameversion":"3.8.0.404", "build":"r280105/r0 ")
# if you log back in (certainly a game client restart) at a
# Planetary Port, then the ApproachSettlement event written will be
# missing the Latitude and Longitude.
# Ref: https://github.com/EDCD/EDMarketConnector/issues/1476
if any(
k not in entry for k in ('Latitude', 'Longitude')
):
logger.debug(
f'ApproachSettlement without at least one of Latitude or Longitude:\n{entry}\n'
)
# No need to alert the user, it will only annoy them
return ""
# WORKAROUND END
#######################################################################
#######################################################################
# Augmentations
#######################################################################
@ -1499,6 +1529,12 @@ def journal_entry( # noqa: C901, CCR001
return this.eddn.export_journal_navroute(cmdr, is_beta, entry)
elif event_name == 'approachsettlement':
# An `ApproachSettlement` can appear *before* `Location` if you
# logged at one. We won't have necessary augmentation data
# at this point, so bail.
if system is None:
return ""
return this.eddn.export_journal_approachsettlement(
cmdr,
system,
@ -1507,6 +1543,14 @@ def journal_entry( # noqa: C901, CCR001
entry
)
# NB: If adding FSSSignalDiscovered these absolutely come in at login
# time **BEFORE** the `Location` event, so we won't yet know things
# like SystemNane, or StarPos.
# We can either have the "now send the batch" code add such (but
# that has corner cases around changing systems in the meantime),
# drop those events, or if the schema allows, send without those
# augmentations.
elif event_name == 'fssallbodiesfound':
return this.eddn.export_journal_fssallbodiesfound(
cmdr,

View File

@ -5,7 +5,7 @@ wheel
# We can't rely on just picking this up from either the base (not venv),
# or venv-init-time version. Specify here so that dependabot will prod us
# about new versions.
setuptools==60.8.2
setuptools==60.9.3
# Static analysis tools
flake8==4.0.1
@ -23,7 +23,7 @@ flake8-use-fstring==1.3
mypy==0.931
pep8-naming==0.12.1
safety==1.10.3
types-requests==2.27.9
types-requests==2.27.10
# Code formatting tools
autopep8==1.6.0
@ -33,14 +33,14 @@ grip==4.6.0
# Packaging
# Used to put together a WiX configuration from template/auto-gen
lxml==4.7.1
lxml==4.8.0
# We only need py2exe on windows.
# Pre-release version addressing semantic_version 2.9.0+ issues:
# <https://github.com/py2exe/py2exe/issues/126>
py2exe==0.11.1.0; sys_platform == 'win32'
# Testing
pytest==7.0.0
pytest==7.0.1
pytest-cov==3.0.0 # Pytest code coverage support
coverage[toml]==6.3.1 # pytest-cov dep. This is here to ensure that it includes TOML support for pyproject.toml configs
# For manipulating folder permissions and the like.

133
theme.py
View File

@ -14,6 +14,9 @@ from tkinter import ttk
from config import config
from ttkHyperlinkLabel import HyperlinkLabel
from EDMCLogging import get_main_logger
logger = get_main_logger()
if __debug__:
from traceback import print_exc
@ -192,17 +195,35 @@ class _Theme(object):
def _enter(self, event, image):
widget = event.widget
if widget and widget['state'] != tk.DISABLED:
widget.configure(state=tk.ACTIVE)
try:
widget.configure(state=tk.ACTIVE)
except Exception:
logger.exception(f'Failure setting widget active: {widget=}')
if image:
image.configure(foreground=self.current['activeforeground'],
background=self.current['activebackground'])
try:
image.configure(foreground=self.current['activeforeground'],
background=self.current['activebackground'])
except Exception:
logger.exception(f'Failure configuring image: {image=}')
def _leave(self, event, image):
widget = event.widget
if widget and widget['state'] != tk.DISABLED:
widget.configure(state=tk.NORMAL)
try:
widget.configure(state=tk.NORMAL)
except Exception:
logger.exception(f'Failure setting widget normal: {widget=}')
if image:
image.configure(foreground=self.current['foreground'], background=self.current['background'])
try:
image.configure(foreground=self.current['foreground'], background=self.current['background'])
except Exception:
logger.exception(f'Failure configuring image: {image=}')
# Set up colors
def _colors(self, root, theme):
@ -266,50 +287,64 @@ class _Theme(object):
widget.winfo_class(), widget, 'text' in widget.keys() and widget['text'])
attribs = self.widgets.get(widget, [])
if isinstance(widget, tk.BitmapImage):
# not a widget
if 'fg' not in attribs:
widget.configure(foreground=self.current['foreground']),
if 'bg' not in attribs:
widget.configure(background=self.current['background'])
elif 'cursor' in widget.keys() and str(widget['cursor']) not in ['', 'arrow']:
# Hack - highlight widgets like HyperlinkLabel with a non-default cursor
if 'fg' not in attribs:
widget.configure(foreground=self.current['highlight']),
if 'insertbackground' in widget.keys(): # tk.Entry
widget.configure(insertbackground=self.current['foreground']),
if 'bg' not in attribs:
widget.configure(background=self.current['background'])
if 'highlightbackground' in widget.keys(): # tk.Entry
widget.configure(highlightbackground=self.current['background'])
if 'font' not in attribs:
widget.configure(font=self.current['font'])
elif 'activeforeground' in widget.keys():
# e.g. tk.Button, tk.Label, tk.Menu
if 'fg' not in attribs:
widget.configure(foreground=self.current['foreground'],
activeforeground=self.current['activeforeground'],
disabledforeground=self.current['disabledforeground'])
if 'bg' not in attribs:
widget.configure(background=self.current['background'],
activebackground=self.current['activebackground'])
if sys.platform == 'darwin' and isinstance(widget, tk.Button):
widget.configure(highlightbackground=self.current['background'])
if 'font' not in attribs:
widget.configure(font=self.current['font'])
elif 'foreground' in widget.keys():
# e.g. ttk.Label
if 'fg' not in attribs:
widget.configure(foreground=self.current['foreground']),
if 'bg' not in attribs:
widget.configure(background=self.current['background'])
if 'font' not in attribs:
widget.configure(font=self.current['font'])
elif 'background' in widget.keys() or isinstance(widget, tk.Canvas):
# e.g. Frame, Canvas
if 'bg' not in attribs:
widget.configure(background=self.current['background'],
highlightbackground=self.current['disabledforeground'])
try:
if isinstance(widget, tk.BitmapImage):
# not a widget
if 'fg' not in attribs:
widget.configure(foreground=self.current['foreground']),
if 'bg' not in attribs:
widget.configure(background=self.current['background'])
elif 'cursor' in widget.keys() and str(widget['cursor']) not in ['', 'arrow']:
# Hack - highlight widgets like HyperlinkLabel with a non-default cursor
if 'fg' not in attribs:
widget.configure(foreground=self.current['highlight']),
if 'insertbackground' in widget.keys(): # tk.Entry
widget.configure(insertbackground=self.current['foreground']),
if 'bg' not in attribs:
widget.configure(background=self.current['background'])
if 'highlightbackground' in widget.keys(): # tk.Entry
widget.configure(highlightbackground=self.current['background'])
if 'font' not in attribs:
widget.configure(font=self.current['font'])
elif 'activeforeground' in widget.keys():
# e.g. tk.Button, tk.Label, tk.Menu
if 'fg' not in attribs:
widget.configure(foreground=self.current['foreground'],
activeforeground=self.current['activeforeground'],
disabledforeground=self.current['disabledforeground'])
if 'bg' not in attribs:
widget.configure(background=self.current['background'],
activebackground=self.current['activebackground'])
if sys.platform == 'darwin' and isinstance(widget, tk.Button):
widget.configure(highlightbackground=self.current['background'])
if 'font' not in attribs:
widget.configure(font=self.current['font'])
elif 'foreground' in widget.keys():
# e.g. ttk.Label
if 'fg' not in attribs:
widget.configure(foreground=self.current['foreground']),
if 'bg' not in attribs:
widget.configure(background=self.current['background'])
if 'font' not in attribs:
widget.configure(font=self.current['font'])
elif 'background' in widget.keys() or isinstance(widget, tk.Canvas):
# e.g. Frame, Canvas
if 'bg' not in attribs:
widget.configure(background=self.current['background'],
highlightbackground=self.current['disabledforeground'])
except Exception:
logger.exception(f'Plugin widget issue ? {widget=}')
# Apply configured theme