1
0
Fork 0
mirror of https://github.com/borgbase/vorta synced 2025-01-03 05:36:19 +00:00

Merge pull request #59 from m3nu/master

UI and bug fixes.
This commit is contained in:
Manuel Riel 2018-11-26 16:07:29 +08:00 committed by GitHub
commit 470a1cd2f2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 79 additions and 56 deletions

View file

@ -230,24 +230,6 @@
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="mountErrors">
<property name="enabled">
<bool>true</bool>
</property>
<property name="font">
<font>
<pointsize>11</pointsize>
</font>
</property>
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;To mount archives, first install &amp;quot;FUSE for macOS&amp;quot; from &lt;a href=&quot;https://osxfuse.github.io/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;here&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
@ -338,6 +320,24 @@
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="mountErrors">
<property name="enabled">
<bool>true</bool>
</property>
<property name="font">
<font>
<pointsize>11</pointsize>
</font>
</property>
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;To mount archives, first install &amp;quot;FUSE for macOS&amp;quot; from &lt;a href=&quot;https://osxfuse.github.io/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;here&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<resources>

View file

@ -181,7 +181,7 @@
<property name="minimumSize">
<size>
<width>0</width>
<height>35</height>
<height>45</height>
</size>
</property>
<property name="font">

View file

@ -92,7 +92,7 @@
<string>...</string>
</property>
<property name="icon">
<iconset>
<iconset resource="../icons/collection.qrc">
<normaloff>:/icons/unlink.svg</normaloff>:/icons/unlink.svg</iconset>
</property>
<property name="autoRaise">
@ -115,6 +115,9 @@
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Remote or local backup repository. For secure remote backups, try &lt;a href=&quot;https://www.borgbase.com/?utm_source=vorta&amp;utm_medium=app&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;BorgBase&lt;/span&gt;&lt;/a&gt;. 100GB free during Beta.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
@ -157,7 +160,7 @@
<string>Copy</string>
</property>
<property name="icon">
<iconset>
<iconset resource="../icons/collection.qrc">
<normaloff>:/icons/copy.svg</normaloff>:/icons/copy.svg</iconset>
</property>
<property name="checkable">
@ -183,6 +186,9 @@
<property name="text">
<string>To securely access remote repositories. Keep default to use all your existing keys. Or create new key.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>

View file

@ -45,6 +45,8 @@ def __init__(self, cmd, params, parent=None):
password = params.get('password')
if password is not None:
env['BORG_PASSPHRASE'] = password
else:
env['BORG_PASSPHRASE'] = '9999999' # Set dummy password to avoid prompt.
env['BORG_RSH'] = 'ssh -oStrictHostKeyChecking=no'
ssh_key = params.get('ssh_key')
@ -93,11 +95,18 @@ def prepare(cls, profile):
ret['message'] = 'Add a backup repository first.'
return ret
# Try to get password from chosen keyring backend.
try:
ret['password'] = keyring.get_password("vorta-repo", profile.repo.url)
except keyring.backends._OS_X_API.Error:
ret['message'] = 'Please make sure you grant Vorta permission to use the Keychain.'
return ret
ret['ssh_key'] = profile.ssh_key
ret['repo_id'] = profile.repo.id
ret['repo_url'] = profile.repo.url
ret['profile_name'] = profile.name
ret['password'] = keyring.get_password("vorta-repo", profile.repo.url) # None if no password.
ret['ok'] = True
return ret

View file

@ -11,7 +11,7 @@
class BorgCreateThread(BorgThread):
def process_result(self, result):
if result['returncode'] in [0, 1]:
if result['returncode'] in [0, 1] and 'archive' in result['data']:
new_snapshot, created = ArchiveModel.get_or_create(
snapshot_id=result['data']['archive']['id'],
defaults={
@ -32,6 +32,8 @@ def process_result(self, result):
repo.total_unique_chunks = stats['total_unique_chunks']
repo.save()
self.app.backup_log_event.emit('Backup finished.')
def log_event(self, msg):
self.app.backup_log_event.emit(msg)
@ -41,7 +43,6 @@ def started_event(self):
def finished_event(self, result):
self.app.backup_finished_event.emit(result)
self.app.backup_log_event.emit('Backup finished.')
@classmethod
def prepare(cls, profile):
@ -102,7 +103,7 @@ def prepare(cls, profile):
cmd.extend(['--exclude-if-present', f.strip()])
# Add repo url and source dirs.
cmd.append(f'{profile.repo.url}::{platform.node()}-{dt.now().isoformat()}')
cmd.append(f"{profile.repo.url}::{platform.node()}-{profile.id}-{dt.now().isoformat(timespec='seconds')}")
for f in SourceDirModel.select().where(SourceDirModel.profile == profile.id):
cmd.append(f.dir)

View file

@ -13,23 +13,6 @@ def __init__(self, parent=None):
self.app = parent
menu = QMenu()
self.status = menu.addAction(self.app.scheduler.next_job)
self.status.setEnabled(False)
self.profile_menu = menu.addMenu('Backup Now')
self.cancel_action = menu.addAction("Cancel Backup")
self.cancel_action.triggered.connect(self.app.backup_cancelled_event.emit)
settings_action = menu.addAction("Settings")
settings_action.triggered.connect(self.app.open_main_window_action)
menu.addSeparator()
exit_action = menu.addAction("Exit")
exit_action.triggered.connect(self.app.quit)
self.on_user_click()
# https://stackoverflow.com/questions/43657890/pyqt5-qsystemtrayicon-activated-signal-not-working
menu.aboutToShow.connect(self.on_user_click)
@ -38,18 +21,42 @@ def __init__(self, parent=None):
self.show()
def on_user_click(self):
"""Adjust labels to reflect current status."""
if BorgThread.is_running():
self.status.setText('Backup in Progress')
self.profile_menu.setEnabled(False)
self.cancel_action.setVisible(True)
else:
self.status.setText(f'Next Task: {self.app.scheduler.next_job}')
self.profile_menu.setEnabled(True)
self.cancel_action.setVisible(False)
"""
Build system tray menu based on current status.
self.profile_menu.clear()
for profile in BackupProfileModel.select():
new_item = self.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))
"""
menu = self.contextMenu()
menu.clear()
status = menu.addAction(self.app.scheduler.next_job)
status.setEnabled(False)
profiles = BackupProfileModel.select()
if profiles.count() > 1:
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))
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)))
if BorgThread.is_running():
status.setText('Backup in Progress')
profile_menu.setVisible(False)
cancel_action = menu.addAction("Cancel Backup")
cancel_action.triggered.connect(self.app.backup_cancelled_event.emit)
else:
status.setText(f'Next Task: {self.app.scheduler.next_job}')
profile_menu.setEnabled(True)
settings_action = menu.addAction("Settings")
settings_action.triggered.connect(self.app.open_main_window_action)
menu.addSeparator()
exit_action = menu.addAction("Exit")
exit_action.triggered.connect(self.app.quit)