mirror of https://github.com/borgbase/vorta
Improve finding assets, make cancelling more reliable.
This commit is contained in:
parent
c77172be05
commit
ff37a8e6e0
|
@ -1,7 +1,7 @@
|
||||||
import sys
|
import sys
|
||||||
from PyQt5.QtWidgets import QApplication
|
from PyQt5.QtWidgets import QApplication
|
||||||
from .tray_menu import TrayMenu
|
from vorta.tray_menu import TrayMenu
|
||||||
from .scheduler import init_scheduler
|
from vorta.scheduler import init_scheduler
|
||||||
|
|
||||||
app = QApplication(sys.argv)
|
app = QApplication(sys.argv)
|
||||||
app.thread = None
|
app.thread = None
|
||||||
|
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
|
@ -38,31 +38,32 @@ class BorgThread(QtCore.QThread):
|
||||||
|
|
||||||
self.env = env
|
self.env = env
|
||||||
self.params = params
|
self.params = params
|
||||||
|
self.process = None
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
with Popen(self.cmd, stdout=PIPE, stderr=PIPE, bufsize=1, universal_newlines=True, env=self.env) as p:
|
self.process = Popen(self.cmd, stdout=PIPE, stderr=PIPE, bufsize=1, universal_newlines=True, env=self.env)
|
||||||
for line in p.stderr:
|
for line in iter(self.process.stderr.readline, b''):
|
||||||
try:
|
|
||||||
parsed = json.loads(line)
|
|
||||||
if parsed['type'] == 'log_message':
|
|
||||||
self.updated.emit(f'{parsed["levelname"]}: {parsed["message"]}')
|
|
||||||
elif parsed['type'] == 'file_status':
|
|
||||||
self.updated.emit(f'{parsed["path"]} ({parsed["status"]})')
|
|
||||||
except json.decoder.JSONDecodeError:
|
|
||||||
self.updated.emit(line.strip())
|
|
||||||
|
|
||||||
p.wait()
|
|
||||||
stdout = p.stdout.read()
|
|
||||||
result = {
|
|
||||||
'params': self.params,
|
|
||||||
'returncode': p.returncode,
|
|
||||||
}
|
|
||||||
try:
|
try:
|
||||||
result['data'] = json.loads(stdout)
|
parsed = json.loads(line)
|
||||||
except:
|
if parsed['type'] == 'log_message':
|
||||||
result['data'] = {}
|
self.updated.emit(f'{parsed["levelname"]}: {parsed["message"]}')
|
||||||
|
elif parsed['type'] == 'file_status':
|
||||||
|
self.updated.emit(f'{parsed["path"]} ({parsed["status"]})')
|
||||||
|
except json.decoder.JSONDecodeError:
|
||||||
|
self.updated.emit(line.strip())
|
||||||
|
|
||||||
self.result.emit(result)
|
self.process.wait()
|
||||||
|
stdout = self.process.stdout.read()
|
||||||
|
result = {
|
||||||
|
'params': self.params,
|
||||||
|
'returncode': self.process.returncode,
|
||||||
|
}
|
||||||
|
try:
|
||||||
|
result['data'] = json.loads(stdout)
|
||||||
|
except:
|
||||||
|
result['data'] = {}
|
||||||
|
|
||||||
|
self.result.emit(result)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def create_thread_factory(cls):
|
def create_thread_factory(cls):
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
from apscheduler.schedulers.qt import QtScheduler
|
from apscheduler.schedulers.qt import QtScheduler
|
||||||
|
from apscheduler.triggers import interval
|
||||||
|
|
||||||
def tick():
|
def tick():
|
||||||
print('scheduler')
|
print('scheduler')
|
||||||
|
|
||||||
def init_scheduler():
|
def init_scheduler():
|
||||||
s = QtScheduler()
|
s = QtScheduler()
|
||||||
s.add_job(tick, 'interval', seconds=3)
|
trigger = interval.IntervalTrigger(seconds=3)
|
||||||
|
s.add_job(tick, trigger, seconds=3)
|
||||||
s.start()
|
s.start()
|
||||||
return s
|
return s
|
||||||
|
|
|
@ -3,13 +3,13 @@ from PyQt5.QtWidgets import QMenu, QApplication, QSystemTrayIcon
|
||||||
from .views.main_window import MainWindow
|
from .views.main_window import MainWindow
|
||||||
from PyQt5.QtGui import QIcon
|
from PyQt5.QtGui import QIcon
|
||||||
|
|
||||||
from .utils import get_relative_asset
|
from .utils import get_asset
|
||||||
from .config import remove_config
|
from .config import remove_config
|
||||||
from .borg_runner import BorgThread
|
from .borg_runner import BorgThread
|
||||||
|
|
||||||
class TrayMenu(QSystemTrayIcon):
|
class TrayMenu(QSystemTrayIcon):
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
icon = QIcon(get_relative_asset('views/UI/icons/hdd-o.png', __file__))
|
icon = QIcon(get_asset('icons/hdd-o.png'))
|
||||||
QSystemTrayIcon.__init__(self, icon, parent)
|
QSystemTrayIcon.__init__(self, icon, parent)
|
||||||
self.app = parent
|
self.app = parent
|
||||||
menu = QMenu()
|
menu = QMenu()
|
||||||
|
@ -59,6 +59,7 @@ class TrayMenu(QSystemTrayIcon):
|
||||||
|
|
||||||
def on_cancel_backup(self):
|
def on_cancel_backup(self):
|
||||||
if self.app.thread and self.app.thread.isRunning():
|
if self.app.thread and self.app.thread.isRunning():
|
||||||
|
self.app.thread.process.kill()
|
||||||
self.app.thread.terminate()
|
self.app.thread.terminate()
|
||||||
|
|
||||||
def on_user_click(self):
|
def on_user_click(self):
|
||||||
|
|
|
@ -45,11 +45,11 @@ def prettyBytes(size):
|
||||||
return str(round(size))+Dic_powerN[n]+'B'
|
return str(round(size))+Dic_powerN[n]+'B'
|
||||||
|
|
||||||
|
|
||||||
def get_relative_asset(path, caller):
|
def get_asset(path):
|
||||||
if getattr(sys, 'frozen', False):
|
if getattr(sys, 'frozen', False):
|
||||||
# we are running in a bundle
|
# we are running in a bundle
|
||||||
bundle_dir = sys._MEIPASS
|
bundle_dir = os.path.join(sys._MEIPASS, 'assets')
|
||||||
else:
|
else:
|
||||||
# we are running in a normal Python environment
|
# we are running in a normal Python environment
|
||||||
bundle_dir = os.path.dirname(os.path.abspath(caller))
|
bundle_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'assets')
|
||||||
return os.path.join(bundle_dir, path)
|
return os.path.join(bundle_dir, path)
|
||||||
|
|
|
@ -8,10 +8,10 @@ from ..borg_runner import BorgThread
|
||||||
from .repo_tab import RepoTab
|
from .repo_tab import RepoTab
|
||||||
from .source_tab import SourceTab
|
from .source_tab import SourceTab
|
||||||
from .snapshots_tab import SnapshotTab
|
from .snapshots_tab import SnapshotTab
|
||||||
from ..utils import get_relative_asset
|
from ..utils import get_asset
|
||||||
|
|
||||||
|
|
||||||
uifile = get_relative_asset('UI/mainwindow.ui', __file__)
|
uifile = get_asset('UI/mainwindow.ui')
|
||||||
MainWindowUI, MainWindowBase = uic.loadUiType(uifile)
|
MainWindowUI, MainWindowBase = uic.loadUiType(uifile)
|
||||||
|
|
||||||
|
|
||||||
|
@ -69,6 +69,7 @@ class MainWindow(MainWindowBase, MainWindowUI):
|
||||||
|
|
||||||
def cancel_create_action(self):
|
def cancel_create_action(self):
|
||||||
try:
|
try:
|
||||||
|
self.app.thread.process.kill()
|
||||||
self.app.thread.terminate()
|
self.app.thread.terminate()
|
||||||
self.app.thread.wait()
|
self.app.thread.wait()
|
||||||
self.createStartBtn.setEnabled(True)
|
self.createStartBtn.setEnabled(True)
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
from PyQt5 import uic
|
from PyQt5 import uic
|
||||||
from ..utils import get_private_keys, get_relative_asset
|
from ..utils import get_private_keys, get_asset
|
||||||
from ..borg_runner import BorgThread
|
from ..borg_runner import BorgThread
|
||||||
|
|
||||||
uifile = get_relative_asset('UI/repoadd.ui', __file__)
|
uifile = get_asset('UI/repoadd.ui')
|
||||||
AddRepoUI, AddRepoBase = uic.loadUiType(uifile)
|
AddRepoUI, AddRepoBase = uic.loadUiType(uifile)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -4,10 +4,10 @@ import keyring
|
||||||
|
|
||||||
from ..models import RepoModel, SnapshotModel
|
from ..models import RepoModel, SnapshotModel
|
||||||
from .repo_add import AddRepoWindow, ExistingRepoWindow
|
from .repo_add import AddRepoWindow, ExistingRepoWindow
|
||||||
from ..utils import prettyBytes, get_private_keys, get_relative_asset
|
from ..utils import prettyBytes, get_private_keys, get_asset
|
||||||
from .ssh_add import SSHAddWindow
|
from .ssh_add import SSHAddWindow
|
||||||
|
|
||||||
uifile = get_relative_asset('UI/repotab.ui', __file__)
|
uifile = get_asset('UI/repotab.ui')
|
||||||
RepoUI, RepoBase = uic.loadUiType(uifile)
|
RepoUI, RepoBase = uic.loadUiType(uifile)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,9 +2,9 @@ from PyQt5 import uic
|
||||||
from PyQt5.QtWidgets import QFileDialog, QTableWidgetItem, QTableView, QHeaderView
|
from PyQt5.QtWidgets import QFileDialog, QTableWidgetItem, QTableView, QHeaderView
|
||||||
|
|
||||||
from ..borg_runner import BorgThread
|
from ..borg_runner import BorgThread
|
||||||
from ..utils import get_relative_asset
|
from ..utils import get_asset
|
||||||
|
|
||||||
uifile = get_relative_asset('UI/snapshottab.ui', __file__)
|
uifile = get_asset('UI/snapshottab.ui')
|
||||||
SnapshotUI, SnapshotBase = uic.loadUiType(uifile)
|
SnapshotUI, SnapshotBase = uic.loadUiType(uifile)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
from PyQt5 import uic
|
from PyQt5 import uic
|
||||||
from PyQt5.QtWidgets import QFileDialog
|
from PyQt5.QtWidgets import QFileDialog
|
||||||
from ..models import SourceDirModel
|
from ..models import SourceDirModel
|
||||||
from ..utils import get_relative_asset
|
from ..utils import get_asset
|
||||||
|
|
||||||
uifile = get_relative_asset('UI/sourcetab.ui', __file__)
|
uifile = get_asset('UI/sourcetab.ui')
|
||||||
SourceUI, SourceBase = uic.loadUiType(uifile)
|
SourceUI, SourceBase = uic.loadUiType(uifile)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -7,9 +7,9 @@ from paramiko.rsakey import RSAKey
|
||||||
from paramiko.ecdsakey import ECDSAKey
|
from paramiko.ecdsakey import ECDSAKey
|
||||||
from paramiko.ed25519key import Ed25519Key
|
from paramiko.ed25519key import Ed25519Key
|
||||||
|
|
||||||
from ..utils import get_relative_asset
|
from ..utils import get_asset
|
||||||
|
|
||||||
uifile = get_relative_asset('UI/sshadd.ui', __file__)
|
uifile = get_asset('UI/sshadd.ui')
|
||||||
SSHAddUI, SSHAddBase = uic.loadUiType(uifile)
|
SSHAddUI, SSHAddBase = uic.loadUiType(uifile)
|
||||||
|
|
||||||
FORMAT_MAPPING = {
|
FORMAT_MAPPING = {
|
||||||
|
|
10
vorta.spec
10
vorta.spec
|
@ -2,14 +2,14 @@
|
||||||
|
|
||||||
block_cipher = None
|
block_cipher = None
|
||||||
|
|
||||||
a = Analysis(['vorta/__main__.py'],
|
a = Analysis(['src/vorta/__main__.py'],
|
||||||
pathex=['/Users/manu/Workspace/vorta'],
|
pathex=['/Users/manu/Workspace/vorta/src'],
|
||||||
binaries=[
|
binaries=[
|
||||||
('bin/macosx64/borg', 'bin')
|
('bin/macosx64/borg', 'bin')
|
||||||
],
|
],
|
||||||
datas=[
|
datas=[
|
||||||
('vorta/UI/*.ui', 'UI'),
|
('src/vorta/assets/UI/*', 'assets/UI'),
|
||||||
('vorta/UI/icons/*', 'UI/icons'),
|
('src/vorta/assets/icons/*', 'assets/icons'),
|
||||||
],
|
],
|
||||||
hiddenimports=[],
|
hiddenimports=[],
|
||||||
hookspath=[],
|
hookspath=[],
|
||||||
|
@ -37,7 +37,7 @@ exe = EXE(pyz,
|
||||||
|
|
||||||
app = BUNDLE(exe,
|
app = BUNDLE(exe,
|
||||||
name='Vorta.app',
|
name='Vorta.app',
|
||||||
icon='vorta/UI/icons/app-icon.icns',
|
icon='src/vorta/assets/icons/app-icon.icns',
|
||||||
bundle_identifier='com.borgbase.client.macos',
|
bundle_identifier='com.borgbase.client.macos',
|
||||||
info_plist={
|
info_plist={
|
||||||
'NSHighResolutionCapable': 'True',
|
'NSHighResolutionCapable': 'True',
|
||||||
|
|
Loading…
Reference in New Issue