* EDMCLogging.Logger.get_streamhandler() method to get the
logger_channel so prefs.py can call setLevel() on it.
* The top-level Logger level is always DEBUG.
* The RotatingFileHandler level is always DEBUG.
* The StreamHandler level is as configured by the user.
* EDMCLogging now creates a singleton of EDMCLogging.Logger and its
associated Logger.
* plug.py tweaked to only import EDMCLogging where it's needed for
getting/creating plugin loggers, else `import logging`.
1. This makes setting up logging everywhere slightly more involved.
2. If I then want to change, say, %(module)s value I'll end up needing
to stack walk again.
So this might be better done in a filter. But these commits for the
record, and to come back to if needs be.
* Log messages propagate up Parent.Child chains, so we don't need a
channel on the plugin logger.
* But it still needs the filter to define qualname and class for
formatting.
Using:
from EDMarketConnector import logger
causes issues if EDMarketConnector is already importing 'this' file.
So just get a logger using logger.getLogger(appname) instead.
`from config import appname` if needs be.
This relies on the logger.Formatter setup to fill in function name
rather than calling out exactly why we're logging. It should be
obvious, i.e. if you're in plug.py:notify_journal_entry then the named
plugin threw an un-caught exception trying to call its method for this.
Where it was in EDMarketConnector.py caused issues because then the
main thread was blocking on the popup when other threads expected it to
be running:
---------------------------------------------------------------------
Exception in thread Journal worker:
Traceback (most recent call last):
File "C:\Users\Athan\AppData\Local\Programs\Python\Python37-32\lib\threading.py", line 926, in _bootstrap_inner
self.run()
File "C:\Users\Athan\AppData\Local\Programs\Python\Python37-32\lib\threading.py", line 870, in run
self._target(*self._args, **self._kwargs)
File "C:\Users\Athan\Documents\Devel\EDMarketConnector-python3\monitor.py", line 273, in worker
self.root.event_generate('<<JournalEvent>>', when="tail")
File "C:\Users\Athan\AppData\Local\Programs\Python\Python37-32\lib\tkinter\__init__.py", line 1673, in event_generate
self.tk.call(args)
RuntimeError: main thread is not in main loop
---------------------------------------------------------------------
However *now* it pops up before the main UI is running properly at all,
so the EDMC window is likely out of position, and won't be
painted/themed yet.
This is deemed acceptable for a 'once a day at most' popup.
The popup title now has 'EDMC: ' at the start to be sure users know
what it's talking about.
It also has some brief advice about how to disable a plugin.
First pass utilising 'futurize' to do most of the work.
There's an issue with ur'\"' in l10n.py which I'm not sure how to
properly fix.
This now has errors when hitting the 'Update' button.
To allow users to sort out their plugins before EDMC itself moves to
Python 3.x warn them if any of their enabled, non-stock, plugins do not
have a plugin_start3() method.
* If any are found without support there's a popup triggered at the
end of AppWindow initialisation.
* Then the user can check Settings > Plugins to see a list of the
plugins without Python 3.x support.
Notify plugins when Cmdr or Beta status changes while the preferences dialog
is open.
Display a note on the Credentials tab when Cmdr is not set. Addresses #224