Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add ability to save logs next to input/output file in the GUI #79

Merged
merged 4 commits into from
Nov 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 35 additions & 18 deletions qgepqwat2ili/gui/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,10 @@
import_xtf_data,
validate_xtf_data,
)
from ..utils.various import CmdException, logger, make_log_path
from ..utils.various import CmdException, LoggingHandlerContext, logger, make_log_path
from .gui_export import GuiExport
from .gui_import import GuiImport

# Always log to temp dir
filename = make_log_path(None, "qgepqwat2ili")
file_handler = logging.FileHandler(filename, mode="w", encoding="utf-8")
file_handler.setLevel(logging.INFO)
file_handler.setFormatter(logging.Formatter("%(levelname)-8s %(message)s"))
logger.addHandler(file_handler)


def _show_results(title, message, log_path, level):
widget = iface.messageBar().createMessage(title, message)
Expand Down Expand Up @@ -73,6 +66,14 @@ def action_import(plugin, pgservice=None):
return
QgsSettings().setValue("qgep_pluging/last_interlis_path", os.path.dirname(file_name))

# Configure logging
s = QgsSettings().value("qgep_plugin/logs_next_to_file", False)
logs_next_to_file = s == True or s == "true"
if logs_next_to_file:
base_log_path = file_name
else:
base_log_path = None

progress_dialog = QProgressDialog("", "", 0, 100, plugin.iface.mainWindow())
progress_dialog.setCancelButton(None)
progress_dialog.setModal(True)
Expand All @@ -81,7 +82,7 @@ def action_import(plugin, pgservice=None):
# Validating the input file
progress_dialog.setLabelText("Validating the input file...")
QApplication.processEvents()
log_path = make_log_path(None, "validate")
log_path = make_log_path(base_log_path, "ilivalidator")
try:
validate_xtf_data(
file_name,
Expand All @@ -99,7 +100,7 @@ def action_import(plugin, pgservice=None):
# Prepare the temporary ili2pg model
progress_dialog.setLabelText("Creating ili schema...")
QApplication.processEvents()
log_path = make_log_path(None, "create")
log_path = make_log_path(base_log_path, "ili2pg-schemaimport")
try:
create_ili_schema(
config.ABWASSER_SCHEMA,
Expand All @@ -120,7 +121,7 @@ def action_import(plugin, pgservice=None):
# Export from ili2pg model to file
progress_dialog.setLabelText("Importing XTF data...")
QApplication.processEvents()
log_path = make_log_path(None, "import")
log_path = make_log_path(base_log_path, "ili2pg-import")
try:
import_xtf_data(
config.ABWASSER_SCHEMA,
Expand All @@ -142,9 +143,14 @@ def action_import(plugin, pgservice=None):
QApplication.processEvents()
import_dialog = GuiImport(plugin.iface.mainWindow())
progress_dialog.setValue(100)
qgep_import(
precommit_callback=import_dialog.init_with_session,
)

log_handler = logging.FileHandler(make_log_path(base_log_path, "qgepqwat2ili-import"), mode="w", encoding="utf-8")
log_handler.setLevel(logging.INFO)
log_handler.setFormatter(logging.Formatter("%(levelname)-8s %(message)s"))
with LoggingHandlerContext(log_handler):
qgep_import(
precommit_callback=import_dialog.init_with_session,
)


def action_export(plugin, pgservice=None):
Expand Down Expand Up @@ -174,6 +180,12 @@ def action_do_export():
return
QgsSettings().setValue("qgep_pluging/last_interlis_path", os.path.dirname(file_name))

# Configure logging
if export_dialog.logs_next_to_file:
base_log_path = file_name
else:
base_log_path = None

progress_dialog = QProgressDialog("", "", 0, 100, plugin.iface.mainWindow())
progress_dialog.setCancelButton(None)
progress_dialog.setModal(True)
Expand All @@ -182,7 +194,7 @@ def action_do_export():
# Prepare the temporary ili2pg model
progress_dialog.setLabelText("Creating ili schema...")
QApplication.processEvents()
log_path = make_log_path(None, "create")
log_path = make_log_path(base_log_path, "ili2pg-schemaimport")
try:
create_ili_schema(
config.ABWASSER_SCHEMA,
Expand Down Expand Up @@ -238,7 +250,12 @@ def action_do_export():
# Export to the temporary ili2pg model
progress_dialog.setLabelText("Converting from QGEP...")
QApplication.processEvents()
qgep_export(selection=export_dialog.selected_ids, labels_file=labels_file_path)

log_handler = logging.FileHandler(make_log_path(file_name, "qgepqwat2ili-export"), mode="w", encoding="utf-8")
log_handler.setLevel(logging.INFO)
log_handler.setFormatter(logging.Formatter("%(levelname)-8s %(message)s"))
with LoggingHandlerContext(log_handler):
qgep_export(selection=export_dialog.selected_ids, labels_file=labels_file_path)
progress_dialog.setValue(50)

# Cleanup
Expand All @@ -247,7 +264,7 @@ def action_do_export():
# Export from ili2pg model to file
progress_dialog.setLabelText("Saving XTF file...")
QApplication.processEvents()
log_path = make_log_path(None, "export")
log_path = make_log_path(base_log_path, "ili2pg-export")
try:
export_xtf_data(
config.ABWASSER_SCHEMA,
Expand All @@ -267,7 +284,7 @@ def action_do_export():

progress_dialog.setLabelText("Validating the output file...")
QApplication.processEvents()
log_path = make_log_path(None, "validate")
log_path = make_log_path(base_log_path, "ilivalidator")
try:
validate_xtf_data(
file_name,
Expand Down
9 changes: 9 additions & 0 deletions qgepqwat2ili/gui/gui_export.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ def __init__(self, parent):
f"Limit to selection ({len(self.structures)} structures and {len(self.reaches)} reaches)"
)

# Remember save next to file checkbox
s = QgsSettings().value("qgep_plugin/logs_next_to_file", False)
self.logs_next_to_file = s == True or s == "true"
self.save_logs_next_to_file_checkbox.setChecked(self.logs_next_to_file)

# Populate the labels list (restoring checked states of scaes)
selected_scales = QgsSettings().value("qgep_plugin/last_selected_scales", "").split(",")
qgis_version_ok = Qgis.QGIS_VERSION_INT >= 32602
Expand All @@ -47,6 +52,10 @@ def __init__(self, parent):
self.labels_groupbox.layout().addWidget(checkbox)

def on_finish(self):
# Remember save next to file checkbox
self.logs_next_to_file = self.save_logs_next_to_file_checkbox.isChecked()
QgsSettings().setValue("qgep_plugin/logs_next_to_file", self.logs_next_to_file)

# Save checked state of scales
if self.labels_groupbox.isChecked():
selected_scales = []
Expand Down
20 changes: 20 additions & 0 deletions qgepqwat2ili/gui/gui_export.ui
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,26 @@
</layout>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="save_logs_next_to_file_checkbox">
<property name="text">
<string>Save logs next to output</string>
</property>
</widget>
</item>
<item row="2" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
Expand Down
17 changes: 16 additions & 1 deletion qgepqwat2ili/utils/various.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,10 +224,25 @@ def get_pgconf():

def make_log_path(next_to_path, step_name):
"""Returns a path for logging purposes. If next_to_path is None, it will be saved in the temp directory"""
now = f"{datetime.datetime.now():%Y%m%d%H%M%S}"
now = f"{datetime.datetime.now():%y%m%d%H%M%S}"
if next_to_path:
return f"{next_to_path}.{now}.{step_name}.log"
else:
temp_path = os.path.join(tempfile.gettempdir(), "qgepqwat2ili")
os.makedirs(temp_path, exist_ok=True)
return os.path.join(temp_path, f"{now}.{step_name}.log")


class LoggingHandlerContext:
"""Temporarily sets a log handler, then removes it"""

def __init__(self, handler):
self.handler = handler

def __enter__(self):
logger.addHandler(self.handler)

def __exit__(self, et, ev, tb):
logger.removeHandler(self.handler)
self.handler.close()
# implicit return of None => don't swallow exceptions