From d2120486ca26de169f3e645eb96a7b92a7d500fd Mon Sep 17 00:00:00 2001 From: boyska Date: Tue, 1 Nov 2011 03:07:05 +0100 Subject: [PATCH] GUI/LIB: support for swap, check at beginning --- src/gui/qt/create.py | 64 ++++++++++++++--- src/gui/qt/create.ui | 153 ++++++++++++++++++++++++++++++++++++---- src/gui/qt/ui_create.py | 79 ++++++++++++++++++--- src/gui/qt/worker.py | 64 +++++++++++++++++ src/gui/tomblib/tomb.py | 9 ++- 5 files changed, 332 insertions(+), 37 deletions(-) create mode 100644 src/gui/qt/worker.py diff --git a/src/gui/qt/create.py b/src/gui/qt/create.py index a9b3695..d011d94 100755 --- a/src/gui/qt/create.py +++ b/src/gui/qt/create.py @@ -1,13 +1,13 @@ import sys, os -#from functools import partial from PyQt4.QtGui import QApplication, QWizard from PyQt4 import QtCore from PyQt4 import QtGui from ui_create import Ui_Wizard -parentdir = sys.path[0].split(os.sep)[:-1] -sys.path.append(os.sep.join(parentdir)) +if __name__ == '__main__': + parentdir = sys.path[0].split(os.sep)[:-1] + sys.path.append(os.sep.join(parentdir)) from tomblib.tomb import Tomb from worker import TombCreateThread @@ -21,17 +21,40 @@ class TombCreateWizard(QWizard): QWizard.__init__(self, *args, **kwargs) self.ui = ui = Ui_Wizard() ui.setupUi(self) - - ui.wizardPage_tomb_location.registerField('tombpath*', ui.lineEdit_tombpath) #required field, note the * + #instance attributes: + self.ignore_swap = False + self._tomb_check = False #ugly; it's used by check_progress_complete + + ui.wizardPage_tomb_location.registerField('tombpath*', + ui.lineEdit_tombpath) #required field, note the * ui.wizardPage_key_location.setCommitPage(True) - QtCore.QObject.connect(ui.button_tombpath, QtCore.SIGNAL(_fromUtf8('clicked()')), self.on_tomb_location_clicked) - QtCore.QObject.connect(self, QtCore.SIGNAL(_fromUtf8('currentIdChanged(int)')), self.on_change_page) + QtCore.QObject.connect(ui.button_tombpath, + QtCore.SIGNAL(_fromUtf8('clicked()')), + self.on_tomb_location_clicked) + QtCore.QObject.connect(self, + QtCore.SIGNAL(_fromUtf8('currentIdChanged(int)')), + self.on_change_page) + QtCore.QObject.connect(ui.radioButton_swapoff, + QtCore.SIGNAL(_fromUtf8('toggled(bool)')), + ui.wizardPage_check.completeChanged) + QtCore.QObject.connect(ui.radioButton_ignore, + QtCore.SIGNAL(_fromUtf8('toggled(bool)')), + ui.wizardPage_check.completeChanged) def check_progress_complete(*args, **kwargs): if self.ui.progressBar.value() == 100: return True return False + def check_is_solved(): + if self._tomb_check: + return True + if self.ui.radioButton_swapoff.isChecked() or \ + self.ui.radioButton_ignore.isChecked(): + return True + return False self.ui.wizardPage_progress.isComplete = check_progress_complete + self.ui.wizardPage_check.isComplete = check_is_solved + self.ui.groupBox_swap.setVisible(False) self.finished.connect(self.on_finish) def _keyloc(self): @@ -49,11 +72,14 @@ class TombCreateWizard(QWizard): return keyloc def on_tomb_location_clicked(self, *args, **kwargs): - filename = QtGui.QFileDialog.getSaveFileName(self, 'Create Tomb', filter="*.tomb") + filename = QtGui.QFileDialog.getSaveFileName(self, 'Create Tomb', + filter="*.tomb") self.ui.lineEdit_tombpath.setText(filename) def on_change_page(self, pagenumber): if self.currentPage() == self.ui.wizardPage_progress: self.create_tomb() + if self.currentPage() == self.ui.wizardPage_check: + self.check_requisite() def on_finish(self, finishedint): if self.currentPage() != self.ui.wizardPage_end: @@ -70,15 +96,31 @@ class TombCreateWizard(QWizard): self.ui.label_progress.setText('Error while creating the tomb!') self.ui.wizardPage_progress.setFinalPage(True) self.ui.wizardPage_progress.completeChanged.emit() - def create_tomb(self, *args, **kwargs): - self.thread = TombCreateThread(self.ui.lineEdit_tombpath.text(), str(self.ui.spinBox_size.value()), self._keyloc()) + def create_tomb(self): + self.thread = TombCreateThread(self.ui.lineEdit_tombpath.text(), + str(self.ui.spinBox_size.value()), self._keyloc(), + no_color=False, ignore_swap=self.ui.radioButton_ignore.isChecked()) self.thread.finished.connect(self.on_thread_creation_finished) self.thread.terminated.connect(self.on_thread_creation_finished) self.thread.line_received.connect(self.ui.textBrowser_log.append) def err_append_to_log(text): - self.ui.textBrowser_log.append('Error: ' + text + '') + self.ui.textBrowser_log.append('Error: ' + text + + '') self.thread.error_received.connect(err_append_to_log) self.thread.start() + def check_requisite(self): + self._tomb_check = check = Tomb.check('create', no_color=False) + self.ui.wizardPage_check.completeChanged.emit() + if check: + self.ui.label_check.setText('Everything seems fine!') + return + self.ui.label_check.setText('Some error occurred') + if Tomb.check('create', no_color=False, ignore_swap=True): # swap is the only error + self.ui.groupBox_swap.setVisible(True) + #TODO: support swapoff + #TODO: calculate the amount of ram available vs swap used + self.ui.radioButton_swapoff.setEnabled(False) + self.ui.label_swapoff.setEnabled(False) if __name__ == '__main__': diff --git a/src/gui/qt/create.ui b/src/gui/qt/create.ui index 413aef7..5f3009f 100755 --- a/src/gui/qt/create.ui +++ b/src/gui/qt/create.ui @@ -39,6 +39,129 @@ + + + Requirements check + + + + + + Checking... + + + + + + + true + + + Swap error + + + + + + It seems that you have swap activated. It is very dangerous, since you could leave LOT of traces on your computer UNencrypted. You have some options: + + + true + + + + + + + + + Swapoff + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Maximum + + + + 20 + 20 + + + + + + + + Note: swapoff could take a long time, and, in case the memory is not enough, could even make your system crash. Your system seems to have %freeram%MB free + + + true + + + + + + + + + + + + + Ignore + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Maximum + + + + 20 + 20 + + + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'DejaVu Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Note:</span> You should use this only if you are sure that your swap is encrypted, or that you are using compcache.</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">If this is not the case, DON'T select this, as it is <span style=" font-weight:600;">VERY DANGEROUS </span>to use encryption with swap activated</p></body></html> + + + true + + + + + + + + + + + + @@ -321,9 +444,9 @@ p, li { white-space: pre-wrap; } <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><title>Log</title><style type="text/css"> p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Log</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-weight:600;"></p></body></html> +</style></head><body style=" font-family:'DejaVu Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; font-weight:600;">Log</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; font-weight:600;"></p></body></html> @@ -363,12 +486,12 @@ p, li { white-space: pre-wrap; } setEnabled(bool) - 81 - 212 + 91 + 56 - 164 - 243 + 53 + 56 @@ -379,12 +502,12 @@ p, li { white-space: pre-wrap; } setEnabled(bool) - 118 - 212 + 98 + 56 - 677 - 246 + 98 + 56 @@ -399,8 +522,8 @@ p, li { white-space: pre-wrap; } 335 - 95 - 267 + 99 + 60 @@ -415,8 +538,8 @@ p, li { white-space: pre-wrap; } 356 - 117 - 267 + 99 + 60 diff --git a/src/gui/qt/ui_create.py b/src/gui/qt/ui_create.py index 28ecd54..65d718c 100644 --- a/src/gui/qt/ui_create.py +++ b/src/gui/qt/ui_create.py @@ -2,8 +2,8 @@ # Form implementation generated from reading ui file 'create.ui' # -# Created: Fri Oct 28 20:11:40 2011 -# by: PyQt4 UI code generator 4.8.5 +# Created: Tue Nov 1 02:35:05 2011 +# by: PyQt4 UI code generator 4.8.6 # # WARNING! All changes made in this file will be lost! @@ -33,6 +33,67 @@ class Ui_Wizard(object): self.label.setObjectName(_fromUtf8("label")) self.verticalLayout.addWidget(self.label) Wizard.addPage(self.wizardPage_intro) + self.wizardPage_check = QtGui.QWizardPage() + self.wizardPage_check.setTitle(QtGui.QApplication.translate("Wizard", "Requirements check", None, QtGui.QApplication.UnicodeUTF8)) + self.wizardPage_check.setObjectName(_fromUtf8("wizardPage_check")) + self.verticalLayout_12 = QtGui.QVBoxLayout(self.wizardPage_check) + self.verticalLayout_12.setObjectName(_fromUtf8("verticalLayout_12")) + self.label_check = QtGui.QLabel(self.wizardPage_check) + self.label_check.setText(QtGui.QApplication.translate("Wizard", "Checking...", None, QtGui.QApplication.UnicodeUTF8)) + self.label_check.setObjectName(_fromUtf8("label_check")) + self.verticalLayout_12.addWidget(self.label_check) + self.groupBox_swap = QtGui.QGroupBox(self.wizardPage_check) + self.groupBox_swap.setEnabled(True) + self.groupBox_swap.setTitle(QtGui.QApplication.translate("Wizard", "Swap error", None, QtGui.QApplication.UnicodeUTF8)) + self.groupBox_swap.setObjectName(_fromUtf8("groupBox_swap")) + self.verticalLayout_13 = QtGui.QVBoxLayout(self.groupBox_swap) + self.verticalLayout_13.setObjectName(_fromUtf8("verticalLayout_13")) + self.label_7 = QtGui.QLabel(self.groupBox_swap) + self.label_7.setText(QtGui.QApplication.translate("Wizard", "It seems that you have swap activated. It is very dangerous, since you could leave LOT of traces on your computer UNencrypted. You have some options:", None, QtGui.QApplication.UnicodeUTF8)) + self.label_7.setWordWrap(True) + self.label_7.setObjectName(_fromUtf8("label_7")) + self.verticalLayout_13.addWidget(self.label_7) + self.verticalLayout_swapoff = QtGui.QVBoxLayout() + self.verticalLayout_swapoff.setObjectName(_fromUtf8("verticalLayout_swapoff")) + self.radioButton_swapoff = QtGui.QRadioButton(self.groupBox_swap) + self.radioButton_swapoff.setText(QtGui.QApplication.translate("Wizard", "Swapoff", None, QtGui.QApplication.UnicodeUTF8)) + self.radioButton_swapoff.setObjectName(_fromUtf8("radioButton_swapoff")) + self.verticalLayout_swapoff.addWidget(self.radioButton_swapoff) + self.horizontalLayout_6 = QtGui.QHBoxLayout() + self.horizontalLayout_6.setObjectName(_fromUtf8("horizontalLayout_6")) + spacerItem = QtGui.QSpacerItem(20, 20, QtGui.QSizePolicy.Maximum, QtGui.QSizePolicy.Minimum) + self.horizontalLayout_6.addItem(spacerItem) + self.label_swapoff = QtGui.QLabel(self.groupBox_swap) + self.label_swapoff.setText(QtGui.QApplication.translate("Wizard", "Note: swapoff could take a long time, and, in case the memory is not enough, could even make your system crash. Your system seems to have %freeram%MB free", None, QtGui.QApplication.UnicodeUTF8)) + self.label_swapoff.setWordWrap(True) + self.label_swapoff.setObjectName(_fromUtf8("label_swapoff")) + self.horizontalLayout_6.addWidget(self.label_swapoff) + self.verticalLayout_swapoff.addLayout(self.horizontalLayout_6) + self.verticalLayout_13.addLayout(self.verticalLayout_swapoff) + self.verticalLayout_11 = QtGui.QVBoxLayout() + self.verticalLayout_11.setObjectName(_fromUtf8("verticalLayout_11")) + self.radioButton_ignore = QtGui.QRadioButton(self.groupBox_swap) + self.radioButton_ignore.setText(QtGui.QApplication.translate("Wizard", "Ignore", None, QtGui.QApplication.UnicodeUTF8)) + self.radioButton_ignore.setObjectName(_fromUtf8("radioButton_ignore")) + self.verticalLayout_11.addWidget(self.radioButton_ignore) + self.horizontalLayout_7 = QtGui.QHBoxLayout() + self.horizontalLayout_7.setObjectName(_fromUtf8("horizontalLayout_7")) + spacerItem1 = QtGui.QSpacerItem(20, 20, QtGui.QSizePolicy.Maximum, QtGui.QSizePolicy.Minimum) + self.horizontalLayout_7.addItem(spacerItem1) + self.label_9 = QtGui.QLabel(self.groupBox_swap) + self.label_9.setText(QtGui.QApplication.translate("Wizard", "\n" +"\n" +"

Note: You should use this only if you are sure that your swap is encrypted, or that you are using compcache.

\n" +"

If this is not the case, DON\'T select this, as it is VERY DANGEROUS to use encryption with swap activated

", None, QtGui.QApplication.UnicodeUTF8)) + self.label_9.setWordWrap(True) + self.label_9.setObjectName(_fromUtf8("label_9")) + self.horizontalLayout_7.addWidget(self.label_9) + self.verticalLayout_11.addLayout(self.horizontalLayout_7) + self.verticalLayout_13.addLayout(self.verticalLayout_11) + self.verticalLayout_12.addWidget(self.groupBox_swap) + Wizard.addPage(self.wizardPage_check) self.wizardPage_tomb_size = QtGui.QWizardPage() self.wizardPage_tomb_size.setObjectName(_fromUtf8("wizardPage_tomb_size")) self.verticalLayout_2 = QtGui.QVBoxLayout(self.wizardPage_tomb_size) @@ -108,8 +169,8 @@ class Ui_Wizard(object): self.verticalLayout_4.addWidget(self.radioButton_usb) self.horizontalLayout_4 = QtGui.QHBoxLayout() self.horizontalLayout_4.setObjectName(_fromUtf8("horizontalLayout_4")) - spacerItem = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Maximum, QtGui.QSizePolicy.Minimum) - self.horizontalLayout_4.addItem(spacerItem) + spacerItem2 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Maximum, QtGui.QSizePolicy.Minimum) + self.horizontalLayout_4.addItem(spacerItem2) self.label_6 = QtGui.QLabel(self.wizardPage_key_location) self.label_6.setEnabled(False) self.label_6.setText(QtGui.QApplication.translate("Wizard", "If you choose to do so, do not insert it NOW. Do it when you are asked to do so", None, QtGui.QApplication.UnicodeUTF8)) @@ -135,8 +196,8 @@ class Ui_Wizard(object): self.verticalLayout_6.addLayout(self.verticalLayout_5) self.horizontalLayout_3 = QtGui.QHBoxLayout() self.horizontalLayout_3.setObjectName(_fromUtf8("horizontalLayout_3")) - spacerItem1 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Maximum, QtGui.QSizePolicy.Minimum) - self.horizontalLayout_3.addItem(spacerItem1) + spacerItem3 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Maximum, QtGui.QSizePolicy.Minimum) + self.horizontalLayout_3.addItem(spacerItem3) self.lineEdit_custom = QtGui.QLineEdit(self.wizardPage_key_location) self.lineEdit_custom.setEnabled(False) self.lineEdit_custom.setObjectName(_fromUtf8("lineEdit_custom")) @@ -184,9 +245,9 @@ class Ui_Wizard(object): self.textBrowser_log.setHtml(QtGui.QApplication.translate("Wizard", "\n" "Log\n" -"

Log

\n" -"

", None, QtGui.QApplication.UnicodeUTF8)) +"\n" +"

Log

\n" +"

", None, QtGui.QApplication.UnicodeUTF8)) self.textBrowser_log.setObjectName(_fromUtf8("textBrowser_log")) self.verticalLayout_9.addWidget(self.textBrowser_log) Wizard.addPage(self.wizardPage_progress) diff --git a/src/gui/qt/worker.py b/src/gui/qt/worker.py new file mode 100644 index 0000000..b1b39ac --- /dev/null +++ b/src/gui/qt/worker.py @@ -0,0 +1,64 @@ +import sys,os +import time +import re +from tempfile import NamedTemporaryFile + +from PyQt4 import QtCore + +parentdir = sys.path[0].split(os.sep)[:-1] +sys.path.append(os.sep.join(parentdir)) +from tomblib.tomb import Tomb + +class TombCreateThread(QtCore.QThread): + line_received = QtCore.pyqtSignal(QtCore.QString) + error_received = QtCore.pyqtSignal(QtCore.QString) + def __init__(self, tombpath, size, keypath, **opts): + QtCore.QThread.__init__(self) + self.tombpath = tombpath + self.size = size + self.keypath = keypath + self.opts = opts + + self.err_thread = TombOutputThread() + self.err_thread.line_received.connect(self.line_received) + self.err_thread.error_received.connect(self.error_received) + + def run(self): + self.err_thread.start() + #Tomb.tombexec = '/home/davide/coding/projects/tomb/src/tomb' + self.status = Tomb.create(str(self.tombpath), str(self.size), + self.keypath, stderr=self.err_thread.buffer, **self.opts) +# self.err_thread.terminate() + + def get_success(self): + return self.status + +class TombOutputThread(QtCore.QThread): + line_received = QtCore.pyqtSignal(QtCore.QString) + error_received = QtCore.pyqtSignal(QtCore.QString) + progressed = QtCore.pyqtSignal(int) #value in percent + + def __init__(self): + QtCore.QThread.__init__(self) + self.buffer = NamedTemporaryFile() + + def run(self): + while True: + where = self.buffer.tell() + line = self.buffer.readline() + if not line: + time.sleep(1) + self.buffer.seek(where) + else: + #ansi color escapes messes this up, but it'ok anyway + self.line_received.emit(line) + self.parse_line(line) + + def parse_line(self, line): + #This could be simplified, and s/search/match, if --no-color supported + #see #59 + #TODO: this should be moved to tomblib.parse + err_regex = re.compile(r'\[!\][^ ]* +(.+)$') + match = err_regex.search(line) + if match: + self.error_received.emit(match.group(1)) diff --git a/src/gui/tomblib/tomb.py b/src/gui/tomblib/tomb.py index f89e905..6f5abe1 100644 --- a/src/gui/tomblib/tomb.py +++ b/src/gui/tomblib/tomb.py @@ -34,9 +34,14 @@ class Tomb(object): return path @classmethod - def check(cls, command, stdout=None, stderr=None, no_color=True): + def check(cls, command, stdout=None, stderr=None, no_color=True, ignore_swap=False): + args = [command] + if no_color: + args += ['--no-color'] + if ignore_swap: + args += ['--ignore-swap'] try: - subprocess.check_call([cls.tombexec, 'check'] + [command], stdout=stdout, stderr=stderr) + subprocess.check_call([cls.tombexec, 'check'] + args, stdout=stdout, stderr=stderr) except subprocess.CalledProcessError: return False return True