mirror of
https://github.com/EDCD/EDMarketConnector.git
synced 2025-04-15 00:30:33 +03:00
Trace: Add support to EDMC.py & misc cleanups
* EDMC: Add --trace (to match EDMarketConnector.py) and TRACE as option to --loglevel. * EDMC: docstrings added. * EDMCLogging: Set logger name based on if GUI or CLI. * EDMarketConnector: * Re-order imports. * Misc. formatting cleanups. * f-strings not .format(). * Removed un-necessary "# noqa: N806" comments.
This commit is contained in:
parent
46e3b3aff8
commit
3c0ac76f90
69
EDMC.py
69
EDMC.py
@ -1,19 +1,23 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
#
|
"""Command-line interface. Requires prior setup through the GUI."""
|
||||||
# Command-line interface. Requires prior setup through the GUI.
|
|
||||||
#
|
|
||||||
|
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
import locale
|
import locale
|
||||||
import logging
|
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
from os.path import getmtime, join
|
from os.path import getmtime, join
|
||||||
from time import sleep, time
|
from time import sleep, time
|
||||||
from typing import Any, Optional
|
from typing import TYPE_CHECKING, Any, Optional
|
||||||
|
|
||||||
|
# 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)
|
||||||
|
|
||||||
# workaround for https://github.com/EDCD/EDMarketConnector/issues/568
|
# workaround for https://github.com/EDCD/EDMarketConnector/issues/568
|
||||||
os.environ["EDMC_NO_UI"] = "1"
|
os.environ["EDMC_NO_UI"] = "1"
|
||||||
@ -21,7 +25,6 @@ os.environ["EDMC_NO_UI"] = "1"
|
|||||||
import collate
|
import collate
|
||||||
import commodity
|
import commodity
|
||||||
import companion
|
import companion
|
||||||
import EDMCLogging
|
|
||||||
import edshipyard
|
import edshipyard
|
||||||
import l10n
|
import l10n
|
||||||
import loadout
|
import loadout
|
||||||
@ -40,11 +43,9 @@ sys.path.append(config.internal_plugin_dir)
|
|||||||
import eddn # noqa: E402
|
import eddn # noqa: E402
|
||||||
# isort: on
|
# isort: on
|
||||||
|
|
||||||
logger = EDMCLogging.Logger(appcmdname).get_logger()
|
|
||||||
logger.setLevel(logging.INFO)
|
|
||||||
|
|
||||||
|
|
||||||
def log_locale(prefix: str) -> None:
|
def log_locale(prefix: str) -> None:
|
||||||
|
"""Log the current state of locale settings."""
|
||||||
logger.debug(f'''Locale: {prefix}
|
logger.debug(f'''Locale: {prefix}
|
||||||
Locale LC_COLLATE: {locale.getlocale(locale.LC_COLLATE)}
|
Locale LC_COLLATE: {locale.getlocale(locale.LC_COLLATE)}
|
||||||
Locale LC_CTYPE: {locale.getlocale(locale.LC_CTYPE)}
|
Locale LC_CTYPE: {locale.getlocale(locale.LC_CTYPE)}
|
||||||
@ -62,12 +63,30 @@ EXIT_SUCCESS, EXIT_SERVER, EXIT_CREDENTIALS, EXIT_VERIFICATION, EXIT_LAGGING, EX
|
|||||||
JOURNAL_RE = re.compile(r'^Journal(Beta)?\.[0-9]{12}\.[0-9]{2}\.log$')
|
JOURNAL_RE = re.compile(r'^Journal(Beta)?\.[0-9]{12}\.[0-9]{2}\.log$')
|
||||||
|
|
||||||
|
|
||||||
# quick and dirty version comparison assuming "strict" numeric only version numbers
|
|
||||||
def versioncmp(versionstring):
|
def versioncmp(versionstring):
|
||||||
|
"""Quick and dirty version comparison assuming "strict" numeric only version numbers."""
|
||||||
return list(map(int, versionstring.split('.')))
|
return list(map(int, versionstring.split('.')))
|
||||||
|
|
||||||
|
|
||||||
def deep_get(target: dict, *args: str, default=None) -> Any:
|
def deep_get(target: dict, *args: str, default=None) -> Any:
|
||||||
|
"""
|
||||||
|
Walk into a dict and return the specified deep value.
|
||||||
|
|
||||||
|
Example usage:
|
||||||
|
|
||||||
|
>>> thing = {'a': {'b': {'c': 'foo'} } }
|
||||||
|
>>> deep_get(thing, ('a', 'b', 'c'), None)
|
||||||
|
'foo'
|
||||||
|
>>> deep_get(thing, ('a', 'b'), None)
|
||||||
|
{'c': 'foo'}
|
||||||
|
>>> deep_get(thing, ('a', 'd'), None)
|
||||||
|
None
|
||||||
|
|
||||||
|
:param target: The dict to walk into for the desired value.
|
||||||
|
:param args: The list of keys to walk down through.
|
||||||
|
:param default: What to return if the target has no value.
|
||||||
|
:return: The value at the target deep key.
|
||||||
|
"""
|
||||||
if not hasattr(target, 'get'):
|
if not hasattr(target, 'get'):
|
||||||
raise ValueError(f"Cannot call get on {target} ({type(target)})")
|
raise ValueError(f"Cannot call get on {target} ({type(target)})")
|
||||||
|
|
||||||
@ -83,6 +102,7 @@ def deep_get(target: dict, *args: str, default=None) -> Any:
|
|||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
"""Run the main code of the program."""
|
||||||
try:
|
try:
|
||||||
# arg parsing
|
# arg parsing
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
@ -93,7 +113,16 @@ def main():
|
|||||||
)
|
)
|
||||||
|
|
||||||
parser.add_argument('-v', '--version', help='print program version and exit', action='store_const', const=True)
|
parser.add_argument('-v', '--version', help='print program version and exit', action='store_const', const=True)
|
||||||
parser.add_argument('--loglevel', metavar='loglevel', help='Set the logging loglevel to one of: CRITICAL, ERROR, WARNING, INFO, DEBUG') # noqa: E501
|
group_loglevel = parser.add_mutually_exclusive_group()
|
||||||
|
group_loglevel.add_argument('--loglevel',
|
||||||
|
metavar='loglevel',
|
||||||
|
help='Set the logging loglevel to one of: '
|
||||||
|
'CRITICAL, ERROR, WARNING, INFO, DEBUG, TRACE',
|
||||||
|
)
|
||||||
|
group_loglevel.add_argument('--trace',
|
||||||
|
help='Set the Debug logging loglevel to TRACE',
|
||||||
|
action='store_true',
|
||||||
|
)
|
||||||
parser.add_argument('-a', metavar='FILE', help='write ship loadout to FILE in Companion API json format')
|
parser.add_argument('-a', metavar='FILE', help='write ship loadout to FILE in Companion API json format')
|
||||||
parser.add_argument('-e', metavar='FILE', help='write ship loadout to FILE in E:D Shipyard plain text format')
|
parser.add_argument('-e', metavar='FILE', help='write ship loadout to FILE in E:D Shipyard plain text format')
|
||||||
parser.add_argument('-l', metavar='FILE', help='write ship locations to FILE in CSV format')
|
parser.add_argument('-l', metavar='FILE', help='write ship locations to FILE in CSV format')
|
||||||
@ -117,11 +146,14 @@ def main():
|
|||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
if args.loglevel:
|
if args.trace:
|
||||||
if args.loglevel not in ('CRITICAL', 'ERROR', 'WARNING', 'INFO', 'DEBUG'):
|
edmclogger.set_channels_loglevel(logging.TRACE)
|
||||||
print('loglevel must be one of: CRITICAL, ERROR, WARNING, INFO, DEBUG', file=sys.stderr)
|
|
||||||
|
elif args.loglevel:
|
||||||
|
if args.loglevel not in ('CRITICAL', 'ERROR', 'WARNING', 'INFO', 'DEBUG', 'TRACE'):
|
||||||
|
print('loglevel must be one of: CRITICAL, ERROR, WARNING, INFO, DEBUG, TRACE', file=sys.stderr)
|
||||||
sys.exit(EXIT_ARGS)
|
sys.exit(EXIT_ARGS)
|
||||||
logger.setLevel(args.loglevel)
|
edmclogger.set_channels_loglevel(args.loglevel)
|
||||||
|
|
||||||
logger.debug(f'Startup v{appversion} : Running on Python v{sys.version}')
|
logger.debug(f'Startup v{appversion} : Running on Python v{sys.version}')
|
||||||
logger.debug(f'''Platform: {sys.platform}
|
logger.debug(f'''Platform: {sys.platform}
|
||||||
@ -250,10 +282,9 @@ sys.path: {sys.path}'''
|
|||||||
stats.export_status(data, args.t)
|
stats.export_status(data, args.t)
|
||||||
|
|
||||||
if data['commander'].get('docked'):
|
if data['commander'].get('docked'):
|
||||||
print('{},{}'.format(
|
print(f'{deep_get(data, "lastSystem", "name", default="Unknown")},'
|
||||||
deep_get(data, 'lastSystem', 'name', default='Unknown'),
|
f'{deep_get(data, "lastStarport", "name", default="Unknown")}'
|
||||||
deep_get(data, 'lastStarport', 'name', default='Unknown')
|
)
|
||||||
))
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
print(deep_get(data, 'lastSystem', 'name', default='Unknown'))
|
print(deep_get(data, 'lastSystem', 'name', default='Unknown'))
|
||||||
|
@ -381,5 +381,11 @@ def get_main_logger() -> logging.Logger:
|
|||||||
loglevel = config.get('loglevel')
|
loglevel = config.get('loglevel')
|
||||||
if not loglevel:
|
if not loglevel:
|
||||||
loglevel = logging.INFO
|
loglevel = logging.INFO
|
||||||
edmclogger = Logger(appname, loglevel=loglevel)
|
|
||||||
|
if not os.getenv('EDMC_NO_UI'):
|
||||||
|
base_logger_name = appname
|
||||||
|
else:
|
||||||
|
base_logger_name = appcmdname
|
||||||
|
|
||||||
|
edmclogger = Logger(base_logger_name, loglevel=loglevel)
|
||||||
logger = edmclogger.get_logger()
|
logger = edmclogger.get_logger()
|
||||||
|
@ -2,20 +2,27 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
from builtins import str
|
import html
|
||||||
from builtins import object
|
|
||||||
import sys
|
|
||||||
from sys import platform
|
|
||||||
import json
|
import json
|
||||||
import locale
|
import locale
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
import webbrowser
|
||||||
|
from builtins import object, str
|
||||||
from os import chdir, environ
|
from os import chdir, environ
|
||||||
from os.path import dirname, isdir, join
|
from os.path import dirname, isdir, join
|
||||||
import re
|
from sys import platform
|
||||||
import html
|
from time import localtime, strftime, time
|
||||||
from time import time, localtime, strftime
|
from typing import TYPE_CHECKING
|
||||||
import webbrowser
|
|
||||||
|
|
||||||
from config import appname, applongname, appversion, appversion_nobuild, copyright, config
|
from EDMCLogging import edmclogger, logger, logging
|
||||||
|
|
||||||
|
# isort: off
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from logging import trace, TRACE # type: ignore # noqa: F401
|
||||||
|
# isort: on
|
||||||
|
|
||||||
|
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
|
# TODO: Test: Make *sure* this redirect is working, else py2exe is going to cause an exit popup
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
@ -37,10 +44,11 @@ if getattr(sys, 'frozen', False):
|
|||||||
environ['TK_LIBRARY'] = join(dirname(sys.path[0]), 'lib', 'tk')
|
environ['TK_LIBRARY'] = join(dirname(sys.path[0]), 'lib', 'tk')
|
||||||
|
|
||||||
import tkinter as tk
|
import tkinter as tk
|
||||||
from tkinter import ttk
|
|
||||||
import tkinter.filedialog
|
import tkinter.filedialog
|
||||||
import tkinter.font
|
import tkinter.font
|
||||||
import tkinter.messagebox
|
import tkinter.messagebox
|
||||||
|
from tkinter import ttk
|
||||||
|
|
||||||
from ttkHyperlinkLabel import HyperlinkLabel
|
from ttkHyperlinkLabel import HyperlinkLabel
|
||||||
|
|
||||||
if __debug__:
|
if __debug__:
|
||||||
@ -50,18 +58,18 @@ if __debug__:
|
|||||||
|
|
||||||
signal.signal(signal.SIGTERM, lambda sig, frame: pdb.Pdb().set_trace(frame))
|
signal.signal(signal.SIGTERM, lambda sig, frame: pdb.Pdb().set_trace(frame))
|
||||||
|
|
||||||
import companion
|
|
||||||
import commodity
|
import commodity
|
||||||
from commodity import COMMODITY_CSV
|
import companion
|
||||||
import td
|
|
||||||
import stats
|
|
||||||
import prefs
|
|
||||||
import plug
|
import plug
|
||||||
|
import prefs
|
||||||
|
import stats
|
||||||
|
import td
|
||||||
|
from commodity import COMMODITY_CSV
|
||||||
|
from dashboard import dashboard
|
||||||
from hotkey import hotkeymgr
|
from hotkey import hotkeymgr
|
||||||
from l10n import Translations
|
from l10n import Translations
|
||||||
from monitor import monitor
|
from monitor import monitor
|
||||||
from protocol import protocolhandler
|
from protocol import protocolhandler
|
||||||
from dashboard import dashboard
|
|
||||||
from theme import theme
|
from theme import theme
|
||||||
|
|
||||||
SERVER_RETRY = 5 # retry pause for Companion servers [s]
|
SERVER_RETRY = 5 # retry pause for Companion servers [s]
|
||||||
@ -935,7 +943,8 @@ class AppWindow(object):
|
|||||||
def onexit(self, event=None):
|
def onexit(self, event=None):
|
||||||
# http://core.tcl.tk/tk/tktview/c84f660833546b1b84e7
|
# http://core.tcl.tk/tk/tktview/c84f660833546b1b84e7
|
||||||
if platform != 'darwin' or self.w.winfo_rooty() > 0:
|
if platform != 'darwin' or self.w.winfo_rooty() > 0:
|
||||||
config.set('geometry', '+{1}+{2}'.format(*self.w.geometry().split('+')))
|
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
|
self.w.withdraw() # Following items can take a few seconds, so hide the main window while they happen
|
||||||
protocolhandler.close()
|
protocolhandler.close()
|
||||||
hotkeymgr.unregister()
|
hotkeymgr.unregister()
|
||||||
@ -987,13 +996,13 @@ def enforce_single_instance() -> None:
|
|||||||
# Ensure only one copy of the app is running under this user account. OSX does this automatically. Linux TODO.
|
# Ensure only one copy of the app is running under this user account. OSX does this automatically. Linux TODO.
|
||||||
if platform == 'win32':
|
if platform == 'win32':
|
||||||
import ctypes
|
import ctypes
|
||||||
from ctypes.wintypes import HWND, LPWSTR, LPCWSTR, INT, BOOL, LPARAM
|
from ctypes.wintypes import BOOL, HWND, INT, LPARAM, LPCWSTR, LPWSTR
|
||||||
|
|
||||||
EnumWindows = ctypes.windll.user32.EnumWindows # noqa: N806
|
EnumWindows = ctypes.windll.user32.EnumWindows # noqa: N806
|
||||||
GetClassName = ctypes.windll.user32.GetClassNameW # noqa: N806
|
GetClassName = ctypes.windll.user32.GetClassNameW # noqa: N806
|
||||||
GetClassName.argtypes = [HWND, LPWSTR, ctypes.c_int] # noqa: N806
|
GetClassName.argtypes = [HWND, LPWSTR, ctypes.c_int]
|
||||||
GetWindowText = ctypes.windll.user32.GetWindowTextW # noqa: N806
|
GetWindowText = ctypes.windll.user32.GetWindowTextW # noqa: N806
|
||||||
GetWindowText.argtypes = [HWND, LPWSTR, ctypes.c_int] # noqa: N806
|
GetWindowText.argtypes = [HWND, LPWSTR, ctypes.c_int]
|
||||||
GetWindowTextLength = ctypes.windll.user32.GetWindowTextLengthW # noqa: N806
|
GetWindowTextLength = ctypes.windll.user32.GetWindowTextLengthW # noqa: N806
|
||||||
GetProcessHandleFromHwnd = ctypes.windll.oleacc.GetProcessHandleFromHwnd # noqa: N806
|
GetProcessHandleFromHwnd = ctypes.windll.oleacc.GetProcessHandleFromHwnd # noqa: N806
|
||||||
|
|
||||||
@ -1076,11 +1085,6 @@ if __name__ == "__main__":
|
|||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
from EDMCLogging import edmclogger, logger, logging
|
|
||||||
# isort: off
|
|
||||||
from logging import trace, TRACE # type: ignore # noqa: F401
|
|
||||||
# isort: on
|
|
||||||
|
|
||||||
if args.trace:
|
if args.trace:
|
||||||
logger.setLevel(logging.TRACE)
|
logger.setLevel(logging.TRACE)
|
||||||
edmclogger.set_channels_loglevel(logging.TRACE)
|
edmclogger.set_channels_loglevel(logging.TRACE)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user