mirror of
https://github.com/netinvent/npbackup.git
synced 2024-09-21 15:26:24 +08:00
Update ls_window since we changed ls output to use live stdout, which is too slow
This commit is contained in:
parent
5441c82808
commit
2229cec1d7
|
@ -47,6 +47,7 @@ from npbackup.customization import (
|
||||||
from npbackup.gui.config import config_gui
|
from npbackup.gui.config import config_gui
|
||||||
from npbackup.gui.operations import operations_gui
|
from npbackup.gui.operations import operations_gui
|
||||||
from npbackup.gui.helpers import get_anon_repo_uri, gui_thread_runner
|
from npbackup.gui.helpers import get_anon_repo_uri, gui_thread_runner
|
||||||
|
from npbackup.gui.notification import display_notification
|
||||||
from npbackup.core.i18n_helper import _t
|
from npbackup.core.i18n_helper import _t
|
||||||
from npbackup.core.upgrade_runner import run_upgrade, check_new_version
|
from npbackup.core.upgrade_runner import run_upgrade, check_new_version
|
||||||
from npbackup.path_helper import CURRENT_DIR
|
from npbackup.path_helper import CURRENT_DIR
|
||||||
|
@ -180,9 +181,6 @@ def _make_treedata_from_json(ls_result: List[dict]) -> sg.TreeData:
|
||||||
"""
|
"""
|
||||||
treedata = sg.TreeData()
|
treedata = sg.TreeData()
|
||||||
count = 0
|
count = 0
|
||||||
# First entry of list of list should be the snapshot description and can be discarded
|
|
||||||
# Since we use an iter now, first result was discarded by ls_window function already
|
|
||||||
# ls_result.pop(0)
|
|
||||||
for entry in ls_result:
|
for entry in ls_result:
|
||||||
# Make sure we drop the prefix '/' so sg.TreeData does not get an empty root
|
# Make sure we drop the prefix '/' so sg.TreeData does not get an empty root
|
||||||
entry["path"] = entry["path"].lstrip("/")
|
entry["path"] = entry["path"].lstrip("/")
|
||||||
|
@ -224,38 +222,35 @@ def _make_treedata_from_json(ls_result: List[dict]) -> sg.TreeData:
|
||||||
|
|
||||||
def ls_window(repo_config: dict, snapshot_id: str) -> bool:
|
def ls_window(repo_config: dict, snapshot_id: str) -> bool:
|
||||||
result = gui_thread_runner(
|
result = gui_thread_runner(
|
||||||
repo_config, "ls", snapshot=snapshot_id, __autoclose=True, __compact=True
|
repo_config, "ls", snapshot=snapshot_id, __stdout=False, __autoclose=True, __compact=True
|
||||||
)
|
)
|
||||||
if not result["result"]:
|
if not result["result"]:
|
||||||
|
sg.Popup("main_gui.snapshot_is_empty")
|
||||||
return None, None
|
return None, None
|
||||||
|
# result is {"result": True, "output": [{snapshot_description}, {entry}, {entry}]}
|
||||||
snapshot_content = result["output"]
|
content = result["output"]
|
||||||
try:
|
# First entry of snapshot list is the snapshot description
|
||||||
# Since ls returns an iter now, we need to use next
|
snapshot = content.pop(0)
|
||||||
snapshot = next(snapshot_content)
|
|
||||||
# Exception that happens when restic cannot successfully get snapshot content
|
|
||||||
except StopIteration:
|
|
||||||
return None, None
|
|
||||||
try:
|
try:
|
||||||
snap_date = dateutil.parser.parse(snapshot["time"])
|
snap_date = dateutil.parser.parse(snapshot["time"])
|
||||||
except (KeyError, IndexError):
|
except (KeyError, IndexError, TypeError):
|
||||||
snap_date = "[inconnu]"
|
snap_date = "[inconnu]"
|
||||||
try:
|
try:
|
||||||
short_id = snapshot["short_id"]
|
short_id = snapshot["short_id"]
|
||||||
except (KeyError, IndexError):
|
except (KeyError, IndexError, TypeError):
|
||||||
short_id = "[inconnu]"
|
short_id = None
|
||||||
try:
|
try:
|
||||||
username = snapshot["username"]
|
username = snapshot["username"]
|
||||||
except (KeyError, IndexError):
|
except (KeyError, IndexError, TypeError):
|
||||||
username = "[inconnu]"
|
username = "[inconnu]"
|
||||||
try:
|
try:
|
||||||
hostname = snapshot["hostname"]
|
hostname = snapshot["hostname"]
|
||||||
except (KeyError, IndexError):
|
except (KeyError, IndexError, TypeError):
|
||||||
hostname = "[inconnu]"
|
hostname = "[inconnu]"
|
||||||
|
|
||||||
backup_id = f"{_t('main_gui.backup_content_from')} {snap_date} {_t('main_gui.run_as')} {username}@{hostname} {_t('main_gui.identified_by')} {short_id}"
|
backup_id = f"{_t('main_gui.backup_content_from')} {snap_date} {_t('main_gui.run_as')} {username}@{hostname} {_t('main_gui.identified_by')} {short_id}"
|
||||||
|
|
||||||
if not backup_id or not snapshot_content:
|
if not backup_id or not snapshot or not short_id:
|
||||||
sg.PopupError(_t("main_gui.cannot_get_content"), keep_on_top=True)
|
sg.PopupError(_t("main_gui.cannot_get_content"), keep_on_top=True)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -265,7 +260,7 @@ def ls_window(repo_config: dict, snapshot_id: str) -> bool:
|
||||||
|
|
||||||
# We get a thread result, hence pylint will complain the thread isn't a tuple
|
# We get a thread result, hence pylint will complain the thread isn't a tuple
|
||||||
# pylint: disable=E1101 (no-member)
|
# pylint: disable=E1101 (no-member)
|
||||||
thread = _make_treedata_from_json(snapshot_content)
|
thread = _make_treedata_from_json(content)
|
||||||
while not thread.done() and not thread.cancelled():
|
while not thread.done() and not thread.cancelled():
|
||||||
sg.PopupAnimated(
|
sg.PopupAnimated(
|
||||||
LOADER_ANIMATION,
|
LOADER_ANIMATION,
|
||||||
|
@ -773,7 +768,7 @@ def _main_gui(viewer_mode: bool):
|
||||||
backup(repo_config)
|
backup(repo_config)
|
||||||
event = "--STATE-BUTTON--"
|
event = "--STATE-BUTTON--"
|
||||||
if event == "--SEE-CONTENT--":
|
if event == "--SEE-CONTENT--":
|
||||||
if not full_config:
|
if not repo_config:
|
||||||
sg.PopupError(_t("main_gui.no_config"))
|
sg.PopupError(_t("main_gui.no_config"))
|
||||||
continue
|
continue
|
||||||
if not values["snapshot-list"]:
|
if not values["snapshot-list"]:
|
||||||
|
|
|
@ -77,6 +77,7 @@ def gui_thread_runner(
|
||||||
__compact: bool = True,
|
__compact: bool = True,
|
||||||
__autoclose: bool = False,
|
__autoclose: bool = False,
|
||||||
__gui_msg: str = "",
|
__gui_msg: str = "",
|
||||||
|
__stdout: bool = True,
|
||||||
*args,
|
*args,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
):
|
):
|
||||||
|
@ -105,16 +106,17 @@ def gui_thread_runner(
|
||||||
if __repo_config:
|
if __repo_config:
|
||||||
runner.repo_config = __repo_config
|
runner.repo_config = __repo_config
|
||||||
|
|
||||||
|
if __stdout:
|
||||||
stdout_queue = queue.Queue()
|
stdout_queue = queue.Queue()
|
||||||
|
runner.stdout = stdout_queue
|
||||||
|
|
||||||
stderr_queue = queue.Queue()
|
stderr_queue = queue.Queue()
|
||||||
|
runner.stderr = stderr_queue
|
||||||
fn = getattr(runner, __fn_name)
|
fn = getattr(runner, __fn_name)
|
||||||
logger.debug(
|
logger.debug(
|
||||||
f"gui_thread_runner runs {fn.__name__} {'with' if USE_THREADING else 'without'} threads"
|
f"gui_thread_runner runs {fn.__name__} {'with' if USE_THREADING else 'without'} threads"
|
||||||
)
|
)
|
||||||
|
|
||||||
runner.stdout = stdout_queue
|
|
||||||
runner.stderr = stderr_queue
|
|
||||||
|
|
||||||
stderr_has_messages = False
|
stderr_has_messages = False
|
||||||
if not __gui_msg:
|
if not __gui_msg:
|
||||||
__gui_msg = "Operation"
|
__gui_msg = "Operation"
|
||||||
|
@ -191,6 +193,7 @@ def gui_thread_runner(
|
||||||
_t("generic.close"),
|
_t("generic.close"),
|
||||||
key="--EXIT--",
|
key="--EXIT--",
|
||||||
button_color=(TXT_COLOR_LDR, BG_COLOR_LDR),
|
button_color=(TXT_COLOR_LDR, BG_COLOR_LDR),
|
||||||
|
disabled=True
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
]
|
]
|
||||||
|
@ -212,13 +215,14 @@ def gui_thread_runner(
|
||||||
use_custom_titlebar=True,
|
use_custom_titlebar=True,
|
||||||
grab_anywhere=True,
|
grab_anywhere=True,
|
||||||
keep_on_top=True,
|
keep_on_top=True,
|
||||||
|
disable_close=True, # Don't allow closing this window via "X" since we still need to update it
|
||||||
background_color=BG_COLOR_LDR,
|
background_color=BG_COLOR_LDR,
|
||||||
titlebar_icon=OEM_ICON,
|
titlebar_icon=OEM_ICON,
|
||||||
)
|
)
|
||||||
# Finalize the window
|
# Finalize the window
|
||||||
event, values = progress_window.read(timeout=0.01)
|
event, values = progress_window.read(timeout=0.01)
|
||||||
|
|
||||||
read_stdout_queue = True
|
read_stdout_queue = __stdout
|
||||||
read_stderr_queue = True
|
read_stderr_queue = True
|
||||||
read_queues = True
|
read_queues = True
|
||||||
if USE_THREADING:
|
if USE_THREADING:
|
||||||
|
@ -237,6 +241,7 @@ def gui_thread_runner(
|
||||||
if event == "--EXPAND--":
|
if event == "--EXPAND--":
|
||||||
_upgrade_from_compact_view()
|
_upgrade_from_compact_view()
|
||||||
# Read stdout queue
|
# Read stdout queue
|
||||||
|
if read_stdout_queue:
|
||||||
try:
|
try:
|
||||||
stdout_data = stdout_queue.get(timeout=GUI_CHECK_INTERVAL)
|
stdout_data = stdout_queue.get(timeout=GUI_CHECK_INTERVAL)
|
||||||
except queue.Empty:
|
except queue.Empty:
|
||||||
|
@ -251,6 +256,7 @@ def gui_thread_runner(
|
||||||
)
|
)
|
||||||
|
|
||||||
# Read stderr queue
|
# Read stderr queue
|
||||||
|
if read_stderr_queue:
|
||||||
try:
|
try:
|
||||||
stderr_data = stderr_queue.get(timeout=GUI_CHECK_INTERVAL)
|
stderr_data = stderr_queue.get(timeout=GUI_CHECK_INTERVAL)
|
||||||
except queue.Empty:
|
except queue.Empty:
|
||||||
|
@ -280,6 +286,7 @@ def gui_thread_runner(
|
||||||
# Make sure we will keep the window visible since we have errors
|
# Make sure we will keep the window visible since we have errors
|
||||||
__autoclose = False
|
__autoclose = False
|
||||||
|
|
||||||
|
progress_window["--EXIT--"].Update(disabled=False)
|
||||||
# Keep the window open until user has done something
|
# Keep the window open until user has done something
|
||||||
progress_window["-LOADER-ANIMATION-"].Update(visible=False)
|
progress_window["-LOADER-ANIMATION-"].Update(visible=False)
|
||||||
if not __autoclose or stderr_has_messages:
|
if not __autoclose or stderr_has_messages:
|
||||||
|
|
|
@ -586,6 +586,9 @@ class ResticRunner:
|
||||||
output_is_list = False
|
output_is_list = False
|
||||||
for line in output:
|
for line in output:
|
||||||
if output_is_list:
|
if output_is_list:
|
||||||
|
try:
|
||||||
|
js["output"].append(json.loads(line))
|
||||||
|
except json.decoder.JSONDecodeError:
|
||||||
js["output"].append(line)
|
js["output"].append(line)
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -43,6 +43,8 @@ en:
|
||||||
config_error: Configuration error
|
config_error: Configuration error
|
||||||
no_config: Please load / create a configuration before proceeding
|
no_config: Please load / create a configuration before proceeding
|
||||||
|
|
||||||
|
snapshot_is_empty: Snapshot is empty
|
||||||
|
|
||||||
# logs
|
# logs
|
||||||
last_messages: Last messages
|
last_messages: Last messages
|
||||||
error_messages: Error messages
|
error_messages: Error messages
|
|
@ -43,6 +43,7 @@ fr:
|
||||||
config_error: Erreur de configuration
|
config_error: Erreur de configuration
|
||||||
no_config: Veuillez charger / créer une configuration avant de procéder
|
no_config: Veuillez charger / créer une configuration avant de procéder
|
||||||
|
|
||||||
|
snapshot_is_empty: L'instantané est vide
|
||||||
# logs
|
# logs
|
||||||
last_messages: Last messages
|
last_messages: Last messages
|
||||||
error_messages: Error messages
|
error_messages: Error messages
|
Loading…
Reference in a new issue