Code deduplication and cleanup

Moved loop handling, exception handling and program
running methods of the gui tools to the utils file.

fixes QubesOS/qubes-issues#5342
This commit is contained in:
Marta Marczykowska-Górecka 2019-09-26 22:31:39 +02:00
parent 8a3653723d
commit 32078242c9
No known key found for this signature in database
GPG Key ID: 9A752C30B26FD04B
8 changed files with 117 additions and 334 deletions

View File

@ -20,18 +20,14 @@
#
#
import traceback
import signal
import quamash
from qubesadmin import Qubes, exc
from qubesadmin import exc
from qubesadmin import utils as admin_utils
from qubesadmin import events
from qubes.storage.file import get_disk_usage
from PyQt5 import QtCore # pylint: disable=import-error
from PyQt5 import QtWidgets # pylint: disable=import-error
from PyQt5 import QtGui
from . import ui_backupdlg # pylint: disable=no-name-in-module
from . import multiselectwidget
@ -393,57 +389,10 @@ class BackupVMsWindow(ui_backupdlg.Ui_Backup, QtWidgets.QWizard):
self.select_dir_page.completeChanged.emit()
# Bases on the original code by:
# Copyright (c) 2002-2007 Pascal Varet <p.varet@gmail.com>
def handle_exception(exc_type, exc_value, exc_traceback):
filename, line, dummy, dummy = traceback.extract_tb(exc_traceback).pop()
filename = os.path.basename(filename)
error = "%s: %s" % (exc_type.__name__, exc_value)
QtWidgets.QMessageBox.critical(
None,
"Houston, we have a problem...",
"Whoops. A critical error has occured. This is most likely a bug "
"in Qubes Global Settings application.<br><br><b><i>%s</i></b>" %
error + "at <b>line %d</b> of file <b>%s</b>.<br/><br/>"
% (line, filename))
def loop_shutdown():
pending = asyncio.Task.all_tasks()
for task in pending:
with suppress(asyncio.CancelledError):
task.cancel()
def main():
qt_app = QtWidgets.QApplication(sys.argv)
qt_app.setOrganizationName("The Qubes Project")
qt_app.setOrganizationDomain("http://qubes-os.org")
qt_app.setApplicationName("Qubes Backup VMs")
qt_app.lastWindowClosed.connect(loop_shutdown)
sys.excepthook = handle_exception
qubes_app = Qubes()
loop = quamash.QEventLoop(qt_app)
asyncio.set_event_loop(loop)
dispatcher = events.EventsDispatcher(qubes_app)
backup_window = BackupVMsWindow(qt_app, qubes_app, dispatcher)
backup_window.show()
try:
loop.run_until_complete(
asyncio.ensure_future(dispatcher.listen_for_events()))
except asyncio.CancelledError:
pass
except Exception: # pylint: disable=broad-except
loop_shutdown()
exc_type, exc_value, exc_traceback = sys.exc_info()[:3]
handle_exception(exc_type, exc_value, exc_traceback)
utils.run_asynchronous("Qubes Backup VMs",
QtGui.QIcon.fromTheme("qubes-manager"),
BackupVMsWindow)
if __name__ == "__main__":

View File

@ -17,7 +17,7 @@
#
#
import sys
import functools
import subprocess
from . import utils
from . import ui_bootfromdevice # pylint: disable=no-name-in-module
@ -28,7 +28,7 @@ from qubesadmin.tools import qvm_start
class VMBootFromDeviceWindow(ui_bootfromdevice.Ui_BootDialog,
QtWidgets.QDialog):
def __init__(self, vm, qapp, parent=None):
def __init__(self, vm, qapp, qubesapp=None, parent=None):
super(VMBootFromDeviceWindow, self).__init__(parent)
self.vm = vm
@ -147,19 +147,8 @@ def main(args=None):
args = parser.parse_args(args)
vm = args.domains.pop()
qapp = QtWidgets.QApplication(sys.argv)
qapp.setOrganizationName('Invisible Things Lab')
qapp.setOrganizationDomain("https://www.qubes-os.org/")
qapp.setApplicationName("Boot Qube From Device")
# if not utils.is_debug(): #FIXME
# sys.excepthook = handle_exception
bootfromdevice_window = VMBootFromDeviceWindow(vm, qapp)
bootfromdevice_window.show()
qapp.exec_()
qapp.exit()
utils.run_synchronous("Boot Qube From Device",
functools.partial(VMBootFromDeviceWindow, vm))
if __name__ == "__main__":

View File

@ -20,14 +20,11 @@
#
#
import sys
import os
import os.path
import traceback
import subprocess
from PyQt5 import QtWidgets # pylint: disable=import-error
from qubesadmin import Qubes
from qubesadmin.utils import parse_size
from . import ui_globalsettingsdlg # pylint: disable=no-name-in-module
@ -406,39 +403,9 @@ class GlobalSettingsWindow(ui_globalsettingsdlg.Ui_GlobalSettings,
self.__apply_updates__()
self.__apply_repos__()
# Bases on the original code by:
# Copyright (c) 2002-2007 Pascal Varet <p.varet@gmail.com>
def handle_exception(exc_type, exc_value, exc_traceback):
filename, line, dummy, dummy = traceback.extract_tb(exc_traceback).pop()
filename = os.path.basename(filename)
error = "%s: %s" % (exc_type.__name__, exc_value)
QtWidgets.QMessageBox.critical(
None,
"Houston, we have a problem...",
"Whoops. A critical error has occured. This is most likely a bug "
"in Qubes Global Settings application.<br><br><b><i>%s</i></b>" %
error + "at <b>line %d</b> of file <b>%s</b>.<br/><br/>"
% (line, filename))
def main():
qtapp = QtWidgets.QApplication(sys.argv)
qtapp.setOrganizationName("The Qubes Project")
qtapp.setOrganizationDomain("http://qubes-os.org")
qtapp.setApplicationName("Qubes Global Settings")
sys.excepthook = handle_exception
app = Qubes()
global_window = GlobalSettingsWindow(qtapp, app)
global_window.show()
qtapp.exec_()
qtapp.exit()
utils.run_synchronous("Qubes Global Settings", GlobalSettingsWindow)
if __name__ == "__main__":

View File

@ -21,21 +21,13 @@
# with this program; if not, see <http://www.gnu.org/licenses/>.
#
#
import sys
import os
import os.path
import subprocess
from datetime import datetime, timedelta
import traceback
from contextlib import suppress
import quamash
import asyncio
from qubesadmin import Qubes
from qubesadmin import exc
from qubesadmin import utils
from qubesadmin import events
from PyQt5 import QtWidgets, QtCore, QtGui # pylint: disable=import-error
@ -1306,71 +1298,11 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QtWidgets.QMainWindow):
log_dlg.exec_()
# Bases on the original code by:
# Copyright (c) 2002-2007 Pascal Varet <p.varet@gmail.com>
def handle_exception(exc_type, exc_value, exc_traceback):
filename, line, dummy, dummy = traceback.extract_tb(exc_traceback).pop()
filename = os.path.basename(filename)
error = "%s: %s" % (exc_type.__name__, exc_value)
strace = ""
stacktrace = traceback.extract_tb(exc_traceback)
while stacktrace:
(filename, line, func, txt) = stacktrace.pop()
strace += "----\n"
strace += "line: %s\n" % txt
strace += "func: %s\n" % func
strace += "line no.: %d\n" % line
strace += "file: %s\n" % filename
msg_box = QtWidgets.QMessageBox()
msg_box.setDetailedText(strace)
msg_box.setIcon(QtWidgets.QMessageBox.Critical)
msg_box.setWindowTitle("Houston, we have a problem...")
msg_box.setText("Whoops. A critical error has occured. "
"This is most likely a bug in Qubes Manager.<br><br>"
"<b><i>%s</i></b>" % error +
"<br/>at line <b>%d</b><br/>of file %s.<br/><br/>"
% (line, filename))
msg_box.exec_()
def loop_shutdown():
pending = asyncio.Task.all_tasks()
for task in pending:
with suppress(asyncio.CancelledError):
task.cancel()
def main():
qt_app = QtWidgets.QApplication(sys.argv)
qt_app.setOrganizationName("The Qubes Project")
qt_app.setOrganizationDomain("http://qubes-os.org")
qt_app.setApplicationName("Qube Manager")
qt_app.setWindowIcon(QtGui.QIcon.fromTheme("qubes-manager"))
qt_app.lastWindowClosed.connect(loop_shutdown)
qubes_app = Qubes()
loop = quamash.QEventLoop(qt_app)
asyncio.set_event_loop(loop)
dispatcher = events.EventsDispatcher(qubes_app)
manager_window = VmManagerWindow(qt_app, qubes_app, dispatcher)
manager_window.show()
try:
loop.run_until_complete(
asyncio.ensure_future(dispatcher.listen_for_events()))
except asyncio.CancelledError:
pass
except Exception: # pylint: disable=broad-except
loop_shutdown()
exc_type, exc_value, exc_traceback = sys.exc_info()[:3]
handle_exception(exc_type, exc_value, exc_traceback)
manager_utils.run_asynchronous(
"Qube Manager",
QtGui.QIcon.fromTheme("qubes-manager"),
VmManagerWindow)
if __name__ == "__main__":

View File

@ -20,11 +20,9 @@
#
#
import sys
from PyQt5 import QtCore, QtWidgets # pylint: disable=import-error
import os
import os.path
import traceback
import logging
import logging.handlers
@ -33,6 +31,7 @@ from qubes import backup
from . import ui_restoredlg # pylint: disable=no-name-in-module
from . import multiselectwidget
from . import backup_utils
from . import utils
from multiprocessing import Queue
from queue import Empty
@ -292,39 +291,8 @@ class RestoreVMsWindow(ui_restoredlg.Ui_Restore, QtWidgets.QWizard):
self.select_dir_page.completeChanged.emit()
# Bases on the original code by:
# Copyright (c) 2002-2007 Pascal Varet <p.varet@gmail.com>
def handle_exception(exc_type, exc_value, exc_traceback):
filename, line, dummy, dummy = traceback.extract_tb(exc_traceback).pop()
filename = os.path.basename(filename)
error = "%s: %s" % (exc_type.__name__, exc_value)
QtWidgets.QMessageBox.critical(
None, "Houston, we have a problem...",
"Whoops. A critical error has occured. This is most likely a bug "
"in Qubes Restore VMs application.<br><br><b><i>%s</i></b>" % error +
"at <b>line %d</b> of file <b>%s</b>.<br/><br/>" % (line, filename))
def main():
qt_app = QtWidgets.QApplication(sys.argv)
qt_app.setOrganizationName("The Qubes Project")
qt_app.setOrganizationDomain("http://qubes-os.org")
qt_app.setApplicationName("Qubes Restore VMs")
sys.excepthook = handle_exception
qubes_app = Qubes()
restore_window = RestoreVMsWindow(qt_app, qubes_app)
restore_window.show()
qt_app.exec_()
qt_app.exit()
utils.run_synchronous("Qubes Restore VMs", RestoreVMsWindow)
if __name__ == "__main__":

View File

@ -23,12 +23,10 @@
#
import collections
import os.path
import os
import functools
import re
import subprocess
import traceback
import sys
from qubesadmin.tools import QubesArgumentParser
from qubesadmin import devices
from qubesadmin import utils as admin_utils
@ -128,11 +126,13 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtWidgets.QDialog):
('services', 5),
))
def __init__(self, vm, qapp, init_page="basic", parent=None):
def __init__(self, vm, init_page="basic", qapp=None, qubesapp=None,
parent=None):
super(VMSettingsWindow, self).__init__(parent)
self.vm = vm
self.qapp = qapp
self.qubesapp = qubesapp
self.threads_list = []
self.progress = None
self.thread_closes = False
@ -1218,38 +1218,6 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtWidgets.QDialog):
self.fw_model.remove_child(i)
# Bases on the original code by:
# Copyright (c) 2002-2007 Pascal Varet <p.varet@gmail.com>
def handle_exception(exc_type, exc_value, exc_traceback):
filename, line, dummy, dummy = traceback.extract_tb(exc_traceback).pop()
filename = os.path.basename(filename)
error = "%s: %s" % (exc_type.__name__, exc_value)
strace = ""
stacktrace = traceback.extract_tb(exc_traceback)
while stacktrace:
(filename, line, func, txt) = stacktrace.pop()
strace += "----\n"
strace += "line: %s\n" % txt
strace += "func: %s\n" % func
strace += "line no.: %d\n" % line
strace += "file: %s\n" % filename
msg_box = QtWidgets.QMessageBox()
msg_box.setDetailedText(strace)
msg_box.setIcon(QtWidgets.QMessageBox.Critical)
msg_box.setWindowTitle("Houston, we have a problem...")
msg_box.setText("Whoops. A critical error has occured. "
"This is most likely a bug in Qubes Manager.<br><br>"
"<b><i>%s</i></b>" % error +
"<br/>at line <b>%d</b><br/>of file %s.<br/><br/>"
% (line, filename))
msg_box.exec_()
parser = QubesArgumentParser(vmname_nargs=1)
parser.add_argument('--tab', metavar='TAB',
@ -1265,19 +1233,8 @@ def main(args=None):
args = parser.parse_args(args)
vm = args.domains.pop()
qapp = QtWidgets.QApplication(sys.argv)
qapp.setOrganizationName('Invisible Things Lab')
qapp.setOrganizationDomain("https://www.qubes-os.org/")
qapp.setApplicationName("Qube Settings")
if not utils.is_debug():
sys.excepthook = handle_exception
settings_window = VMSettingsWindow(vm, qapp, args.tab)
settings_window.show()
qapp.exec_()
qapp.exit()
utils.run_synchronous("Qube Settings",
functools.partial(VMSettingsWindow, vm, args.tab))
if __name__ == "__main__":

View File

@ -20,21 +20,12 @@
#
#
import sys
import os
import os.path
import traceback
import quamash
import asyncio
from contextlib import suppress
from qubesadmin import Qubes
from qubesadmin import exc
from qubesadmin import events
from PyQt5 import QtWidgets, QtGui, QtCore # pylint: disable=import-error
from . import ui_templatemanager # pylint: disable=no-name-in-module
from . import utils
column_names = ['State', 'Qube', 'Current template', 'New template']
@ -385,72 +376,11 @@ class VMRow:
row, column_names.index('State'))
self.checkbox = None
# Bases on the original code by:
# Copyright (c) 2002-2007 Pascal Varet <p.varet@gmail.com>
def handle_exception(exc_type, exc_value, exc_traceback):
filename, line, dummy, dummy = traceback.extract_tb(exc_traceback).pop()
filename = os.path.basename(filename)
error = "%s: %s" % (exc_type.__name__, exc_value)
strace = ""
stacktrace = traceback.extract_tb(exc_traceback)
while stacktrace:
(filename, line, func, txt) = stacktrace.pop()
strace += "----\n"
strace += "line: %s\n" % txt
strace += "func: %s\n" % func
strace += "line no.: %d\n" % line
strace += "file: %s\n" % filename
msg_box = QtWidgets.QMessageBox()
msg_box.setDetailedText(strace)
msg_box.setIcon(QtWidgets.QMessageBox.Critical)
msg_box.setWindowTitle("Houston, we have a problem...")
msg_box.setText("Whoops. A critical error has occured. "
"This is most likely a bug in Qubes Manager.<br><br>"
"<b><i>%s</i></b>" % error +
"<br/>at line <b>%d</b><br/>of file %s.<br/><br/>"
% (line, filename))
msg_box.exec_()
def loop_shutdown():
pending = asyncio.Task.all_tasks()
for task in pending:
with suppress(asyncio.CancelledError):
task.cancel()
def main():
qt_app = QtWidgets.QApplication(sys.argv)
qt_app.setOrganizationName("The Qubes Project")
qt_app.setOrganizationDomain("http://qubes-os.org")
qt_app.setApplicationName("Qube Manager")
qt_app.setWindowIcon(QtGui.QIcon.fromTheme("qubes-manager"))
qt_app.lastWindowClosed.connect(loop_shutdown)
qubes_app = Qubes()
loop = quamash.QEventLoop(qt_app)
asyncio.set_event_loop(loop)
dispatcher = events.EventsDispatcher(qubes_app)
manager_window = TemplateManagerWindow(qt_app, qubes_app, dispatcher)
manager_window.show()
try:
loop.run_until_complete(
asyncio.ensure_future(dispatcher.listen_for_events()))
except asyncio.CancelledError:
pass
except Exception: # pylint: disable=broad-except
loop_shutdown()
exc_type, exc_value, exc_traceback = sys.exc_info()[:3]
handle_exception(exc_type, exc_value, exc_traceback)
utils.run_asynchronous("Template Manager",
QtGui.QIcon.fromTheme("qubes-manager"),
TemplateManagerWindow)
if __name__ == "__main__":

View File

@ -23,7 +23,14 @@ import itertools
import os
import re
import qubesadmin
import traceback
import asyncio
from contextlib import suppress
import sys
import quamash
from qubesadmin import events
from PyQt5 import QtWidgets
from PyQt5.QtGui import QIcon # pylint: disable=import-error
@ -215,3 +222,87 @@ def format_dependencies_list(dependencies):
prop, holder.name)
return list_text
def loop_shutdown():
pending = asyncio.Task.all_tasks()
for task in pending:
with suppress(asyncio.CancelledError):
task.cancel()
# Bases on the original code by:
# Copyright (c) 2002-2007 Pascal Varet <p.varet@gmail.com>
def handle_exception(exc_type, exc_value, exc_traceback):
filename, line, dummy, dummy = traceback.extract_tb(exc_traceback).pop()
filename = os.path.basename(filename)
error = "%s: %s" % (exc_type.__name__, exc_value)
strace = ""
stacktrace = traceback.extract_tb(exc_traceback)
while stacktrace:
(filename, line, func, txt) = stacktrace.pop()
strace += "----\n"
strace += "line: %s\n" % txt
strace += "func: %s\n" % func
strace += "line no.: %d\n" % line
strace += "file: %s\n" % filename
msg_box = QtWidgets.QMessageBox()
msg_box.setDetailedText(strace)
msg_box.setIcon(QtWidgets.QMessageBox.Critical)
msg_box.setWindowTitle("Houston, we have a problem...")
msg_box.setText("Whoops. A critical error has occured. "
"This is most likely a bug in Qubes Manager.<br><br>"
"<b><i>%s</i></b>" % error +
"<br/>at line <b>%d</b><br/>of file %s.<br/><br/>"
% (line, filename))
msg_box.exec_()
def run_asynchronous(app_name, icon, window_class):
qt_app = QtWidgets.QApplication(sys.argv)
qt_app.setOrganizationName("The Qubes Project")
qt_app.setOrganizationDomain("http://qubes-os.org")
qt_app.setApplicationName(app_name)
qt_app.setWindowIcon(icon)
qt_app.lastWindowClosed.connect(loop_shutdown)
qubes_app = qubesadmin.Qubes()
loop = quamash.QEventLoop(qt_app)
asyncio.set_event_loop(loop)
dispatcher = events.EventsDispatcher(qubes_app)
window = window_class(qt_app, qubes_app, dispatcher)
window.show()
try:
loop.run_until_complete(
asyncio.ensure_future(dispatcher.listen_for_events()))
except asyncio.CancelledError:
pass
except Exception: # pylint: disable=broad-except
loop_shutdown()
exc_type, exc_value, exc_traceback = sys.exc_info()[:3]
handle_exception(exc_type, exc_value, exc_traceback)
def run_synchronous(app_name, window_class):
qt_app = QtWidgets.QApplication(sys.argv)
qt_app.setOrganizationName("The Qubes Project")
qt_app.setOrganizationDomain("http://qubes-os.org")
qt_app.setApplicationName(app_name)
sys.excepthook = handle_exception
qubes_app = qubesadmin.Qubes()
window = window_class(qt_app, qubes_app)
window.show()
qt_app.exec_()
qt_app.exit()