diff --git a/src/vorta/application.py b/src/vorta/application.py
index 8857a51eb..40714d5b0 100644
--- a/src/vorta/application.py
+++ b/src/vorta/application.py
@@ -40,7 +40,7 @@ class VortaApp(QtSingleApplication):
backup_finished_event = QtCore.pyqtSignal(dict)
backup_cancelled_event = QtCore.pyqtSignal()
backup_log_event = QtCore.pyqtSignal(str, dict)
- backup_progress_event = QtCore.pyqtSignal(str)
+ backup_progress_event = QtCore.pyqtSignal(int, str)
check_failed_event = QtCore.pyqtSignal(dict)
def __init__(self, args_raw, single_app=False):
@@ -121,7 +121,7 @@ def create_backup_action(self, profile_id=None):
translate('messages', msg['message']),
level='error',
)
- self.backup_progress_event.emit(f"[{profile.name}] {translate('messages', msg['message'])}")
+ self.backup_progress_event.emit(profile.id, f"[{profile.name}] {translate('messages', msg['message'])}")
return None
def open_main_window_action(self):
@@ -257,7 +257,7 @@ def react_to_log(self, mgs, context):
def break_lock(self, profile):
params = BorgBreakJob.prepare(profile)
if not params['ok']:
- self.backup_progress_event.emit(f"[{profile.name}] {params['message']}")
+ self.backup_progress_event.emit(profile.id, f"[{profile.name}] {params['message']}")
return
job = BorgBreakJob(params['cmd'], params)
self.jobs_manager.add_job(job)
diff --git a/src/vorta/borg/borg_job.py b/src/vorta/borg/borg_job.py
index 9cf6a1551..d0af78ec2 100644
--- a/src/vorta/borg/borg_job.py
+++ b/src/vorta/borg/borg_job.py
@@ -296,7 +296,9 @@ def read_async(fd):
# f"{translate('BorgJob','Compressed')}: {pretty_bytes(parsed['compressed_size'])}, "
f"{translate('BorgJob','Deduplicated')}: {pretty_bytes(parsed['deduplicated_size'])}" # noqa: E501
)
- self.app.backup_progress_event.emit(f"[{self.params['profile_name']}] {msg}")
+ self.app.backup_progress_event.emit(
+ self.params['profile_id'], f"[{self.params['profile_name']}] {msg}"
+ )
except json.decoder.JSONDecodeError:
msg = line.strip()
if msg: # Log only if there is something to log.
diff --git a/src/vorta/borg/break_lock.py b/src/vorta/borg/break_lock.py
index 0184b6558..91a20ec4b 100644
--- a/src/vorta/borg/break_lock.py
+++ b/src/vorta/borg/break_lock.py
@@ -4,12 +4,15 @@
class BorgBreakJob(BorgJob):
def started_event(self):
self.app.backup_started_event.emit()
- self.app.backup_progress_event.emit(f"[{self.params['profile_name']}] {self.tr('Breaking repository lock…')}")
+ self.app.backup_progress_event.emit(
+ self.params['profile_id'], f"[{self.params['profile_name']}] {self.tr('Breaking repository lock…')}"
+ )
def finished_event(self, result):
self.app.backup_finished_event.emit(result)
self.app.backup_progress_event.emit(
- f"[{self.params['profile_name']}] {self.tr('Repository lock broken. Please redo your last action.')}"
+ self.params['profile_id'],
+ f"[{self.params['profile_name']}] {self.tr('Repository lock broken. Please redo your last action.')}",
)
self.result.emit(result)
diff --git a/src/vorta/borg/check.py b/src/vorta/borg/check.py
index e25443fdf..cf67db630 100644
--- a/src/vorta/borg/check.py
+++ b/src/vorta/borg/check.py
@@ -10,7 +10,9 @@
class BorgCheckJob(BorgJob):
def started_event(self):
self.app.backup_started_event.emit()
- self.app.backup_progress_event.emit(f"[{self.params['profile_name']}] {self.tr('Starting consistency check…')}")
+ self.app.backup_progress_event.emit(
+ self.params['profile_id'], f"[{self.params['profile_name']}] {self.tr('Starting consistency check…')}"
+ )
def finished_event(self, result: Dict[str, Any]):
"""
@@ -25,14 +27,17 @@ def finished_event(self, result: Dict[str, Any]):
self.result.emit(result)
if result['returncode'] != 0:
self.app.backup_progress_event.emit(
+ self.params['profile_id'],
f"[{self.params['profile_name']}] "
+ translate('RepoCheckJob', 'Repo check failed. See the logs for details.').format(
config.LOG_DIR.as_uri()
- )
+ ),
)
self.app.check_failed_event.emit(result)
else:
- self.app.backup_progress_event.emit(f"[{self.params['profile_name']}] {self.tr('Check completed.')}")
+ self.app.backup_progress_event.emit(
+ self.params['profile_id'], f"[{self.params['profile_name']}] {self.tr('Check completed.')}"
+ )
@classmethod
def prepare(cls, profile):
diff --git a/src/vorta/borg/compact.py b/src/vorta/borg/compact.py
index 12bc160c4..75b174977 100644
--- a/src/vorta/borg/compact.py
+++ b/src/vorta/borg/compact.py
@@ -11,7 +11,7 @@ class BorgCompactJob(BorgJob):
def started_event(self):
self.app.backup_started_event.emit()
self.app.backup_progress_event.emit(
- f"[{self.params['profile_name']} {self.tr('Starting repository compaction...')}]"
+ self.params['profile_id'], f"[{self.params['profile_name']} {self.tr('Starting repository compaction...')}]"
)
def finished_event(self, result: Dict[str, Any]):
@@ -27,13 +27,16 @@ def finished_event(self, result: Dict[str, Any]):
self.result.emit(result)
if result['returncode'] != 0:
self.app.backup_progress_event.emit(
+ self.params['profile_id'],
f"[{self.params['profile_name']}] "
+ translate(
'BorgCompactJob', 'Errors during compaction. See the logs for details.'
- ).format(config.LOG_DIR.as_uri())
+ ).format(config.LOG_DIR.as_uri()),
)
else:
- self.app.backup_progress_event.emit(f"[{self.params['profile_name']}] {self.tr('Compaction completed.')}")
+ self.app.backup_progress_event.emit(
+ self.params['profile_id'], f"[{self.params['profile_name']}] {self.tr('Compaction completed.')}"
+ )
@classmethod
def prepare(cls, profile):
diff --git a/src/vorta/borg/create.py b/src/vorta/borg/create.py
index 4b2e8b84b..a9f0f0009 100644
--- a/src/vorta/borg/create.py
+++ b/src/vorta/borg/create.py
@@ -43,22 +43,26 @@ def process_result(self, result):
if result['returncode'] == 1:
self.app.backup_progress_event.emit(
+ self.params['profile_id'],
f"[{self.params['profile_name']}] "
+ translate(
'BorgCreateJob',
'Backup finished with warnings. See the logs for details.',
- ).format(config.LOG_DIR.as_uri())
+ ).format(config.LOG_DIR.as_uri()),
)
else:
- self.app.backup_log_event.emit('', {})
- self.app.backup_progress_event.emit(f"[{self.params['profile_name']}] {self.tr('Backup finished.')}")
+ self.app.backup_progress_event.emit(
+ self.params['profile_id'], f"[{self.params['profile_name']}] {self.tr('Backup finished.')}"
+ )
def progress_event(self, fmt):
- self.app.backup_progress_event.emit(f"[{self.params['profile_name']}] {fmt}")
+ self.app.backup_progress_event.emit(self.params['profile_id'], f"[{self.params['profile_name']}] {fmt}")
def started_event(self):
self.app.backup_started_event.emit()
- self.app.backup_progress_event.emit(f"[{self.params['profile_name']}] {self.tr('Backup started.')}")
+ self.app.backup_progress_event.emit(
+ self.params['profile_id'], f"[{self.params['profile_name']}] {self.tr('Backup started.')}"
+ )
def finished_event(self, result):
self.app.backup_finished_event.emit(result)
diff --git a/src/vorta/borg/delete.py b/src/vorta/borg/delete.py
index 5b1fe72f0..b7690be56 100644
--- a/src/vorta/borg/delete.py
+++ b/src/vorta/borg/delete.py
@@ -9,7 +9,9 @@
class BorgDeleteJob(BorgJob):
def started_event(self):
self.app.backup_started_event.emit()
- self.app.backup_progress_event.emit(f"[{self.params['profile_name']}] {self.tr('Deleting archive…')}")
+ self.app.backup_progress_event.emit(
+ self.params['profile_id'], f"[{self.params['profile_name']}] {self.tr('Deleting archive…')}"
+ )
def finished_event(self, result):
# set repo stats to N/A
@@ -22,7 +24,9 @@ def finished_event(self, result):
self.app.backup_finished_event.emit(result)
self.result.emit(result)
- self.app.backup_progress_event.emit(f"[{self.params['profile_name']}] {self.tr('Archive deleted.')}")
+ self.app.backup_progress_event.emit(
+ self.params['profile_id'], f"[{self.params['profile_name']}] {self.tr('Archive deleted.')}"
+ )
@classmethod
def prepare(cls, profile, archives: List[str]):
diff --git a/src/vorta/borg/diff.py b/src/vorta/borg/diff.py
index cd09ff815..6a34c525b 100644
--- a/src/vorta/borg/diff.py
+++ b/src/vorta/borg/diff.py
@@ -7,13 +7,15 @@ class BorgDiffJob(BorgJob):
def started_event(self):
self.app.backup_started_event.emit()
self.app.backup_progress_event.emit(
- f"[{self.params['profile_name']}] {self.tr('Requesting differences between archives…')}"
+ self.params['profile_id'],
+ f"[{self.params['profile_name']}] {self.tr('Requesting differences between archives…')}",
)
def finished_event(self, result):
self.app.backup_finished_event.emit(result)
self.app.backup_progress_event.emit(
- f"[{self.params['profile_name']}] {self.tr('Obtained differences between archives.')}"
+ self.params['profile_id'],
+ f"[{self.params['profile_name']}] {self.tr('Obtained differences between archives.')}",
)
self.result.emit(result)
diff --git a/src/vorta/borg/extract.py b/src/vorta/borg/extract.py
index 41108721f..d2cd7e15d 100644
--- a/src/vorta/borg/extract.py
+++ b/src/vorta/borg/extract.py
@@ -13,14 +13,14 @@ class BorgExtractJob(BorgJob):
def started_event(self):
self.app.backup_started_event.emit()
self.app.backup_progress_event.emit(
- f"[{self.params['profile_name']}] {self.tr('Downloading files from archive…')}"
+ self.params['profile_id'], f"[{self.params['profile_name']}] {self.tr('Downloading files from archive…')}"
)
def finished_event(self, result):
self.app.backup_finished_event.emit(result)
self.result.emit(result)
self.app.backup_progress_event.emit(
- f"[{self.params['profile_name']}] {self.tr('Restored files from archive.')}"
+ self.params['profile_id'], f"[{self.params['profile_name']}] {self.tr('Restored files from archive.')}"
)
@classmethod
diff --git a/src/vorta/borg/info_archive.py b/src/vorta/borg/info_archive.py
index afb94b2f3..9b124c37f 100644
--- a/src/vorta/borg/info_archive.py
+++ b/src/vorta/borg/info_archive.py
@@ -7,12 +7,16 @@
class BorgInfoArchiveJob(BorgJob):
def started_event(self):
self.app.backup_started_event.emit()
- self.app.backup_progress_event.emit(f"[{self.params['profile_name']}] {self.tr('Refreshing archive…')}")
+ self.app.backup_progress_event.emit(
+ self.params['profile_id'], f"[{self.params['profile_name']}] {self.tr('Refreshing archive…')}"
+ )
def finished_event(self, result):
self.app.backup_finished_event.emit(result)
self.result.emit(result)
- self.app.backup_progress_event.emit(f"[{self.params['profile_name']}] {self.tr('Refreshing archive done.')}")
+ self.app.backup_progress_event.emit(
+ self.params['profile_id'], f"[{self.params['profile_name']}] {self.tr('Refreshing archive done.')}"
+ )
@classmethod
def prepare(cls, profile, archive_name):
diff --git a/src/vorta/borg/list_archive.py b/src/vorta/borg/list_archive.py
index ef00a0134..a544592bc 100644
--- a/src/vorta/borg/list_archive.py
+++ b/src/vorta/borg/list_archive.py
@@ -6,12 +6,14 @@
class BorgListArchiveJob(BorgJob):
def started_event(self):
self.app.backup_started_event.emit()
- self.app.backup_progress_event.emit(f"[{self.params['profile_name']}] {self.tr('Getting archive content…')}")
+ self.app.backup_progress_event.emit(
+ self.params['profile_id'], f"[{self.params['profile_name']}] {self.tr('Getting archive content…')}"
+ )
def finished_event(self, result):
self.app.backup_finished_event.emit(result)
self.app.backup_progress_event.emit(
- f"[{self.params['profile_name']}] {self.tr('Done getting archive content.')}"
+ self.params['profile_id'], f"[{self.params['profile_name']}] {self.tr('Done getting archive content.')}"
)
self.result.emit(result)
diff --git a/src/vorta/borg/list_repo.py b/src/vorta/borg/list_repo.py
index 664778d64..90a9c48bc 100644
--- a/src/vorta/borg/list_repo.py
+++ b/src/vorta/borg/list_repo.py
@@ -9,12 +9,16 @@
class BorgListRepoJob(BorgJob):
def started_event(self):
self.app.backup_started_event.emit()
- self.app.backup_progress_event.emit(f"[{self.params['profile_name']}] {self.tr('Refreshing archives…')}")
+ self.app.backup_progress_event.emit(
+ self.params['profile_id'], f"[{self.params['profile_name']}] {self.tr('Refreshing archives…')}"
+ )
def finished_event(self, result):
self.app.backup_finished_event.emit(result)
self.result.emit(result)
- self.app.backup_progress_event.emit(f"[{self.params['profile_name']}] {self.tr('Refreshing archives done.')}")
+ self.app.backup_progress_event.emit(
+ self.params['profile_id'], f"[{self.params['profile_name']}] {self.tr('Refreshing archives done.')}"
+ )
@classmethod
def prepare(cls, profile):
diff --git a/src/vorta/borg/prune.py b/src/vorta/borg/prune.py
index aba888fb3..47bafbd95 100644
--- a/src/vorta/borg/prune.py
+++ b/src/vorta/borg/prune.py
@@ -7,7 +7,9 @@
class BorgPruneJob(BorgJob):
def started_event(self):
self.app.backup_started_event.emit()
- self.app.backup_progress_event.emit(f"[{self.params['profile_name']}] {self.tr('Pruning old archives…')}")
+ self.app.backup_progress_event.emit(
+ self.params['profile_id'], f"[{self.params['profile_name']}] {self.tr('Pruning old archives…')}"
+ )
def finished_event(self, result):
# set repo stats to N/A
@@ -20,7 +22,9 @@ def finished_event(self, result):
self.app.backup_finished_event.emit(result)
self.result.emit(result)
- self.app.backup_progress_event.emit(f"[{self.params['profile_name']}] {self.tr('Pruning done.')}")
+ self.app.backup_progress_event.emit(
+ self.params['profile_id'], f"[{self.params['profile_name']}] {self.tr('Pruning done.')}"
+ )
@classmethod
def prepare(cls, profile):
diff --git a/src/vorta/store/models.py b/src/vorta/store/models.py
index 400299fb2..214887e55 100644
--- a/src/vorta/store/models.py
+++ b/src/vorta/store/models.py
@@ -102,6 +102,7 @@ class BackupProfileModel(BaseModel):
pre_backup_cmd = pw.CharField(default='')
post_backup_cmd = pw.CharField(default='')
dont_run_on_metered_networks = pw.BooleanField(default=True)
+ last_status = pw.CharField(default='', null=True)
def refresh(self):
return type(self).get(self._pk_expr())
diff --git a/src/vorta/views/main_window.py b/src/vorta/views/main_window.py
index 78cf40f47..39a1dc49b 100644
--- a/src/vorta/views/main_window.py
+++ b/src/vorta/views/main_window.py
@@ -22,7 +22,7 @@
is_system_tray_available,
)
from vorta.views.partials.loading_button import LoadingButton
-from vorta.views.utils import get_colored_icon
+from vorta.views.utils import extract_profile_name, get_colored_icon
from .about_tab import AboutTab
from .archive_tab import ArchiveTab
@@ -135,13 +135,22 @@ def set_icons(self):
self.profileDeleteButton.setIcon(get_colored_icon('minus'))
self.miscButton.setIcon(get_colored_icon('settings_wheel'))
- def set_progress(self, text=''):
- self.progressText.setText(text)
- self.progressText.repaint()
+ def set_progress(self, profile_id, text=''):
+ profile = BackupProfileModel.get_by_id(profile_id)
+ profile.last_status = text
+ profile.save()
+ if profile.name == self.current_profile.name:
+ self.progressText.setText(text)
+ self.progressText.repaint()
def set_log(self, text=''):
- self.logText.setText(text)
- self.logText.repaint()
+ profile = extract_profile_name(text)
+ if profile == self.current_profile.name:
+ self.logText.setText(text)
+ self.logText.repaint()
+ else:
+ self.logText.setText('')
+ self.logText.repaint()
def _toggle_buttons(self, create_enabled=True):
if create_enabled:
@@ -188,6 +197,8 @@ def profile_selection_changed_action(self, index):
SettingsModel.key == 'previous_profile_id'
).execute()
self.archiveTab.toggle_compact_button_visibility()
+ self.app.backup_progress_event.emit(self.current_profile.id, self.current_profile.last_status)
+ self.app.backup_log_event.emit("", {})
def profile_clicked_action(self):
if self.miscWidget.isVisible():
diff --git a/src/vorta/views/utils.py b/src/vorta/views/utils.py
index 5a9697a73..d3d7365c0 100644
--- a/src/vorta/views/utils.py
+++ b/src/vorta/views/utils.py
@@ -1,5 +1,6 @@
import json
import os
+import re
import sys
from PyQt6.QtGui import QIcon, QImage, QPixmap
@@ -49,3 +50,14 @@ def get_exclusion_presets():
'tags': preset['tags'],
}
return allPresets
+
+
+def extract_profile_name(text):
+ pattern = r'\[([^]]+)\]'
+
+ match = re.search(pattern, text)
+
+ if match:
+ return match.group(1)
+ else:
+ return None