-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' of github.com:DINFO-UniFI/RoofClassify
- Loading branch information
Showing
4 changed files
with
223 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
#! python3 # noqa: E265 | ||
from .log_handler import PlgLogger # noqa: F401 | ||
from .preferences import PlgOptionsManager # noqa: F401 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
#! python3 # noqa: E265 | ||
|
||
# standard library | ||
import logging | ||
|
||
# PyQGIS | ||
from qgis.core import QgsMessageLog | ||
from qgis.utils import iface | ||
|
||
# project package | ||
import roof_classify.toolbelt.preferences as plg_prefs_hdlr | ||
from roof_classify.__about__ import __title__ | ||
|
||
# ############################################################################ | ||
# ########## Classes ############### | ||
# ################################## | ||
|
||
|
||
class PlgLogger(logging.Handler): | ||
"""Python logging handler supercharged with QGIS useful methods.""" | ||
|
||
@staticmethod | ||
def log( | ||
message: str, | ||
application: str = __title__, | ||
log_level: int = 0, | ||
push: bool = False, | ||
): | ||
"""Send messages to QGIS messages windows and to the user as a message bar. \ | ||
Plugin name is used as title. If debug mode is disabled, only warnings (1) and \ | ||
errors (2) or with push are sent. | ||
:param message: message to display | ||
:type message: str | ||
:param application: name of the application sending the message. \ | ||
Defaults to __about__.__title__ | ||
:type application: str, optional | ||
:param log_level: message level. Possible values: 0 (info), 1 (warning), \ | ||
2 (critical), 3 (success), 4 (none - grey). Defaults to 0 (info) | ||
:type log_level: int, optional | ||
:param push: also display the message in the QGIS message bar in addition to \ | ||
the log, defaults to False | ||
:type push: bool, optional | ||
:Example: | ||
.. code-block:: python | ||
log(message="Plugin loaded - INFO", log_level=0, push=1) | ||
log(message="Plugin loaded - WARNING", log_level=1, push=1) | ||
log(message="Plugin loaded - ERROR", log_level=2, push=1) | ||
log(message="Plugin loaded - SUCCESS", log_level=3, push=1) | ||
log(message="Plugin loaded - TEST", log_level=4, push=1) | ||
""" | ||
# if debug mode, let's ignore INFO, SUCCESS and TEST | ||
debug_mode = plg_prefs_hdlr.PlgOptionsManager.get_plg_settings().debug_mode | ||
if not debug_mode and (1 < log_level < 3 or not push): | ||
return | ||
|
||
# ensure message is a string | ||
if not isinstance(message, str): | ||
try: | ||
message = str(message) | ||
except Exception as err: | ||
err_msg = "Log message must be a string, not: {}. Trace: {}".format( | ||
type(message), err | ||
) | ||
logging.error(err_msg) | ||
message = err_msg | ||
|
||
# send it to QGIS messages panel | ||
QgsMessageLog.logMessage( | ||
message=message, tag=application, notifyUser=push, level=log_level | ||
) | ||
|
||
# optionally, display message on QGIS Message bar (above the map canvas) | ||
if push: | ||
iface.messageBar().pushMessage( | ||
title=application, | ||
text=message, | ||
level=log_level, | ||
duration=(log_level + 1) * 3, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
#! python3 # noqa: E265 | ||
|
||
""" | ||
Plugin settings. | ||
""" | ||
|
||
# standard | ||
from typing import NamedTuple | ||
|
||
# PyQGIS | ||
from qgis.core import QgsSettings | ||
|
||
# package | ||
import roof_classify.toolbelt.log_handler as log_hdlr | ||
from roof_classify.__about__ import __title__, __version__ | ||
|
||
# ############################################################################ | ||
# ########## Classes ############### | ||
# ################################## | ||
|
||
|
||
class PlgSettingsStructure(NamedTuple): | ||
"""Plugin settings structure and defaults values.""" | ||
|
||
# misc | ||
debug_mode: bool = False | ||
version: str = __version__ | ||
|
||
class PlgOptionsManager: | ||
@staticmethod | ||
def get_plg_settings() -> PlgSettingsStructure: | ||
"""Load and return plugin settings as a dictionary. \ | ||
Useful to get user preferences across plugin logic. | ||
:return: plugin settings | ||
:rtype: PlgSettingsStructure | ||
""" | ||
settings = QgsSettings() | ||
settings.beginGroup(__title__) | ||
|
||
options = PlgSettingsStructure( | ||
# misc | ||
debug_mode=settings.value(key="debug_mode", defaultValue=False, type=bool), | ||
version=settings.value(key="version", defaultValue=__version__, type=str), | ||
) | ||
|
||
settings.endGroup() | ||
|
||
return options | ||
|
||
@staticmethod | ||
def get_value_from_key(key: str, default=None, exp_type=None): | ||
"""Load and return plugin settings as a dictionary. \ | ||
Useful to get user preferences across plugin logic. | ||
:return: plugin settings value matching key | ||
""" | ||
if not hasattr(PlgSettingsStructure, key): | ||
log_hdlr.PlgLogger.log( | ||
message="Bad settings key. Must be one of: {}".format( | ||
",".join(PlgSettingsStructure._fields) | ||
), | ||
log_level=1, | ||
) | ||
return None | ||
|
||
settings = QgsSettings() | ||
settings.beginGroup(__title__) | ||
|
||
try: | ||
out_value = settings.value(key=key, defaultValue=default, type=exp_type) | ||
except Exception as err: | ||
log_hdlr.PlgLogger.log( | ||
message="Error occurred trying to get settings: {}.Trace: {}".format( | ||
key, err | ||
) | ||
) | ||
out_value = None | ||
|
||
settings.endGroup() | ||
|
||
return out_value | ||
|
||
@staticmethod | ||
def set_value_from_key(key: str, value): | ||
"""Load and return plugin settings as a dictionary. \ | ||
Useful to get user preferences across plugin logic. | ||
:return: plugin settings value matching key | ||
""" | ||
if not hasattr(PlgSettingsStructure, key): | ||
log_hdlr.PlgLogger.log( | ||
message="Bad settings key. Must be one of: {}".format( | ||
",".join(PlgSettingsStructure._fields) | ||
), | ||
log_level=2, | ||
) | ||
return False | ||
|
||
settings = QgsSettings() | ||
settings.beginGroup(__title__) | ||
|
||
try: | ||
settings.setValue(key, value) | ||
out_value = True | ||
except Exception as err: | ||
log_hdlr.PlgLogger.log( | ||
message="Error occurred trying to set settings: {}.Trace: {}".format( | ||
key, err | ||
) | ||
) | ||
out_value = False | ||
|
||
settings.endGroup() | ||
|
||
return out_value |