1
0
mirror of https://github.com/EDCD/EDMarketConnector.git synced 2025-04-21 11:27:38 +03:00

Merge branch 'release-4.2.1' into releases

This commit is contained in:
Athanasius 2021-03-15 19:38:13 +00:00
commit 52f9320c44
20 changed files with 371 additions and 34 deletions

View File

@ -1,6 +1,40 @@
This is the master changelog for Elite Dangerous Market Connector. Entries are in reverse chronological order (latest first).
---
Release 4.2.1
===
This is a bug-fix release.
* Updated translations. Thanks once again to all those contributing as per
[Translations](https://github.com/EDCD/EDMarketConnector/wiki/Translations).
* PLUGINS.md: Clarify when `CargoJSON` is populated.
* macOS: `pip install -r requirements.txt` will now include `pyobjc` so that
running this application works at all. Check the updated [Running from
source](https://github.com/EDCD/EDMarketConnector/wiki/Running-from-source)
for some advice if attempting to run on macOS.
* JournalLock: Handle when the Journal directory isn't set at all, rather than
erroring. Fixes [#910 - Not launching (Linux)](https://github.com/EDCD/EDMarketConnector/issues/910).
* Extra logging added to track down cause of [#909 - Authentication not possible (PC)](https://github.com/EDCD/EDMarketConnector/issues/909)
. The debug log file might now indicate what's wrong, or we might need
you to run
```
"c:\Program Files (x86)\EDMarketConnector/EDMarketConnector.exe" --trace
```
in order to increase the log level and gather some extra information.
Caution is advised if sharing a `--trace` log file as it will now contain
some of the actual auth data returned from Frontier.
* Ensure that 'Save Raw Data' will work. Fixes [#908 - Raw export of CAPI data broken](https://github.com/EDCD/EDMarketConnector/issues/908).
* Prevent EDDN plugin from erroring when we determine if the commander has
Horizons. Fixes [#907 - Modules is a list not a dict on damaged stations](https://github.com/EDCD/EDMarketConnector/issues/907)
Release 4.2.0
===

View File

@ -33,7 +33,7 @@ if __name__ == '__main__':
# After the redirect in case config does logging setup
from config import appversion, appversion_nobuild, config, copyright
from EDMCLogging import edmclogger, logger, logging
from journal_lock import JournalLock
from journal_lock import JournalLock, JournalLockResult
if __name__ == '__main__': # noqa: C901
# Command-line arguments
@ -72,16 +72,14 @@ if __name__ == '__main__': # noqa: C901
config.set_auth_force_localserver()
def handle_edmc_callback_or_foregrounding(): # noqa: CCR001
"""
Handle any edmc:// auth callback, else foreground existing window.
"""
"""Handle any edmc:// auth callback, else foreground existing window."""
logger.trace('Begin...')
if platform == 'win32':
# If *this* instance hasn't locked, then another already has and we
# now need to do the edmc:// checks for auth callback
if not locked:
if locked != JournalLockResult.LOCKED:
import ctypes
from ctypes.wintypes import BOOL, HWND, INT, LPARAM, LPCWSTR, LPWSTR
@ -190,7 +188,7 @@ if __name__ == '__main__': # noqa: C901
handle_edmc_callback_or_foregrounding()
if not locked:
if locked == JournalLockResult.ALREADY_LOCKED:
# There's a copy already running.
logger.info("An EDMarketConnector.exe process was already running, exiting.")
@ -697,7 +695,7 @@ class AppWindow(object):
system=data['lastSystem']['name'],
station=data['commander'].get('docked') and '.' + data['lastStarport']['name'] or '',
timestamp=strftime('%Y-%m-%dT%H.%M.%S', localtime())), 'wb') as h:
h.write(json.dumps(data,
h.write(json.dumps(dict(data),
ensure_ascii=False,
indent=2,
sort_keys=True,
@ -920,6 +918,7 @@ class AppWindow(object):
# cAPI auth
def auth(self, event=None):
logger.debug('Received "<<CompanionAuthEvent>>')
try:
companion.session.auth_callback()
# Successfully authenticated with the Frontier website
@ -927,14 +926,18 @@ class AppWindow(object):
if platform == 'darwin':
self.view_menu.entryconfigure(0, state=tk.NORMAL) # Status
self.file_menu.entryconfigure(0, state=tk.NORMAL) # Save Raw Data
else:
self.file_menu.entryconfigure(0, state=tk.NORMAL) # Status
self.file_menu.entryconfigure(1, state=tk.NORMAL) # Save Raw Data
except companion.ServerError as e:
self.status['text'] = str(e)
except Exception as e:
logger.debug('Frontier CAPI Auth:', exc_info=e)
self.status['text'] = str(e)
self.cooldown()
# Handle Status event
@ -1119,7 +1122,7 @@ class AppWindow(object):
initialfile=f'{last_system}{last_starport}.{timestamp}')
if f:
with open(f, 'wb') as h:
h.write(json.dumps(data,
h.write(json.dumps(dict(data),
ensure_ascii=False,
indent=2,
sort_keys=True,

View File

@ -46,6 +46,9 @@
/* Folder selection button on Windows. [prefs.py] */
"Browse..." = "Procházet...";
/* No 'commander' data in CAPI [EDMarketConnector.py] */
"CAPI: No commander data returned" = "CAPI: Nebyla vrácena žádná data komandéra";
/* Federation rank. [stats.py] */
"Cadet" = "Cadet";
@ -226,9 +229,15 @@
/* Hotkey/Shortcut settings prompt on Windows. [prefs.py] */
"Hotkey" = "Klávesová zkratka";
/* Changed journal update_lock failed [monitor.py] */
"Ignore" = "Ignorovat";
/* Section heading in settings. [inara.py] */
"Inara credentials" = "Přihlašovací údaje k Inaře";
/* Changed journal update_lock failed [monitor.py] */
"Journal directory already locked" = "Adresář deníku je již uzamčen";
/* Hotkey/Shortcut settings prompt on OSX. [prefs.py] */
"Keyboard shortcut" = "Klávesová zkratka";
@ -409,6 +418,9 @@
/* Help menu item. [EDMarketConnector.py] */
"Release Notes" = "Poznámky k verzi";
/* Changed journal update_lock failed [monitor.py] */
"Retry" = "Opakovat";
/* Multicrew role label in main window. [EDMarketConnector.py] */
"Role" = "Role";
@ -454,6 +466,9 @@
/* Setting to decide which ship outfitting website to link to - either E:D Shipyard or Coriolis. [prefs.py] */
"Shipyard" = "Loděnice";
/* Status line text that appears when process exit sequence starts [EDMarketConnector.py] */
"Shutting down..." = "Vypínání...";
/* Empire rank. [stats.py] */
"Squire" = "Squire";
@ -475,6 +490,9 @@
/* Main window. [EDMarketConnector.py] */
"System" = "Systém";
/* Changed journal update_lock failed [monitor.py] */
"The new Journal Directory location is already locked.{CR}You can either attempt to resolve this and then Retry, or choose to Ignore this." = "Nové umístění adresáře deníku je již uzamčeno. {CR} Můžete zkusit tento problém vyřešit a Opakovat, nebo Ignorovat.";
/* Appearance setting. [prefs.py] */
"Theme" = "Schéma";

View File

@ -46,6 +46,9 @@
/* Folder selection button on Windows. [prefs.py] */
"Browse..." = "Durchsuchen...";
/* No 'commander' data in CAPI [EDMarketConnector.py] */
"CAPI: No commander data returned" = "CAPI: Keine Kommandanten-Daten erhalten";
/* Federation rank. [stats.py] */
"Cadet" = "Kadett";
@ -226,9 +229,15 @@
/* Hotkey/Shortcut settings prompt on Windows. [prefs.py] */
"Hotkey" = "Hotkey";
/* Changed journal update_lock failed [monitor.py] */
"Ignore" = "Ignorieren";
/* Section heading in settings. [inara.py] */
"Inara credentials" = "Inara-Anmeldedaten";
/* Changed journal update_lock failed [monitor.py] */
"Journal directory already locked" = "Journal-Ordner bereits gesperrt";
/* Hotkey/Shortcut settings prompt on OSX. [prefs.py] */
"Keyboard shortcut" = "Makro";
@ -409,6 +418,9 @@
/* Help menu item. [EDMarketConnector.py] */
"Release Notes" = "Anmerkungen";
/* Changed journal update_lock failed [monitor.py] */
"Retry" = "Wiederholen";
/* Multicrew role label in main window. [EDMarketConnector.py] */
"Role" = "Rolle";
@ -454,6 +466,9 @@
/* Setting to decide which ship outfitting website to link to - either E:D Shipyard or Coriolis. [prefs.py] */
"Shipyard" = "Werft";
/* Status line text that appears when process exit sequence starts [EDMarketConnector.py] */
"Shutting down..." = "Programm schließt...";
/* Empire rank. [stats.py] */
"Squire" = "Knappe";
@ -475,6 +490,9 @@
/* Main window. [EDMarketConnector.py] */
"System" = "System";
/* Changed journal update_lock failed [monitor.py] */
"The new Journal Directory location is already locked.{CR}You can either attempt to resolve this and then Retry, or choose to Ignore this." = "Der neue Journal-Ordnerpfad ist bereits gesperrt.{CR}Du kannst entweder versuchen, das zu beheben und es nochmal zu probieren, oder diese Meldung ignorieren.";
/* Appearance setting. [prefs.py] */
"Theme" = "Theme";

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" = "Telakka";
/* Status line text that appears when process exit sequence starts [EDMarketConnector.py] */
"Shutting down..." = "Sulkeutuu...";
/* Empire rank. [stats.py] */
"Squire" = "Squire";

View File

@ -1,3 +1,9 @@
/* Label for 'UI Scaling' option [prefs.py] */
"UI Scale Percentage" = "Percentuale zoom della UI";
/* Text describing that value '100' means 'default', and changes require a restart [prefs.py] */
"100 means Default{CR}Restart Required for{CR}changes to take effect!" = "100 significa Default{CR}Riavvio Richiesto per{CR}applicare i cambiamenti!";
/* Language name */
"!Language" = "Italiano";
@ -40,6 +46,9 @@
/* Folder selection button on Windows. [prefs.py] */
"Browse..." = "Sfoglia...";
/* No 'commander' data in CAPI [EDMarketConnector.py] */
"CAPI: No commander data returned" = "CAPI: Nessun dato sul commandante";
/* Federation rank. [stats.py] */
"Cadet" = "Cadet";
@ -220,9 +229,15 @@
/* Hotkey/Shortcut settings prompt on Windows. [prefs.py] */
"Hotkey" = "Hotkey";
/* Changed journal update_lock failed [monitor.py] */
"Ignore" = "Ignora";
/* Section heading in settings. [inara.py] */
"Inara credentials" = "Credenziali per Inara";
/* Changed journal update_lock failed [monitor.py] */
"Journal directory already locked" = "cartella Journal già bloccata";
/* Hotkey/Shortcut settings prompt on OSX. [prefs.py] */
"Keyboard shortcut" = "Scorciatoia di tastiera";
@ -403,6 +418,9 @@
/* Help menu item. [EDMarketConnector.py] */
"Release Notes" = "Note di rilascio";
/* Changed journal update_lock failed [monitor.py] */
"Retry" = "Riprova";
/* Multicrew role label in main window. [EDMarketConnector.py] */
"Role" = "Ruolo";
@ -448,6 +466,9 @@
/* Setting to decide which ship outfitting website to link to - either E:D Shipyard or Coriolis. [prefs.py] */
"Shipyard" = "Spazioporto";
/* Status line text that appears when process exit sequence starts [EDMarketConnector.py] */
"Shutting down..." = "Spegnimento...";
/* Empire rank. [stats.py] */
"Squire" = "Squire";
@ -469,6 +490,9 @@
/* Main window. [EDMarketConnector.py] */
"System" = "Sistema";
/* Changed journal update_lock failed [monitor.py] */
"The new Journal Directory location is already locked.{CR}You can either attempt to resolve this and then Retry, or choose to Ignore this." = "La nuova cartella dove risiede il Journal è già bloccata.{CR}Puoi provare a risolvere Riprovando, oppure scegliere di ignorare la cosa.";
/* Appearance setting. [prefs.py] */
"Theme" = "Tema";

View File

@ -46,6 +46,9 @@
/* Folder selection button on Windows. [prefs.py] */
"Browse..." = "参照...";
/* No 'commander' data in CAPI [EDMarketConnector.py] */
"CAPI: No commander data returned" = "CAPI: コマンダーのデータが返ってきませんでした";
/* Federation rank. [stats.py] */
"Cadet" = "Cadet";
@ -226,9 +229,15 @@
/* Hotkey/Shortcut settings prompt on Windows. [prefs.py] */
"Hotkey" = "ホットキー";
/* Changed journal update_lock failed [monitor.py] */
"Ignore" = "無視";
/* Section heading in settings. [inara.py] */
"Inara credentials" = "Inara認証情報";
/* Changed journal update_lock failed [monitor.py] */
"Journal directory already locked" = "ジャーナルディレクトリは既にロックされています";
/* Hotkey/Shortcut settings prompt on OSX. [prefs.py] */
"Keyboard shortcut" = "ショートカット";
@ -409,6 +418,9 @@
/* Help menu item. [EDMarketConnector.py] */
"Release Notes" = "リリースノート";
/* Changed journal update_lock failed [monitor.py] */
"Retry" = "再試行";
/* Multicrew role label in main window. [EDMarketConnector.py] */
"Role" = "役割";
@ -454,6 +466,9 @@
/* Setting to decide which ship outfitting website to link to - either E:D Shipyard or Coriolis. [prefs.py] */
"Shipyard" = "造船所";
/* Status line text that appears when process exit sequence starts [EDMarketConnector.py] */
"Shutting down..." = "終了します...";
/* Empire rank. [stats.py] */
"Squire" = "Squire";
@ -475,6 +490,9 @@
/* Main window. [EDMarketConnector.py] */
"System" = "星系";
/* Changed journal update_lock failed [monitor.py] */
"The new Journal Directory location is already locked.{CR}You can either attempt to resolve this and then Retry, or choose to Ignore this." = "新しいジャーナルディレクトリは既にロックされています。{CR}この問題を解決して再試行するか、無視するかを選択してください。";
/* Appearance setting. [prefs.py] */
"Theme" = "テーマ";

View File

@ -1,3 +1,9 @@
/* Label for 'UI Scaling' option [prefs.py] */
"UI Scale Percentage" = "Skalowanie UI";
/* Text describing that value '100' means 'default', and changes require a restart [prefs.py] */
"100 means Default{CR}Restart Required for{CR}changes to take effect!" = "100 oznacza wartość domyślną{CR}Zmiany zostaną wprowadzone po{CR}ponownym uruchomieniu programu!";
/* Language name */
"!Language" = "Polski";
@ -40,6 +46,9 @@
/* Folder selection button on Windows. [prefs.py] */
"Browse..." = "Przeglądaj...";
/* No 'commander' data in CAPI [EDMarketConnector.py] */
"CAPI: No commander data returned" = "CAPI: Nie zwrócono danych dowódcy";
/* Federation rank. [stats.py] */
"Cadet" = "Cadet";
@ -101,7 +110,7 @@
"Delay sending until docked" = "Czekaj z wysłaniem na zadokowanie";
/* Option to disabled Automatic Check For Updates whilst in-game [prefs.py] */
"Disable Automatic Application Updates Check when in-game" = "Wyłącz Sprawdzanie Aktualnej Wersji Aplikacji, gdy jesteś w grze";
"Disable Automatic Application Updates Check when in-game" = "Wyłącz automatyczne wyszukiwanie aktualizacji, gdy jesteś w grze";
/* List of plugins in settings. [prefs.py] */
"Disabled Plugins" = "Pluginy wyłączone";
@ -220,9 +229,15 @@
/* Hotkey/Shortcut settings prompt on Windows. [prefs.py] */
"Hotkey" = "Skr. Klaw.";
/* Changed journal update_lock failed [monitor.py] */
"Ignore" = "Zignoruj";
/* Section heading in settings. [inara.py] */
"Inara credentials" = "Inara - uprawnienia";
/* Changed journal update_lock failed [monitor.py] */
"Journal directory already locked" = "Katalog dziennika zablokowany";
/* Hotkey/Shortcut settings prompt on OSX. [prefs.py] */
"Keyboard shortcut" = "Skrót klawiaturowy";
@ -403,6 +418,9 @@
/* Help menu item. [EDMarketConnector.py] */
"Release Notes" = "Informacje o wersji";
/* Changed journal update_lock failed [monitor.py] */
"Retry" = "Ponów";
/* Multicrew role label in main window. [EDMarketConnector.py] */
"Role" = "Rola";
@ -448,6 +466,9 @@
/* Setting to decide which ship outfitting website to link to - either E:D Shipyard or Coriolis. [prefs.py] */
"Shipyard" = "Stocznia";
/* Status line text that appears when process exit sequence starts [EDMarketConnector.py] */
"Shutting down..." = "Wyłączanie...";
/* Empire rank. [stats.py] */
"Squire" = "Squire";
@ -469,6 +490,9 @@
/* Main window. [EDMarketConnector.py] */
"System" = "System";
/* Changed journal update_lock failed [monitor.py] */
"The new Journal Directory location is already locked.{CR}You can either attempt to resolve this and then Retry, or choose to Ignore this." = "Nowa pozycja katalogu dziennika jest zablokowana. {CR}Możesz spróbować to rozwiązać na własną rękę lub zignorować.";
/* Appearance setting. [prefs.py] */
"Theme" = "Schemat kolorystyczny";
@ -525,3 +549,6 @@
/* Shortcut settings prompt on OSX. [prefs.py] */
"{APP} needs permission to use shortcuts" = "{APP} wymaga uprawnień by{CR}móc korzystać ze skrótów klawiszowych.";
/* Label for user configured level of logging [prefs.py] */
"Log Level" = "Poziom logowania";

View File

@ -46,6 +46,9 @@
/* Folder selection button on Windows. [prefs.py] */
"Browse..." = "Procurar...";
/* No 'commander' data in CAPI [EDMarketConnector.py] */
"CAPI: No commander data returned" = "CAPI: Dados do Comandante não recebidos";
/* Federation rank. [stats.py] */
"Cadet" = "Cadete";
@ -226,9 +229,15 @@
/* Hotkey/Shortcut settings prompt on Windows. [prefs.py] */
"Hotkey" = "Tecla Rápida";
/* Changed journal update_lock failed [monitor.py] */
"Ignore" = "Ignorar";
/* Section heading in settings. [inara.py] */
"Inara credentials" = "Credenciais Inara";
/* Changed journal update_lock failed [monitor.py] */
"Journal directory already locked" = "Directório do Diário já se encontra bloqueado";
/* Hotkey/Shortcut settings prompt on OSX. [prefs.py] */
"Keyboard shortcut" = "Atalho de Teclado";
@ -409,6 +418,9 @@
/* Help menu item. [EDMarketConnector.py] */
"Release Notes" = "Notas da Versão";
/* Changed journal update_lock failed [monitor.py] */
"Retry" = "Tentar Novamente";
/* Multicrew role label in main window. [EDMarketConnector.py] */
"Role" = "Função";
@ -454,6 +466,9 @@
/* Setting to decide which ship outfitting website to link to - either E:D Shipyard or Coriolis. [prefs.py] */
"Shipyard" = "Estaleiro";
/* Status line text that appears when process exit sequence starts [EDMarketConnector.py] */
"Shutting down..." = "A Desligar...";
/* Empire rank. [stats.py] */
"Squire" = "Escudeiro";
@ -475,6 +490,9 @@
/* Main window. [EDMarketConnector.py] */
"System" = "Sistema";
/* Changed journal update_lock failed [monitor.py] */
"The new Journal Directory location is already locked.{CR}You can either attempt to resolve this and then Retry, or choose to Ignore this." = "O novo directório do Diário já se encontra bloqueado.{CR}Pode tentar resolver este problema e depois Tentar Novamente, ou Ignorar isto.";
/* Appearance setting. [prefs.py] */
"Theme" = "Tema";

View File

@ -46,6 +46,9 @@
/* Folder selection button on Windows. [prefs.py] */
"Browse..." = "Просмотреть...";
/* No 'commander' data in CAPI [EDMarketConnector.py] */
"CAPI: No commander data returned" = "CAPI: Нет данных пилота";
/* Federation rank. [stats.py] */
"Cadet" = "Кадет";
@ -226,9 +229,15 @@
/* Hotkey/Shortcut settings prompt on Windows. [prefs.py] */
"Hotkey" = "Горячая клавиша";
/* Changed journal update_lock failed [monitor.py] */
"Ignore" = "Игнорировать";
/* Section heading in settings. [inara.py] */
"Inara credentials" = "Учётные данные Inara";
/* Changed journal update_lock failed [monitor.py] */
"Journal directory already locked" = "Каталог журнала уже заблокирован";
/* Hotkey/Shortcut settings prompt on OSX. [prefs.py] */
"Keyboard shortcut" = "Сочетание клавиш";
@ -409,6 +418,9 @@
/* Help menu item. [EDMarketConnector.py] */
"Release Notes" = "Заметки о текущем релизе";
/* Changed journal update_lock failed [monitor.py] */
"Retry" = "Повтор";
/* Multicrew role label in main window. [EDMarketConnector.py] */
"Role" = "Роль";
@ -454,6 +466,9 @@
/* Setting to decide which ship outfitting website to link to - either E:D Shipyard or Coriolis. [prefs.py] */
"Shipyard" = "Верфи";
/* Status line text that appears when process exit sequence starts [EDMarketConnector.py] */
"Shutting down..." = "Выключение...";
/* Empire rank. [stats.py] */
"Squire" = "Оруженосец";
@ -475,6 +490,9 @@
/* Main window. [EDMarketConnector.py] */
"System" = "Система";
/* Changed journal update_lock failed [monitor.py] */
"The new Journal Directory location is already locked.{CR}You can either attempt to resolve this and then Retry, or choose to Ignore this." = "Каталог журнала заблокирован..{CR}Вы можете устранить ошибку и нажать \"Повтор\", или игнорировать эту ошибку.";
/* Appearance setting. [prefs.py] */
"Theme" = "Тема оформления";

View File

@ -46,6 +46,9 @@
/* Folder selection button on Windows. [prefs.py] */
"Browse..." = "Potraži...";
/* No 'commander' data in CAPI [EDMarketConnector.py] */
"CAPI: No commander data returned" = "CAPI: Nema podataka o komandantu";
/* Federation rank. [stats.py] */
"Cadet" = "Cadet";
@ -226,9 +229,15 @@
/* Hotkey/Shortcut settings prompt on Windows. [prefs.py] */
"Hotkey" = "Prečica";
/* Changed journal update_lock failed [monitor.py] */
"Ignore" = "Ignoriši";
/* Section heading in settings. [inara.py] */
"Inara credentials" = "Kredencijali za Inara";
/* Changed journal update_lock failed [monitor.py] */
"Journal directory already locked" = "Journal direktorijum je već zaključan";
/* Hotkey/Shortcut settings prompt on OSX. [prefs.py] */
"Keyboard shortcut" = "Prečica";
@ -409,6 +418,9 @@
/* Help menu item. [EDMarketConnector.py] */
"Release Notes" = "Informacije o verziji";
/* Changed journal update_lock failed [monitor.py] */
"Retry" = "Probaj ponovo";
/* Multicrew role label in main window. [EDMarketConnector.py] */
"Role" = "Uloga";
@ -454,6 +466,9 @@
/* Setting to decide which ship outfitting website to link to - either E:D Shipyard or Coriolis. [prefs.py] */
"Shipyard" = "Brodogradilište";
/* Status line text that appears when process exit sequence starts [EDMarketConnector.py] */
"Shutting down..." = "Zatvaranje programa...";
/* Empire rank. [stats.py] */
"Squire" = "Squire";
@ -475,6 +490,9 @@
/* Main window. [EDMarketConnector.py] */
"System" = "Sistem";
/* Changed journal update_lock failed [monitor.py] */
"The new Journal Directory location is already locked.{CR}You can either attempt to resolve this and then Retry, or choose to Ignore this." = "Novi journal direktorijum je već zaključan.{CR}Možete pokušati da riješite problem i Probate ponovo ili da ga Ignorišete.";
/* Appearance setting. [prefs.py] */
"Theme" = "Tema";

View File

@ -46,6 +46,9 @@
/* Folder selection button on Windows. [prefs.py] */
"Browse..." = "Potraži...";
/* No 'commander' data in CAPI [EDMarketConnector.py] */
"CAPI: No commander data returned" = "CAPI: Nema podataka o komandiru";
/* Federation rank. [stats.py] */
"Cadet" = "Cadet";
@ -226,9 +229,15 @@
/* Hotkey/Shortcut settings prompt on Windows. [prefs.py] */
"Hotkey" = "Skraćenica";
/* Changed journal update_lock failed [monitor.py] */
"Ignore" = "Ignoriši";
/* Section heading in settings. [inara.py] */
"Inara credentials" = "Inara kredencijali";
/* Changed journal update_lock failed [monitor.py] */
"Journal directory already locked" = "Žurnal direktorijum je već zaključan";
/* Hotkey/Shortcut settings prompt on OSX. [prefs.py] */
"Keyboard shortcut" = "Skraćenica";
@ -409,6 +418,9 @@
/* Help menu item. [EDMarketConnector.py] */
"Release Notes" = "Informacije o ovoj verziji";
/* Changed journal update_lock failed [monitor.py] */
"Retry" = "Probaj ponovo";
/* Multicrew role label in main window. [EDMarketConnector.py] */
"Role" = "Uloga";
@ -454,6 +466,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..." = "Gasim...";
/* Empire rank. [stats.py] */
"Squire" = "Squire";
@ -475,6 +490,9 @@
/* Main window. [EDMarketConnector.py] */
"System" = "Sistem";
/* Changed journal update_lock failed [monitor.py] */
"The new Journal Directory location is already locked.{CR}You can either attempt to resolve this and then Retry, or choose to Ignore this." = "Novi Žurnal direktorijum je već zaključan.{CR}Možete probati da rešite problem i probate ponovo ili da ga ignorišete.";
/* Appearance setting. [prefs.py] */
"Theme" = "Tema";

View File

@ -1,3 +1,9 @@
/* Label for 'UI Scaling' option [prefs.py] */
"UI Scale Percentage" = "UI 缩放比例";
/* Text describing that value '100' means 'default', and changes require a restart [prefs.py] */
"100 means Default{CR}Restart Required for{CR}changes to take effect!" = "100 为默认设置{CR}需要重启应用{CR}以使修改生效";
/* Language name */
"!Language" = "简体中文";
@ -40,6 +46,9 @@
/* Folder selection button on Windows. [prefs.py] */
"Browse..." = "浏览…";
/* No 'commander' data in CAPI [EDMarketConnector.py] */
"CAPI: No commander data returned" = "CAPI没有指挥官数据";
/* Federation rank. [stats.py] */
"Cadet" = "Cadet";
@ -50,7 +59,7 @@
"Change..." = "更改…";
/* Menu item. [EDMarketConnector.py] */
"Check for Updates..." = "检查可用更新…";
"Check for Updates..." = "检查版本更新…";
/* Federation rank. [stats.py] */
"Chief Petty Officer" = "Chief Petty Officer";
@ -100,6 +109,9 @@
/* Output setting under 'Send system and scan data to the Elite Dangerous Data Network' new in E:D 2.2. [eddn.py] */
"Delay sending until docked" = "延时更新,靠站时再发送";
/* Option to disabled Automatic Check For Updates whilst in-game [prefs.py] */
"Disable Automatic Application Updates Check when in-game" = "当我在玩游戏时,禁止此应用自动检查版本更新。";
/* List of plugins in settings. [prefs.py] */
"Disabled Plugins" = "已禁用插件";
@ -217,9 +229,15 @@
/* Hotkey/Shortcut settings prompt on Windows. [prefs.py] */
"Hotkey" = "快捷键";
/* Changed journal update_lock failed [monitor.py] */
"Ignore" = "忽略";
/* Section heading in settings. [inara.py] */
"Inara credentials" = "Inara 授权凭证";
/* Changed journal update_lock failed [monitor.py] */
"Journal directory already locked" = "日志目录已被锁定";
/* Hotkey/Shortcut settings prompt on OSX. [prefs.py] */
"Keyboard shortcut" = "键盘快捷键";
@ -334,6 +352,18 @@
/* Section heading in settings. [prefs.py] */
"Plugins folder" = "插件文件夹";
/* Popup title: Warning about plugins without Python 3.x support [EDMarketConnector.py] */
"EDMC: Plugins Without Python 3.x Support" = "EDMC不支持 Python 3.x 的插件";
/* Popup body: Warning about plugins without Python 3.x support [EDMarketConnector.py] */
"One or more of your enabled plugins do not yet have support for Python 3.x. Please see the list on the '{PLUGINS}' tab of '{FILE}' > '{SETTINGS}'. You should check if there is an updated version available, else alert the developer that they need to update the code for Python 3.x.\r\n\r\nYou can disable a plugin by renaming its folder to have '{DISABLED}' on the end of the name." = "一项或多项你所启用的插件尚不支持 Python 3.x详情请见 {FILE} > {SETTINGS} > {PLUGINS}。请检查上述插件是否有可用的更新,若没有,则应与插件的开发者就 Python 3.x 的支持问题取得联系。\n\n你也可以禁用某一项插件只需在其文件夹名称的末尾添加 {DISABLED} 即可。";
/* Settings>Plugins>Plugins without Python 3.x support [prefs.py] */
"Plugins Without Python 3.x Support" = "不支持 Python 3.x 的插件";
/* Settings>Plugins>Information on migrating plugins [prefs.py] */
"Information on migrating plugins" = "关于插件迁移";
/* Federation rank. [stats.py] */
"Post Captain" = "Post Captain";
@ -388,6 +418,9 @@
/* Help menu item. [EDMarketConnector.py] */
"Release Notes" = "更新说明";
/* Changed journal update_lock failed [monitor.py] */
"Retry" = "重试";
/* Multicrew role label in main window. [EDMarketConnector.py] */
"Role" = "角色";
@ -433,6 +466,9 @@
/* Setting to decide which ship outfitting website to link to - either E:D Shipyard or Coriolis. [prefs.py] */
"Shipyard" = "配船";
/* Status line text that appears when process exit sequence starts [EDMarketConnector.py] */
"Shutting down..." = "应用关闭中…";
/* Empire rank. [stats.py] */
"Squire" = "Squire";
@ -454,6 +490,9 @@
/* Main window. [EDMarketConnector.py] */
"System" = "星系";
/* Changed journal update_lock failed [monitor.py] */
"The new Journal Directory location is already locked.{CR}You can either attempt to resolve this and then Retry, or choose to Ignore this." = "新的日志目录位置已被锁定。{CR}你可以尝试解锁并“重试”以解决此问题,或者选择“忽略”。";
/* Appearance setting. [prefs.py] */
"Theme" = "主题";
@ -475,6 +514,9 @@
/* Update button in main window. [EDMarketConnector.py] */
"Update" = "更新";
/* Option to use alternate URL method on shipyard links [prefs.py] */
"Use alternate URL method" = "若链接过长无法打开,请勾选此项";
/* Status dialog subtitle - CR value of ship. [stats.py] */
"Value" = "价值";
@ -508,3 +550,5 @@
/* Shortcut settings prompt on OSX. [prefs.py] */
"{APP} needs permission to use shortcuts" = "{APP} 需要权限以使用快捷键";
/* Label for user configured level of logging [prefs.py] */
"Log Level" = "诊断模式";

View File

@ -460,8 +460,13 @@ typically about once a second when in orbital flight.
New in version 4.1.6:
`CargoJSON` contains the raw data from the last read of `cargo.json` passed through json.load.
It contains more information about the cargo contents, such as the mission ID for mission specific cargo
`CargoJSON` contains the raw data from the last read of `Cargo.json` passed
through json.load. It contains more information about the cargo contents, such
as the mission ID for mission specific cargo
**NB: Because this is only the data loaded from the `Cargo.json` file, and that
is not written at Commander login (instead the in-Journal `Cargo` event
contains all the data), this will not be populated at login.**
#### Getting Commander Data

View File

@ -263,6 +263,7 @@ class Auth(object):
except (ValueError, requests.RequestException, ):
logger.exception(f"Frontier CAPI Auth: Can't refresh token for \"{self.cmdr}\"")
self.dump(r)
else:
logger.error(f"Frontier CAPI Auth: No token for \"{self.cmdr}\"")
@ -360,7 +361,11 @@ class Auth(object):
# noinspection PyMethodMayBeStatic
def dump(self, r: requests.Response) -> None:
"""Dump details of HTTP failure from oAuth attempt."""
logger.debug(f'Frontier CAPI Auth: {r.url} {r.status_code} {r.reason if r.reason else "None"} {r.text}')
if r:
logger.debug(f'Frontier CAPI Auth: {r.url} {r.status_code} {r.reason if r.reason else "None"} {r.text}')
else:
logger.debug(f'Frontier CAPI Auth: failed with `r` False: {r!r}')
# noinspection PyMethodMayBeStatic
def base64_url_encode(self, text: bytes) -> str:
@ -432,8 +437,8 @@ class Session(object):
# Callback from protocol handler
def auth_callback(self) -> None:
"""Handle callback from edmc:// handler."""
logger.debug('Handling callback from edmc:// handler')
"""Handle callback from edmc:// or localhost:/auth handler."""
logger.debug('Handling auth callback')
if self.state != Session.STATE_AUTH:
# Shouldn't be getting a callback
logger.debug('Got an auth callback while not doing auth')

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.2.0' #-rc1+a872b5f'
appversion = '4.2.1' #-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'

View File

@ -2,6 +2,7 @@
import pathlib
import tkinter as tk
from enum import Enum
from os import getpid as os_getpid
from sys import platform
from tkinter import ttk
@ -17,23 +18,49 @@ if TYPE_CHECKING:
return x
class JournalLockResult(Enum):
"""Enumeration of possible outcomes of trying to lock the Journal Directory."""
LOCKED = 1
JOURNALDIR_NOTEXIST = 2
JOURNALDIR_READONLY = 3
ALREADY_LOCKED = 4
JOURNALDIR_IS_NONE = 5
class JournalLock:
"""Handle locking of journal directory."""
def __init__(self) -> None:
"""Initialise where the journal directory and lock file are."""
self.journal_dir: str = config.get('journaldir') or config.default_journal_dir
self.journal_dir_path = pathlib.Path(self.journal_dir)
self.journal_dir_path: Optional[pathlib.Path] = None
self.set_path_from_journaldir()
self.journal_dir_lockfile_name: Optional[pathlib.Path] = None
# We never test truthiness of this, so let it be defined when first assigned. Avoids type hint issues.
# self.journal_dir_lockfile: Optional[IO] = None
self.locked = False
def obtain_lock(self) -> bool:
def set_path_from_journaldir(self):
if self.journal_dir is None:
self.journal_dir_path = None
else:
try:
self.journal_dir_path = pathlib.Path(self.journal_dir)
except Exception:
logger.exception("Couldn't make pathlib.Path from journal_dir")
def obtain_lock(self) -> JournalLockResult:
"""
Attempt to obtain a lock on the journal directory.
:return: bool - True if we successfully obtained the lock
:return: LockResult - See the class Enum definition
"""
if self.journal_dir_path is None:
return JournalLockResult.JOURNALDIR_IS_NONE
self.journal_dir_lockfile_name = self.journal_dir_path / 'edmc-journal-lock.txt'
logger.trace(f'journal_dir_lockfile_name = {self.journal_dir_lockfile_name!r}')
try:
@ -44,7 +71,7 @@ class JournalLock:
except Exception as e: # For remote FS this could be any of a wide range of exceptions
logger.warning(f"Couldn't open \"{self.journal_dir_lockfile_name}\" for \"w+\""
f" Aborting duplicate process checks: {e!r}")
return False
return JournalLockResult.JOURNALDIR_READONLY
if platform == 'win32':
logger.trace('win32, using msvcrt')
@ -57,7 +84,7 @@ class JournalLock:
except Exception as e:
logger.info(f"Exception: Couldn't lock journal directory \"{self.journal_dir}\""
f", assuming another process running: {e!r}")
return False
return JournalLockResult.ALREADY_LOCKED
else:
logger.trace('NOT win32, using fcntl')
@ -67,7 +94,7 @@ class JournalLock:
except ImportError:
logger.warning("Not on win32 and we have no fcntl, can't use a file lock!"
"Allowing multiple instances!")
return True # Lie about being locked
return JournalLockResult.LOCKED
try:
fcntl.flock(self.journal_dir_lockfile, fcntl.LOCK_EX | fcntl.LOCK_NB)
@ -75,20 +102,25 @@ class JournalLock:
except Exception as e:
logger.info(f"Exception: Couldn't lock journal directory \"{self.journal_dir}\", "
f"assuming another process running: {e!r}")
return False
return JournalLockResult.ALREADY_LOCKED
self.journal_dir_lockfile.write(f"Path: {self.journal_dir}\nPID: {os_getpid()}\n")
self.journal_dir_lockfile.flush()
logger.trace('Done')
return True
self.locked = True
return JournalLockResult.LOCKED
def release_lock(self) -> bool:
"""
Release lock on journal directory.
:return: bool - Success of unlocking operation.
:return: bool - Whether we're now unlocked.
"""
if not self.locked:
return True # We weren't locked, and still aren't
unlocked = False
if platform == 'win32':
logger.trace('win32, using msvcrt')
@ -206,8 +238,9 @@ class JournalLock:
self.release_lock()
self.journal_dir = current_journaldir
self.journal_dir_path = pathlib.Path(self.journal_dir)
if not self.obtain_lock():
self.set_path_from_journaldir()
if self.obtain_lock() == JournalLockResult.ALREADY_LOCKED:
# Pop-up message asking for Retry or Ignore
self.retry_popup = self.JournalAlreadyLocked(parent, self.retry_lock)
@ -225,7 +258,7 @@ class JournalLock:
current_journaldir = config.get('journaldir') or config.default_journal_dir
self.journal_dir = current_journaldir
self.journal_dir_path = pathlib.Path(self.journal_dir)
if not self.obtain_lock():
self.set_path_from_journaldir()
if self.obtain_lock() == JournalLockResult.ALREADY_LOCKED:
# Pop-up message asking for Retry or Ignore
self.retry_popup = self.JournalAlreadyLocked(parent, self.retry_lock)

View File

@ -789,8 +789,30 @@ MAP_STR_ANY = Mapping[str, Any]
def is_horizons(economies: MAP_STR_ANY, modules: MAP_STR_ANY, ships: MAP_STR_ANY) -> bool:
return (
any(economy['name'] == 'Colony' for economy in economies.values()) or
any(module.get('sku') == HORIZ_SKU for module in modules.values()) or
any(ship.get('sku') == HORIZ_SKU for ship in (ships['shipyard_list'] or {}).values())
)
economies_colony = False
modules_horizons = False
ship_horizons = False
if isinstance(economies, dict):
economies_colony = any(economy['name'] == 'Colony' for economy in economies.values())
else:
logger.error(f'economies type is {type(economies)}')
if isinstance(modules, dict):
modules_horizons = any(module.get('sku') == HORIZ_SKU for module in modules.values())
else:
logger.error(f'modules type is {type(modules)}')
if isinstance(ships, dict):
if ships.get('shipyard_list') is not None:
ship_horizons = any(ship.get('sku') == HORIZ_SKU for ship in ships['shipyard_list'].values())
else:
logger.debug('No ships["shipyard_list"] - Damaged station or FC ?')
else:
logger.error(f'ships type is {type(ships)}')
return economies_colony or modules_horizons or ship_horizons

View File

@ -36,7 +36,9 @@ class GenericProtocolHandler(object):
def event(self, url):
self.lastpayload = url
logger.trace(f'Payload: {self.lastpayload}')
if not config.shutting_down:
logger.debug('event_generate("<<CompanionAuthEvent>>"')
self.master.event_generate('<<CompanionAuthEvent>>', when="tail")
@ -190,12 +192,16 @@ elif sys.platform == 'win32' and getattr(sys, 'frozen', False) and not is_wine a
None)
msg = MSG()
while GetMessage(byref(msg), None, 0, 0) != 0:
logger.trace(f'DDE message of type: {msg.message}')
if msg.message == WM_DDE_EXECUTE:
args = wstring_at(GlobalLock(msg.lParam)).strip()
GlobalUnlock(msg.lParam)
if args.lower().startswith('open("') and args.endswith('")'):
logger.trace(f'args are: {args}')
url = urllib.parse.unquote(args[6:-2]).strip()
logger.trace(f'Parsed url: {url}')
if url.startswith(self.redirect):
logger.debug(f'Message starts with {self.redirect}')
self.event(url)
SetForegroundWindow(GetParent(self.master.winfo_id())) # raise app window
PostMessage(msg.wParam, WM_DDE_ACK, hwnd, PackDDElParam(WM_DDE_ACK, 0x80, msg.lParam))
@ -242,8 +248,10 @@ else: # Linux / Run from source
class HTTPRequestHandler(BaseHTTPRequestHandler):
def parse(self):
logger.trace(f'Got message on path: {self.path}')
url = urllib.parse.unquote(self.path)
if url.startswith('/auth'):
logger.debug('Request starts with /auth, sending to protocolhandler.event()')
protocolhandler.event(url)
self.send_response(200)
return True

View File

@ -4,3 +4,6 @@ watchdog==0.10.3
# argh==0.26.2 watchdog dep
# pyyaml==5.3.1 watchdog dep
semantic-version==2.8.5
# Base requirement for MacOS
pyobjc; sys_platform == 'darwin'