From 92e776c6d6fe3844a78089f14eca4e9e1e94631b Mon Sep 17 00:00:00 2001 From: BoySka Date: Mon, 24 Oct 2011 04:04:50 +0200 Subject: [PATCH 01/25] First draft for a gui --- src/gui/.gitignore | 1 + src/gui/HACKING.txt | 12 + src/gui/qt/create.py | 29 ++ src/gui/qt/create.ui | 481 ++++++++++++++++++++++++++++++++ src/gui/qt/ui_create.py | 226 +++++++++++++++ src/gui/qt/wizardpage_pass.py | 31 ++ src/gui/tomblib/.wrapper.py.swp | Bin 0 -> 12288 bytes src/gui/tomblib/__init__.py | 0 src/gui/tomblib/wrapper.py | 5 + 9 files changed, 785 insertions(+) create mode 100644 src/gui/.gitignore create mode 100644 src/gui/HACKING.txt create mode 100755 src/gui/qt/create.py create mode 100755 src/gui/qt/create.ui create mode 100755 src/gui/qt/ui_create.py create mode 100755 src/gui/qt/wizardpage_pass.py create mode 100755 src/gui/tomblib/.wrapper.py.swp create mode 100755 src/gui/tomblib/__init__.py create mode 100755 src/gui/tomblib/wrapper.py diff --git a/src/gui/.gitignore b/src/gui/.gitignore new file mode 100644 index 0000000..a01ee28 --- /dev/null +++ b/src/gui/.gitignore @@ -0,0 +1 @@ +.*.swp diff --git a/src/gui/HACKING.txt b/src/gui/HACKING.txt new file mode 100644 index 0000000..ca87184 --- /dev/null +++ b/src/gui/HACKING.txt @@ -0,0 +1,12 @@ +### Code organization: +* tomblib: a library that wraps on tomb. Meant to be used by various scripts, and every UI +* qt / wx / whatever: directory for different gui implementations + +### QT project: + +status: only create wizard +the graphical part is done through create.ui, which can be edited by designer + +The UI should be (if possible) completely autocontained in this .ui file, and no code (or very few) should be added to make it work. +* ATM, some code has been added for the "password don't match" part. +* Some code need to be added to make the filedialog work diff --git a/src/gui/qt/create.py b/src/gui/qt/create.py new file mode 100755 index 0000000..a3f1265 --- /dev/null +++ b/src/gui/qt/create.py @@ -0,0 +1,29 @@ +import sys, os +from PyQt4.QtGui import QApplication, QWizard +from PyQt4 import QtCore +from ui_create import Ui_Wizard + +parentdir = sys.path[0].split(os.sep)[:-1] +sys.path.append(os.sep.join(parentdir)) +from tomblib import wrapper + +app = QApplication(sys.argv) +window = QWizard() +ui = Ui_Wizard() +ui.setupUi(window) + +def create_tomb(*args, **kwargs): + print 'creating' + wrapper.Tomb.create(1,2,3) + print 'created!' + +try: + _fromUtf8 = QtCore.QString.fromUtf8 +except AttributeError: + _fromUtf8 = lambda s: s +QtCore.QObject.connect(window, QtCore.SIGNAL(_fromUtf8('finished(int)')), create_tomb) + +window.show() +sys.exit(app.exec_()) + + diff --git a/src/gui/qt/create.ui b/src/gui/qt/create.ui new file mode 100755 index 0000000..418a68d --- /dev/null +++ b/src/gui/qt/create.ui @@ -0,0 +1,481 @@ + + + Wizard + + + + 0 + 0 + 710 + 368 + + + + Wizard + + + QWizard::HaveHelpButton|QWizard::IndependentPages + + + + Tomb + + + tomb creation + + + + + + This wizard will guide you to the creation of a tomb.<br> It will be fun! + + + Qt::RichText + + + true + + + + + + + + + + + Please enter tomb size. Digging the tomb will require some time: usually, one minute per GB, but your mileage may vary. <br>Keep in mind that resizing it in the future is still NOT implemented + + + true + + + + + + + + + Enter tomb size, in MB. 1GB=1000MB) + + + spinBox + + + + + + + 100000 + + + 100 + + + + + + + + + + + + + Where do you want your tomb to be digged? + + + true + + + lineEdit + + + + + + + + + + + + Open file + + + + + + + + + + Key creation + + + Choose the location for your key + + + + + + <!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:'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;">Now, you have to decide where to put the <span style=" font-weight:600;">key</span> for your tomb<br />You should not leave your key at the door, as this will lower security A LOT</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Also, the keyfile is very small (less than a KB), so disk space is not an issue</p></body></html> + + + Qt::RichText + + + true + + + + + + + + + + + On a USB pen (best security) + + + true + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Maximum + + + + 40 + 20 + + + + + + + + If you choose to do so, do not insert it NOW. Do it when you are asked to do so + + + + + + + + + + + <!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:'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;">It will be created as a regular file in the same directory of your tomb.</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">It is much easier to use, but also much more <span style=" font-style:italic;">insecure</span>: all your security will be guaranteed by your <span style=" font-weight:600;">password</span>. If you really want to do this, choose a strong password (lot of random/non-dictionary words, spaces, numbers, odd characters)</p></body></html> + + + Near to the tomb itself (this is BAD) + + + + + + + Specify location + + + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Maximum + + + + 40 + 20 + + + + + + + + false + + + + + + + false + + + Choose location + + + + + + + + + <!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:'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;">Help: </span>the key file is very small, so disk usage is not an issue</p></body></html> + + + true + + + + + + + + false + + + Key + + + Password + + + + + + Choose a <b>strong</b> password now + + + + + + + + + Password + + + lineEdit_pass + + + + + + + QLineEdit::Password + + + + + + + Password (again, for confirmation) + + + lineEdit_pass_again + + + + + + + QLineEdit::Password + + + + + + + + + <!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:'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;">Warning: password doesn't match</span></p></body></html> + + + + + + + + + + + You successfully created the tomb! + + + + + + + Open the just-created tomb NOW! + + + true + + + false + + + + + + + + + WizardPage_pass + QWizardPage +
wizardpage_pass.h
+ 1 + + password_not_match(bool) + check_password_match() + +
+
+ + + + radioButton_3 + toggled(bool) + lineEdit_2 + setEnabled(bool) + + + 62 + 212 + + + 164 + 243 + + + + + radioButton_3 + toggled(bool) + pushButton_2 + setEnabled(bool) + + + 118 + 212 + + + 677 + 246 + + + + + Wizard + currentIdChanged(int) + label_11 + hide() + + + 181 + 335 + + + 77 + 267 + + + + + Wizard + helpRequested() + label_11 + show() + + + 135 + 356 + + + 117 + 267 + + + + + lineEdit_pass + textChanged(QString) + wizardPage_pass + check_password_match() + + + 339 + 105 + + + 99 + 85 + + + + + wizardPage_pass + password_match(bool) + label_pwd_match + setVisible(bool) + + + 99 + 85 + + + 117 + 152 + + + + + lineEdit_pass_again + textChanged(QString) + wizardPage_pass + check_password_match() + + + 289 + 126 + + + 49 + 70 + + + + + + check_passwords_equal() + +
diff --git a/src/gui/qt/ui_create.py b/src/gui/qt/ui_create.py new file mode 100755 index 0000000..f013726 --- /dev/null +++ b/src/gui/qt/ui_create.py @@ -0,0 +1,226 @@ +# -*- coding: utf-8 -*- + +# Form implementation generated from reading ui file 'create.ui' +# +# Created: Mon Oct 24 03:26:55 2011 +# by: PyQt4 UI code generator 4.8.5 +# +# WARNING! All changes made in this file will be lost! + +from PyQt4 import QtCore, QtGui + +try: + _fromUtf8 = QtCore.QString.fromUtf8 +except AttributeError: + _fromUtf8 = lambda s: s + +class Ui_Wizard(object): + def setupUi(self, Wizard): + Wizard.setObjectName(_fromUtf8("Wizard")) + Wizard.resize(710, 368) + Wizard.setWindowTitle(QtGui.QApplication.translate("Wizard", "Wizard", None, QtGui.QApplication.UnicodeUTF8)) + Wizard.setWizardStyle(QtGui.QWizard.ModernStyle) + Wizard.setOptions(QtGui.QWizard.HaveHelpButton|QtGui.QWizard.IndependentPages) + self.wizardPage_intro = QtGui.QWizardPage() + self.wizardPage_intro.setTitle(QtGui.QApplication.translate("Wizard", "Tomb", None, QtGui.QApplication.UnicodeUTF8)) + self.wizardPage_intro.setSubTitle(QtGui.QApplication.translate("Wizard", "tomb creation", None, QtGui.QApplication.UnicodeUTF8)) + self.wizardPage_intro.setObjectName(_fromUtf8("wizardPage_intro")) + self.verticalLayout = QtGui.QVBoxLayout(self.wizardPage_intro) + self.verticalLayout.setObjectName(_fromUtf8("verticalLayout")) + self.label = QtGui.QLabel(self.wizardPage_intro) + self.label.setText(QtGui.QApplication.translate("Wizard", "This wizard will guide you to the creation of a tomb.
It will be fun!", None, QtGui.QApplication.UnicodeUTF8)) + self.label.setTextFormat(QtCore.Qt.RichText) + self.label.setWordWrap(True) + self.label.setObjectName(_fromUtf8("label")) + self.verticalLayout.addWidget(self.label) + Wizard.addPage(self.wizardPage_intro) + self.wizardPage_tomb_size = QtGui.QWizardPage() + self.wizardPage_tomb_size.setObjectName(_fromUtf8("wizardPage_tomb_size")) + self.verticalLayout_2 = QtGui.QVBoxLayout(self.wizardPage_tomb_size) + self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2")) + self.label_2 = QtGui.QLabel(self.wizardPage_tomb_size) + self.label_2.setText(QtGui.QApplication.translate("Wizard", "Please enter tomb size. Digging the tomb will require some time: usually, one minute per GB, but your mileage may vary.
Keep in mind that resizing it in the future is still NOT implemented", None, QtGui.QApplication.UnicodeUTF8)) + self.label_2.setWordWrap(True) + self.label_2.setObjectName(_fromUtf8("label_2")) + self.verticalLayout_2.addWidget(self.label_2) + self.horizontalLayout = QtGui.QHBoxLayout() + self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout")) + self.label_3 = QtGui.QLabel(self.wizardPage_tomb_size) + self.label_3.setText(QtGui.QApplication.translate("Wizard", "Enter tomb size, in MB. 1GB=1000MB)", None, QtGui.QApplication.UnicodeUTF8)) + self.label_3.setObjectName(_fromUtf8("label_3")) + self.horizontalLayout.addWidget(self.label_3) + self.spinBox = QtGui.QSpinBox(self.wizardPage_tomb_size) + self.spinBox.setMaximum(100000) + self.spinBox.setProperty("value", 100) + self.spinBox.setObjectName(_fromUtf8("spinBox")) + self.horizontalLayout.addWidget(self.spinBox) + self.verticalLayout_2.addLayout(self.horizontalLayout) + Wizard.addPage(self.wizardPage_tomb_size) + self.wizardPage_tomb_location = QtGui.QWizardPage() + self.wizardPage_tomb_location.setObjectName(_fromUtf8("wizardPage_tomb_location")) + self.verticalLayout_3 = QtGui.QVBoxLayout(self.wizardPage_tomb_location) + self.verticalLayout_3.setObjectName(_fromUtf8("verticalLayout_3")) + self.label_4 = QtGui.QLabel(self.wizardPage_tomb_location) + self.label_4.setText(QtGui.QApplication.translate("Wizard", "Where do you want your tomb to be digged?", None, QtGui.QApplication.UnicodeUTF8)) + self.label_4.setWordWrap(True) + self.label_4.setObjectName(_fromUtf8("label_4")) + self.verticalLayout_3.addWidget(self.label_4) + self.horizontalLayout_2 = QtGui.QHBoxLayout() + self.horizontalLayout_2.setObjectName(_fromUtf8("horizontalLayout_2")) + self.lineEdit = QtGui.QLineEdit(self.wizardPage_tomb_location) + self.lineEdit.setObjectName(_fromUtf8("lineEdit")) + self.horizontalLayout_2.addWidget(self.lineEdit) + self.pushButton = QtGui.QPushButton(self.wizardPage_tomb_location) + self.pushButton.setText(QtGui.QApplication.translate("Wizard", "Open file", None, QtGui.QApplication.UnicodeUTF8)) + self.pushButton.setObjectName(_fromUtf8("pushButton")) + self.horizontalLayout_2.addWidget(self.pushButton) + self.verticalLayout_3.addLayout(self.horizontalLayout_2) + Wizard.addPage(self.wizardPage_tomb_location) + self.wizardPage_key_location = QtGui.QWizardPage() + self.wizardPage_key_location.setTitle(QtGui.QApplication.translate("Wizard", "Key creation", None, QtGui.QApplication.UnicodeUTF8)) + self.wizardPage_key_location.setSubTitle(QtGui.QApplication.translate("Wizard", "Choose the location for your key", None, QtGui.QApplication.UnicodeUTF8)) + self.wizardPage_key_location.setObjectName(_fromUtf8("wizardPage_key_location")) + self.verticalLayout_6 = QtGui.QVBoxLayout(self.wizardPage_key_location) + self.verticalLayout_6.setObjectName(_fromUtf8("verticalLayout_6")) + self.label_5 = QtGui.QLabel(self.wizardPage_key_location) + self.label_5.setText(QtGui.QApplication.translate("Wizard", "\n" +"\n" +"

Now, you have to decide where to put the key for your tomb
You should not leave your key at the door, as this will lower security A LOT

\n" +"

Also, the keyfile is very small (less than a KB), so disk space is not an issue

", None, QtGui.QApplication.UnicodeUTF8)) + self.label_5.setTextFormat(QtCore.Qt.RichText) + self.label_5.setWordWrap(True) + self.label_5.setObjectName(_fromUtf8("label_5")) + self.verticalLayout_6.addWidget(self.label_5) + self.verticalLayout_5 = QtGui.QVBoxLayout() + self.verticalLayout_5.setObjectName(_fromUtf8("verticalLayout_5")) + self.verticalLayout_4 = QtGui.QVBoxLayout() + self.verticalLayout_4.setObjectName(_fromUtf8("verticalLayout_4")) + self.radioButton = QtGui.QRadioButton(self.wizardPage_key_location) + self.radioButton.setText(QtGui.QApplication.translate("Wizard", "On a USB pen (best security)", None, QtGui.QApplication.UnicodeUTF8)) + self.radioButton.setChecked(True) + self.radioButton.setObjectName(_fromUtf8("radioButton")) + self.verticalLayout_4.addWidget(self.radioButton) + 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) + self.label_6 = QtGui.QLabel(self.wizardPage_key_location) + 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)) + self.label_6.setObjectName(_fromUtf8("label_6")) + self.horizontalLayout_4.addWidget(self.label_6) + self.verticalLayout_4.addLayout(self.horizontalLayout_4) + self.verticalLayout_5.addLayout(self.verticalLayout_4) + self.radioButton_2 = QtGui.QRadioButton(self.wizardPage_key_location) + self.radioButton_2.setToolTip(QtGui.QApplication.translate("Wizard", "\n" +"\n" +"

It will be created as a regular file in the same directory of your tomb.

\n" +"

It is much easier to use, but also much more insecure: all your security will be guaranteed by your password. If you really want to do this, choose a strong password (lot of random/non-dictionary words, spaces, numbers, odd characters)

", None, QtGui.QApplication.UnicodeUTF8)) + self.radioButton_2.setText(QtGui.QApplication.translate("Wizard", "Near to the tomb itself (this is BAD)", None, QtGui.QApplication.UnicodeUTF8)) + self.radioButton_2.setObjectName(_fromUtf8("radioButton_2")) + self.verticalLayout_5.addWidget(self.radioButton_2) + self.radioButton_3 = QtGui.QRadioButton(self.wizardPage_key_location) + self.radioButton_3.setText(QtGui.QApplication.translate("Wizard", "Specify location", None, QtGui.QApplication.UnicodeUTF8)) + self.radioButton_3.setObjectName(_fromUtf8("radioButton_3")) + self.verticalLayout_5.addWidget(self.radioButton_3) + 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) + self.lineEdit_2 = QtGui.QLineEdit(self.wizardPage_key_location) + self.lineEdit_2.setEnabled(False) + self.lineEdit_2.setObjectName(_fromUtf8("lineEdit_2")) + self.horizontalLayout_3.addWidget(self.lineEdit_2) + self.pushButton_2 = QtGui.QPushButton(self.wizardPage_key_location) + self.pushButton_2.setEnabled(False) + self.pushButton_2.setText(QtGui.QApplication.translate("Wizard", "Choose location", None, QtGui.QApplication.UnicodeUTF8)) + self.pushButton_2.setObjectName(_fromUtf8("pushButton_2")) + self.horizontalLayout_3.addWidget(self.pushButton_2) + self.verticalLayout_6.addLayout(self.horizontalLayout_3) + self.label_11 = QtGui.QLabel(self.wizardPage_key_location) + self.label_11.setText(QtGui.QApplication.translate("Wizard", "\n" +"\n" +"

Help: the key file is very small, so disk usage is not an issue

", None, QtGui.QApplication.UnicodeUTF8)) + self.label_11.setWordWrap(True) + self.label_11.setObjectName(_fromUtf8("label_11")) + self.verticalLayout_6.addWidget(self.label_11) + Wizard.addPage(self.wizardPage_key_location) + self.wizardPage_pass = WizardPage_pass() + self.wizardPage_pass.setAutoFillBackground(False) + self.wizardPage_pass.setTitle(QtGui.QApplication.translate("Wizard", "Key", None, QtGui.QApplication.UnicodeUTF8)) + self.wizardPage_pass.setSubTitle(QtGui.QApplication.translate("Wizard", "Password", None, QtGui.QApplication.UnicodeUTF8)) + self.wizardPage_pass.setObjectName(_fromUtf8("wizardPage_pass")) + self.verticalLayout_7 = QtGui.QVBoxLayout(self.wizardPage_pass) + self.verticalLayout_7.setObjectName(_fromUtf8("verticalLayout_7")) + self.label_7 = QtGui.QLabel(self.wizardPage_pass) + self.label_7.setText(QtGui.QApplication.translate("Wizard", "Choose a strong password now", None, QtGui.QApplication.UnicodeUTF8)) + self.label_7.setObjectName(_fromUtf8("label_7")) + self.verticalLayout_7.addWidget(self.label_7) + self.formLayout = QtGui.QFormLayout() + self.formLayout.setObjectName(_fromUtf8("formLayout")) + self.label_8 = QtGui.QLabel(self.wizardPage_pass) + self.label_8.setText(QtGui.QApplication.translate("Wizard", "Password", None, QtGui.QApplication.UnicodeUTF8)) + self.label_8.setObjectName(_fromUtf8("label_8")) + self.formLayout.setWidget(0, QtGui.QFormLayout.LabelRole, self.label_8) + self.lineEdit_pass = QtGui.QLineEdit(self.wizardPage_pass) + self.lineEdit_pass.setEchoMode(QtGui.QLineEdit.Password) + self.lineEdit_pass.setObjectName(_fromUtf8("lineEdit_pass")) + self.formLayout.setWidget(0, QtGui.QFormLayout.FieldRole, self.lineEdit_pass) + self.label_9 = QtGui.QLabel(self.wizardPage_pass) + self.label_9.setText(QtGui.QApplication.translate("Wizard", "Password (again, for confirmation)", None, QtGui.QApplication.UnicodeUTF8)) + self.label_9.setObjectName(_fromUtf8("label_9")) + self.formLayout.setWidget(1, QtGui.QFormLayout.LabelRole, self.label_9) + self.lineEdit_pass_again = QtGui.QLineEdit(self.wizardPage_pass) + self.lineEdit_pass_again.setEchoMode(QtGui.QLineEdit.Password) + self.lineEdit_pass_again.setObjectName(_fromUtf8("lineEdit_pass_again")) + self.formLayout.setWidget(1, QtGui.QFormLayout.FieldRole, self.lineEdit_pass_again) + self.verticalLayout_7.addLayout(self.formLayout) + self.label_pwd_match = QtGui.QLabel(self.wizardPage_pass) + self.label_pwd_match.setText(QtGui.QApplication.translate("Wizard", "\n" +"\n" +"

Warning: password doesn\'t match

", None, QtGui.QApplication.UnicodeUTF8)) + self.label_pwd_match.setObjectName(_fromUtf8("label_pwd_match")) + self.verticalLayout_7.addWidget(self.label_pwd_match) + Wizard.addPage(self.wizardPage_pass) + self.wizardPage_end = QtGui.QWizardPage() + self.wizardPage_end.setObjectName(_fromUtf8("wizardPage_end")) + self.verticalLayout_8 = QtGui.QVBoxLayout(self.wizardPage_end) + self.verticalLayout_8.setObjectName(_fromUtf8("verticalLayout_8")) + self.label_10 = QtGui.QLabel(self.wizardPage_end) + self.label_10.setText(QtGui.QApplication.translate("Wizard", "You successfully created the tomb!", None, QtGui.QApplication.UnicodeUTF8)) + self.label_10.setObjectName(_fromUtf8("label_10")) + self.verticalLayout_8.addWidget(self.label_10) + self.checkBox = QtGui.QCheckBox(self.wizardPage_end) + self.checkBox.setText(QtGui.QApplication.translate("Wizard", "Open the just-created tomb NOW!", None, QtGui.QApplication.UnicodeUTF8)) + self.checkBox.setChecked(True) + self.checkBox.setTristate(False) + self.checkBox.setObjectName(_fromUtf8("checkBox")) + self.verticalLayout_8.addWidget(self.checkBox) + Wizard.addPage(self.wizardPage_end) + self.label_3.setBuddy(self.spinBox) + self.label_4.setBuddy(self.lineEdit) + self.label_8.setBuddy(self.lineEdit_pass) + self.label_9.setBuddy(self.lineEdit_pass_again) + + self.retranslateUi(Wizard) + QtCore.QObject.connect(self.radioButton_3, QtCore.SIGNAL(_fromUtf8("toggled(bool)")), self.lineEdit_2.setEnabled) + QtCore.QObject.connect(self.radioButton_3, QtCore.SIGNAL(_fromUtf8("toggled(bool)")), self.pushButton_2.setEnabled) + QtCore.QObject.connect(Wizard, QtCore.SIGNAL(_fromUtf8("currentIdChanged(int)")), self.label_11.hide) + QtCore.QObject.connect(Wizard, QtCore.SIGNAL(_fromUtf8("helpRequested()")), self.label_11.show) + QtCore.QObject.connect(self.lineEdit_pass, QtCore.SIGNAL(_fromUtf8("textChanged(QString)")), self.wizardPage_pass.check_password_match) + QtCore.QObject.connect(self.wizardPage_pass, QtCore.SIGNAL(_fromUtf8("password_match(bool)")), self.label_pwd_match.setVisible) + QtCore.QObject.connect(self.lineEdit_pass_again, QtCore.SIGNAL(_fromUtf8("textChanged(QString)")), self.wizardPage_pass.check_password_match) + QtCore.QMetaObject.connectSlotsByName(Wizard) + + def retranslateUi(self, Wizard): + pass + +from wizardpage_pass import WizardPage_pass diff --git a/src/gui/qt/wizardpage_pass.py b/src/gui/qt/wizardpage_pass.py new file mode 100755 index 0000000..f7153f5 --- /dev/null +++ b/src/gui/qt/wizardpage_pass.py @@ -0,0 +1,31 @@ +''' +This module provide some methods to enhance the password page +of the wizard. It could have been avoided, but this way make +it easier to do things from the designer. + +Indeed, it's possible to use password_match(bool) signal +and check_password_match(slot) from the designer. +''' + +from PyQt4.QtGui import QWizardPage +from PyQt4 import QtCore, QtGui +try: + _fromUtf8 = QtCore.QString.fromUtf8 +except AttributeError: + _fromUtf8 = lambda s: s +class WizardPage_pass(QWizardPage): + password_match = QtCore.pyqtSignal(bool) + def __init__(self, *args, **kwargs): + QWizardPage.__init__(self, *args, **kwargs) + def _password_match(self): + pass1 = self.findChild(QtGui.QLineEdit, _fromUtf8('lineEdit_pass')).text() + pass2 = self.findChild(QtGui.QLineEdit, _fromUtf8('lineEdit_pass_again')).text() + return pass1 == pass2 + def check_password_match(self): + self.password_match.emit(not self._password_match()) + self.completeChanged.emit() + def isComplete(self): #this will make the "Next" button disabled if password doesn't match + return self._password_match() + + + diff --git a/src/gui/tomblib/.wrapper.py.swp b/src/gui/tomblib/.wrapper.py.swp new file mode 100755 index 0000000000000000000000000000000000000000..59d5d6db0ed2845814e27ea49055920042ffda21 GIT binary patch literal 12288 zcmeI&KTg9i6bA5DBt`@(7cejsq|y{RfS3>xLxy$&R^%kF)TNFi=M^Yt-~b$e3vdeV zz!|s$I1z}gbYZE!Cq2cHKU?x|%b%os75CLqr$?bSh?;LNgXacOKPJlboyoYGm|v;3 z1^fA#YBsXDMEoGvmaX%%NSsZg(x=hQ)I<}LME717VW&SGn`~4^lIqv=wElZpdbJN2tWV= z5P$##AOHafKmY;|SP}u95uL3QjYC)8|EqTZA7T6+`Ze@Z=z4BR&WmF}00Izz00bZa z0SG_<0uX=z1pZe*eV5m!WHoRS+hW3&bK&gVd*|sVQFxP!YQ;)hl{-=9H`uB}84p$J ySqtx0|Iim&Mr~D^M{cWIo>jMdCw1_&6fGvTEF+guI?-jRF2agkmy9`;kop4OuvJI^ literal 0 HcmV?d00001 diff --git a/src/gui/tomblib/__init__.py b/src/gui/tomblib/__init__.py new file mode 100755 index 0000000..e69de29 diff --git a/src/gui/tomblib/wrapper.py b/src/gui/tomblib/wrapper.py new file mode 100755 index 0000000..b38bdea --- /dev/null +++ b/src/gui/tomblib/wrapper.py @@ -0,0 +1,5 @@ +class Tomb(object): + @staticmethod + def create(tombpath, size, keypath): + print 'I am not implemented' + raise NotImplementedError From afd399efe2cc51cdec99dd188e852daf0af95403 Mon Sep 17 00:00:00 2001 From: BoySka Date: Mon, 24 Oct 2011 18:52:10 +0200 Subject: [PATCH 02/25] Code reorganization, tomblocation required field --- src/gui/qt/create.py | 32 ++++++++++++++++----------- src/gui/qt/create.ui | 49 +++++++++++++++++++++++------------------ src/gui/qt/ui_create.py | 13 ++++++----- 3 files changed, 54 insertions(+), 40 deletions(-) diff --git a/src/gui/qt/create.py b/src/gui/qt/create.py index a3f1265..3816c72 100755 --- a/src/gui/qt/create.py +++ b/src/gui/qt/create.py @@ -7,23 +7,29 @@ parentdir = sys.path[0].split(os.sep)[:-1] sys.path.append(os.sep.join(parentdir)) from tomblib import wrapper -app = QApplication(sys.argv) -window = QWizard() -ui = Ui_Wizard() -ui.setupUi(window) - -def create_tomb(*args, **kwargs): - print 'creating' - wrapper.Tomb.create(1,2,3) - print 'created!' - try: _fromUtf8 = QtCore.QString.fromUtf8 except AttributeError: _fromUtf8 = lambda s: s -QtCore.QObject.connect(window, QtCore.SIGNAL(_fromUtf8('finished(int)')), create_tomb) -window.show() -sys.exit(app.exec_()) +class TombCreateWizard(QWizard): + def __init__(self, *args, **kwargs): + 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 * + + QtCore.QObject.connect(self, QtCore.SIGNAL(_fromUtf8('finished(int)')), self.create_tomb) + + def create_tomb(self, *args, **kwargs): + print 'creating' + wrapper.Tomb.create(1,2,3) + print 'created!' +if __name__ == '__main__': + app = QApplication(sys.argv) + window = TombCreateWizard() + window.show() + sys.exit(app.exec_()) diff --git a/src/gui/qt/create.ui b/src/gui/qt/create.ui index 418a68d..eb5c85d 100755 --- a/src/gui/qt/create.ui +++ b/src/gui/qt/create.ui @@ -88,14 +88,21 @@ true - lineEdit + lineEdit_tombpath - + + + true + + + /path/to/file.tomb + + @@ -370,11 +377,11 @@ p, li { white-space: pre-wrap; } 62 - 212 + 29 - 164 - 243 + 99 + 29 @@ -385,12 +392,12 @@ p, li { white-space: pre-wrap; } setEnabled(bool) - 118 - 212 + 99 + 29 - 677 - 246 + 99 + 29 @@ -406,7 +413,7 @@ p, li { white-space: pre-wrap; } 77 - 267 + 29 @@ -421,8 +428,8 @@ p, li { white-space: pre-wrap; } 356 - 117 - 267 + 99 + 29 @@ -433,12 +440,12 @@ p, li { white-space: pre-wrap; } check_password_match() - 339 - 105 + 99 + 29 99 - 85 + 29 @@ -450,11 +457,11 @@ p, li { white-space: pre-wrap; } 99 - 85 + 29 - 117 - 152 + 99 + 29 @@ -465,12 +472,12 @@ p, li { white-space: pre-wrap; } check_password_match() - 289 - 126 + 99 + 29 49 - 70 + 14 diff --git a/src/gui/qt/ui_create.py b/src/gui/qt/ui_create.py index f013726..f1312f2 100755 --- a/src/gui/qt/ui_create.py +++ b/src/gui/qt/ui_create.py @@ -2,7 +2,7 @@ # Form implementation generated from reading ui file 'create.ui' # -# Created: Mon Oct 24 03:26:55 2011 +# Created: Mon Oct 24 18:27:59 2011 # by: PyQt4 UI code generator 4.8.5 # # WARNING! All changes made in this file will be lost! @@ -19,7 +19,6 @@ class Ui_Wizard(object): Wizard.setObjectName(_fromUtf8("Wizard")) Wizard.resize(710, 368) Wizard.setWindowTitle(QtGui.QApplication.translate("Wizard", "Wizard", None, QtGui.QApplication.UnicodeUTF8)) - Wizard.setWizardStyle(QtGui.QWizard.ModernStyle) Wizard.setOptions(QtGui.QWizard.HaveHelpButton|QtGui.QWizard.IndependentPages) self.wizardPage_intro = QtGui.QWizardPage() self.wizardPage_intro.setTitle(QtGui.QApplication.translate("Wizard", "Tomb", None, QtGui.QApplication.UnicodeUTF8)) @@ -67,9 +66,11 @@ class Ui_Wizard(object): self.verticalLayout_3.addWidget(self.label_4) self.horizontalLayout_2 = QtGui.QHBoxLayout() self.horizontalLayout_2.setObjectName(_fromUtf8("horizontalLayout_2")) - self.lineEdit = QtGui.QLineEdit(self.wizardPage_tomb_location) - self.lineEdit.setObjectName(_fromUtf8("lineEdit")) - self.horizontalLayout_2.addWidget(self.lineEdit) + self.lineEdit_tombpath = QtGui.QLineEdit(self.wizardPage_tomb_location) + self.lineEdit_tombpath.setFrame(True) + self.lineEdit_tombpath.setPlaceholderText(QtGui.QApplication.translate("Wizard", "/path/to/file.tomb", None, QtGui.QApplication.UnicodeUTF8)) + self.lineEdit_tombpath.setObjectName(_fromUtf8("lineEdit_tombpath")) + self.horizontalLayout_2.addWidget(self.lineEdit_tombpath) self.pushButton = QtGui.QPushButton(self.wizardPage_tomb_location) self.pushButton.setText(QtGui.QApplication.translate("Wizard", "Open file", None, QtGui.QApplication.UnicodeUTF8)) self.pushButton.setObjectName(_fromUtf8("pushButton")) @@ -206,7 +207,7 @@ class Ui_Wizard(object): self.verticalLayout_8.addWidget(self.checkBox) Wizard.addPage(self.wizardPage_end) self.label_3.setBuddy(self.spinBox) - self.label_4.setBuddy(self.lineEdit) + self.label_4.setBuddy(self.lineEdit_tombpath) self.label_8.setBuddy(self.lineEdit_pass) self.label_9.setBuddy(self.lineEdit_pass_again) From 2a962d788d45d73d6287346c67635610dee75162 Mon Sep 17 00:00:00 2001 From: BoySka Date: Thu, 27 Oct 2011 00:03:15 +0200 Subject: [PATCH 03/25] Starting to write libtomb --- src/gui/.gitignore | 1 + src/gui/tomblib/tomb.py | 60 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 src/gui/tomblib/tomb.py diff --git a/src/gui/.gitignore b/src/gui/.gitignore index a01ee28..3bb2efd 100644 --- a/src/gui/.gitignore +++ b/src/gui/.gitignore @@ -1 +1,2 @@ .*.swp +*.pyc diff --git a/src/gui/tomblib/tomb.py b/src/gui/tomblib/tomb.py new file mode 100644 index 0000000..3d53927 --- /dev/null +++ b/src/gui/tomblib/tomb.py @@ -0,0 +1,60 @@ +''' +Module structure: + +this contain a class, which is indeed just a collection of functions +(the methods are all static). +It's meant to behave in a way which is similar to the command line, for + +Notes: consider moving to a more typical usage (instantiate, then use method) +to make it more configurable (ie set the tomb executable path). +''' + +import os +import subprocess + +class Tomb(object): + ''' + This is just a collection of static methods, so you should NOT instantiate + + The methods are meant to resemble the command line interface as much as + possible + + There is no support to things like threading, multiprocessing, whatever. + If you want to interact asynchronously with tomb, just do it in a separate + layer. + ''' + #TODO: support setting a "pipe" to pass out/err on + def _check_exec_path(self): + '''Checks, using which, if tomb is available. + Returns None on error, the path on success. + ''' + try: + path=subprocess.check_output(['which', 'tomb']) + except subprocess.CalledProcessError: + return None + return path + + @staticmethod + def create(tombpath,tombsize,keypath): + '''If keypath is None, it will be created adjacent to the tomb. + This is unsafe, and you should NOT do it. + + Note that this will invoke pinentry + ''' + args = [tombpath, '-s', tombsize] + if keypath is not None: + args += ['-k', keypath] + try: + subprocess.check_call(['tomb', 'create'] + args) + except subprocess.CalledProcessError: + return False + return True + + @staticmethod + def open(tombpath,keypath=None): + raise NotImplementedError + + +if __name__ == '__main__': + #Debug stuff. Also useful for an example + print Tomb.create('/tmp/a.tomb', '10', '/tmp/akey') From 4f1bb6401091a82beea0a15e3b63f1936d1f3c3e Mon Sep 17 00:00:00 2001 From: BoySka Date: Thu, 27 Oct 2011 02:22:39 +0200 Subject: [PATCH 04/25] Working draft (works bad) Password input is removed: not secure, tomb provides pinentry key location option is actually ignored. USB support is yet to come --- src/gui/qt/create.py | 21 +++- src/gui/qt/create.ui | 193 ++++++++++------------------------ src/gui/qt/notes.txt | 9 ++ src/gui/qt/ui_create.py | 87 ++++++--------- src/gui/qt/wizardpage_pass.py | 31 ------ 5 files changed, 112 insertions(+), 229 deletions(-) create mode 100644 src/gui/qt/notes.txt delete mode 100755 src/gui/qt/wizardpage_pass.py diff --git a/src/gui/qt/create.py b/src/gui/qt/create.py index 3816c72..a99c75a 100755 --- a/src/gui/qt/create.py +++ b/src/gui/qt/create.py @@ -1,11 +1,12 @@ import sys, os 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)) -from tomblib import wrapper +from tomblib import tomb try: _fromUtf8 = QtCore.QString.fromUtf8 @@ -19,13 +20,23 @@ class TombCreateWizard(QWizard): ui.setupUi(self) ui.wizardPage_tomb_location.registerField('tombpath*', ui.lineEdit_tombpath) #required field, note the * + ui.wizardPage_key_location.setCommitPage(True) - QtCore.QObject.connect(self, QtCore.SIGNAL(_fromUtf8('finished(int)')), self.create_tomb) + 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) + def on_tomb_location_clicked(self, *args, **kwargs): + filename = QtGui.QFileDialog.getSaveFileName(self, 'Create Tomb', filter="*.tomb") + print filename + self.ui.lineEdit_tombpath.setText(filename) + def on_change_page(self, pagenumber): + if self.currentPage() == self.ui.wizardPage_progress: + self.create_tomb() def create_tomb(self, *args, **kwargs): - print 'creating' - wrapper.Tomb.create(1,2,3) - print 'created!' + #FIXME: this will lock up the GUI + #FIXME: no support for other keypath than "next to tomb" + tomb.Tomb.create(self.ui.lineEdit_tombpath.text(), str(self.ui.spinBox_size.value()), None) + self.ui.progressBar.setValue(100) if __name__ == '__main__': diff --git a/src/gui/qt/create.ui b/src/gui/qt/create.ui index eb5c85d..c9275e7 100755 --- a/src/gui/qt/create.ui +++ b/src/gui/qt/create.ui @@ -59,12 +59,12 @@ Enter tomb size, in MB. 1GB=1000MB) - spinBox + spinBox_size - + 100000 @@ -105,7 +105,7 @@ - + Open file @@ -261,74 +261,49 @@ p, li { white-space: pre-wrap; } - - - false - + - Key + Creating - Password + Please wait - - - - - Choose a <b>strong</b> password now - - - - - - - - - Password - - - lineEdit_pass - - - - - - - QLineEdit::Password - - - - - - - Password (again, for confirmation) - - - lineEdit_pass_again - - - - - - - QLineEdit::Password - - - - - - - - - <!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:'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;">Warning: password doesn't match</span></p></body></html> - - - - + + + + 30 + 30 + 276 + 52 + + + + + + + 0 + + + true + + + false + + + + + + + + + Creating tomb, please wait... + + + + + + + @@ -355,18 +330,6 @@ p, li { white-space: pre-wrap; } - - - WizardPage_pass - QWizardPage -
wizardpage_pass.h
- 1 - - password_not_match(bool) - check_password_match() - -
-
@@ -376,12 +339,12 @@ p, li { white-space: pre-wrap; } setEnabled(bool) - 62 - 29 + 81 + 212 - 99 - 29 + 164 + 243 @@ -392,12 +355,12 @@ p, li { white-space: pre-wrap; } setEnabled(bool) - 99 - 29 + 118 + 212 - 99 - 29 + 677 + 246 @@ -412,8 +375,8 @@ p, li { white-space: pre-wrap; } 335 - 77 - 29 + 95 + 267 @@ -428,56 +391,8 @@ p, li { white-space: pre-wrap; } 356 - 99 - 29 - - - - - lineEdit_pass - textChanged(QString) - wizardPage_pass - check_password_match() - - - 99 - 29 - - - 99 - 29 - - - - - wizardPage_pass - password_match(bool) - label_pwd_match - setVisible(bool) - - - 99 - 29 - - - 99 - 29 - - - - - lineEdit_pass_again - textChanged(QString) - wizardPage_pass - check_password_match() - - - 99 - 29 - - - 49 - 14 + 117 + 267 diff --git a/src/gui/qt/notes.txt b/src/gui/qt/notes.txt new file mode 100644 index 0000000..05525f5 --- /dev/null +++ b/src/gui/qt/notes.txt @@ -0,0 +1,9 @@ +Some conventions: +.ui files are designers files +Sometimes it's necessary to create custom widget to extend the functionality +given by designer in a clean way. These files should be called ui_whatever.py + +.ui files must be "compiled" using pyuic4. This should be done with make, but +won't be right now. So, for the moment, I'll keep compiled files directly in +the sources, for easiness. + diff --git a/src/gui/qt/ui_create.py b/src/gui/qt/ui_create.py index f1312f2..c2bae30 100755 --- a/src/gui/qt/ui_create.py +++ b/src/gui/qt/ui_create.py @@ -2,7 +2,7 @@ # Form implementation generated from reading ui file 'create.ui' # -# Created: Mon Oct 24 18:27:59 2011 +# Created: Thu Oct 27 01:57:45 2011 # by: PyQt4 UI code generator 4.8.5 # # WARNING! All changes made in this file will be lost! @@ -48,11 +48,11 @@ class Ui_Wizard(object): self.label_3.setText(QtGui.QApplication.translate("Wizard", "Enter tomb size, in MB. 1GB=1000MB)", None, QtGui.QApplication.UnicodeUTF8)) self.label_3.setObjectName(_fromUtf8("label_3")) self.horizontalLayout.addWidget(self.label_3) - self.spinBox = QtGui.QSpinBox(self.wizardPage_tomb_size) - self.spinBox.setMaximum(100000) - self.spinBox.setProperty("value", 100) - self.spinBox.setObjectName(_fromUtf8("spinBox")) - self.horizontalLayout.addWidget(self.spinBox) + self.spinBox_size = QtGui.QSpinBox(self.wizardPage_tomb_size) + self.spinBox_size.setMaximum(100000) + self.spinBox_size.setProperty("value", 100) + self.spinBox_size.setObjectName(_fromUtf8("spinBox_size")) + self.horizontalLayout.addWidget(self.spinBox_size) self.verticalLayout_2.addLayout(self.horizontalLayout) Wizard.addPage(self.wizardPage_tomb_size) self.wizardPage_tomb_location = QtGui.QWizardPage() @@ -71,10 +71,10 @@ class Ui_Wizard(object): self.lineEdit_tombpath.setPlaceholderText(QtGui.QApplication.translate("Wizard", "/path/to/file.tomb", None, QtGui.QApplication.UnicodeUTF8)) self.lineEdit_tombpath.setObjectName(_fromUtf8("lineEdit_tombpath")) self.horizontalLayout_2.addWidget(self.lineEdit_tombpath) - self.pushButton = QtGui.QPushButton(self.wizardPage_tomb_location) - self.pushButton.setText(QtGui.QApplication.translate("Wizard", "Open file", None, QtGui.QApplication.UnicodeUTF8)) - self.pushButton.setObjectName(_fromUtf8("pushButton")) - self.horizontalLayout_2.addWidget(self.pushButton) + self.button_tombpath = QtGui.QPushButton(self.wizardPage_tomb_location) + self.button_tombpath.setText(QtGui.QApplication.translate("Wizard", "Open file", None, QtGui.QApplication.UnicodeUTF8)) + self.button_tombpath.setObjectName(_fromUtf8("button_tombpath")) + self.horizontalLayout_2.addWidget(self.button_tombpath) self.verticalLayout_3.addLayout(self.horizontalLayout_2) Wizard.addPage(self.wizardPage_tomb_location) self.wizardPage_key_location = QtGui.QWizardPage() @@ -152,45 +152,30 @@ class Ui_Wizard(object): self.label_11.setObjectName(_fromUtf8("label_11")) self.verticalLayout_6.addWidget(self.label_11) Wizard.addPage(self.wizardPage_key_location) - self.wizardPage_pass = WizardPage_pass() - self.wizardPage_pass.setAutoFillBackground(False) - self.wizardPage_pass.setTitle(QtGui.QApplication.translate("Wizard", "Key", None, QtGui.QApplication.UnicodeUTF8)) - self.wizardPage_pass.setSubTitle(QtGui.QApplication.translate("Wizard", "Password", None, QtGui.QApplication.UnicodeUTF8)) - self.wizardPage_pass.setObjectName(_fromUtf8("wizardPage_pass")) - self.verticalLayout_7 = QtGui.QVBoxLayout(self.wizardPage_pass) + self.wizardPage_progress = QtGui.QWizardPage() + self.wizardPage_progress.setTitle(QtGui.QApplication.translate("Wizard", "Creating", None, QtGui.QApplication.UnicodeUTF8)) + self.wizardPage_progress.setSubTitle(QtGui.QApplication.translate("Wizard", "Please wait", None, QtGui.QApplication.UnicodeUTF8)) + self.wizardPage_progress.setObjectName(_fromUtf8("wizardPage_progress")) + self.widget = QtGui.QWidget(self.wizardPage_progress) + self.widget.setGeometry(QtCore.QRect(30, 30, 276, 52)) + self.widget.setObjectName(_fromUtf8("widget")) + self.verticalLayout_7 = QtGui.QVBoxLayout(self.widget) + self.verticalLayout_7.setMargin(0) self.verticalLayout_7.setObjectName(_fromUtf8("verticalLayout_7")) - self.label_7 = QtGui.QLabel(self.wizardPage_pass) - self.label_7.setText(QtGui.QApplication.translate("Wizard", "Choose a strong password now", None, QtGui.QApplication.UnicodeUTF8)) + self.progressBar = QtGui.QProgressBar(self.widget) + self.progressBar.setProperty("value", 0) + self.progressBar.setTextVisible(True) + self.progressBar.setInvertedAppearance(False) + self.progressBar.setObjectName(_fromUtf8("progressBar")) + self.verticalLayout_7.addWidget(self.progressBar) + self.horizontalLayout_5 = QtGui.QHBoxLayout() + self.horizontalLayout_5.setObjectName(_fromUtf8("horizontalLayout_5")) + self.label_7 = QtGui.QLabel(self.widget) + self.label_7.setText(QtGui.QApplication.translate("Wizard", "Creating tomb, please wait...", None, QtGui.QApplication.UnicodeUTF8)) self.label_7.setObjectName(_fromUtf8("label_7")) - self.verticalLayout_7.addWidget(self.label_7) - self.formLayout = QtGui.QFormLayout() - self.formLayout.setObjectName(_fromUtf8("formLayout")) - self.label_8 = QtGui.QLabel(self.wizardPage_pass) - self.label_8.setText(QtGui.QApplication.translate("Wizard", "Password", None, QtGui.QApplication.UnicodeUTF8)) - self.label_8.setObjectName(_fromUtf8("label_8")) - self.formLayout.setWidget(0, QtGui.QFormLayout.LabelRole, self.label_8) - self.lineEdit_pass = QtGui.QLineEdit(self.wizardPage_pass) - self.lineEdit_pass.setEchoMode(QtGui.QLineEdit.Password) - self.lineEdit_pass.setObjectName(_fromUtf8("lineEdit_pass")) - self.formLayout.setWidget(0, QtGui.QFormLayout.FieldRole, self.lineEdit_pass) - self.label_9 = QtGui.QLabel(self.wizardPage_pass) - self.label_9.setText(QtGui.QApplication.translate("Wizard", "Password (again, for confirmation)", None, QtGui.QApplication.UnicodeUTF8)) - self.label_9.setObjectName(_fromUtf8("label_9")) - self.formLayout.setWidget(1, QtGui.QFormLayout.LabelRole, self.label_9) - self.lineEdit_pass_again = QtGui.QLineEdit(self.wizardPage_pass) - self.lineEdit_pass_again.setEchoMode(QtGui.QLineEdit.Password) - self.lineEdit_pass_again.setObjectName(_fromUtf8("lineEdit_pass_again")) - self.formLayout.setWidget(1, QtGui.QFormLayout.FieldRole, self.lineEdit_pass_again) - self.verticalLayout_7.addLayout(self.formLayout) - self.label_pwd_match = QtGui.QLabel(self.wizardPage_pass) - self.label_pwd_match.setText(QtGui.QApplication.translate("Wizard", "\n" -"\n" -"

Warning: password doesn\'t match

", None, QtGui.QApplication.UnicodeUTF8)) - self.label_pwd_match.setObjectName(_fromUtf8("label_pwd_match")) - self.verticalLayout_7.addWidget(self.label_pwd_match) - Wizard.addPage(self.wizardPage_pass) + self.horizontalLayout_5.addWidget(self.label_7) + self.verticalLayout_7.addLayout(self.horizontalLayout_5) + Wizard.addPage(self.wizardPage_progress) self.wizardPage_end = QtGui.QWizardPage() self.wizardPage_end.setObjectName(_fromUtf8("wizardPage_end")) self.verticalLayout_8 = QtGui.QVBoxLayout(self.wizardPage_end) @@ -206,22 +191,16 @@ class Ui_Wizard(object): self.checkBox.setObjectName(_fromUtf8("checkBox")) self.verticalLayout_8.addWidget(self.checkBox) Wizard.addPage(self.wizardPage_end) - self.label_3.setBuddy(self.spinBox) + self.label_3.setBuddy(self.spinBox_size) self.label_4.setBuddy(self.lineEdit_tombpath) - self.label_8.setBuddy(self.lineEdit_pass) - self.label_9.setBuddy(self.lineEdit_pass_again) self.retranslateUi(Wizard) QtCore.QObject.connect(self.radioButton_3, QtCore.SIGNAL(_fromUtf8("toggled(bool)")), self.lineEdit_2.setEnabled) QtCore.QObject.connect(self.radioButton_3, QtCore.SIGNAL(_fromUtf8("toggled(bool)")), self.pushButton_2.setEnabled) QtCore.QObject.connect(Wizard, QtCore.SIGNAL(_fromUtf8("currentIdChanged(int)")), self.label_11.hide) QtCore.QObject.connect(Wizard, QtCore.SIGNAL(_fromUtf8("helpRequested()")), self.label_11.show) - QtCore.QObject.connect(self.lineEdit_pass, QtCore.SIGNAL(_fromUtf8("textChanged(QString)")), self.wizardPage_pass.check_password_match) - QtCore.QObject.connect(self.wizardPage_pass, QtCore.SIGNAL(_fromUtf8("password_match(bool)")), self.label_pwd_match.setVisible) - QtCore.QObject.connect(self.lineEdit_pass_again, QtCore.SIGNAL(_fromUtf8("textChanged(QString)")), self.wizardPage_pass.check_password_match) QtCore.QMetaObject.connectSlotsByName(Wizard) def retranslateUi(self, Wizard): pass -from wizardpage_pass import WizardPage_pass diff --git a/src/gui/qt/wizardpage_pass.py b/src/gui/qt/wizardpage_pass.py deleted file mode 100755 index f7153f5..0000000 --- a/src/gui/qt/wizardpage_pass.py +++ /dev/null @@ -1,31 +0,0 @@ -''' -This module provide some methods to enhance the password page -of the wizard. It could have been avoided, but this way make -it easier to do things from the designer. - -Indeed, it's possible to use password_match(bool) signal -and check_password_match(slot) from the designer. -''' - -from PyQt4.QtGui import QWizardPage -from PyQt4 import QtCore, QtGui -try: - _fromUtf8 = QtCore.QString.fromUtf8 -except AttributeError: - _fromUtf8 = lambda s: s -class WizardPage_pass(QWizardPage): - password_match = QtCore.pyqtSignal(bool) - def __init__(self, *args, **kwargs): - QWizardPage.__init__(self, *args, **kwargs) - def _password_match(self): - pass1 = self.findChild(QtGui.QLineEdit, _fromUtf8('lineEdit_pass')).text() - pass2 = self.findChild(QtGui.QLineEdit, _fromUtf8('lineEdit_pass_again')).text() - return pass1 == pass2 - def check_password_match(self): - self.password_match.emit(not self._password_match()) - self.completeChanged.emit() - def isComplete(self): #this will make the "Next" button disabled if password doesn't match - return self._password_match() - - - From 559c1d8710a5ef36ce00e0365e51d36417605ba8 Mon Sep 17 00:00:00 2001 From: BoySka Date: Thu, 27 Oct 2011 15:01:27 +0200 Subject: [PATCH 05/25] Options other than 'near to tomb' are clearly unsupported --- src/gui/qt/create.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/gui/qt/create.py b/src/gui/qt/create.py index a99c75a..1dc200a 100755 --- a/src/gui/qt/create.py +++ b/src/gui/qt/create.py @@ -27,7 +27,6 @@ class TombCreateWizard(QWizard): def on_tomb_location_clicked(self, *args, **kwargs): filename = QtGui.QFileDialog.getSaveFileName(self, 'Create Tomb', filter="*.tomb") - print filename self.ui.lineEdit_tombpath.setText(filename) def on_change_page(self, pagenumber): if self.currentPage() == self.ui.wizardPage_progress: @@ -35,7 +34,19 @@ class TombCreateWizard(QWizard): def create_tomb(self, *args, **kwargs): #FIXME: this will lock up the GUI #FIXME: no support for other keypath than "next to tomb" - tomb.Tomb.create(self.ui.lineEdit_tombpath.text(), str(self.ui.spinBox_size.value()), None) + keyloc = None + if self.ui.radioButton_usb.isChecked(): + print 'Warning: it is not supported' + raise NotImplementedError + elif self.ui.radioButton_near.isChecked(): + print 'going near' + keyloc = None + else: + keyloc = self.ui.lineEdit_custom.text() + if not keyloc: + raise ValueError + + tomb.Tomb.create(self.ui.lineEdit_tombpath.text(), str(self.ui.spinBox_size.value()), keyloc) self.ui.progressBar.setValue(100) From c6784c6b6408079ec1f0a7d7aa2e584ab3813bce Mon Sep 17 00:00:00 2001 From: BoySka Date: Fri, 28 Oct 2011 02:29:03 +0200 Subject: [PATCH 06/25] Tomb in a thread: gui don't freeze anymore --- src/gui/qt/create.py | 19 ++++++++++-- src/gui/qt/create.ui | 20 ++++++------- src/gui/qt/ui_create.py | 64 ++++++++++++++++++++--------------------- 3 files changed, 58 insertions(+), 45 deletions(-) diff --git a/src/gui/qt/create.py b/src/gui/qt/create.py index 1dc200a..d63634b 100755 --- a/src/gui/qt/create.py +++ b/src/gui/qt/create.py @@ -1,4 +1,6 @@ import sys, os +from functools import partial + from PyQt4.QtGui import QApplication, QWizard from PyQt4 import QtCore from PyQt4 import QtGui @@ -6,7 +8,7 @@ from ui_create import Ui_Wizard parentdir = sys.path[0].split(os.sep)[:-1] sys.path.append(os.sep.join(parentdir)) -from tomblib import tomb +from tomblib.tomb import Tomb try: _fromUtf8 = QtCore.QString.fromUtf8 @@ -46,9 +48,20 @@ class TombCreateWizard(QWizard): if not keyloc: raise ValueError - tomb.Tomb.create(self.ui.lineEdit_tombpath.text(), str(self.ui.spinBox_size.value()), keyloc) - self.ui.progressBar.setValue(100) + self.thread = TombCreateThread(self.ui.lineEdit_tombpath.text(), str(self.ui.spinBox_size.value()), keyloc) + self.thread.finished.connect(partial(self.ui.progressBar.setValue, 100)) + self.thread.terminated.connect(partial(self.ui.progressBar.setValue, 100)) + self.thread.start() +class TombCreateThread(QtCore.QThread): + def __init__(self, tombpath, size, keypath): + QtCore.QThread.__init__(self) + self.tombpath = tombpath + self.size = size + self.keypath = keypath + + def run(self): + Tomb.create(self.tombpath, str(self.size), self.keypath) if __name__ == '__main__': app = QApplication(sys.argv) diff --git a/src/gui/qt/create.ui b/src/gui/qt/create.ui index c9275e7..3723d68 100755 --- a/src/gui/qt/create.ui +++ b/src/gui/qt/create.ui @@ -146,7 +146,7 @@ p, li { white-space: pre-wrap; } - + On a USB pen (best security) @@ -185,7 +185,7 @@ 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" /><style type="text/css"> @@ -200,7 +200,7 @@ p, li { white-space: pre-wrap; } - + Specify location @@ -227,14 +227,14 @@ p, li { white-space: pre-wrap; } - + false - + false @@ -268,7 +268,7 @@ p, li { white-space: pre-wrap; } Please wait - + 30 @@ -333,9 +333,9 @@ p, li { white-space: pre-wrap; } - radioButton_3 + radioButton_custom toggled(bool) - lineEdit_2 + lineEdit_custom setEnabled(bool) @@ -349,9 +349,9 @@ p, li { white-space: pre-wrap; } - radioButton_3 + radioButton_custom toggled(bool) - pushButton_2 + pushButton_custom setEnabled(bool) diff --git a/src/gui/qt/ui_create.py b/src/gui/qt/ui_create.py index c2bae30..5cb5476 100755 --- a/src/gui/qt/ui_create.py +++ b/src/gui/qt/ui_create.py @@ -2,7 +2,7 @@ # Form implementation generated from reading ui file 'create.ui' # -# Created: Thu Oct 27 01:57:45 2011 +# Created: Fri Oct 28 02:27:24 2011 # by: PyQt4 UI code generator 4.8.5 # # WARNING! All changes made in this file will be lost! @@ -98,11 +98,11 @@ class Ui_Wizard(object): self.verticalLayout_5.setObjectName(_fromUtf8("verticalLayout_5")) self.verticalLayout_4 = QtGui.QVBoxLayout() self.verticalLayout_4.setObjectName(_fromUtf8("verticalLayout_4")) - self.radioButton = QtGui.QRadioButton(self.wizardPage_key_location) - self.radioButton.setText(QtGui.QApplication.translate("Wizard", "On a USB pen (best security)", None, QtGui.QApplication.UnicodeUTF8)) - self.radioButton.setChecked(True) - self.radioButton.setObjectName(_fromUtf8("radioButton")) - self.verticalLayout_4.addWidget(self.radioButton) + self.radioButton_usb = QtGui.QRadioButton(self.wizardPage_key_location) + self.radioButton_usb.setText(QtGui.QApplication.translate("Wizard", "On a USB pen (best security)", None, QtGui.QApplication.UnicodeUTF8)) + self.radioButton_usb.setChecked(True) + self.radioButton_usb.setObjectName(_fromUtf8("radioButton_usb")) + 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) @@ -113,34 +113,34 @@ class Ui_Wizard(object): self.horizontalLayout_4.addWidget(self.label_6) self.verticalLayout_4.addLayout(self.horizontalLayout_4) self.verticalLayout_5.addLayout(self.verticalLayout_4) - self.radioButton_2 = QtGui.QRadioButton(self.wizardPage_key_location) - self.radioButton_2.setToolTip(QtGui.QApplication.translate("Wizard", "\n" + self.radioButton_near = QtGui.QRadioButton(self.wizardPage_key_location) + self.radioButton_near.setToolTip(QtGui.QApplication.translate("Wizard", "\n" "\n" "

It will be created as a regular file in the same directory of your tomb.

\n" "

It is much easier to use, but also much more insecure: all your security will be guaranteed by your password. If you really want to do this, choose a strong password (lot of random/non-dictionary words, spaces, numbers, odd characters)

", None, QtGui.QApplication.UnicodeUTF8)) - self.radioButton_2.setText(QtGui.QApplication.translate("Wizard", "Near to the tomb itself (this is BAD)", None, QtGui.QApplication.UnicodeUTF8)) - self.radioButton_2.setObjectName(_fromUtf8("radioButton_2")) - self.verticalLayout_5.addWidget(self.radioButton_2) - self.radioButton_3 = QtGui.QRadioButton(self.wizardPage_key_location) - self.radioButton_3.setText(QtGui.QApplication.translate("Wizard", "Specify location", None, QtGui.QApplication.UnicodeUTF8)) - self.radioButton_3.setObjectName(_fromUtf8("radioButton_3")) - self.verticalLayout_5.addWidget(self.radioButton_3) + self.radioButton_near.setText(QtGui.QApplication.translate("Wizard", "Near to the tomb itself (this is BAD)", None, QtGui.QApplication.UnicodeUTF8)) + self.radioButton_near.setObjectName(_fromUtf8("radioButton_near")) + self.verticalLayout_5.addWidget(self.radioButton_near) + self.radioButton_custom = QtGui.QRadioButton(self.wizardPage_key_location) + self.radioButton_custom.setText(QtGui.QApplication.translate("Wizard", "Specify location", None, QtGui.QApplication.UnicodeUTF8)) + self.radioButton_custom.setObjectName(_fromUtf8("radioButton_custom")) + self.verticalLayout_5.addWidget(self.radioButton_custom) 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) - self.lineEdit_2 = QtGui.QLineEdit(self.wizardPage_key_location) - self.lineEdit_2.setEnabled(False) - self.lineEdit_2.setObjectName(_fromUtf8("lineEdit_2")) - self.horizontalLayout_3.addWidget(self.lineEdit_2) - self.pushButton_2 = QtGui.QPushButton(self.wizardPage_key_location) - self.pushButton_2.setEnabled(False) - self.pushButton_2.setText(QtGui.QApplication.translate("Wizard", "Choose location", None, QtGui.QApplication.UnicodeUTF8)) - self.pushButton_2.setObjectName(_fromUtf8("pushButton_2")) - self.horizontalLayout_3.addWidget(self.pushButton_2) + self.lineEdit_custom = QtGui.QLineEdit(self.wizardPage_key_location) + self.lineEdit_custom.setEnabled(False) + self.lineEdit_custom.setObjectName(_fromUtf8("lineEdit_custom")) + self.horizontalLayout_3.addWidget(self.lineEdit_custom) + self.pushButton_custom = QtGui.QPushButton(self.wizardPage_key_location) + self.pushButton_custom.setEnabled(False) + self.pushButton_custom.setText(QtGui.QApplication.translate("Wizard", "Choose location", None, QtGui.QApplication.UnicodeUTF8)) + self.pushButton_custom.setObjectName(_fromUtf8("pushButton_custom")) + self.horizontalLayout_3.addWidget(self.pushButton_custom) self.verticalLayout_6.addLayout(self.horizontalLayout_3) self.label_11 = QtGui.QLabel(self.wizardPage_key_location) self.label_11.setText(QtGui.QApplication.translate("Wizard", "\n" @@ -156,13 +156,13 @@ class Ui_Wizard(object): self.wizardPage_progress.setTitle(QtGui.QApplication.translate("Wizard", "Creating", None, QtGui.QApplication.UnicodeUTF8)) self.wizardPage_progress.setSubTitle(QtGui.QApplication.translate("Wizard", "Please wait", None, QtGui.QApplication.UnicodeUTF8)) self.wizardPage_progress.setObjectName(_fromUtf8("wizardPage_progress")) - self.widget = QtGui.QWidget(self.wizardPage_progress) - self.widget.setGeometry(QtCore.QRect(30, 30, 276, 52)) - self.widget.setObjectName(_fromUtf8("widget")) - self.verticalLayout_7 = QtGui.QVBoxLayout(self.widget) + self.layoutWidget = QtGui.QWidget(self.wizardPage_progress) + self.layoutWidget.setGeometry(QtCore.QRect(30, 30, 276, 52)) + self.layoutWidget.setObjectName(_fromUtf8("layoutWidget")) + self.verticalLayout_7 = QtGui.QVBoxLayout(self.layoutWidget) self.verticalLayout_7.setMargin(0) self.verticalLayout_7.setObjectName(_fromUtf8("verticalLayout_7")) - self.progressBar = QtGui.QProgressBar(self.widget) + self.progressBar = QtGui.QProgressBar(self.layoutWidget) self.progressBar.setProperty("value", 0) self.progressBar.setTextVisible(True) self.progressBar.setInvertedAppearance(False) @@ -170,7 +170,7 @@ class Ui_Wizard(object): self.verticalLayout_7.addWidget(self.progressBar) self.horizontalLayout_5 = QtGui.QHBoxLayout() self.horizontalLayout_5.setObjectName(_fromUtf8("horizontalLayout_5")) - self.label_7 = QtGui.QLabel(self.widget) + self.label_7 = QtGui.QLabel(self.layoutWidget) self.label_7.setText(QtGui.QApplication.translate("Wizard", "Creating tomb, please wait...", None, QtGui.QApplication.UnicodeUTF8)) self.label_7.setObjectName(_fromUtf8("label_7")) self.horizontalLayout_5.addWidget(self.label_7) @@ -195,8 +195,8 @@ class Ui_Wizard(object): self.label_4.setBuddy(self.lineEdit_tombpath) self.retranslateUi(Wizard) - QtCore.QObject.connect(self.radioButton_3, QtCore.SIGNAL(_fromUtf8("toggled(bool)")), self.lineEdit_2.setEnabled) - QtCore.QObject.connect(self.radioButton_3, QtCore.SIGNAL(_fromUtf8("toggled(bool)")), self.pushButton_2.setEnabled) + QtCore.QObject.connect(self.radioButton_custom, QtCore.SIGNAL(_fromUtf8("toggled(bool)")), self.lineEdit_custom.setEnabled) + QtCore.QObject.connect(self.radioButton_custom, QtCore.SIGNAL(_fromUtf8("toggled(bool)")), self.pushButton_custom.setEnabled) QtCore.QObject.connect(Wizard, QtCore.SIGNAL(_fromUtf8("currentIdChanged(int)")), self.label_11.hide) QtCore.QObject.connect(Wizard, QtCore.SIGNAL(_fromUtf8("helpRequested()")), self.label_11.show) QtCore.QMetaObject.connectSlotsByName(Wizard) From 51b5394bbc822a3c43b05f78d102880a7ea8bd79 Mon Sep 17 00:00:00 2001 From: BoySka Date: Fri, 28 Oct 2011 12:06:00 +0200 Subject: [PATCH 07/25] GUI handles errors;progresschecked by isComplete --- src/gui/qt/Makefile | 10 ++++++++ src/gui/qt/create.py | 53 +++++++++++++++++++++++++++++++---------- src/gui/qt/create.ui | 18 +++++++++++--- src/gui/qt/ui_create.py | 28 ++++++++++++---------- 4 files changed, 81 insertions(+), 28 deletions(-) create mode 100644 src/gui/qt/Makefile mode change 100755 => 100644 src/gui/qt/ui_create.py diff --git a/src/gui/qt/Makefile b/src/gui/qt/Makefile new file mode 100644 index 0000000..9aa5313 --- /dev/null +++ b/src/gui/qt/Makefile @@ -0,0 +1,10 @@ +all: ui_create.py +test: ui_create.py + python2 create.py +ui_create.py: create.ui + pyuic4 create.ui -o ui_create.py + +clean: + rm ui_create.py + +.PHONY: test clean diff --git a/src/gui/qt/create.py b/src/gui/qt/create.py index d63634b..6c47b09 100755 --- a/src/gui/qt/create.py +++ b/src/gui/qt/create.py @@ -26,16 +26,14 @@ class TombCreateWizard(QWizard): 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) + def check_progress_complete(*args, **kwargs): + if self.ui.progressBar.value() == 100: + return True + return False + self.ui.wizardPage_progress.isComplete = check_progress_complete + self.finished.connect(self.on_finish) - def on_tomb_location_clicked(self, *args, **kwargs): - 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() - def create_tomb(self, *args, **kwargs): - #FIXME: this will lock up the GUI - #FIXME: no support for other keypath than "next to tomb" + def _keyloc(self): keyloc = None if self.ui.radioButton_usb.isChecked(): print 'Warning: it is not supported' @@ -47,10 +45,36 @@ class TombCreateWizard(QWizard): keyloc = self.ui.lineEdit_custom.text() if not keyloc: raise ValueError + return keyloc - self.thread = TombCreateThread(self.ui.lineEdit_tombpath.text(), str(self.ui.spinBox_size.value()), keyloc) - self.thread.finished.connect(partial(self.ui.progressBar.setValue, 100)) - self.thread.terminated.connect(partial(self.ui.progressBar.setValue, 100)) + def on_tomb_location_clicked(self, *args, **kwargs): + 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() + + def on_finish(self, finishedint): + if self.currentPage() != self.ui.wizardPage_end: + #there has been an error + return + + if self.ui.checkBox_open.isChecked(): + Tomb.open(self.ui.lineEdit_tombpath.text(), self._keyloc()) + def on_thread_creation_finished(self): + if self.thread.get_success(): + self.ui.progressBar.setValue(100) + else: + self.ui.progressBar.setEnabled(False) + 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): + #TODO: report error + keyloc = self._keyloc() + self.thread = TombCreateThread(self.ui.lineEdit_tombpath.text(), str(self.ui.spinBox_size.value()), self._keyloc()) + self.thread.finished.connect(self.on_thread_creation_finished) + self.thread.terminated.connect(self.on_thread_creation_finished) self.thread.start() class TombCreateThread(QtCore.QThread): @@ -61,7 +85,10 @@ class TombCreateThread(QtCore.QThread): self.keypath = keypath def run(self): - Tomb.create(self.tombpath, str(self.size), self.keypath) + self.status = Tomb.create(self.tombpath, str(self.size), self.keypath) + + def get_success(self): + return self.status if __name__ == '__main__': app = QApplication(sys.argv) diff --git a/src/gui/qt/create.ui b/src/gui/qt/create.ui index 3723d68..9b8782e 100755 --- a/src/gui/qt/create.ui +++ b/src/gui/qt/create.ui @@ -147,12 +147,18 @@ p, li { white-space: pre-wrap; } + + false + On a USB pen (best security) - + true + + false + @@ -175,6 +181,9 @@ p, li { white-space: pre-wrap; } + + false + If you choose to do so, do not insert it NOW. Do it when you are asked to do so @@ -197,6 +206,9 @@ p, li { white-space: pre-wrap; } Near to the tomb itself (this is BAD) + + true + @@ -294,7 +306,7 @@ p, li { white-space: pre-wrap; } - + Creating tomb, please wait... @@ -315,7 +327,7 @@ p, li { white-space: pre-wrap; } - + Open the just-created tomb NOW! diff --git a/src/gui/qt/ui_create.py b/src/gui/qt/ui_create.py old mode 100755 new mode 100644 index 5cb5476..d9f5659 --- a/src/gui/qt/ui_create.py +++ b/src/gui/qt/ui_create.py @@ -2,7 +2,7 @@ # Form implementation generated from reading ui file 'create.ui' # -# Created: Fri Oct 28 02:27:24 2011 +# Created: Fri Oct 28 10:43:28 2011 # by: PyQt4 UI code generator 4.8.5 # # WARNING! All changes made in this file will be lost! @@ -99,8 +99,10 @@ class Ui_Wizard(object): self.verticalLayout_4 = QtGui.QVBoxLayout() self.verticalLayout_4.setObjectName(_fromUtf8("verticalLayout_4")) self.radioButton_usb = QtGui.QRadioButton(self.wizardPage_key_location) + self.radioButton_usb.setEnabled(False) self.radioButton_usb.setText(QtGui.QApplication.translate("Wizard", "On a USB pen (best security)", None, QtGui.QApplication.UnicodeUTF8)) - self.radioButton_usb.setChecked(True) + self.radioButton_usb.setCheckable(True) + self.radioButton_usb.setChecked(False) self.radioButton_usb.setObjectName(_fromUtf8("radioButton_usb")) self.verticalLayout_4.addWidget(self.radioButton_usb) self.horizontalLayout_4 = QtGui.QHBoxLayout() @@ -108,6 +110,7 @@ class Ui_Wizard(object): spacerItem = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Maximum, QtGui.QSizePolicy.Minimum) self.horizontalLayout_4.addItem(spacerItem) 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)) self.label_6.setObjectName(_fromUtf8("label_6")) self.horizontalLayout_4.addWidget(self.label_6) @@ -121,6 +124,7 @@ class Ui_Wizard(object): "

It will be created as a regular file in the same directory of your tomb.

\n" "

It is much easier to use, but also much more insecure: all your security will be guaranteed by your password. If you really want to do this, choose a strong password (lot of random/non-dictionary words, spaces, numbers, odd characters)

", None, QtGui.QApplication.UnicodeUTF8)) self.radioButton_near.setText(QtGui.QApplication.translate("Wizard", "Near to the tomb itself (this is BAD)", None, QtGui.QApplication.UnicodeUTF8)) + self.radioButton_near.setChecked(True) self.radioButton_near.setObjectName(_fromUtf8("radioButton_near")) self.verticalLayout_5.addWidget(self.radioButton_near) self.radioButton_custom = QtGui.QRadioButton(self.wizardPage_key_location) @@ -170,10 +174,10 @@ class Ui_Wizard(object): self.verticalLayout_7.addWidget(self.progressBar) self.horizontalLayout_5 = QtGui.QHBoxLayout() self.horizontalLayout_5.setObjectName(_fromUtf8("horizontalLayout_5")) - self.label_7 = QtGui.QLabel(self.layoutWidget) - self.label_7.setText(QtGui.QApplication.translate("Wizard", "Creating tomb, please wait...", None, QtGui.QApplication.UnicodeUTF8)) - self.label_7.setObjectName(_fromUtf8("label_7")) - self.horizontalLayout_5.addWidget(self.label_7) + self.label_progress = QtGui.QLabel(self.layoutWidget) + self.label_progress.setText(QtGui.QApplication.translate("Wizard", "Creating tomb, please wait...", None, QtGui.QApplication.UnicodeUTF8)) + self.label_progress.setObjectName(_fromUtf8("label_progress")) + self.horizontalLayout_5.addWidget(self.label_progress) self.verticalLayout_7.addLayout(self.horizontalLayout_5) Wizard.addPage(self.wizardPage_progress) self.wizardPage_end = QtGui.QWizardPage() @@ -184,12 +188,12 @@ class Ui_Wizard(object): self.label_10.setText(QtGui.QApplication.translate("Wizard", "You successfully created the tomb!", None, QtGui.QApplication.UnicodeUTF8)) self.label_10.setObjectName(_fromUtf8("label_10")) self.verticalLayout_8.addWidget(self.label_10) - self.checkBox = QtGui.QCheckBox(self.wizardPage_end) - self.checkBox.setText(QtGui.QApplication.translate("Wizard", "Open the just-created tomb NOW!", None, QtGui.QApplication.UnicodeUTF8)) - self.checkBox.setChecked(True) - self.checkBox.setTristate(False) - self.checkBox.setObjectName(_fromUtf8("checkBox")) - self.verticalLayout_8.addWidget(self.checkBox) + self.checkBox_open = QtGui.QCheckBox(self.wizardPage_end) + self.checkBox_open.setText(QtGui.QApplication.translate("Wizard", "Open the just-created tomb NOW!", None, QtGui.QApplication.UnicodeUTF8)) + self.checkBox_open.setChecked(True) + self.checkBox_open.setTristate(False) + self.checkBox_open.setObjectName(_fromUtf8("checkBox_open")) + self.verticalLayout_8.addWidget(self.checkBox_open) Wizard.addPage(self.wizardPage_end) self.label_3.setBuddy(self.spinBox_size) self.label_4.setBuddy(self.lineEdit_tombpath) From bbe25d0f85e086948ad7a7d414f42d60642abe48 Mon Sep 17 00:00:00 2001 From: BoySka Date: Sun, 30 Oct 2011 22:07:16 +0100 Subject: [PATCH 08/25] GUI: progressbar monitor tomb output Warning: sudo behave strangely when watching both stdout and stderr It seems to be solved watching only stderr, which is where 99% of tomb output goes, but this is quite an hack --- src/gui/qt/Makefile | 2 +- src/gui/qt/create.py | 21 +++-------- src/gui/qt/create.ui | 84 +++++++++++++++++++++++------------------ src/gui/qt/ui_create.py | 26 +++++++++---- src/gui/tomblib/tomb.py | 8 ++-- 5 files changed, 77 insertions(+), 64 deletions(-) diff --git a/src/gui/qt/Makefile b/src/gui/qt/Makefile index 9aa5313..317ee9b 100644 --- a/src/gui/qt/Makefile +++ b/src/gui/qt/Makefile @@ -1,6 +1,6 @@ all: ui_create.py test: ui_create.py - python2 create.py + python2 -3 create.py ui_create.py: create.ui pyuic4 create.ui -o ui_create.py diff --git a/src/gui/qt/create.py b/src/gui/qt/create.py index 6c47b09..a9b3695 100755 --- a/src/gui/qt/create.py +++ b/src/gui/qt/create.py @@ -1,5 +1,5 @@ import sys, os -from functools import partial +#from functools import partial from PyQt4.QtGui import QApplication, QWizard from PyQt4 import QtCore @@ -9,6 +9,7 @@ from ui_create import Ui_Wizard parentdir = sys.path[0].split(os.sep)[:-1] sys.path.append(os.sep.join(parentdir)) from tomblib.tomb import Tomb +from worker import TombCreateThread try: _fromUtf8 = QtCore.QString.fromUtf8 @@ -70,25 +71,15 @@ class TombCreateWizard(QWizard): self.ui.wizardPage_progress.setFinalPage(True) self.ui.wizardPage_progress.completeChanged.emit() def create_tomb(self, *args, **kwargs): - #TODO: report error - keyloc = self._keyloc() self.thread = TombCreateThread(self.ui.lineEdit_tombpath.text(), str(self.ui.spinBox_size.value()), self._keyloc()) 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.thread.error_received.connect(err_append_to_log) self.thread.start() -class TombCreateThread(QtCore.QThread): - def __init__(self, tombpath, size, keypath): - QtCore.QThread.__init__(self) - self.tombpath = tombpath - self.size = size - self.keypath = keypath - - def run(self): - self.status = Tomb.create(self.tombpath, str(self.size), self.keypath) - - def get_success(self): - return self.status if __name__ == '__main__': app = QApplication(sys.argv) diff --git a/src/gui/qt/create.ui b/src/gui/qt/create.ui index 9b8782e..413aef7 100755 --- a/src/gui/qt/create.ui +++ b/src/gui/qt/create.ui @@ -65,6 +65,9 @@
+ + 10 + 100000 @@ -280,42 +283,51 @@ p, li { white-space: pre-wrap; } Please wait - - - - 30 - 30 - 276 - 52 - - - - - - - 0 - - - true - - - false - - - - - - - - - Creating tomb, please wait... - - - - - - - + + + + + + + 0 + + + true + + + false + + + + + + + + + Creating tomb, please wait... + + + + + + + + + + + Log + + + <!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> + + + + diff --git a/src/gui/qt/ui_create.py b/src/gui/qt/ui_create.py index d9f5659..28ecd54 100644 --- a/src/gui/qt/ui_create.py +++ b/src/gui/qt/ui_create.py @@ -2,7 +2,7 @@ # Form implementation generated from reading ui file 'create.ui' # -# Created: Fri Oct 28 10:43:28 2011 +# Created: Fri Oct 28 20:11:40 2011 # by: PyQt4 UI code generator 4.8.5 # # WARNING! All changes made in this file will be lost! @@ -49,6 +49,7 @@ class Ui_Wizard(object): self.label_3.setObjectName(_fromUtf8("label_3")) self.horizontalLayout.addWidget(self.label_3) self.spinBox_size = QtGui.QSpinBox(self.wizardPage_tomb_size) + self.spinBox_size.setMinimum(10) self.spinBox_size.setMaximum(100000) self.spinBox_size.setProperty("value", 100) self.spinBox_size.setObjectName(_fromUtf8("spinBox_size")) @@ -160,13 +161,11 @@ class Ui_Wizard(object): self.wizardPage_progress.setTitle(QtGui.QApplication.translate("Wizard", "Creating", None, QtGui.QApplication.UnicodeUTF8)) self.wizardPage_progress.setSubTitle(QtGui.QApplication.translate("Wizard", "Please wait", None, QtGui.QApplication.UnicodeUTF8)) self.wizardPage_progress.setObjectName(_fromUtf8("wizardPage_progress")) - self.layoutWidget = QtGui.QWidget(self.wizardPage_progress) - self.layoutWidget.setGeometry(QtCore.QRect(30, 30, 276, 52)) - self.layoutWidget.setObjectName(_fromUtf8("layoutWidget")) - self.verticalLayout_7 = QtGui.QVBoxLayout(self.layoutWidget) - self.verticalLayout_7.setMargin(0) + self.verticalLayout_9 = QtGui.QVBoxLayout(self.wizardPage_progress) + self.verticalLayout_9.setObjectName(_fromUtf8("verticalLayout_9")) + self.verticalLayout_7 = QtGui.QVBoxLayout() self.verticalLayout_7.setObjectName(_fromUtf8("verticalLayout_7")) - self.progressBar = QtGui.QProgressBar(self.layoutWidget) + self.progressBar = QtGui.QProgressBar(self.wizardPage_progress) self.progressBar.setProperty("value", 0) self.progressBar.setTextVisible(True) self.progressBar.setInvertedAppearance(False) @@ -174,11 +173,22 @@ class Ui_Wizard(object): self.verticalLayout_7.addWidget(self.progressBar) self.horizontalLayout_5 = QtGui.QHBoxLayout() self.horizontalLayout_5.setObjectName(_fromUtf8("horizontalLayout_5")) - self.label_progress = QtGui.QLabel(self.layoutWidget) + self.label_progress = QtGui.QLabel(self.wizardPage_progress) self.label_progress.setText(QtGui.QApplication.translate("Wizard", "Creating tomb, please wait...", None, QtGui.QApplication.UnicodeUTF8)) self.label_progress.setObjectName(_fromUtf8("label_progress")) self.horizontalLayout_5.addWidget(self.label_progress) self.verticalLayout_7.addLayout(self.horizontalLayout_5) + self.verticalLayout_9.addLayout(self.verticalLayout_7) + self.textBrowser_log = QtGui.QTextBrowser(self.wizardPage_progress) + self.textBrowser_log.setDocumentTitle(QtGui.QApplication.translate("Wizard", "Log", None, QtGui.QApplication.UnicodeUTF8)) + self.textBrowser_log.setHtml(QtGui.QApplication.translate("Wizard", "\n" +"Log\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) self.wizardPage_end = QtGui.QWizardPage() self.wizardPage_end.setObjectName(_fromUtf8("wizardPage_end")) diff --git a/src/gui/tomblib/tomb.py b/src/gui/tomblib/tomb.py index 3d53927..2b19172 100644 --- a/src/gui/tomblib/tomb.py +++ b/src/gui/tomblib/tomb.py @@ -23,7 +23,7 @@ class Tomb(object): If you want to interact asynchronously with tomb, just do it in a separate layer. ''' - #TODO: support setting a "pipe" to pass out/err on + tombexec = 'tomb' def _check_exec_path(self): '''Checks, using which, if tomb is available. Returns None on error, the path on success. @@ -34,8 +34,8 @@ class Tomb(object): return None return path - @staticmethod - def create(tombpath,tombsize,keypath): + @classmethod + def create(cls, tombpath,tombsize,keypath, stdout=None, stderr=None): '''If keypath is None, it will be created adjacent to the tomb. This is unsafe, and you should NOT do it. @@ -45,7 +45,7 @@ class Tomb(object): if keypath is not None: args += ['-k', keypath] try: - subprocess.check_call(['tomb', 'create'] + args) + subprocess.check_call([cls.tombexec, 'create'] + args, stdout=stdout, stderr=stderr) except subprocess.CalledProcessError: return False return True From 2f4cf42e74422cf67e6f427ea4091e669a3846b8 Mon Sep 17 00:00:00 2001 From: boyska Date: Tue, 1 Nov 2011 00:10:17 +0100 Subject: [PATCH 09/25] TOMBLIB: Support for --no-color, --ignore-swap --- src/gui/tomblib/tomb.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/gui/tomblib/tomb.py b/src/gui/tomblib/tomb.py index 2b19172..5a06f52 100644 --- a/src/gui/tomblib/tomb.py +++ b/src/gui/tomblib/tomb.py @@ -9,7 +9,6 @@ Notes: consider moving to a more typical usage (instantiate, then use method) to make it more configurable (ie set the tomb executable path). ''' -import os import subprocess class Tomb(object): @@ -35,15 +34,22 @@ class Tomb(object): return path @classmethod - def create(cls, tombpath,tombsize,keypath, stdout=None, stderr=None): + def create(cls, tombpath,tombsize,keypath, stdout=None, stderr=None, no_color=True, ignore_swap=False): '''If keypath is None, it will be created adjacent to the tomb. This is unsafe, and you should NOT do it. Note that this will invoke pinentry + + no_color is supported as an option for short-lived retrocompatibility: + it will be removed as soon as no-color will be integrated ''' args = [tombpath, '-s', tombsize] if keypath is not None: args += ['-k', keypath] + if no_color: + args += ['--no-color'] + if ignore_swap: + args += ['--ignore-swap'] try: subprocess.check_call([cls.tombexec, 'create'] + args, stdout=stdout, stderr=stderr) except subprocess.CalledProcessError: From 1f290078bdee77eeb8fee375ce4dac2a2fc325ca Mon Sep 17 00:00:00 2001 From: boyska Date: Tue, 1 Nov 2011 00:36:14 +0100 Subject: [PATCH 10/25] Add subcommand 'check' and support in tomblib --- src/gui/tomblib/tomb.py | 8 ++++++++ src/tomb | 25 +++++++++++++++++++------ 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/gui/tomblib/tomb.py b/src/gui/tomblib/tomb.py index 5a06f52..f89e905 100644 --- a/src/gui/tomblib/tomb.py +++ b/src/gui/tomblib/tomb.py @@ -33,6 +33,14 @@ class Tomb(object): return None return path + @classmethod + def check(cls, command, stdout=None, stderr=None, no_color=True): + try: + subprocess.check_call([cls.tombexec, 'check'] + [command], stdout=stdout, stderr=stderr) + except subprocess.CalledProcessError: + return False + return True + @classmethod def create(cls, tombpath,tombsize,keypath, stdout=None, stderr=None, no_color=True, ignore_swap=False): '''If keypath is None, it will be created adjacent to the tomb. diff --git a/src/tomb b/src/tomb index a7de2a3..bee6b70 100755 --- a/src/tomb +++ b/src/tomb @@ -298,8 +298,20 @@ EOF return 0 } # }}} -# }}} -# {{{ - TOMB USAGE +check_command() { + #generic checks; useful for interaction, to check if there are problems + #before wasting user's time + + if ! option_is_set --ignore-swap; then + if [[ $1 == 'create' || $1 == 'open' ]]; then + if ! check_swap; then + error "Swap activated. Disable it with swapoff, or use --ignore-swap" + exit 1 + fi + fi + fi +} + usage() { cat < Date: Tue, 1 Nov 2011 03:07:05 +0100 Subject: [PATCH 11/25] 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 From ab706fc639fe394f55d72de26b8366ae3828f420 Mon Sep 17 00:00:00 2001 From: boyska Date: Thu, 3 Nov 2011 00:00:48 +0100 Subject: [PATCH 12/25] Move parsing code from gui/qt to tomblib.parser --- src/gui/qt/worker.py | 9 ++++----- src/gui/tomblib/parser.py | 20 ++++++++++++++++++++ src/gui/tomblib/tomb.py | 4 ++-- 3 files changed, 26 insertions(+), 7 deletions(-) create mode 100644 src/gui/tomblib/parser.py diff --git a/src/gui/qt/worker.py b/src/gui/qt/worker.py index b1b39ac..fca34bd 100644 --- a/src/gui/qt/worker.py +++ b/src/gui/qt/worker.py @@ -1,6 +1,5 @@ import sys,os import time -import re from tempfile import NamedTemporaryFile from PyQt4 import QtCore @@ -8,6 +7,7 @@ from PyQt4 import QtCore parentdir = sys.path[0].split(os.sep)[:-1] sys.path.append(os.sep.join(parentdir)) from tomblib.tomb import Tomb +from tomblib.parser import parse_line class TombCreateThread(QtCore.QThread): line_received = QtCore.pyqtSignal(QtCore.QString) @@ -58,7 +58,6 @@ class TombOutputThread(QtCore.QThread): #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)) + parsed = parse_line(line) + if parsed and parsed['type'] == 'error': + self.error_received.emit(parsed.content) diff --git a/src/gui/tomblib/parser.py b/src/gui/tomblib/parser.py new file mode 100644 index 0000000..5edc7cf --- /dev/null +++ b/src/gui/tomblib/parser.py @@ -0,0 +1,20 @@ +''' +Utilities to analyze tomb output +''' +import re + +_err_regex = re.compile(r'\[!\][^ ]* +(.+)$') +def parse_line(line): + '''Analyze a single line. + Return None if no standard format is detected, a dict otherwise. + The fields 'type' and 'content' are always in the dict; 'content' may be + empty + 'type' can be 'error', 'progress' + ''' + + match = _err_regex.search(line) + if match: + return { 'type': 'error', 'content': match.group(1) } + return None + + diff --git a/src/gui/tomblib/tomb.py b/src/gui/tomblib/tomb.py index 6f5abe1..7597351 100644 --- a/src/gui/tomblib/tomb.py +++ b/src/gui/tomblib/tomb.py @@ -28,7 +28,7 @@ class Tomb(object): Returns None on error, the path on success. ''' try: - path=subprocess.check_output(['which', 'tomb']) + path = subprocess.check_output(['which', 'tomb']) except subprocess.CalledProcessError: return None return path @@ -47,7 +47,7 @@ class Tomb(object): return True @classmethod - def create(cls, tombpath,tombsize,keypath, stdout=None, stderr=None, no_color=True, ignore_swap=False): + def create(cls, tombpath, tombsize,keypath, stdout=None, stderr=None, no_color=True, ignore_swap=False): '''If keypath is None, it will be created adjacent to the tomb. This is unsafe, and you should NOT do it. From 13b66a40da7b02b1c87f21aabf7298c3d0befe44 Mon Sep 17 00:00:00 2001 From: boyska Date: Thu, 3 Nov 2011 00:18:22 +0100 Subject: [PATCH 13/25] Disable option to open the tomb; it's not ready yet --- src/gui/qt/create.ui | 5 ++++- src/gui/qt/ui_create.py | 5 +++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/gui/qt/create.ui b/src/gui/qt/create.ui index 5f3009f..2c50955 100755 --- a/src/gui/qt/create.ui +++ b/src/gui/qt/create.ui @@ -463,11 +463,14 @@ p, li { white-space: pre-wrap; }
+ + false + Open the just-created tomb NOW! - true + false false diff --git a/src/gui/qt/ui_create.py b/src/gui/qt/ui_create.py index 65d718c..0f25993 100644 --- a/src/gui/qt/ui_create.py +++ b/src/gui/qt/ui_create.py @@ -2,7 +2,7 @@ # Form implementation generated from reading ui file 'create.ui' # -# Created: Tue Nov 1 02:35:05 2011 +# Created: Thu Nov 3 00:16:51 2011 # by: PyQt4 UI code generator 4.8.6 # # WARNING! All changes made in this file will be lost! @@ -260,8 +260,9 @@ class Ui_Wizard(object): self.label_10.setObjectName(_fromUtf8("label_10")) self.verticalLayout_8.addWidget(self.label_10) self.checkBox_open = QtGui.QCheckBox(self.wizardPage_end) + self.checkBox_open.setEnabled(False) self.checkBox_open.setText(QtGui.QApplication.translate("Wizard", "Open the just-created tomb NOW!", None, QtGui.QApplication.UnicodeUTF8)) - self.checkBox_open.setChecked(True) + self.checkBox_open.setChecked(False) self.checkBox_open.setTristate(False) self.checkBox_open.setObjectName(_fromUtf8("checkBox_open")) self.verticalLayout_8.addWidget(self.checkBox_open) From 6aade0ffc85715d5d24f97e3680816e262031255 Mon Sep 17 00:00:00 2001 From: boyska Date: Thu, 3 Nov 2011 13:42:43 +0100 Subject: [PATCH 14/25] GUI/PY: change dir layout; setup.py for tomblib Now pytomb/ contains the python library, which will be available as tomblib qt/ contains only the qt gui They all are directly under src/ Also, tomblib has a setup.py to install/package/develop --- src/{gui => }/HACKING.txt | 0 src/gui/tomblib/wrapper.py | 5 ----- src/pytomb/.gitignore | 5 +++++ src/{gui/tomblib => pytomb}/.wrapper.py.swp | Bin src/pytomb/setup.py | 11 +++++++++++ src/{gui => pytomb}/tomblib/__init__.py | 0 src/{gui => pytomb}/tomblib/parser.py | 0 src/{gui => pytomb}/tomblib/tomb.py | 0 src/{gui => qt}/.gitignore | 0 src/{gui => }/qt/Makefile | 0 src/{gui => }/qt/create.py | 0 src/{gui => }/qt/create.ui | 0 src/{gui => }/qt/notes.txt | 0 src/{gui => }/qt/ui_create.py | 0 src/{gui => }/qt/worker.py | 0 15 files changed, 16 insertions(+), 5 deletions(-) rename src/{gui => }/HACKING.txt (100%) delete mode 100755 src/gui/tomblib/wrapper.py create mode 100644 src/pytomb/.gitignore rename src/{gui/tomblib => pytomb}/.wrapper.py.swp (100%) create mode 100644 src/pytomb/setup.py rename src/{gui => pytomb}/tomblib/__init__.py (100%) rename src/{gui => pytomb}/tomblib/parser.py (100%) rename src/{gui => pytomb}/tomblib/tomb.py (100%) rename src/{gui => qt}/.gitignore (100%) rename src/{gui => }/qt/Makefile (100%) rename src/{gui => }/qt/create.py (100%) rename src/{gui => }/qt/create.ui (100%) rename src/{gui => }/qt/notes.txt (100%) rename src/{gui => }/qt/ui_create.py (100%) rename src/{gui => }/qt/worker.py (100%) diff --git a/src/gui/HACKING.txt b/src/HACKING.txt similarity index 100% rename from src/gui/HACKING.txt rename to src/HACKING.txt diff --git a/src/gui/tomblib/wrapper.py b/src/gui/tomblib/wrapper.py deleted file mode 100755 index b38bdea..0000000 --- a/src/gui/tomblib/wrapper.py +++ /dev/null @@ -1,5 +0,0 @@ -class Tomb(object): - @staticmethod - def create(tombpath, size, keypath): - print 'I am not implemented' - raise NotImplementedError diff --git a/src/pytomb/.gitignore b/src/pytomb/.gitignore new file mode 100644 index 0000000..31a3caf --- /dev/null +++ b/src/pytomb/.gitignore @@ -0,0 +1,5 @@ +.*.swp +*.pyc +*.egg-info +build +dist diff --git a/src/gui/tomblib/.wrapper.py.swp b/src/pytomb/.wrapper.py.swp similarity index 100% rename from src/gui/tomblib/.wrapper.py.swp rename to src/pytomb/.wrapper.py.swp diff --git a/src/pytomb/setup.py b/src/pytomb/setup.py new file mode 100644 index 0000000..bed4e7f --- /dev/null +++ b/src/pytomb/setup.py @@ -0,0 +1,11 @@ +from setuptools import setup + +setup( + name = 'TombLib', + version = '1.1', + packages = ['tomblib'], + + test_suite = 'nose.collector' +) + + diff --git a/src/gui/tomblib/__init__.py b/src/pytomb/tomblib/__init__.py similarity index 100% rename from src/gui/tomblib/__init__.py rename to src/pytomb/tomblib/__init__.py diff --git a/src/gui/tomblib/parser.py b/src/pytomb/tomblib/parser.py similarity index 100% rename from src/gui/tomblib/parser.py rename to src/pytomb/tomblib/parser.py diff --git a/src/gui/tomblib/tomb.py b/src/pytomb/tomblib/tomb.py similarity index 100% rename from src/gui/tomblib/tomb.py rename to src/pytomb/tomblib/tomb.py diff --git a/src/gui/.gitignore b/src/qt/.gitignore similarity index 100% rename from src/gui/.gitignore rename to src/qt/.gitignore diff --git a/src/gui/qt/Makefile b/src/qt/Makefile similarity index 100% rename from src/gui/qt/Makefile rename to src/qt/Makefile diff --git a/src/gui/qt/create.py b/src/qt/create.py similarity index 100% rename from src/gui/qt/create.py rename to src/qt/create.py diff --git a/src/gui/qt/create.ui b/src/qt/create.ui similarity index 100% rename from src/gui/qt/create.ui rename to src/qt/create.ui diff --git a/src/gui/qt/notes.txt b/src/qt/notes.txt similarity index 100% rename from src/gui/qt/notes.txt rename to src/qt/notes.txt diff --git a/src/gui/qt/ui_create.py b/src/qt/ui_create.py similarity index 100% rename from src/gui/qt/ui_create.py rename to src/qt/ui_create.py diff --git a/src/gui/qt/worker.py b/src/qt/worker.py similarity index 100% rename from src/gui/qt/worker.py rename to src/qt/worker.py From b6105ca5b6f5a4509ee7fef7457a85a963c8d0fb Mon Sep 17 00:00:00 2001 From: boyska Date: Fri, 4 Nov 2011 00:24:33 +0100 Subject: [PATCH 15/25] QT: change dir layout, packaging begins --- src/pytomb/tomblib/test_parser.py | 29 +++++++++++++++++++ src/qt/.gitignore | 2 ++ src/qt/setup.py | 46 +++++++++++++++++++++++++++++++ src/qt/{ => tombqt}/create.py | 0 src/qt/{ => tombqt}/create.ui | 0 src/qt/{ => tombqt}/ui_create.py | 0 src/qt/{ => tombqt}/worker.py | 0 7 files changed, 77 insertions(+) create mode 100644 src/pytomb/tomblib/test_parser.py create mode 100644 src/qt/setup.py rename src/qt/{ => tombqt}/create.py (100%) rename src/qt/{ => tombqt}/create.ui (100%) rename src/qt/{ => tombqt}/ui_create.py (100%) rename src/qt/{ => tombqt}/worker.py (100%) diff --git a/src/pytomb/tomblib/test_parser.py b/src/pytomb/tomblib/test_parser.py new file mode 100644 index 0000000..d601f4d --- /dev/null +++ b/src/pytomb/tomblib/test_parser.py @@ -0,0 +1,29 @@ +from tomblib.parser import * + +class TestWrong: + def test_wrong_tag(self): + assert parse_line(' [a] foo') is None + def test_no_space(self): + assert parse_line(' [!]foo') is None + +class TestError: + def test_simple(self): + parse = parse_line('[!] foo') + assert parse is not None + assert parse['type'] == 'error' + assert parse['content'] == 'foo' + def test_preceding(self): + parse = parse_line(' [!] foo') + assert parse is not None + assert parse['type'] == 'error' + assert parse['content'] == 'foo' + def test_following(self): + parse = parse_line('[!]shdad foo') + assert parse is not None + assert parse['type'] == 'error' + assert parse['content'] == 'foo' + def test_mul_words(self): + parse = parse_line('[!] shdad foo') + assert parse is not None + assert parse['type'] == 'error' + assert parse['content'] == 'shdad foo' diff --git a/src/qt/.gitignore b/src/qt/.gitignore index 3bb2efd..dd75296 100644 --- a/src/qt/.gitignore +++ b/src/qt/.gitignore @@ -1,2 +1,4 @@ .*.swp *.pyc +TombQt.egg-info +build diff --git a/src/qt/setup.py b/src/qt/setup.py new file mode 100644 index 0000000..cca8ae2 --- /dev/null +++ b/src/qt/setup.py @@ -0,0 +1,46 @@ +import os +import glob +from setuptools import setup +from StringIO import StringIO + +from distutils import log +from distutils.core import Command +from distutils.dep_util import newer + +class build_ui(Command): +# Stolen from picard + description = "build Qt UI files" + user_options = [] + + def initialize_options(self): + pass + + def finalize_options(self): + pass + + def run(self): + from PyQt4 import uic + for uifile in glob.glob("tombqt/*.ui"): + pyfile = "ui_%s.py" % os.path.splitext(os.path.basename(uifile))[0] + pyfile = os.path.join('tombqt', pyfile) + if newer(uifile, pyfile): + log.info("compiling %s -> %s", uifile, pyfile) + tmp = StringIO() + uic.compileUi(uifile, tmp) + source = tmp.getvalue() + f = open(pyfile, "w") + f.write(source) + f.close() + +setup( + name = 'TombQt', + version = '0.1', + packages = ['tombqt'], + cmdclass = { + 'build_ui': build_ui + } +) + + + + diff --git a/src/qt/create.py b/src/qt/tombqt/create.py similarity index 100% rename from src/qt/create.py rename to src/qt/tombqt/create.py diff --git a/src/qt/create.ui b/src/qt/tombqt/create.ui similarity index 100% rename from src/qt/create.ui rename to src/qt/tombqt/create.ui diff --git a/src/qt/ui_create.py b/src/qt/tombqt/ui_create.py similarity index 100% rename from src/qt/ui_create.py rename to src/qt/tombqt/ui_create.py diff --git a/src/qt/worker.py b/src/qt/tombqt/worker.py similarity index 100% rename from src/qt/worker.py rename to src/qt/tombqt/worker.py From ffbd019c4b7380719c2de1c33f78d87d15469eb0 Mon Sep 17 00:00:00 2001 From: boyska Date: Fri, 4 Nov 2011 00:40:35 +0100 Subject: [PATCH 16/25] QT packaging: seems to do the basic work --- src/qt/setup.py | 5 +++++ src/qt/tombqt/__init__.py | 0 src/qt/tombqt/create.py | 7 ++++++- 3 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 src/qt/tombqt/__init__.py diff --git a/src/qt/setup.py b/src/qt/setup.py index cca8ae2..36a9335 100644 --- a/src/qt/setup.py +++ b/src/qt/setup.py @@ -38,6 +38,11 @@ setup( packages = ['tombqt'], cmdclass = { 'build_ui': build_ui + }, + entry_points = { + 'gui_scripts': [ + 'tomb-qt-create = tombqt.create:run_create_wizard' + ] } ) diff --git a/src/qt/tombqt/__init__.py b/src/qt/tombqt/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/qt/tombqt/create.py b/src/qt/tombqt/create.py index d011d94..ed7b525 100755 --- a/src/qt/tombqt/create.py +++ b/src/qt/tombqt/create.py @@ -109,6 +109,7 @@ class TombCreateWizard(QWizard): self.thread.error_received.connect(err_append_to_log) self.thread.start() def check_requisite(self): + Tomb.tombexec = '/home/davide/coding/projects/tomb/src/tomb' self._tomb_check = check = Tomb.check('create', no_color=False) self.ui.wizardPage_check.completeChanged.emit() if check: @@ -123,8 +124,12 @@ class TombCreateWizard(QWizard): self.ui.label_swapoff.setEnabled(False) -if __name__ == '__main__': +def run_create_wizard(): app = QApplication(sys.argv) window = TombCreateWizard() window.show() sys.exit(app.exec_()) + +if __name__ == '__main__': + run_create_wizard() + From fddddf9c6b20f1cca41fef2143652e953ae309f1 Mon Sep 17 00:00:00 2001 From: boyska Date: Wed, 9 Nov 2011 00:23:31 +0100 Subject: [PATCH 17/25] FIX stupid things (test code removed) --- src/qt/tombqt/create.py | 1 - src/qt/tombqt/worker.py | 1 - 2 files changed, 2 deletions(-) diff --git a/src/qt/tombqt/create.py b/src/qt/tombqt/create.py index ed7b525..639b028 100755 --- a/src/qt/tombqt/create.py +++ b/src/qt/tombqt/create.py @@ -109,7 +109,6 @@ class TombCreateWizard(QWizard): self.thread.error_received.connect(err_append_to_log) self.thread.start() def check_requisite(self): - Tomb.tombexec = '/home/davide/coding/projects/tomb/src/tomb' self._tomb_check = check = Tomb.check('create', no_color=False) self.ui.wizardPage_check.completeChanged.emit() if check: diff --git a/src/qt/tombqt/worker.py b/src/qt/tombqt/worker.py index fca34bd..3064bac 100644 --- a/src/qt/tombqt/worker.py +++ b/src/qt/tombqt/worker.py @@ -25,7 +25,6 @@ class TombCreateThread(QtCore.QThread): 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() From 4a3d59c3a48477715aa40237875df1a7b6aa2f86 Mon Sep 17 00:00:00 2001 From: boyska Date: Sat, 7 Jan 2012 15:48:27 +0100 Subject: [PATCH 18/25] QT open: draft --- src/qt/tombqt/open.ui | 239 ++++++++++++++++++++++++++++++++ src/qt/tombqt/open_choosekey.ui | 147 ++++++++++++++++++++ 2 files changed, 386 insertions(+) create mode 100644 src/qt/tombqt/open.ui create mode 100644 src/qt/tombqt/open_choosekey.ui diff --git a/src/qt/tombqt/open.ui b/src/qt/tombqt/open.ui new file mode 100644 index 0000000..aeb6793 --- /dev/null +++ b/src/qt/tombqt/open.ui @@ -0,0 +1,239 @@ + + + Dialog + + + Tomb open + + + Open a tomb file; this will require a passphrase + + + false + + + true + + + + + + + + <!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-size:14pt; font-weight:600;">Opening %tombname%</span></p></body></html> + + + Qt::RichText + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Maximum + + + + 40 + 20 + + + + + + + + Size: %tombsize% + + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 25 + + + + + + + + Opening key + + + false + + + false + + + + + + Key found in %autokeypath% + + + + + + + Select a key to open the tomb + + + Choose another key + + + true + + + false + + + false + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Preferred + + + + 20 + 40 + + + + + + + + <!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;">HELP</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">To open a tomb, you need both:</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"> 1. a key, which is a file with secret information.</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"> 2. a passphrase</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">This dialog will help you choose the keyfile. We try hard to find the key, but if we can't found the right one, choose it yourself using the button</p></body></html> + + + true + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Help|QDialogButtonBox::Open + + + false + + + + + + + + + buttonBox + rejected() + Dialog + reject() + + + 578 + 751 + + + 529 + 381 + + + + + buttonBox + accepted() + Dialog + accept() + + + 447 + 735 + + + 279 + 326 + + + + + Dialog + created() + label_4 + hide() + + + 141 + 756 + + + 136 + 692 + + + + + buttonBox + helpRequested() + label_4 + hide() + + + 39 + 738 + + + 71 + 676 + + + + + + created() + + diff --git a/src/qt/tombqt/open_choosekey.ui b/src/qt/tombqt/open_choosekey.ui new file mode 100644 index 0000000..e45b8f3 --- /dev/null +++ b/src/qt/tombqt/open_choosekey.ui @@ -0,0 +1,147 @@ + + + Dialog + + + + 0 + 0 + + + + Dialog + + + true + + + + + + <!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-size:12pt; font-weight:600;">Auto-search</span></p></body></html> + + + Qt::RichText + + + + + + + Qt::Vertical + + + QSizePolicy::Expanding + + + + 20 + 40 + + + + + + + + + + + + Custom location + + + + + + + + + false + + + /path/to/keyfile + + + + + + + Choose file + + + + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Expanding + + + + 20 + 40 + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + Dialog + accept() + + + 247 + 604 + + + 157 + 274 + + + + + buttonBox + rejected() + Dialog + reject() + + + 315 + 604 + + + 286 + 274 + + + + + From 72b44a84f60a3b29000b94edb8d2ef599160017b Mon Sep 17 00:00:00 2001 From: boyska Date: Mon, 23 Jan 2012 03:34:25 +0100 Subject: [PATCH 19/25] --option-parsing: useful for completion --- src/tomb | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/src/tomb b/src/tomb index bee6b70..3906de9 100755 --- a/src/tomb +++ b/src/tomb @@ -1603,19 +1603,19 @@ main() { # to add some options? Well, keep in mind that an option CAN'T # have differente meanings/behaviour in different subcommands. - # For example, "-s" means "size" and accept an argument. If you are tempted to add - # an option "-s" (that means, for example "silent", and doesn't accept an argument) - # DON'T DO IT! + # For example, "-s" means "size" and accept an argument. If you are tempted to add + # an option "-s" (that means, for example "silent", and doesn't accept an argument) + # DON'T DO IT! - # There are two reasons for that: + # There are two reasons for that: # I. usability; user expect that "-s" is "size" - # II. Option parsing WILL EXPLODE if you do this kind of bad things - # (it will say "option defined more than once, and he's right") + # II. Option parsing WILL EXPLODE if you do this kind of bad things + # (it will say "option defined more than once, and he's right") # # If you want to use the same option in multiple commands then # you can only use the non-abbreviated long-option version like: # -force and NOT -f - main_opts=(q -quiet=q D -debug=D h -help=h v -version=v -no-color) + main_opts=(q -quiet=q D -debug=D h -help=h v -version=v -no-color) subcommands_opts[__default]="" subcommands_opts[open]="f n -nohook=n k: -key=k o: -mount-options=o" subcommands_opts[mount]=${subcommands_opts[open]} @@ -1648,7 +1648,20 @@ main() { done local -a oldstar oldstar=($argv) - zparseopts -M -E -D -Adiscardme ${every_opts} + #### detect early: useful for --optiion-parsing + zparseopts -M -D -Adiscardme ${every_opts} + if [[ -n ${(k)discardme[--option-parsing]} ]]; then + echo $1 + if [[ -n "$1" ]]; then + return 1 + fi + return 0 + fi + unset discardme + if ! zparseopts -M -E -D -Adiscardme ${every_opts}; then + error "error parsing" + return 127 + fi unset discardme subcommand=$1 if [[ -z $subcommand ]]; then @@ -1783,8 +1796,9 @@ EOF # {{{ RUNTIME check_bin main $@ -if [[ $? != 0 ]]; then #this "if" seems useless, but avoid source tomb source from exiting - exit $? +ret=$? +if [[ $ret != 0 ]]; then #this "if" seems useless, but avoid source tomb source from exiting + exit $ret fi # }}} From 9318377aca8742be722b2ae94d1b6b22db2a662d Mon Sep 17 00:00:00 2001 From: boyska Date: Tue, 24 Jan 2012 01:18:34 +0100 Subject: [PATCH 20/25] Initial open support in pytomb/gui --- src/pytomb/tomblib/tomb.py | 20 ++++++++++++++++---- src/qt/Makefile | 25 +++++++++++++++++++------ src/qt/tombqt/create.py | 2 +- 3 files changed, 36 insertions(+), 11 deletions(-) diff --git a/src/pytomb/tomblib/tomb.py b/src/pytomb/tomblib/tomb.py index 7597351..8e70148 100644 --- a/src/pytomb/tomblib/tomb.py +++ b/src/pytomb/tomblib/tomb.py @@ -47,7 +47,8 @@ class Tomb(object): return True @classmethod - def create(cls, tombpath, tombsize,keypath, stdout=None, stderr=None, no_color=True, ignore_swap=False): + def create(cls, tombpath, tombsize,keypath, stdout=None, stderr=None, + no_color=True, ignore_swap=False): '''If keypath is None, it will be created adjacent to the tomb. This is unsafe, and you should NOT do it. @@ -69,9 +70,20 @@ class Tomb(object): return False return True - @staticmethod - def open(tombpath,keypath=None): - raise NotImplementedError + @classmethod + def open(cls, tombpath,keypath=None, no_color=True, ignore_swap=False): + args = [tombpath] + if keypath is not None: + args += ['-k', keypath] + if no_color: + args += ['--no-color'] + if ignore_swap: + args += ['--ignore-swap'] + try: + subprocess.check_call([cls.tombexec, 'open'] + args) + except subprocess.CalledProcessError: + return False + return True if __name__ == '__main__': diff --git a/src/qt/Makefile b/src/qt/Makefile index 317ee9b..aeb1a38 100644 --- a/src/qt/Makefile +++ b/src/qt/Makefile @@ -1,10 +1,23 @@ -all: ui_create.py -test: ui_create.py - python2 -3 create.py -ui_create.py: create.ui - pyuic4 create.ui -o ui_create.py +TARGETS_OPEN=tombqt/ui_open_tombfile.py tombqt/ui_open_keymethod.py tombqt/ui_open_success.py +TARGETS=tombqt/ui_create.py $(TARGETS_OPEN) + +all: $(TARGETS) +test_create: tombqt/ui_create.py + python2 -3 tombqt/create.py +test_open: $(TARGETS_OPEN) + python2 -3 tombqt/open.py + + +tombqt/ui_create.py: tombqt/create.ui + pyuic4 create.ui -o tombqt/ui_create.py +tombqt/ui_open_tombfile.py: tombqt/open_tombfile.ui + pyuic4 tombqt/open_tombfile.ui -o tombqt/ui_open_tombfile.py +tombqt/ui_open_keymethod.py: tombqt/open_keymethod.ui + pyuic4 tombqt/open_keymethod.ui -o tombqt/ui_open_keymethod.py +tombqt/ui_open_success.py: tombqt/open_success.ui + pyuic4 tombqt/open_success.ui -o tombqt/ui_open_success.py clean: - rm ui_create.py + rm $(TARGETS) .PHONY: test clean diff --git a/src/qt/tombqt/create.py b/src/qt/tombqt/create.py index 639b028..d39697c 100755 --- a/src/qt/tombqt/create.py +++ b/src/qt/tombqt/create.py @@ -73,7 +73,7 @@ class TombCreateWizard(QWizard): def on_tomb_location_clicked(self, *args, **kwargs): filename = QtGui.QFileDialog.getSaveFileName(self, 'Create Tomb', - filter="*.tomb") + filter="Tomb(*.tomb)") self.ui.lineEdit_tombpath.setText(filename) def on_change_page(self, pagenumber): if self.currentPage() == self.ui.wizardPage_progress: From a0eb6ba9c373d8c8ae6b572de38df8d13729e4bd Mon Sep 17 00:00:00 2001 From: boyska Date: Sat, 28 Jan 2012 04:15:23 +0100 Subject: [PATCH 21/25] GUI: open functionality is barely functional pytomb: adds undertaker, better parser (updated for new tomb messages) undertaker: fix some things to make it work with new tomb the rest is ui stuff :) the ui does: - allow auto-searching for the key near the tomb itself - allow manually choosing a key location - mount the tomb ;) the ui DOESN'T: - support usb nor anything else (shouldn't be that difficult) - support periodical polling - anything else --- src/pytomb/tomblib/parser.py | 20 +++++- src/pytomb/tomblib/test_parser.py | 63 +++++++++++------ src/pytomb/tomblib/undertaker.py | 79 +++++++++++++++++++++ src/qt/.gitignore | 2 + src/qt/tombqt/open.py | 109 +++++++++++++++++++++++++++++ src/qt/tombqt/open_keymethod.ui | 84 ++++++++++++++++++++++ src/qt/tombqt/open_success.ui | 34 +++++++++ src/qt/tombqt/open_tombfile.ui | 79 +++++++++++++++++++++ src/qt/tombqt/ui_open_keymethod.py | 51 ++++++++++++++ src/qt/tombqt/ui_open_success.py | 35 +++++++++ src/qt/tombqt/ui_open_tombfile.py | 52 ++++++++++++++ src/undertaker | 26 +++---- 12 files changed, 599 insertions(+), 35 deletions(-) create mode 100644 src/pytomb/tomblib/undertaker.py create mode 100644 src/qt/tombqt/open.py create mode 100644 src/qt/tombqt/open_keymethod.ui create mode 100644 src/qt/tombqt/open_success.ui create mode 100644 src/qt/tombqt/open_tombfile.ui create mode 100644 src/qt/tombqt/ui_open_keymethod.py create mode 100644 src/qt/tombqt/ui_open_success.py create mode 100644 src/qt/tombqt/ui_open_tombfile.py diff --git a/src/pytomb/tomblib/parser.py b/src/pytomb/tomblib/parser.py index 5edc7cf..e9eb7f9 100644 --- a/src/pytomb/tomblib/parser.py +++ b/src/pytomb/tomblib/parser.py @@ -3,7 +3,13 @@ Utilities to analyze tomb output ''' import re -_err_regex = re.compile(r'\[!\][^ ]* +(.+)$') +#found: [m] followed by some ID (usually "found") inside square brackets, then +#something else, then a space, then the content +_found_regex = re.compile(r'^\[m\]\[([^]]+)\] +(([^:]+)://(.+))$') +#generic: programname, then some identifiers in square (or round) brackets, +#then maybe something else, then a space, then the context +_generic_regex = re.compile(r'^[a-z-]+ [[(]([^]]+)[\])] +(.+)$') +types = {'E':'error', 'W':'warning', 'D':'debug', '*':'success'} def parse_line(line): '''Analyze a single line. Return None if no standard format is detected, a dict otherwise. @@ -12,9 +18,17 @@ def parse_line(line): 'type' can be 'error', 'progress' ''' - match = _err_regex.search(line) + + match = _found_regex.match(line) if match: - return { 'type': 'error', 'content': match.group(1) } + return { 'type': types.get(match.group(1)) or match.group(1), + 'content': match.group(2), 'scheme': match.group(3), + 'path': match.group(4) } + match = _generic_regex.search(line) + if match: + return { 'type': types.get(match.group(1)) or match.group(1), + 'content': match.group(2) } + return None diff --git a/src/pytomb/tomblib/test_parser.py b/src/pytomb/tomblib/test_parser.py index d601f4d..4ea2334 100644 --- a/src/pytomb/tomblib/test_parser.py +++ b/src/pytomb/tomblib/test_parser.py @@ -1,29 +1,52 @@ from tomblib.parser import * class TestWrong: - def test_wrong_tag(self): - assert parse_line(' [a] foo') is None - def test_no_space(self): - assert parse_line(' [!]foo') is None + def test_short(self): + '''short format is not supported anymore''' + assert parse_line('[!] foo') is None + def test_colors(self): + '''parsing while using colors should fail''' + parse = parse_line('\033[32mundertaker [W] url protocol not recognized: nonscheme') + assert parse is None + def test_no_spaces_in_programname(self): + parse = parse_line('tomb open [W] url protocol not recognized: nonscheme') + assert parse is None -class TestError: +class TestFound: def test_simple(self): - parse = parse_line('[!] foo') + parse = parse_line('[m][found] scheme:///and/path') assert parse is not None - assert parse['type'] == 'error' - assert parse['content'] == 'foo' - def test_preceding(self): - parse = parse_line(' [!] foo') + assert parse['type'] == 'found' + assert parse['content'] == 'scheme:///and/path' + assert 'scheme' in parse + assert parse['scheme'] == 'scheme' + assert 'path' in parse + assert parse['path'] == '/and/path' + +class TestGeneric: + def test_simple(self): + parse = parse_line('undertaker [W] url protocol not recognized: nonscheme') assert parse is not None - assert parse['type'] == 'error' - assert parse['content'] == 'foo' - def test_following(self): - parse = parse_line('[!]shdad foo') + assert parse['type'] == 'warning' + assert parse['content'] == 'url protocol not recognized: nonscheme' + + def test_debug(self): + parse = parse_line('undertaker [D] url protocol not recognized: nonscheme') assert parse is not None - assert parse['type'] == 'error' - assert parse['content'] == 'foo' - def test_mul_words(self): - parse = parse_line('[!] shdad foo') + assert parse['type'] == 'debug' + assert parse['content'] == 'url protocol not recognized: nonscheme' + + def test_success(self): + parse = parse_line('undertaker (*) url protocol not recognized: nonscheme') assert parse is not None - assert parse['type'] == 'error' - assert parse['content'] == 'shdad foo' + assert parse['type'] == 'success' + assert parse['content'] == 'url protocol not recognized: nonscheme' + + def test_dash(self): + parse = parse_line('tomb-open [W] url protocol not recognized: nonscheme') + assert parse is not None + assert parse['type'] == 'warning' + assert parse['content'] == 'url protocol not recognized: nonscheme' + + + diff --git a/src/pytomb/tomblib/undertaker.py b/src/pytomb/tomblib/undertaker.py new file mode 100644 index 0000000..d73e740 --- /dev/null +++ b/src/pytomb/tomblib/undertaker.py @@ -0,0 +1,79 @@ +import subprocess +from tempfile import NamedTemporaryFile + +import parser + +class Undertaker(object): + ''' + This is similar to Tomb class, and provides a wrapper on undertaker. + + TODO: + * methods for automagical scan + * output parsing, giving meaningful output + + Due to the non-interactive nature of undertaker, it's simpler than Tomb + ''' + undertakerexec = 'undertaker' + @classmethod + def check(cls, paths): + '''Will check if there are keys available there, as in --path + + paths can be a string (one address), or a list of + ''' + #TODO: more solid check: something like + if type(paths) is not str: + out = [] + for p in paths: + try: + res = cls.check(p) + except: + continue + else: + if res: + out.extend(res) + return out + + buf = NamedTemporaryFile() + try: + subprocess.check_call([cls.undertakerexec, paths, '--batch', + '--path'], stdout=buf) + except subprocess.CalledProcessError as exc: + return False + + out = [] + buf.seek(0) + for line in buf: + ret = parser.parse_line(line) + if ret and ret['type'] == 'found': + out.append(ret['content']) + return out + + + @classmethod + def get(cls, paths): + ''' + Similar to check, but truly get the key content. + If paths is iterable, stop at the first successful path + ''' + if type(paths) is not str: + for p in paths: + try: + res = cls.get(p) + except: + continue + else: + if res: + return res + buf = NamedTemporaryFile() + try: + subprocess.check_call([cls.undertakerexec, paths, '--batch'], + stdout=buf) + except subprocess.CalledProcessError: + return False + buf.seek(0) + return buf.read() + + +if __name__ == '__main__': + Undertaker.undertakerexec = '/home/davide/coding/projects/tomb/src/undertaker' + print Undertaker.get('near:///home/davide/Desktop/testing.tomb') diff --git a/src/qt/.gitignore b/src/qt/.gitignore index dd75296..cf9dc94 100644 --- a/src/qt/.gitignore +++ b/src/qt/.gitignore @@ -2,3 +2,5 @@ *.pyc TombQt.egg-info build +dist +disk diff --git a/src/qt/tombqt/open.py b/src/qt/tombqt/open.py new file mode 100644 index 0000000..e2171bd --- /dev/null +++ b/src/qt/tombqt/open.py @@ -0,0 +1,109 @@ +import sys + +from PyQt4 import QtCore, QtGui + +from ui_open_tombfile import Ui_tombfile +from ui_open_keymethod import Ui_keymethod +from ui_open_success import Ui_success + +from tomblib.tomb import Tomb +from tomblib.undertaker import Undertaker + +try: + _fromUtf8 = QtCore.QString.fromUtf8 +except AttributeError: + _fromUtf8 = lambda s: s + +class TombfilePage(QtGui.QWizardPage): + def __init__(self, *args, **kwargs): + QtGui.QWizardPage.__init__(self, *args) + self.ui = Ui_tombfile() + self.ui.setupUi(self) + if 'tombfile' in kwargs and kwargs['tombfile'] is not None: + self.ui.tomb_line.setText(kwargs['tombfile']) + self.ui.tomb_browse.clicked.connect(self.on_tomb_location_clicked) + def on_tomb_location_clicked(self, *args, **kwargs): + filename = QtGui.QFileDialog.getOpenFileName(self, 'Select Tomb', + filter="Tomb (*.tomb)") + self.ui.tomb_line.setText(filename) + +class MethodPage(QtGui.QWizardPage): + def __init__(self, *args, **kwargs): + QtGui.QWizardPage.__init__(self, *args, **kwargs) + self.ui = Ui_keymethod() + self.ui.setupUi(self) + self.group = group = QtGui.QButtonGroup() + for radio in self.children(): + if type(radio) == QtGui.QRadioButton: + group.addButton(radio) + + def initializePage(self): + self.found = Undertaker.check( str('near://' + self.wizard().get_tombfile()) ) or [] + box = self.ui.radio_layout + + for key in self.found: + radio = QtGui.QRadioButton('Automatically found: ' + key, parent=self) + radio.setChecked(True) + radio.setProperty('path', key) + box.insertWidget(0, radio) + self.group.addButton(radio) + + + def nextId(self): + '''Virtual method reimplemented to decide next page''' + if self.ui.fs.isChecked(): + keyfile = QtGui.QFileDialog.getOpenFileName(self.wizard(), 'Key file', + filter="Tomb keys (*.tomb.key);;Buried keys (*.jpeg)") + if keyfile: + #TODO: check if this really is a success :) + if Tomb.open(self.wizard().get_tombfile(), keyfile): #bugs when wrong password + return TombOpenWizard.SUCCESS_PAGE + #else: #TODO: should alert the user that we failed + return TombOpenWizard.METHOD_PAGE + if self.ui.usb.isChecked(): + return TombOpenWizard.USB_PAGE + print self.group.checkedButton().property('path').toPyObject() + return TombOpenWizard.SUCCESS_PAGE + +class SuccessPage(QtGui.QWizardPage): + def __init__(self, *args, **kwargs): + QtGui.QWizardPage.__init__(self, *args, **kwargs) + self.ui = Ui_success() + self.ui.setupUi(self) + +class TombOpenWizard(QtGui.QWizard): + TOMBFILE_PAGE=1 + METHOD_PAGE=2 + SUCCESS_PAGE=99 + USB_PAGE=20 + def __init__(self, *args, **kwargs): + QtGui.QWizard.__init__(self, *args) + self.setPage(TombOpenWizard.TOMBFILE_PAGE, + TombfilePage(self, tombfile = kwargs['tombfile'] + if 'tombfile' in kwargs else None)) + self.setPage(TombOpenWizard.METHOD_PAGE, MethodPage(self)) + self.setPage(TombOpenWizard.SUCCESS_PAGE, SuccessPage(self)) + if 'tombfile' in kwargs and kwargs['tombfile'] is not None: + self.setStartId(TombOpenWizard.METHOD_PAGE) + + def get_tombfile(self): + page = self.page(TombOpenWizard.TOMBFILE_PAGE) + return page.ui.tomb_line.text() + + + +def run_open_wizard(): + app = QtGui.QApplication(sys.argv) + window = TombOpenWizard(tombfile=sys.argv[1] if len(sys.argv) > 1 else None) + window.show() + sys.exit(app.exec_()) + +if __name__ == '__main__': + Undertaker.undertakerexec = '/home/davide/coding/projects/tomb/src/undertaker' + run_open_wizard() + + + + + + diff --git a/src/qt/tombqt/open_keymethod.ui b/src/qt/tombqt/open_keymethod.ui new file mode 100644 index 0000000..2299936 --- /dev/null +++ b/src/qt/tombqt/open_keymethod.ui @@ -0,0 +1,84 @@ + + + keymethod + + + + 0 + 0 + 480 + 640 + + + + WizardPage + + + Choose key + + + + + + Qt::Vertical + + + + 20 + 265 + + + + + + + + + + Filesystem + + + true + + + + + + + false + + + USB drive + + + + + + + false + + + Retrieve via bluetooth (advanced) + + + + + + + + + Qt::Vertical + + + + 20 + 265 + + + + + + + + + diff --git a/src/qt/tombqt/open_success.ui b/src/qt/tombqt/open_success.ui new file mode 100644 index 0000000..200e4fd --- /dev/null +++ b/src/qt/tombqt/open_success.ui @@ -0,0 +1,34 @@ + + + success + + + + 0 + 0 + 480 + 640 + + + + WizardPage + + + Tomb opened + + + success + + + + + + You successfully opened the tomb + + + + + + + + diff --git a/src/qt/tombqt/open_tombfile.ui b/src/qt/tombqt/open_tombfile.ui new file mode 100644 index 0000000..3b73ab2 --- /dev/null +++ b/src/qt/tombqt/open_tombfile.ui @@ -0,0 +1,79 @@ + + + tombfile + + + + 0 + 0 + 480 + 640 + + + + WizardPage + + + Choose tomb + + + + + + Qt::Vertical + + + + 20 + 276 + + + + + + + + + + Choose a tomb file on your filesystem + + + + + + + + + /path/to/your.tomb + + + + + + + Browse + + + + + + + + + + + Qt::Vertical + + + + 20 + 276 + + + + + + + + + diff --git a/src/qt/tombqt/ui_open_keymethod.py b/src/qt/tombqt/ui_open_keymethod.py new file mode 100644 index 0000000..21b9951 --- /dev/null +++ b/src/qt/tombqt/ui_open_keymethod.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- + +# Form implementation generated from reading ui file 'tombqt/open_keymethod.ui' +# +# Created: Sat Jan 28 03:36:11 2012 +# by: PyQt4 UI code generator 4.9 +# +# WARNING! All changes made in this file will be lost! + +from PyQt4 import QtCore, QtGui + +try: + _fromUtf8 = QtCore.QString.fromUtf8 +except AttributeError: + _fromUtf8 = lambda s: s + +class Ui_keymethod(object): + def setupUi(self, keymethod): + keymethod.setObjectName(_fromUtf8("keymethod")) + keymethod.resize(480, 640) + self.verticalLayout = QtGui.QVBoxLayout(keymethod) + self.verticalLayout.setObjectName(_fromUtf8("verticalLayout")) + spacerItem = QtGui.QSpacerItem(20, 265, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) + self.verticalLayout.addItem(spacerItem) + self.radio_layout = QtGui.QVBoxLayout() + self.radio_layout.setObjectName(_fromUtf8("radio_layout")) + self.fs = QtGui.QRadioButton(keymethod) + self.fs.setObjectName(_fromUtf8("fs")) + self.radio_layout.addWidget(self.fs) + self.usb = QtGui.QRadioButton(keymethod) + self.usb.setEnabled(False) + self.usb.setObjectName(_fromUtf8("usb")) + self.radio_layout.addWidget(self.usb) + self.bluetooth = QtGui.QRadioButton(keymethod) + self.bluetooth.setEnabled(False) + self.bluetooth.setObjectName(_fromUtf8("bluetooth")) + self.radio_layout.addWidget(self.bluetooth) + self.verticalLayout.addLayout(self.radio_layout) + spacerItem1 = QtGui.QSpacerItem(20, 265, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) + self.verticalLayout.addItem(spacerItem1) + + self.retranslateUi(keymethod) + QtCore.QMetaObject.connectSlotsByName(keymethod) + + def retranslateUi(self, keymethod): + keymethod.setWindowTitle(QtGui.QApplication.translate("keymethod", "WizardPage", None, QtGui.QApplication.UnicodeUTF8)) + keymethod.setTitle(QtGui.QApplication.translate("keymethod", "Choose key", None, QtGui.QApplication.UnicodeUTF8)) + self.fs.setText(QtGui.QApplication.translate("keymethod", "Filesystem", None, QtGui.QApplication.UnicodeUTF8)) + self.usb.setText(QtGui.QApplication.translate("keymethod", "USB drive", None, QtGui.QApplication.UnicodeUTF8)) + self.bluetooth.setText(QtGui.QApplication.translate("keymethod", "Retrieve via bluetooth (advanced)", None, QtGui.QApplication.UnicodeUTF8)) + diff --git a/src/qt/tombqt/ui_open_success.py b/src/qt/tombqt/ui_open_success.py new file mode 100644 index 0000000..700081f --- /dev/null +++ b/src/qt/tombqt/ui_open_success.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- + +# Form implementation generated from reading ui file 'tombqt/open_success.ui' +# +# Created: Mon Jan 23 23:06:38 2012 +# by: PyQt4 UI code generator 4.9 +# +# WARNING! All changes made in this file will be lost! + +from PyQt4 import QtCore, QtGui + +try: + _fromUtf8 = QtCore.QString.fromUtf8 +except AttributeError: + _fromUtf8 = lambda s: s + +class Ui_success(object): + def setupUi(self, success): + success.setObjectName(_fromUtf8("success")) + success.resize(480, 640) + self.verticalLayout = QtGui.QVBoxLayout(success) + self.verticalLayout.setObjectName(_fromUtf8("verticalLayout")) + self.label = QtGui.QLabel(success) + self.label.setObjectName(_fromUtf8("label")) + self.verticalLayout.addWidget(self.label) + + self.retranslateUi(success) + QtCore.QMetaObject.connectSlotsByName(success) + + def retranslateUi(self, success): + success.setWindowTitle(QtGui.QApplication.translate("success", "WizardPage", None, QtGui.QApplication.UnicodeUTF8)) + success.setTitle(QtGui.QApplication.translate("success", "Tomb opened", None, QtGui.QApplication.UnicodeUTF8)) + success.setSubTitle(QtGui.QApplication.translate("success", "success", None, QtGui.QApplication.UnicodeUTF8)) + self.label.setText(QtGui.QApplication.translate("success", "You successfully opened the tomb", None, QtGui.QApplication.UnicodeUTF8)) + diff --git a/src/qt/tombqt/ui_open_tombfile.py b/src/qt/tombqt/ui_open_tombfile.py new file mode 100644 index 0000000..d9f1eb6 --- /dev/null +++ b/src/qt/tombqt/ui_open_tombfile.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- + +# Form implementation generated from reading ui file 'tombqt/open_tombfile.ui' +# +# Created: Tue Jan 24 00:49:10 2012 +# by: PyQt4 UI code generator 4.9 +# +# WARNING! All changes made in this file will be lost! + +from PyQt4 import QtCore, QtGui + +try: + _fromUtf8 = QtCore.QString.fromUtf8 +except AttributeError: + _fromUtf8 = lambda s: s + +class Ui_tombfile(object): + def setupUi(self, tombfile): + tombfile.setObjectName(_fromUtf8("tombfile")) + tombfile.resize(480, 640) + self.verticalLayout_2 = QtGui.QVBoxLayout(tombfile) + self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2")) + spacerItem = QtGui.QSpacerItem(20, 276, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) + self.verticalLayout_2.addItem(spacerItem) + self.verticalLayout = QtGui.QVBoxLayout() + self.verticalLayout.setObjectName(_fromUtf8("verticalLayout")) + self.label = QtGui.QLabel(tombfile) + self.label.setObjectName(_fromUtf8("label")) + self.verticalLayout.addWidget(self.label) + self.horizontalLayout = QtGui.QHBoxLayout() + self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout")) + self.tomb_line = QtGui.QLineEdit(tombfile) + self.tomb_line.setObjectName(_fromUtf8("tomb_line")) + self.horizontalLayout.addWidget(self.tomb_line) + self.tomb_browse = QtGui.QPushButton(tombfile) + self.tomb_browse.setObjectName(_fromUtf8("tomb_browse")) + self.horizontalLayout.addWidget(self.tomb_browse) + self.verticalLayout.addLayout(self.horizontalLayout) + self.verticalLayout_2.addLayout(self.verticalLayout) + spacerItem1 = QtGui.QSpacerItem(20, 276, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) + self.verticalLayout_2.addItem(spacerItem1) + + self.retranslateUi(tombfile) + QtCore.QMetaObject.connectSlotsByName(tombfile) + + def retranslateUi(self, tombfile): + tombfile.setWindowTitle(QtGui.QApplication.translate("tombfile", "WizardPage", None, QtGui.QApplication.UnicodeUTF8)) + tombfile.setTitle(QtGui.QApplication.translate("tombfile", "Choose tomb", None, QtGui.QApplication.UnicodeUTF8)) + self.label.setText(QtGui.QApplication.translate("tombfile", "Choose a tomb file on your filesystem", None, QtGui.QApplication.UnicodeUTF8)) + self.tomb_line.setPlaceholderText(QtGui.QApplication.translate("tombfile", "/path/to/your.tomb", None, QtGui.QApplication.UnicodeUTF8)) + self.tomb_browse.setText(QtGui.QApplication.translate("tombfile", "Browse", None, QtGui.QApplication.UnicodeUTF8)) + diff --git a/src/undertaker b/src/undertaker index 084083c..ec64e3c 100755 --- a/src/undertaker +++ b/src/undertaker @@ -37,7 +37,7 @@ fi key_found() { # $1 is "url" - if option_is_set --machine-parseable; then + if option_is_set --batch; then print -n '[m]' fi print "$fg[white][found] $1" @@ -46,7 +46,7 @@ key_found() { function undertaker_scheme() { - zparseopts -D -print-path=print_path + zparseopts -D -path=print_path local scheme scheme=$1 @@ -60,7 +60,7 @@ function undertaker_scheme() { act "access to bluetooth protocol requested" which obexftp &> /dev/null if [[ $? != 0 ]]; then - error "obexftp not found, needed for bluetooth: operation aborted." + _warning "obexftp not found, needed for bluetooth: operation aborted." return 64 fi keytmp=`safe_dir undertaker` @@ -95,10 +95,10 @@ function undertaker_scheme() { file) if ! [[ -f $keypath ]]; then - error "Invalid path $keypath" + _warning "Invalid path $keypath" return 1 fi - if [[ -n $print_path ]]; then + if option_is_set --path; then key_found $scheme://$keypath; else < $keypath @@ -122,7 +122,7 @@ function undertaker_scheme() { #It implements automounting using udisks; udisks is a (recently) #new technology, so we can't rely on it being present if ! which udisks &> /dev/null; then - error 'udisks not found' + _warning 'udisks not found' exit 64 fi while true; do @@ -149,7 +149,7 @@ function undertaker_scheme() { *) if ! which undertaker-$scheme &> /dev/null; then - error "url protocol not recognized: $scheme" + _warning "url protocol not recognized: $scheme" return 64 fi undertaker-$scheme ${print_path[@]} ${scheme}://$keypath @@ -162,13 +162,14 @@ function main() { typeset -A opts zparseopts -M -E -D -Aopts -poll -path -batch if ! [ $1 ] ; then - error "an argument is missing, the undertaker is confused" - act "usage: undertaker [options] url://host:path/to/tomb.key" + echo "[W] an argument is missing, the undertaker is confused" + echo "usage: undertaker [options] url://host:path/to/tomb.key" exit 1; fi local -a tomb_opts if [[ -n ${(k)opts[--batch]} ]]; then - tomb_opts+='--batch' + tomb_opts+='--no-color' + tomb_opts+='--quiet' fi local -a under_opts if [[ -n ${(k)opts[--path]} ]]; then @@ -178,13 +179,14 @@ function main() { for a in ${(k)opts}; do backupopts[$a]=${opts[$a]} done - source tomb ${tomb_opts[@]} source + source tomb ${tomb_opts[@]} source + TOMBEXEC=undertaker for a in ${(k)backupopts}; do opts[$a]=${backupopts[$a]} done check_bin - notice "Undertaker will look for $1" + _success "Undertaker will look for $1" ARG1=${1} scheme=${ARG1%://*} From 261755b824e2a2f0c6421541951d7c36e1220e51 Mon Sep 17 00:00:00 2001 From: boyska Date: Sat, 28 Jan 2012 12:28:24 +0100 Subject: [PATCH 22/25] FIX setup.py for tomb-qt-open --- src/qt/setup.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/qt/setup.py b/src/qt/setup.py index 36a9335..37d2529 100644 --- a/src/qt/setup.py +++ b/src/qt/setup.py @@ -41,7 +41,8 @@ setup( }, entry_points = { 'gui_scripts': [ - 'tomb-qt-create = tombqt.create:run_create_wizard' + 'tomb-qt-create = tombqt.create:run_create_wizard', + 'tomb-qt-open = tombqt.open:run_open_wizard' ] } ) From 4d24e247aa7ed4b5c859dcd5bc71eed8ccbfbb48 Mon Sep 17 00:00:00 2001 From: boyska Date: Sat, 28 Jan 2012 15:35:22 +0100 Subject: [PATCH 23/25] Add undertaker to Makefile.am --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile.am b/src/Makefile.am index 6b093ae..d4656cf 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,5 +1,5 @@ -bin_SCRIPTS = tomb tomb-open +bin_SCRIPTS = tomb tomb-open undertaker bin_PROGRAMS = tomb-status From 17c04782403a9592ef5431356fe03c859de2a0ac Mon Sep 17 00:00:00 2001 From: boyska Date: Sun, 29 Jan 2012 16:16:06 +0100 Subject: [PATCH 24/25] undertaker/python: ported to stderr messages --- src/pytomb/tomblib/undertaker.py | 2 +- src/undertaker | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/pytomb/tomblib/undertaker.py b/src/pytomb/tomblib/undertaker.py index d73e740..0b22b91 100644 --- a/src/pytomb/tomblib/undertaker.py +++ b/src/pytomb/tomblib/undertaker.py @@ -36,7 +36,7 @@ class Undertaker(object): buf = NamedTemporaryFile() try: subprocess.check_call([cls.undertakerexec, paths, '--batch', - '--path'], stdout=buf) + '--path'], stderr=buf) except subprocess.CalledProcessError as exc: return False diff --git a/src/undertaker b/src/undertaker index ec64e3c..349f3ad 100755 --- a/src/undertaker +++ b/src/undertaker @@ -32,15 +32,15 @@ TRAPSTOP() die "STOP signal caught, undertaker aborting." # first of all source the tomb core functions which tomb > /dev/null if [[ $? != 0 ]]; then - print "$fg[red][!]$fg[white] Tomb command not found, operation aborted."; exit 1 + print "$fg[red][!]$fg[white] Tomb command not found, operation aborted." >&2; exit 1 fi key_found() { # $1 is "url" if option_is_set --batch; then - print -n '[m]' + print -n '[m]' >&2 fi - print "$fg[white][found] $1" + print "$fg[white][found] $1" >&2 } @@ -162,8 +162,8 @@ function main() { typeset -A opts zparseopts -M -E -D -Aopts -poll -path -batch if ! [ $1 ] ; then - echo "[W] an argument is missing, the undertaker is confused" - echo "usage: undertaker [options] url://host:path/to/tomb.key" + print "[W] an argument is missing, the undertaker is confused" >&2 + print "usage: undertaker [options] url://host:path/to/tomb.key" >&2 exit 1; fi local -a tomb_opts From 7de7f851090cbb53bd7692258a659712ea02392c Mon Sep 17 00:00:00 2001 From: boyska Date: Sun, 29 Jan 2012 16:25:16 +0100 Subject: [PATCH 25/25] _msg resets colors after use --- src/tomb | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/tomb b/src/tomb index 3906de9..f4aef24 100755 --- a/src/tomb +++ b/src/tomb @@ -48,8 +48,8 @@ PATH=/sbin:/bin:/usr/sbin:/usr/bin function _msg() { local command="print -P" - local progname="$fg[magenta]${TOMBEXEC##*/}$fg[reset_color]" - local message="$fg_bold[normal]$fg_no_bold[normal]${2}$fg[reset_color]" + local progname="$fg[magenta]${TOMBEXEC##*/}$reset_color" + local message="$fg_bold[normal]$fg_no_bold[normal]${2}$reset_color" local -i returncode case "$1" in @@ -57,19 +57,19 @@ function _msg() { command+=" -n"; pchars=" > "; pcolor="yellow" ;; message) - pchars=" . "; pcolor="white"; message="$fg_no_bold[$pcolor]${2}$fg[reset_color]" + pchars=" . "; pcolor="white"; message="$fg_no_bold[$pcolor]${2}$reset_color" ;; verbose) pchars="[D]"; pcolor="blue" ;; success) - pchars="(*)"; pcolor="green"; message="$fg_no_bold[$pcolor]${2}$fg[reset_color]" + pchars="(*)"; pcolor="green"; message="$fg_no_bold[$pcolor]${2}$reset_color" ;; warning) - pchars="[W]"; pcolor="yellow"; message="$fg_no_bold[$pcolor]${2}$fg[reset_color]" + pchars="[W]"; pcolor="yellow"; message="$fg_no_bold[$pcolor]${2}$reset_color" ;; failure) - pchars="[E]"; pcolor="red"; message="$fg_no_bold[$pcolor]${2}$fg[reset_color]" + pchars="[E]"; pcolor="red"; message="$fg_no_bold[$pcolor]${2}$reset_color" returncode=1 ;; *) @@ -78,7 +78,7 @@ function _msg() { returncode=127 ;; esac - ${=command} "${progname} $fg_bold[$pcolor]$pchars$fg[reset_color] ${message}$color[reset_color]" >&2 + ${=command} "${progname} $fg_bold[$pcolor]$pchars$reset_color ${message}$color[reset_color]" >&2 return $returncode } function _message say()