mirror of
https://github.com/borgbase/vorta
synced 2025-03-09 13:53:26 +00:00
v0.5.3 (#80)
* Apply selection status to children in restore-dialog. Fixes #69 * Backup triggered from system tray wont use correct profile. Fixes #78 * Use the term FILE if both FILE or FOLDER is meant. Fixes #55 * Implement update check on/off setting for macOS * Implement autostart setting for macOS. Fixes #56
This commit is contained in:
parent
0f203101e7
commit
3c519e4928
16 changed files with 131 additions and 84 deletions
|
@ -57,6 +57,13 @@
|
|||
<item>
|
||||
<widget class="QTreeView" name="treeView"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Note: If you select a top-level folder and deselect its children, they will still be restored.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="topMargin">
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0">
|
||||
<item>
|
||||
<widget class="QListWidget" name="sourceDirectoriesWidget">
|
||||
<widget class="QListWidget" name="sourceFilesWidget">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
|
|
|
@ -44,6 +44,7 @@ class BorgThread(QtCore.QThread, BackupProfileMixin):
|
|||
|
||||
env = os.environ.copy()
|
||||
env['BORG_HOSTNAME_IS_UNIQUE'] = '1'
|
||||
env['BORG_RELOCATED_REPO_ACCESS_IS_OK'] = '1'
|
||||
password = params.get('password')
|
||||
if password is not None:
|
||||
env['BORG_PASSPHRASE'] = password
|
||||
|
|
|
@ -5,7 +5,7 @@ from dateutil import parser
|
|||
from datetime import datetime as dt
|
||||
|
||||
from ..utils import get_current_wifi
|
||||
from ..models import SourceDirModel, ArchiveModel, WifiSettingModel, RepoModel
|
||||
from ..models import SourceFileModel, ArchiveModel, WifiSettingModel, RepoModel
|
||||
from .borg_thread import BorgThread
|
||||
|
||||
|
||||
|
@ -56,7 +56,7 @@ class BorgCreateThread(BorgThread):
|
|||
else:
|
||||
ret['ok'] = False # Set back to false, so we can do our own checks here.
|
||||
|
||||
n_backup_folders = SourceDirModel.select().count()
|
||||
n_backup_folders = SourceFileModel.select().count()
|
||||
if n_backup_folders == 0:
|
||||
ret['message'] = 'Add some folders to back up first.'
|
||||
return ret
|
||||
|
@ -105,7 +105,7 @@ class BorgCreateThread(BorgThread):
|
|||
# Add repo url and source dirs.
|
||||
cmd.append(f"{profile.repo.url}::{platform.node()}-{profile.slug()}-{dt.now().isoformat(timespec='seconds')}")
|
||||
|
||||
for f in SourceDirModel.select().where(SourceDirModel.profile == profile.id):
|
||||
for f in SourceFileModel.select().where(SourceFileModel.profile == profile.id):
|
||||
cmd.append(f.dir)
|
||||
|
||||
ret['message'] = 'Starting backup..'
|
||||
|
|
|
@ -91,7 +91,7 @@ class BackupProfileModel(pw.Model):
|
|||
database = db
|
||||
|
||||
|
||||
class SourceDirModel(pw.Model):
|
||||
class SourceFileModel(pw.Model):
|
||||
"""A folder to be backed up, related to a Backup Configuration."""
|
||||
dir = pw.CharField()
|
||||
profile = pw.ForeignKeyField(BackupProfileModel, default=1)
|
||||
|
@ -99,6 +99,7 @@ class SourceDirModel(pw.Model):
|
|||
|
||||
class Meta:
|
||||
database = db
|
||||
table_name = 'sourcedirmodel'
|
||||
|
||||
|
||||
class ArchiveModel(pw.Model):
|
||||
|
@ -181,7 +182,7 @@ def _apply_schema_update(current_schema, version_after, *operations):
|
|||
def init_db(con):
|
||||
db.initialize(con)
|
||||
db.connect()
|
||||
db.create_tables([RepoModel, RepoPassword, BackupProfileModel, SourceDirModel, SettingsModel,
|
||||
db.create_tables([RepoModel, RepoPassword, BackupProfileModel, SourceFileModel, SettingsModel,
|
||||
ArchiveModel, WifiSettingModel, EventLogModel, SchemaVersion])
|
||||
|
||||
if BackupProfileModel.select().count() == 0:
|
||||
|
@ -201,6 +202,8 @@ def init_db(con):
|
|||
'label': 'Display notifications when background tasks fail.'},
|
||||
{'key': 'check_for_updates', 'value': True, 'type': 'checkbox',
|
||||
'label': 'Check for updates on startup.'},
|
||||
{'key': 'updates_include_beta', 'value': False, 'type': 'checkbox',
|
||||
'label': 'Include pre-release versions when checking for updates.'},
|
||||
]
|
||||
|
||||
for setting in settings: # Create missing settings and update labels.
|
||||
|
@ -242,7 +245,7 @@ def init_db(con):
|
|||
if current_schema.version < 7:
|
||||
_apply_schema_update(
|
||||
current_schema, 7,
|
||||
migrator.rename_column(SourceDirModel._meta.table_name, 'config_id', 'profile_id'),
|
||||
migrator.rename_column(SourceFileModel._meta.table_name, 'config_id', 'profile_id'),
|
||||
migrator.drop_column(EventLogModel._meta.table_name, 'profile_id'),
|
||||
migrator.add_column(EventLogModel._meta.table_name, 'profile', pw.CharField(null=True))
|
||||
)
|
||||
|
|
|
@ -39,12 +39,11 @@ class TrayMenu(QSystemTrayIcon):
|
|||
profile_menu = menu.addMenu('Backup Now')
|
||||
for profile in profiles:
|
||||
new_item = profile_menu.addAction(profile.name)
|
||||
new_item.setData(profile.id)
|
||||
new_item.triggered.connect(lambda profile_id=profile.id: self.app.create_backup_action(profile_id))
|
||||
new_item.triggered.connect(lambda state, i=profile.id: self.app.create_backup_action(i))
|
||||
else:
|
||||
profile = profiles.first()
|
||||
profile_menu = menu.addAction('Backup Now')
|
||||
profile_menu.triggered.connect(lambda profile_id=profile.id: self.app.create_backup_action(profile_id))
|
||||
profile_menu.triggered.connect(lambda state, i=profile.id: self.app.create_backup_action(i))
|
||||
|
||||
settings_action = menu.addAction("Settings")
|
||||
settings_action.triggered.connect(self.app.open_main_window_action)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import sys
|
||||
import os
|
||||
from vorta.models import SettingsModel
|
||||
|
||||
|
||||
def get_updater():
|
||||
|
@ -10,9 +11,14 @@ def get_updater():
|
|||
bundle_path = os.path.join(os.path.dirname(sys.executable), os.pardir, 'Frameworks', 'Sparkle.framework')
|
||||
loadBundle('Sparkle', globals(), bundle_path)
|
||||
sparkle = SUUpdater.sharedUpdater() # noqa: F821
|
||||
sparkle.setAutomaticallyChecksForUpdates_(True)
|
||||
if SettingsModel.get(key='updates_include_beta').value:
|
||||
sparkle.SharedUpdater.FeedURL = 'https://borgbase.github.io/vorta/appcast-pre.xml'
|
||||
|
||||
if SettingsModel.get(key='check_for_updates').value:
|
||||
sparkle.setAutomaticallyChecksForUpdates_(True)
|
||||
sparkle.checkForUpdatesInBackground()
|
||||
|
||||
sparkle.setAutomaticallyDownloadsUpdates_(False)
|
||||
sparkle.checkForUpdatesInBackground()
|
||||
return sparkle
|
||||
|
||||
else: # TODO: implement for Linux
|
||||
|
|
|
@ -79,7 +79,7 @@ def get_dict_from_list(dataDict, mapList):
|
|||
return reduce(operator.getitem, mapList, dataDict)
|
||||
|
||||
|
||||
def choose_folder_dialog(parent, title, want_folder=True):
|
||||
def choose_file_dialog(parent, title, want_folder=True):
|
||||
options = QFileDialog.Options()
|
||||
if want_folder:
|
||||
options |= QFileDialog.ShowDirsOnly
|
||||
|
@ -219,3 +219,23 @@ def set_tray_icon(tray, active=False):
|
|||
icon_name = f"icons/hdd-o{'-active' if active else ''}-{'light' if use_light_style else 'dark'}.png"
|
||||
icon = QIcon(get_asset(icon_name))
|
||||
tray.setIcon(icon)
|
||||
|
||||
|
||||
def open_app_at_startup(enabled=True):
|
||||
if sys.platform == 'darwin':
|
||||
# From https://stackoverflow.com/questions/26213884/cocoa-add-app-to-startup-in-sandbox-using-pyobjc
|
||||
from Foundation import NSDictionary
|
||||
from Cocoa import NSBundle, NSURL
|
||||
from CoreFoundation import kCFAllocatorDefault
|
||||
from LaunchServices import (LSSharedFileListCreate, kLSSharedFileListSessionLoginItems,
|
||||
LSSharedFileListInsertItemURL, kLSSharedFileListItemHidden,
|
||||
kLSSharedFileListItemLast, LSSharedFileListItemRemove)
|
||||
app_path = NSBundle.mainBundle().bundlePath()
|
||||
url = NSURL.alloc().initFileURLWithPath_(app_path)
|
||||
login_items = LSSharedFileListCreate(kCFAllocatorDefault, kLSSharedFileListSessionLoginItems, None)
|
||||
props = NSDictionary.dictionaryWithObject_forKey_(True, kLSSharedFileListItemHidden)
|
||||
|
||||
new_item = LSSharedFileListInsertItemURL(login_items, kLSSharedFileListItemLast,
|
||||
None, None, url, props, None)
|
||||
if not enabled:
|
||||
LSSharedFileListItemRemove(login_items, new_item)
|
||||
|
|
|
@ -11,7 +11,7 @@ from vorta.borg.mount import BorgMountThread
|
|||
from vorta.borg.extract import BorgExtractThread
|
||||
from vorta.borg.umount import BorgUmountThread
|
||||
from vorta.views.extract_dialog import ExtractDialog
|
||||
from vorta.utils import get_asset, pretty_bytes, choose_folder_dialog
|
||||
from vorta.utils import get_asset, pretty_bytes, choose_file_dialog
|
||||
from vorta.models import BackupProfileMixin, ArchiveModel
|
||||
|
||||
uifile = get_asset('UI/archivetab.ui')
|
||||
|
@ -177,7 +177,7 @@ class ArchiveTab(ArchiveTabBase, ArchiveTabUI, BackupProfileMixin):
|
|||
thread.result.connect(self.mount_result)
|
||||
thread.start()
|
||||
|
||||
dialog = choose_folder_dialog(self, "Choose Mount Point")
|
||||
dialog = choose_file_dialog(self, "Choose Mount Point")
|
||||
dialog.open(receive)
|
||||
|
||||
def mount_result(self, result):
|
||||
|
@ -274,7 +274,7 @@ class ArchiveTab(ArchiveTabBase, ArchiveTabUI, BackupProfileMixin):
|
|||
else:
|
||||
self._set_status(params['message'])
|
||||
|
||||
dialog = choose_folder_dialog(self, "Choose Extraction Point")
|
||||
dialog = choose_file_dialog(self, "Choose Extraction Point")
|
||||
dialog.open(receive)
|
||||
|
||||
def extract_archive_result(self, result):
|
||||
|
|
|
@ -56,56 +56,13 @@ class ExtractDialog(ExtractDialogBase, ExtractDialogUI):
|
|||
self.selected = selected_files_folders
|
||||
|
||||
|
||||
class FileItem:
|
||||
def __init__(self, name, modified, size, parent=None):
|
||||
self.parentItem = parent
|
||||
self.itemData = [name, modified, size] # dt.strptime(modified, ISO_FORMAT)
|
||||
self.checkedState = False
|
||||
|
||||
def childCount(self):
|
||||
return 0
|
||||
|
||||
def columnCount(self):
|
||||
return 3
|
||||
|
||||
def data(self, column):
|
||||
if column == 1:
|
||||
return self.itemData[column] # .strftime('%Y-%m-%dT%H:%M')
|
||||
elif column == 2:
|
||||
return pretty_bytes(self.itemData[column])
|
||||
elif column == 0:
|
||||
return self.itemData[column]
|
||||
|
||||
def parent(self):
|
||||
return self.parentItem
|
||||
|
||||
def row(self):
|
||||
return self.parentItem.childItems.index(self)
|
||||
|
||||
def setCheckedState(self, value):
|
||||
if value == 2:
|
||||
self.checkedState = True
|
||||
selected_files_folders.add(
|
||||
os.path.join(self.parentItem.path, self.parentItem.data(0), self.itemData[0]))
|
||||
else:
|
||||
self.checkedState = False
|
||||
selected_files_folders.remove(
|
||||
os.path.join(self.parentItem.path, self.parentItem.data(0), self.itemData[0]))
|
||||
|
||||
def getCheckedState(self):
|
||||
if self.checkedState:
|
||||
return Qt.Checked
|
||||
else:
|
||||
return Qt.Unchecked
|
||||
|
||||
|
||||
class FolderItem(FileItem):
|
||||
class FolderItem:
|
||||
def __init__(self, path, name, modified, parent=None):
|
||||
self.parentItem = parent
|
||||
self.path = path
|
||||
self.itemData = [name, modified]
|
||||
self.checkedState = False
|
||||
self.childItems = []
|
||||
self.checkedState = False
|
||||
|
||||
# Pre-filter children
|
||||
self._filtered_children = []
|
||||
|
@ -114,6 +71,8 @@ class FolderItem(FileItem):
|
|||
for root_folder in nested_file_list.keys():
|
||||
self._filtered_children.append((0, '', root_folder, '', ))
|
||||
else:
|
||||
self.checkedState = parent.checkedState # If there is a parent, use its checked-status.
|
||||
|
||||
# This adds direct children.
|
||||
self._filtered_children = [f for f in files_with_attributes if search_path == f[3]]
|
||||
|
||||
|
@ -142,6 +101,27 @@ class FolderItem(FileItem):
|
|||
|
||||
self.is_loaded = True
|
||||
|
||||
def setCheckedState(self, value):
|
||||
if value == 2:
|
||||
self.checkedState = True
|
||||
selected_files_folders.add(
|
||||
os.path.join(self.parentItem.path, self.parentItem.data(0), self.itemData[0]))
|
||||
else:
|
||||
self.checkedState = False
|
||||
path_to_remove = os.path.join(self.parentItem.path, self.parentItem.data(0), self.itemData[0])
|
||||
if path_to_remove in selected_files_folders:
|
||||
selected_files_folders.remove(path_to_remove)
|
||||
|
||||
if hasattr(self, 'childItems'):
|
||||
for child in self.childItems:
|
||||
child.setCheckedState(value)
|
||||
|
||||
def getCheckedState(self):
|
||||
if self.checkedState:
|
||||
return Qt.Checked
|
||||
else:
|
||||
return Qt.Unchecked
|
||||
|
||||
def child(self, row):
|
||||
return self.childItems[row]
|
||||
|
||||
|
@ -167,6 +147,33 @@ class FolderItem(FileItem):
|
|||
return 0
|
||||
|
||||
|
||||
class FileItem(FolderItem):
|
||||
def __init__(self, name, modified, size, parent=None):
|
||||
self.parentItem = parent
|
||||
self.itemData = [name, modified, size] # dt.strptime(modified, ISO_FORMAT)
|
||||
self.checkedState = parent.checkedState
|
||||
|
||||
def childCount(self):
|
||||
return 0
|
||||
|
||||
def columnCount(self):
|
||||
return 3
|
||||
|
||||
def data(self, column):
|
||||
if column == 1:
|
||||
return self.itemData[column] # .strftime('%Y-%m-%dT%H:%M')
|
||||
elif column == 2:
|
||||
return pretty_bytes(self.itemData[column])
|
||||
elif column == 0:
|
||||
return self.itemData[column]
|
||||
|
||||
def parent(self):
|
||||
return self.parentItem
|
||||
|
||||
def row(self):
|
||||
return self.parentItem.childItems.index(self)
|
||||
|
||||
|
||||
class TreeModel(QAbstractItemModel):
|
||||
column_names = ['Name', 'Modified', 'Size']
|
||||
|
||||
|
@ -196,6 +203,7 @@ class TreeModel(QAbstractItemModel):
|
|||
if role == Qt.CheckStateRole:
|
||||
item = index.internalPointer()
|
||||
item.setCheckedState(value)
|
||||
self.dataChanged.emit(QModelIndex(), QModelIndex(), [])
|
||||
|
||||
return True
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
from PyQt5 import uic
|
||||
from PyQt5.QtWidgets import QCheckBox
|
||||
from vorta.utils import get_asset
|
||||
from vorta.utils import get_asset, open_app_at_startup
|
||||
from vorta.models import SettingsModel
|
||||
from vorta._version import __version__
|
||||
|
||||
|
@ -26,3 +26,6 @@ class MiscTab(MiscTabBase, MiscTabUI):
|
|||
setting = SettingsModel.get(key=key)
|
||||
setting.value = bool(new_value)
|
||||
setting.save()
|
||||
|
||||
if key == 'autostart':
|
||||
open_app_at_startup(new_value)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
from PyQt5 import uic
|
||||
from ..utils import get_private_keys, get_asset, choose_folder_dialog
|
||||
from ..utils import get_private_keys, get_asset, choose_file_dialog
|
||||
from vorta.borg.init import BorgInitThread
|
||||
from vorta.borg.info import BorgInfoThread
|
||||
|
||||
|
@ -41,7 +41,7 @@ class AddRepoWindow(AddRepoBase, AddRepoUI):
|
|||
self.sshComboBox.setEnabled(False)
|
||||
self.repoLabel.setText('Repository Path:')
|
||||
|
||||
dialog = choose_folder_dialog(self, "Choose Location of Borg Repository")
|
||||
dialog = choose_file_dialog(self, "Choose Location of Borg Repository")
|
||||
dialog.open(receive)
|
||||
|
||||
def use_remote_repo_action(self):
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
from PyQt5 import uic
|
||||
from ..models import SourceDirModel, BackupProfileMixin
|
||||
from ..utils import get_asset, choose_folder_dialog
|
||||
from ..models import SourceFileModel, BackupProfileMixin
|
||||
from ..utils import get_asset, choose_file_dialog
|
||||
|
||||
uifile = get_asset('UI/sourcetab.ui')
|
||||
SourceUI, SourceBase = uic.loadUiType(uifile)
|
||||
|
@ -22,12 +22,12 @@ class SourceTab(SourceBase, SourceUI, BackupProfileMixin):
|
|||
profile = self.profile()
|
||||
self.excludePatternsField.textChanged.disconnect()
|
||||
self.excludeIfPresentField.textChanged.disconnect()
|
||||
self.sourceDirectoriesWidget.clear()
|
||||
self.sourceFilesWidget.clear()
|
||||
self.excludePatternsField.clear()
|
||||
self.excludeIfPresentField.clear()
|
||||
|
||||
for source in SourceDirModel.select().where(SourceDirModel.profile == profile):
|
||||
self.sourceDirectoriesWidget.addItem(source.dir)
|
||||
for source in SourceFileModel.select().where(SourceFileModel.profile == profile):
|
||||
self.sourceFilesWidget.addItem(source.dir)
|
||||
|
||||
self.excludePatternsField.appendPlainText(profile.exclude_patterns)
|
||||
self.excludeIfPresentField.appendPlainText(profile.exclude_if_present)
|
||||
|
@ -38,18 +38,18 @@ class SourceTab(SourceBase, SourceUI, BackupProfileMixin):
|
|||
def receive():
|
||||
dir = dialog.selectedFiles()
|
||||
if dir:
|
||||
new_source, created = SourceDirModel.get_or_create(dir=dir[0], profile=self.profile())
|
||||
new_source, created = SourceFileModel.get_or_create(dir=dir[0], profile=self.profile())
|
||||
if created:
|
||||
self.sourceDirectoriesWidget.addItem(dir[0])
|
||||
self.sourceFilesWidget.addItem(dir[0])
|
||||
new_source.save()
|
||||
|
||||
item = "directory" if want_folder else "file"
|
||||
dialog = choose_folder_dialog(self, "Choose %s to back up" % item, want_folder=want_folder)
|
||||
dialog = choose_file_dialog(self, "Choose %s to back up" % item, want_folder=want_folder)
|
||||
dialog.open(receive)
|
||||
|
||||
def source_remove(self):
|
||||
item = self.sourceDirectoriesWidget.takeItem(self.sourceDirectoriesWidget.currentRow())
|
||||
db_item = SourceDirModel.get(dir=item.text())
|
||||
item = self.sourceFilesWidget.takeItem(self.sourceFilesWidget.currentRow())
|
||||
db_item = SourceFileModel.get(dir=item.text())
|
||||
db_item.delete_instance()
|
||||
item = None
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ from datetime import datetime as dt
|
|||
|
||||
import vorta
|
||||
from vorta.application import VortaApp
|
||||
from vorta.models import RepoModel, SourceDirModel, ArchiveModel, BackupProfileModel
|
||||
from vorta.models import RepoModel, SourceFileModel, ArchiveModel, BackupProfileModel
|
||||
|
||||
|
||||
def pytest_configure(config):
|
||||
|
@ -28,7 +28,7 @@ def app(tmpdir, qtbot):
|
|||
test_archive = ArchiveModel(snapshot_id='99999', name='test-archive', time=dt(2000, 1, 1, 0, 0), repo=1)
|
||||
test_archive.save()
|
||||
|
||||
source_dir = SourceDirModel(dir='/tmp/another', repo=new_repo)
|
||||
source_dir = SourceFileModel(dir='/tmp/another', repo=new_repo)
|
||||
source_dir.save()
|
||||
|
||||
app = VortaApp([])
|
||||
|
@ -38,7 +38,7 @@ def app(tmpdir, qtbot):
|
|||
|
||||
|
||||
@pytest.fixture
|
||||
def choose_folder_dialog(*args):
|
||||
def choose_file_dialog(*args):
|
||||
class MockFileDialog:
|
||||
def __init__(self, *args, **kwargs):
|
||||
pass
|
||||
|
|
|
@ -71,10 +71,10 @@ def test_check(app, mocker, borg_json_output, qtbot):
|
|||
|
||||
qtbot.mouseClick(tab.checkButton, QtCore.Qt.LeftButton)
|
||||
success_text = 'INFO: Archive consistency check complete'
|
||||
qtbot.waitUntil(lambda: main.createProgressText.text().startswith(success_text))
|
||||
qtbot.waitUntil(lambda: main.createProgressText.text().startswith(success_text), timeout=3000)
|
||||
|
||||
|
||||
def test_archive_mount(app, qtbot, mocker, borg_json_output, monkeypatch, choose_folder_dialog):
|
||||
def test_archive_mount(app, qtbot, mocker, borg_json_output, monkeypatch, choose_file_dialog):
|
||||
def psutil_disk_partitions(**kwargs):
|
||||
DiskPartitions = namedtuple('DiskPartitions', ['device', 'mountpoint'])
|
||||
return [DiskPartitions('borgfs', '/tmp')]
|
||||
|
@ -94,7 +94,7 @@ def test_archive_mount(app, qtbot, mocker, borg_json_output, monkeypatch, choose
|
|||
mocker.patch.object(vorta.borg.borg_thread, 'Popen', return_value=popen_result)
|
||||
|
||||
monkeypatch.setattr(
|
||||
vorta.views.archive_tab, "choose_folder_dialog", choose_folder_dialog
|
||||
vorta.views.archive_tab, "choose_file_dialog", choose_file_dialog
|
||||
)
|
||||
|
||||
qtbot.mouseClick(tab.mountButton, QtCore.Qt.LeftButton)
|
||||
|
|
|
@ -4,16 +4,16 @@ import vorta.models
|
|||
import vorta.views
|
||||
|
||||
|
||||
def test_add_folder(app, qtbot, tmpdir, monkeypatch, choose_folder_dialog):
|
||||
def test_add_folder(app, qtbot, tmpdir, monkeypatch, choose_file_dialog):
|
||||
monkeypatch.setattr(
|
||||
vorta.views.source_tab, "choose_folder_dialog", choose_folder_dialog
|
||||
vorta.views.source_tab, "choose_file_dialog", choose_file_dialog
|
||||
)
|
||||
main = app.main_window
|
||||
main.tabWidget.setCurrentIndex(1)
|
||||
tab = main.sourceTab
|
||||
|
||||
qtbot.mouseClick(tab.sourceAddFolder, QtCore.Qt.LeftButton)
|
||||
qtbot.waitUntil(lambda: tab.sourceDirectoriesWidget.count() == 2)
|
||||
qtbot.waitUntil(lambda: tab.sourceFilesWidget.count() == 2)
|
||||
|
||||
for src in vorta.models.SourceDirModel.select():
|
||||
for src in vorta.models.SourceFileModel.select():
|
||||
logging.error(src.dir, src.profile)
|
||||
|
|
Loading…
Add table
Reference in a new issue