Merge branch 'master' of https://github.com/Bitmessage/PyBitmessage
This commit is contained in:
commit
48f3e7084c
|
@ -15,3 +15,4 @@ references
|
||||||
* [project website](https://bitmessage.org)
|
* [project website](https://bitmessage.org)
|
||||||
* [protocol specification](https://bitmessage.org/wiki/Protocol_specification)
|
* [protocol specification](https://bitmessage.org/wiki/Protocol_specification)
|
||||||
* [whitepaper](https://bitmessage.org/bitmessage.pdf)
|
* [whitepaper](https://bitmessage.org/bitmessage.pdf)
|
||||||
|
* [installation](https://bitmessage.org/wiki/Compiling_instructions)
|
||||||
|
|
15
src/bitmessagemain.py
Normal file → Executable file
15
src/bitmessagemain.py
Normal file → Executable file
|
@ -23,6 +23,14 @@ import json
|
||||||
import singleton
|
import singleton
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
# OSX python version check
|
||||||
|
import sys
|
||||||
|
if sys.platform == 'darwin':
|
||||||
|
if float("{1}.{2}".format(*sys.version_info)) < 7.5:
|
||||||
|
print "You should use python 2.7.5 or greater."
|
||||||
|
print "Your version: {0}.{1}.{2}".format(*sys.version_info)
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
# Classes
|
# Classes
|
||||||
from class_sqlThread import *
|
from class_sqlThread import *
|
||||||
from class_singleCleaner import *
|
from class_singleCleaner import *
|
||||||
|
@ -34,13 +42,6 @@ from class_addressGenerator import *
|
||||||
# Helper Functions
|
# Helper Functions
|
||||||
import helper_bootstrap
|
import helper_bootstrap
|
||||||
|
|
||||||
import sys
|
|
||||||
if sys.platform == 'darwin':
|
|
||||||
if float("{1}.{2}".format(*sys.version_info)) < 7.5:
|
|
||||||
print "You should use python 2.7.5 or greater."
|
|
||||||
print "Your version: {0}.{1}.{2}".format(*sys.version_info)
|
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
def connectToStream(streamNumber):
|
def connectToStream(streamNumber):
|
||||||
selfInitiatedConnections[streamNumber] = {}
|
selfInitiatedConnections[streamNumber] = {}
|
||||||
if sys.platform[0:3] == 'win':
|
if sys.platform[0:3] == 'win':
|
||||||
|
|
|
@ -14,6 +14,7 @@ except ImportError:
|
||||||
from addresses import *
|
from addresses import *
|
||||||
import shared
|
import shared
|
||||||
from bitmessageui import *
|
from bitmessageui import *
|
||||||
|
from namecoin import namecoinConnection, ensureNamecoinOptions
|
||||||
from newaddressdialog import *
|
from newaddressdialog import *
|
||||||
from newsubscriptiondialog import *
|
from newsubscriptiondialog import *
|
||||||
from regenerateaddresses import *
|
from regenerateaddresses import *
|
||||||
|
@ -141,6 +142,8 @@ class MyForm(QtGui.QMainWindow):
|
||||||
"clicked()"), self.click_pushButtonSend)
|
"clicked()"), self.click_pushButtonSend)
|
||||||
QtCore.QObject.connect(self.ui.pushButtonLoadFromAddressBook, QtCore.SIGNAL(
|
QtCore.QObject.connect(self.ui.pushButtonLoadFromAddressBook, QtCore.SIGNAL(
|
||||||
"clicked()"), self.click_pushButtonLoadFromAddressBook)
|
"clicked()"), self.click_pushButtonLoadFromAddressBook)
|
||||||
|
QtCore.QObject.connect(self.ui.pushButtonFetchNamecoinID, QtCore.SIGNAL(
|
||||||
|
"clicked()"), self.click_pushButtonFetchNamecoinID)
|
||||||
QtCore.QObject.connect(self.ui.radioButtonBlacklist, QtCore.SIGNAL(
|
QtCore.QObject.connect(self.ui.radioButtonBlacklist, QtCore.SIGNAL(
|
||||||
"clicked()"), self.click_radioButtonBlacklist)
|
"clicked()"), self.click_radioButtonBlacklist)
|
||||||
QtCore.QObject.connect(self.ui.radioButtonWhitelist, QtCore.SIGNAL(
|
QtCore.QObject.connect(self.ui.radioButtonWhitelist, QtCore.SIGNAL(
|
||||||
|
@ -429,11 +432,26 @@ class MyForm(QtGui.QMainWindow):
|
||||||
"removeInboxRowByMsgid(PyQt_PyObject)"), self.removeInboxRowByMsgid)
|
"removeInboxRowByMsgid(PyQt_PyObject)"), self.removeInboxRowByMsgid)
|
||||||
self.UISignalThread.start()
|
self.UISignalThread.start()
|
||||||
|
|
||||||
# Below this point, it would be good if all of the necessary global data
|
# Below this point, it would be good if all of the necessary global data
|
||||||
# structures were initialized.
|
# structures were initialized.
|
||||||
|
|
||||||
self.rerenderComboBoxSendFrom()
|
self.rerenderComboBoxSendFrom()
|
||||||
|
|
||||||
|
# Check to see whether we can connect to namecoin. Hide the 'Fetch Namecoin ID' button if we can't.
|
||||||
|
try:
|
||||||
|
options = {}
|
||||||
|
options["type"] = shared.config.get('bitmessagesettings', 'namecoinrpctype')
|
||||||
|
options["host"] = shared.config.get('bitmessagesettings', 'namecoinrpchost')
|
||||||
|
options["port"] = shared.config.get('bitmessagesettings', 'namecoinrpcport')
|
||||||
|
options["user"] = shared.config.get('bitmessagesettings', 'namecoinrpcuser')
|
||||||
|
options["password"] = shared.config.get('bitmessagesettings', 'namecoinrpcpassword')
|
||||||
|
nc = namecoinConnection(options)
|
||||||
|
if nc.test()[0] == 'failed':
|
||||||
|
self.ui.pushButtonFetchNamecoinID.hide()
|
||||||
|
except:
|
||||||
|
print 'There was a problem testing for a Namecoin daemon. Hiding the Fetch Namecoin ID button'
|
||||||
|
self.ui.pushButtonFetchNamecoinID.hide()
|
||||||
|
|
||||||
|
|
||||||
# Show or hide the application window after clicking an item within the
|
# Show or hide the application window after clicking an item within the
|
||||||
# tray icon or, on Windows, the try icon itself.
|
# tray icon or, on Windows, the try icon itself.
|
||||||
|
@ -1699,6 +1717,17 @@ class MyForm(QtGui.QMainWindow):
|
||||||
self.statusBar().showMessage(_translate(
|
self.statusBar().showMessage(_translate(
|
||||||
"MainWindow", "Right click one or more entries in your address book and select \'Send message to this address\'."))
|
"MainWindow", "Right click one or more entries in your address book and select \'Send message to this address\'."))
|
||||||
|
|
||||||
|
def click_pushButtonFetchNamecoinID(self):
|
||||||
|
nc = namecoinConnection()
|
||||||
|
err, addr = nc.query(str(self.ui.lineEditTo.text()))
|
||||||
|
if err is not None:
|
||||||
|
self.statusBar().showMessage(_translate(
|
||||||
|
"MainWindow", "Error: " + err))
|
||||||
|
else:
|
||||||
|
self.ui.lineEditTo.setText(addr)
|
||||||
|
self.statusBar().showMessage(_translate(
|
||||||
|
"MainWindow", "Fetched address from namecoin identity."))
|
||||||
|
|
||||||
def redrawLabelFrom(self, index):
|
def redrawLabelFrom(self, index):
|
||||||
self.ui.labelFrom.setText(
|
self.ui.labelFrom.setText(
|
||||||
self.ui.comboBoxSendFrom.itemData(index).toPyObject())
|
self.ui.comboBoxSendFrom.itemData(index).toPyObject())
|
||||||
|
@ -2028,6 +2057,18 @@ class MyForm(QtGui.QMainWindow):
|
||||||
self.settingsDialogInstance.ui.lineEditSocksPassword.text()))
|
self.settingsDialogInstance.ui.lineEditSocksPassword.text()))
|
||||||
shared.config.set('bitmessagesettings', 'sockslisten', str(
|
shared.config.set('bitmessagesettings', 'sockslisten', str(
|
||||||
self.settingsDialogInstance.ui.checkBoxSocksListen.isChecked()))
|
self.settingsDialogInstance.ui.checkBoxSocksListen.isChecked()))
|
||||||
|
|
||||||
|
shared.config.set('bitmessagesettings', 'namecoinrpctype',
|
||||||
|
self.settingsDialogInstance.getNamecoinType())
|
||||||
|
shared.config.set('bitmessagesettings', 'namecoinrpchost', str(
|
||||||
|
self.settingsDialogInstance.ui.lineEditNamecoinHost.text()))
|
||||||
|
shared.config.set('bitmessagesettings', 'namecoinrpcport', str(
|
||||||
|
self.settingsDialogInstance.ui.lineEditNamecoinPort.text()))
|
||||||
|
shared.config.set('bitmessagesettings', 'namecoinrpcuser', str(
|
||||||
|
self.settingsDialogInstance.ui.lineEditNamecoinUser.text()))
|
||||||
|
shared.config.set('bitmessagesettings', 'namecoinrpcpassword', str(
|
||||||
|
self.settingsDialogInstance.ui.lineEditNamecoinPassword.text()))
|
||||||
|
|
||||||
if float(self.settingsDialogInstance.ui.lineEditTotalDifficulty.text()) >= 1:
|
if float(self.settingsDialogInstance.ui.lineEditTotalDifficulty.text()) >= 1:
|
||||||
shared.config.set('bitmessagesettings', 'defaultnoncetrialsperbyte', str(int(float(
|
shared.config.set('bitmessagesettings', 'defaultnoncetrialsperbyte', str(int(float(
|
||||||
self.settingsDialogInstance.ui.lineEditTotalDifficulty.text()) * shared.networkDefaultProofOfWorkNonceTrialsPerByte)))
|
self.settingsDialogInstance.ui.lineEditTotalDifficulty.text()) * shared.networkDefaultProofOfWorkNonceTrialsPerByte)))
|
||||||
|
@ -2347,7 +2388,7 @@ class MyForm(QtGui.QMainWindow):
|
||||||
# self.ui.comboBoxSendFrom.setEditText(str(self.ui.tableWidgetInbox.item(currentInboxRow,0).text))
|
# self.ui.comboBoxSendFrom.setEditText(str(self.ui.tableWidgetInbox.item(currentInboxRow,0).text))
|
||||||
self.ui.textEditMessage.setText('\n\n------------------------------------------------------\n' + self.ui.tableWidgetInbox.item(
|
self.ui.textEditMessage.setText('\n\n------------------------------------------------------\n' + self.ui.tableWidgetInbox.item(
|
||||||
currentInboxRow, 2).data(Qt.UserRole).toPyObject())
|
currentInboxRow, 2).data(Qt.UserRole).toPyObject())
|
||||||
if self.ui.tableWidgetInbox.item(currentInboxRow, 2).text()[0:3] == 'Re:':
|
if self.ui.tableWidgetInbox.item(currentInboxRow, 2).text()[0:3] in ['Re:', 'RE:']:
|
||||||
self.ui.lineEditSubject.setText(
|
self.ui.lineEditSubject.setText(
|
||||||
self.ui.tableWidgetInbox.item(currentInboxRow, 2).text())
|
self.ui.tableWidgetInbox.item(currentInboxRow, 2).text())
|
||||||
else:
|
else:
|
||||||
|
@ -3057,6 +3098,35 @@ class settingsDialog(QtGui.QDialog):
|
||||||
self.ui.lineEditMaxAcceptableSmallMessageDifficulty.setText(str((float(shared.config.getint(
|
self.ui.lineEditMaxAcceptableSmallMessageDifficulty.setText(str((float(shared.config.getint(
|
||||||
'bitmessagesettings', 'maxacceptablepayloadlengthextrabytes')) / shared.networkDefaultPayloadLengthExtraBytes)))
|
'bitmessagesettings', 'maxacceptablepayloadlengthextrabytes')) / shared.networkDefaultPayloadLengthExtraBytes)))
|
||||||
|
|
||||||
|
# Namecoin integration tab
|
||||||
|
nmctype = shared.config.get('bitmessagesettings', 'namecoinrpctype')
|
||||||
|
self.ui.lineEditNamecoinHost.setText(str(
|
||||||
|
shared.config.get('bitmessagesettings', 'namecoinrpchost')))
|
||||||
|
self.ui.lineEditNamecoinPort.setText(str(
|
||||||
|
shared.config.get('bitmessagesettings', 'namecoinrpcport')))
|
||||||
|
self.ui.lineEditNamecoinUser.setText(str(
|
||||||
|
shared.config.get('bitmessagesettings', 'namecoinrpcuser')))
|
||||||
|
self.ui.lineEditNamecoinPassword.setText(str(
|
||||||
|
shared.config.get('bitmessagesettings', 'namecoinrpcpassword')))
|
||||||
|
|
||||||
|
if nmctype == "namecoind":
|
||||||
|
self.ui.radioButtonNamecoinNamecoind.setChecked(True)
|
||||||
|
elif nmctype == "nmcontrol":
|
||||||
|
self.ui.radioButtonNamecoinNmcontrol.setChecked(True)
|
||||||
|
self.ui.lineEditNamecoinUser.setEnabled(False)
|
||||||
|
self.ui.labelNamecoinUser.setEnabled(False)
|
||||||
|
self.ui.lineEditNamecoinPassword.setEnabled(False)
|
||||||
|
self.ui.labelNamecoinPassword.setEnabled(False)
|
||||||
|
else:
|
||||||
|
assert False
|
||||||
|
|
||||||
|
QtCore.QObject.connect(self.ui.radioButtonNamecoinNamecoind, QtCore.SIGNAL(
|
||||||
|
"toggled(bool)"), self.namecoinTypeChanged)
|
||||||
|
QtCore.QObject.connect(self.ui.radioButtonNamecoinNmcontrol, QtCore.SIGNAL(
|
||||||
|
"toggled(bool)"), self.namecoinTypeChanged)
|
||||||
|
QtCore.QObject.connect(self.ui.pushButtonNamecoinTest, QtCore.SIGNAL(
|
||||||
|
"clicked()"), self.click_pushButtonNamecoinTest)
|
||||||
|
|
||||||
#'System' tab removed for now.
|
#'System' tab removed for now.
|
||||||
"""try:
|
"""try:
|
||||||
maxCores = shared.config.getint('bitmessagesettings', 'maxcores')
|
maxCores = shared.config.getint('bitmessagesettings', 'maxcores')
|
||||||
|
@ -3096,6 +3166,49 @@ class settingsDialog(QtGui.QDialog):
|
||||||
self.ui.lineEditSocksPassword.setEnabled(True)
|
self.ui.lineEditSocksPassword.setEnabled(True)
|
||||||
self.ui.lineEditTCPPort.setEnabled(False)
|
self.ui.lineEditTCPPort.setEnabled(False)
|
||||||
|
|
||||||
|
# Check status of namecoin integration radio buttons and translate
|
||||||
|
# it to a string as in the options.
|
||||||
|
def getNamecoinType(self):
|
||||||
|
if self.ui.radioButtonNamecoinNamecoind.isChecked():
|
||||||
|
return "namecoind"
|
||||||
|
if self.ui.radioButtonNamecoinNmcontrol.isChecked():
|
||||||
|
return "nmcontrol"
|
||||||
|
assert False
|
||||||
|
|
||||||
|
# Namecoin connection type was changed.
|
||||||
|
def namecoinTypeChanged(self, checked):
|
||||||
|
nmctype = self.getNamecoinType()
|
||||||
|
assert nmctype == "namecoind" or nmctype == "nmcontrol"
|
||||||
|
|
||||||
|
isNamecoind = (nmctype == "namecoind")
|
||||||
|
self.ui.lineEditNamecoinUser.setEnabled(isNamecoind)
|
||||||
|
self.ui.labelNamecoinUser.setEnabled(isNamecoind)
|
||||||
|
self.ui.lineEditNamecoinPassword.setEnabled(isNamecoind)
|
||||||
|
self.ui.labelNamecoinPassword.setEnabled(isNamecoind)
|
||||||
|
|
||||||
|
if isNamecoind:
|
||||||
|
self.ui.lineEditNamecoinPort.setText(shared.namecoinDefaultRpcPort)
|
||||||
|
else:
|
||||||
|
self.ui.lineEditNamecoinPort.setText("9000")
|
||||||
|
|
||||||
|
# Test the namecoin settings specified in the settings dialog.
|
||||||
|
def click_pushButtonNamecoinTest(self):
|
||||||
|
self.ui.labelNamecoinTestResult.setText(_translate(
|
||||||
|
"MainWindow", "Testing..."))
|
||||||
|
options = {}
|
||||||
|
options["type"] = self.getNamecoinType()
|
||||||
|
options["host"] = self.ui.lineEditNamecoinHost.text()
|
||||||
|
options["port"] = self.ui.lineEditNamecoinPort.text()
|
||||||
|
options["user"] = self.ui.lineEditNamecoinUser.text()
|
||||||
|
options["password"] = self.ui.lineEditNamecoinPassword.text()
|
||||||
|
nc = namecoinConnection(options)
|
||||||
|
response = nc.test()
|
||||||
|
responseStatus = response[0]
|
||||||
|
responseText = response[1]
|
||||||
|
self.ui.labelNamecoinTestResult.setText(responseText)
|
||||||
|
if responseStatus== 'success':
|
||||||
|
self.parent.ui.pushButtonFetchNamecoinID.show()
|
||||||
|
|
||||||
|
|
||||||
class SpecialAddressBehaviorDialog(QtGui.QDialog):
|
class SpecialAddressBehaviorDialog(QtGui.QDialog):
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
# Form implementation generated from reading ui file 'bitmessageui.ui'
|
# Form implementation generated from reading ui file 'bitmessageui.ui'
|
||||||
#
|
#
|
||||||
# Created: Fri Aug 9 14:17:50 2013
|
# Created: Mon Aug 12 00:08:20 2013
|
||||||
# by: PyQt4 UI code generator 4.10
|
# by: PyQt4 UI code generator 4.10.2
|
||||||
#
|
#
|
||||||
# WARNING! All changes made in this file will be lost!
|
# WARNING! All changes made in this file will be lost!
|
||||||
|
|
||||||
|
@ -110,7 +110,13 @@ class Ui_MainWindow(object):
|
||||||
font.setPointSize(7)
|
font.setPointSize(7)
|
||||||
self.pushButtonLoadFromAddressBook.setFont(font)
|
self.pushButtonLoadFromAddressBook.setFont(font)
|
||||||
self.pushButtonLoadFromAddressBook.setObjectName(_fromUtf8("pushButtonLoadFromAddressBook"))
|
self.pushButtonLoadFromAddressBook.setObjectName(_fromUtf8("pushButtonLoadFromAddressBook"))
|
||||||
self.gridLayout_2.addWidget(self.pushButtonLoadFromAddressBook, 3, 2, 1, 2)
|
self.gridLayout_2.addWidget(self.pushButtonLoadFromAddressBook, 3, 2, 1, 1)
|
||||||
|
self.pushButtonFetchNamecoinID = QtGui.QPushButton(self.send)
|
||||||
|
font = QtGui.QFont()
|
||||||
|
font.setPointSize(7)
|
||||||
|
self.pushButtonFetchNamecoinID.setFont(font)
|
||||||
|
self.pushButtonFetchNamecoinID.setObjectName(_fromUtf8("pushButtonFetchNamecoinID"))
|
||||||
|
self.gridLayout_2.addWidget(self.pushButtonFetchNamecoinID, 3, 3, 1, 1)
|
||||||
self.label_4 = QtGui.QLabel(self.send)
|
self.label_4 = QtGui.QLabel(self.send)
|
||||||
self.label_4.setObjectName(_fromUtf8("label_4"))
|
self.label_4.setObjectName(_fromUtf8("label_4"))
|
||||||
self.gridLayout_2.addWidget(self.label_4, 5, 0, 1, 1)
|
self.gridLayout_2.addWidget(self.label_4, 5, 0, 1, 1)
|
||||||
|
@ -422,7 +428,7 @@ class Ui_MainWindow(object):
|
||||||
self.gridLayout.addWidget(self.tabWidget, 0, 0, 1, 1)
|
self.gridLayout.addWidget(self.tabWidget, 0, 0, 1, 1)
|
||||||
MainWindow.setCentralWidget(self.centralwidget)
|
MainWindow.setCentralWidget(self.centralwidget)
|
||||||
self.menubar = QtGui.QMenuBar(MainWindow)
|
self.menubar = QtGui.QMenuBar(MainWindow)
|
||||||
self.menubar.setGeometry(QtCore.QRect(0, 0, 795, 27))
|
self.menubar.setGeometry(QtCore.QRect(0, 0, 795, 18))
|
||||||
self.menubar.setObjectName(_fromUtf8("menubar"))
|
self.menubar.setObjectName(_fromUtf8("menubar"))
|
||||||
self.menuFile = QtGui.QMenu(self.menubar)
|
self.menuFile = QtGui.QMenu(self.menubar)
|
||||||
self.menuFile.setObjectName(_fromUtf8("menuFile"))
|
self.menuFile.setObjectName(_fromUtf8("menuFile"))
|
||||||
|
@ -533,14 +539,15 @@ class Ui_MainWindow(object):
|
||||||
item.setText(_translate("MainWindow", "Received", None))
|
item.setText(_translate("MainWindow", "Received", None))
|
||||||
self.tabWidget.setTabText(self.tabWidget.indexOf(self.inbox), _translate("MainWindow", "Inbox", None))
|
self.tabWidget.setTabText(self.tabWidget.indexOf(self.inbox), _translate("MainWindow", "Inbox", None))
|
||||||
self.pushButtonLoadFromAddressBook.setText(_translate("MainWindow", "Load from Address book", None))
|
self.pushButtonLoadFromAddressBook.setText(_translate("MainWindow", "Load from Address book", None))
|
||||||
|
self.pushButtonFetchNamecoinID.setText(_translate("MainWindow", "Fetch Namecoin ID", None))
|
||||||
self.label_4.setText(_translate("MainWindow", "Message:", None))
|
self.label_4.setText(_translate("MainWindow", "Message:", None))
|
||||||
self.label_3.setText(_translate("MainWindow", "Subject:", None))
|
self.label_3.setText(_translate("MainWindow", "Subject:", None))
|
||||||
self.radioButtonSpecific.setText(_translate("MainWindow", "Send to one or more specific people", None))
|
self.radioButtonSpecific.setText(_translate("MainWindow", "Send to one or more specific people", None))
|
||||||
self.textEditMessage.setHtml(_translate("MainWindow", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
|
self.textEditMessage.setHtml(_translate("MainWindow", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
|
||||||
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
|
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
|
||||||
"p, li { white-space: pre-wrap; }\n"
|
"p, li { white-space: pre-wrap; }\n"
|
||||||
"</style></head><body style=\" font-family:\'Droid Sans\'; font-size:9pt; font-weight:400; font-style:normal;\">\n"
|
"</style></head><body style=\" font-family:\'MS Shell Dlg 2\'; font-size:9pt; font-weight:400; font-style:normal;\">\n"
|
||||||
"<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:\'MS Shell Dlg 2\';\"><br /></p></body></html>", None))
|
"<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;\"><br /></p></body></html>", None))
|
||||||
self.label.setText(_translate("MainWindow", "To:", None))
|
self.label.setText(_translate("MainWindow", "To:", None))
|
||||||
self.label_2.setText(_translate("MainWindow", "From:", None))
|
self.label_2.setText(_translate("MainWindow", "From:", None))
|
||||||
self.radioButtonBroadcast.setText(_translate("MainWindow", "Broadcast to everyone who is subscribed to your address", None))
|
self.radioButtonBroadcast.setText(_translate("MainWindow", "Broadcast to everyone who is subscribed to your address", None))
|
||||||
|
|
|
@ -195,7 +195,7 @@
|
||||||
<string>Send</string>
|
<string>Send</string>
|
||||||
</attribute>
|
</attribute>
|
||||||
<layout class="QGridLayout" name="gridLayout_2">
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
<item row="3" column="2" colspan="2">
|
<item row="3" column="2">
|
||||||
<widget class="QPushButton" name="pushButtonLoadFromAddressBook">
|
<widget class="QPushButton" name="pushButtonLoadFromAddressBook">
|
||||||
<property name="font">
|
<property name="font">
|
||||||
<font>
|
<font>
|
||||||
|
@ -207,6 +207,18 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="3" column="3">
|
||||||
|
<widget class="QPushButton" name="pushButtonFetchNamecoinID">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>7</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Fetch Namecoin ID</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item row="5" column="0">
|
<item row="5" column="0">
|
||||||
<widget class="QLabel" name="label_4">
|
<widget class="QLabel" name="label_4">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
|
@ -257,8 +269,8 @@
|
||||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
<string><!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">
|
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||||
p, li { white-space: pre-wrap; }
|
p, li { white-space: pre-wrap; }
|
||||||
</style></head><body style=" font-family:'Droid Sans'; font-size:9pt; font-weight:400; font-style:normal;">
|
</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;">
|
||||||
<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:'MS Shell Dlg 2';"><br /></p></body></html></string>
|
<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;"><br /></p></body></html></string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -1011,7 +1023,7 @@ p, li { white-space: pre-wrap; }
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>795</width>
|
<width>795</width>
|
||||||
<height>27</height>
|
<height>18</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QMenu" name="menuFile">
|
<widget class="QMenu" name="menuFile">
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
# Form implementation generated from reading ui file 'settings.ui'
|
# Form implementation generated from reading ui file 'settings.ui'
|
||||||
#
|
#
|
||||||
# Created: Wed Aug 7 16:58:45 2013
|
# Created: Wed Aug 14 18:31:34 2013
|
||||||
# by: PyQt4 UI code generator 4.10
|
# by: PyQt4 UI code generator 4.10
|
||||||
#
|
#
|
||||||
# WARNING! All changes made in this file will be lost!
|
# WARNING! All changes made in this file will be lost!
|
||||||
|
@ -26,7 +26,7 @@ except AttributeError:
|
||||||
class Ui_settingsDialog(object):
|
class Ui_settingsDialog(object):
|
||||||
def setupUi(self, settingsDialog):
|
def setupUi(self, settingsDialog):
|
||||||
settingsDialog.setObjectName(_fromUtf8("settingsDialog"))
|
settingsDialog.setObjectName(_fromUtf8("settingsDialog"))
|
||||||
settingsDialog.resize(462, 343)
|
settingsDialog.resize(567, 343)
|
||||||
self.gridLayout = QtGui.QGridLayout(settingsDialog)
|
self.gridLayout = QtGui.QGridLayout(settingsDialog)
|
||||||
self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
|
self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
|
||||||
self.buttonBox = QtGui.QDialogButtonBox(settingsDialog)
|
self.buttonBox = QtGui.QDialogButtonBox(settingsDialog)
|
||||||
|
@ -230,6 +230,75 @@ class Ui_settingsDialog(object):
|
||||||
spacerItem7 = QtGui.QSpacerItem(20, 147, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
|
spacerItem7 = QtGui.QSpacerItem(20, 147, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
|
||||||
self.gridLayout_7.addItem(spacerItem7, 3, 1, 1, 1)
|
self.gridLayout_7.addItem(spacerItem7, 3, 1, 1, 1)
|
||||||
self.tabWidgetSettings.addTab(self.tab_2, _fromUtf8(""))
|
self.tabWidgetSettings.addTab(self.tab_2, _fromUtf8(""))
|
||||||
|
self.tabNamecoin = QtGui.QWidget()
|
||||||
|
self.tabNamecoin.setObjectName(_fromUtf8("tabNamecoin"))
|
||||||
|
self.gridLayout_8 = QtGui.QGridLayout(self.tabNamecoin)
|
||||||
|
self.gridLayout_8.setObjectName(_fromUtf8("gridLayout_8"))
|
||||||
|
spacerItem8 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
|
||||||
|
self.gridLayout_8.addItem(spacerItem8, 2, 0, 1, 1)
|
||||||
|
self.label_16 = QtGui.QLabel(self.tabNamecoin)
|
||||||
|
self.label_16.setWordWrap(True)
|
||||||
|
self.label_16.setObjectName(_fromUtf8("label_16"))
|
||||||
|
self.gridLayout_8.addWidget(self.label_16, 0, 0, 1, 3)
|
||||||
|
self.label_17 = QtGui.QLabel(self.tabNamecoin)
|
||||||
|
self.label_17.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||||
|
self.label_17.setObjectName(_fromUtf8("label_17"))
|
||||||
|
self.gridLayout_8.addWidget(self.label_17, 2, 1, 1, 1)
|
||||||
|
self.lineEditNamecoinHost = QtGui.QLineEdit(self.tabNamecoin)
|
||||||
|
self.lineEditNamecoinHost.setObjectName(_fromUtf8("lineEditNamecoinHost"))
|
||||||
|
self.gridLayout_8.addWidget(self.lineEditNamecoinHost, 2, 2, 1, 1)
|
||||||
|
spacerItem9 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
|
||||||
|
self.gridLayout_8.addItem(spacerItem9, 3, 0, 1, 1)
|
||||||
|
spacerItem10 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
|
||||||
|
self.gridLayout_8.addItem(spacerItem10, 4, 0, 1, 1)
|
||||||
|
self.label_18 = QtGui.QLabel(self.tabNamecoin)
|
||||||
|
self.label_18.setEnabled(True)
|
||||||
|
self.label_18.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||||
|
self.label_18.setObjectName(_fromUtf8("label_18"))
|
||||||
|
self.gridLayout_8.addWidget(self.label_18, 3, 1, 1, 1)
|
||||||
|
self.lineEditNamecoinPort = QtGui.QLineEdit(self.tabNamecoin)
|
||||||
|
self.lineEditNamecoinPort.setObjectName(_fromUtf8("lineEditNamecoinPort"))
|
||||||
|
self.gridLayout_8.addWidget(self.lineEditNamecoinPort, 3, 2, 1, 1)
|
||||||
|
spacerItem11 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
|
||||||
|
self.gridLayout_8.addItem(spacerItem11, 8, 1, 1, 1)
|
||||||
|
self.labelNamecoinUser = QtGui.QLabel(self.tabNamecoin)
|
||||||
|
self.labelNamecoinUser.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||||
|
self.labelNamecoinUser.setObjectName(_fromUtf8("labelNamecoinUser"))
|
||||||
|
self.gridLayout_8.addWidget(self.labelNamecoinUser, 4, 1, 1, 1)
|
||||||
|
self.lineEditNamecoinUser = QtGui.QLineEdit(self.tabNamecoin)
|
||||||
|
self.lineEditNamecoinUser.setObjectName(_fromUtf8("lineEditNamecoinUser"))
|
||||||
|
self.gridLayout_8.addWidget(self.lineEditNamecoinUser, 4, 2, 1, 1)
|
||||||
|
spacerItem12 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
|
||||||
|
self.gridLayout_8.addItem(spacerItem12, 5, 0, 1, 1)
|
||||||
|
self.labelNamecoinPassword = QtGui.QLabel(self.tabNamecoin)
|
||||||
|
self.labelNamecoinPassword.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||||
|
self.labelNamecoinPassword.setObjectName(_fromUtf8("labelNamecoinPassword"))
|
||||||
|
self.gridLayout_8.addWidget(self.labelNamecoinPassword, 5, 1, 1, 1)
|
||||||
|
self.lineEditNamecoinPassword = QtGui.QLineEdit(self.tabNamecoin)
|
||||||
|
self.lineEditNamecoinPassword.setInputMethodHints(QtCore.Qt.ImhHiddenText|QtCore.Qt.ImhNoAutoUppercase|QtCore.Qt.ImhNoPredictiveText)
|
||||||
|
self.lineEditNamecoinPassword.setEchoMode(QtGui.QLineEdit.Password)
|
||||||
|
self.lineEditNamecoinPassword.setObjectName(_fromUtf8("lineEditNamecoinPassword"))
|
||||||
|
self.gridLayout_8.addWidget(self.lineEditNamecoinPassword, 5, 2, 1, 1)
|
||||||
|
self.labelNamecoinTestResult = QtGui.QLabel(self.tabNamecoin)
|
||||||
|
self.labelNamecoinTestResult.setText(_fromUtf8(""))
|
||||||
|
self.labelNamecoinTestResult.setObjectName(_fromUtf8("labelNamecoinTestResult"))
|
||||||
|
self.gridLayout_8.addWidget(self.labelNamecoinTestResult, 7, 0, 1, 2)
|
||||||
|
self.pushButtonNamecoinTest = QtGui.QPushButton(self.tabNamecoin)
|
||||||
|
self.pushButtonNamecoinTest.setObjectName(_fromUtf8("pushButtonNamecoinTest"))
|
||||||
|
self.gridLayout_8.addWidget(self.pushButtonNamecoinTest, 7, 2, 1, 1)
|
||||||
|
self.horizontalLayout = QtGui.QHBoxLayout()
|
||||||
|
self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout"))
|
||||||
|
self.label_21 = QtGui.QLabel(self.tabNamecoin)
|
||||||
|
self.label_21.setObjectName(_fromUtf8("label_21"))
|
||||||
|
self.horizontalLayout.addWidget(self.label_21)
|
||||||
|
self.radioButtonNamecoinNamecoind = QtGui.QRadioButton(self.tabNamecoin)
|
||||||
|
self.radioButtonNamecoinNamecoind.setObjectName(_fromUtf8("radioButtonNamecoinNamecoind"))
|
||||||
|
self.horizontalLayout.addWidget(self.radioButtonNamecoinNamecoind)
|
||||||
|
self.radioButtonNamecoinNmcontrol = QtGui.QRadioButton(self.tabNamecoin)
|
||||||
|
self.radioButtonNamecoinNmcontrol.setObjectName(_fromUtf8("radioButtonNamecoinNmcontrol"))
|
||||||
|
self.horizontalLayout.addWidget(self.radioButtonNamecoinNmcontrol)
|
||||||
|
self.gridLayout_8.addLayout(self.horizontalLayout, 1, 0, 1, 3)
|
||||||
|
self.tabWidgetSettings.addTab(self.tabNamecoin, _fromUtf8(""))
|
||||||
self.gridLayout.addWidget(self.tabWidgetSettings, 0, 0, 1, 1)
|
self.gridLayout.addWidget(self.tabWidgetSettings, 0, 0, 1, 1)
|
||||||
|
|
||||||
self.retranslateUi(settingsDialog)
|
self.retranslateUi(settingsDialog)
|
||||||
|
@ -287,4 +356,14 @@ class Ui_settingsDialog(object):
|
||||||
self.label_13.setText(_translate("settingsDialog", "Maximum acceptable total difficulty:", None))
|
self.label_13.setText(_translate("settingsDialog", "Maximum acceptable total difficulty:", None))
|
||||||
self.label_14.setText(_translate("settingsDialog", "Maximum acceptable small message difficulty:", None))
|
self.label_14.setText(_translate("settingsDialog", "Maximum acceptable small message difficulty:", None))
|
||||||
self.tabWidgetSettings.setTabText(self.tabWidgetSettings.indexOf(self.tab_2), _translate("settingsDialog", "Max acceptable difficulty", None))
|
self.tabWidgetSettings.setTabText(self.tabWidgetSettings.indexOf(self.tab_2), _translate("settingsDialog", "Max acceptable difficulty", None))
|
||||||
|
self.label_16.setText(_translate("settingsDialog", "<html><head/><body><p>Bitmessage can utilize a different Bitcoin-based program called Namecoin to make addresses human-friendly. For example, instead of having to tell your friend your long Bitmessage address, you can simply tell him to send a message to <span style=\" font-style:italic;\">test. </span></p><p>(Getting your own Bitmessage address into Namecoin is still rather difficult).</p><p>Bitmessage can use either namecoind directly or a running nmcontrol instance.</p></body></html>", None))
|
||||||
|
self.label_17.setText(_translate("settingsDialog", "Host:", None))
|
||||||
|
self.label_18.setText(_translate("settingsDialog", "Port:", None))
|
||||||
|
self.labelNamecoinUser.setText(_translate("settingsDialog", "Username:", None))
|
||||||
|
self.labelNamecoinPassword.setText(_translate("settingsDialog", "Password:", None))
|
||||||
|
self.pushButtonNamecoinTest.setText(_translate("settingsDialog", "Test", None))
|
||||||
|
self.label_21.setText(_translate("settingsDialog", "Connect to:", None))
|
||||||
|
self.radioButtonNamecoinNamecoind.setText(_translate("settingsDialog", "Namecoind", None))
|
||||||
|
self.radioButtonNamecoinNmcontrol.setText(_translate("settingsDialog", "NMControl", None))
|
||||||
|
self.tabWidgetSettings.setTabText(self.tabWidgetSettings.indexOf(self.tabNamecoin), _translate("settingsDialog", "Namecoin integration", None))
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>462</width>
|
<width>567</width>
|
||||||
<height>343</height>
|
<height>343</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
|
@ -505,6 +505,189 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
<widget class="QWidget" name="tabNamecoin">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Namecoin integration</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_8">
|
||||||
|
<item row="2" column="0">
|
||||||
|
<spacer name="horizontalSpacer_6">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0" colspan="3">
|
||||||
|
<widget class="QLabel" name="label_16">
|
||||||
|
<property name="text">
|
||||||
|
<string><html><head/><body><p>Bitmessage can utilize a different Bitcoin-based program called Namecoin to make addresses human-friendly. For example, instead of having to tell your friend your long Bitmessage address, you can simply tell him to send a message to <span style=" font-style:italic;">test. </span></p><p>(Getting your own Bitmessage address into Namecoin is still rather difficult).</p><p>Bitmessage can use either namecoind directly or a running nmcontrol instance.</p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QLabel" name="label_17">
|
||||||
|
<property name="text">
|
||||||
|
<string>Host:</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="2">
|
||||||
|
<widget class="QLineEdit" name="lineEditNamecoinHost"/>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<spacer name="horizontalSpacer_7">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="0">
|
||||||
|
<spacer name="horizontalSpacer_8">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QLabel" name="label_18">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Port:</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="2">
|
||||||
|
<widget class="QLineEdit" name="lineEditNamecoinPort"/>
|
||||||
|
</item>
|
||||||
|
<item row="8" column="1">
|
||||||
|
<spacer name="verticalSpacer_4">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="1">
|
||||||
|
<widget class="QLabel" name="labelNamecoinUser">
|
||||||
|
<property name="text">
|
||||||
|
<string>Username:</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="2">
|
||||||
|
<widget class="QLineEdit" name="lineEditNamecoinUser"/>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="0">
|
||||||
|
<spacer name="horizontalSpacer_9">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="1">
|
||||||
|
<widget class="QLabel" name="labelNamecoinPassword">
|
||||||
|
<property name="text">
|
||||||
|
<string>Password:</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="2">
|
||||||
|
<widget class="QLineEdit" name="lineEditNamecoinPassword">
|
||||||
|
<property name="inputMethodHints">
|
||||||
|
<set>Qt::ImhHiddenText|Qt::ImhNoAutoUppercase|Qt::ImhNoPredictiveText</set>
|
||||||
|
</property>
|
||||||
|
<property name="echoMode">
|
||||||
|
<enum>QLineEdit::Password</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="7" column="0" colspan="2">
|
||||||
|
<widget class="QLabel" name="labelNamecoinTestResult">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="7" column="2">
|
||||||
|
<widget class="QPushButton" name="pushButtonNamecoinTest">
|
||||||
|
<property name="text">
|
||||||
|
<string>Test</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0" colspan="3">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_21">
|
||||||
|
<property name="text">
|
||||||
|
<string>Connect to:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="radioButtonNamecoinNamecoind">
|
||||||
|
<property name="text">
|
||||||
|
<string>Namecoind</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="radioButtonNamecoinNmcontrol">
|
||||||
|
<property name="text">
|
||||||
|
<string>NMControl</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
|
|
@ -6,6 +6,7 @@ import shutil # used for moving the messages.dat file
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
from debug import logger
|
from debug import logger
|
||||||
|
from namecoin import ensureNamecoinOptions
|
||||||
|
|
||||||
# This thread exists because SQLITE3 is so un-threadsafe that we must
|
# This thread exists because SQLITE3 is so un-threadsafe that we must
|
||||||
# submit queries to it and it puts results back in a different queue. They
|
# submit queries to it and it puts results back in a different queue. They
|
||||||
|
@ -190,6 +191,8 @@ class sqlThread(threading.Thread):
|
||||||
if not shared.config.has_option('bitmessagesettings', 'sockslisten'):
|
if not shared.config.has_option('bitmessagesettings', 'sockslisten'):
|
||||||
shared.config.set('bitmessagesettings', 'sockslisten', 'false')
|
shared.config.set('bitmessagesettings', 'sockslisten', 'false')
|
||||||
|
|
||||||
|
ensureNamecoinOptions()
|
||||||
|
|
||||||
# Add a new column to the inventory table to store the first 20 bytes of encrypted messages to support Android app
|
# Add a new column to the inventory table to store the first 20 bytes of encrypted messages to support Android app
|
||||||
item = '''SELECT value FROM settings WHERE key='version';'''
|
item = '''SELECT value FROM settings WHERE key='version';'''
|
||||||
parameters = ''
|
parameters = ''
|
||||||
|
|
|
@ -3,6 +3,8 @@ import ConfigParser
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
from namecoin import ensureNamecoinOptions
|
||||||
|
|
||||||
storeConfigFilesInSameDirectoryAsProgramByDefault = False # The user may de-select Portable Mode in the settings if they want the config files to stay in the application data folder.
|
storeConfigFilesInSameDirectoryAsProgramByDefault = False # The user may de-select Portable Mode in the settings if they want the config files to stay in the application data folder.
|
||||||
|
|
||||||
def loadConfig():
|
def loadConfig():
|
||||||
|
@ -67,6 +69,7 @@ def loadConfig():
|
||||||
shared.config.set(
|
shared.config.set(
|
||||||
'bitmessagesettings', 'maxacceptablepayloadlengthextrabytes', '0')
|
'bitmessagesettings', 'maxacceptablepayloadlengthextrabytes', '0')
|
||||||
shared.config.set('bitmessagesettings', 'dontconnect', 'true')
|
shared.config.set('bitmessagesettings', 'dontconnect', 'true')
|
||||||
|
ensureNamecoinOptions()
|
||||||
|
|
||||||
if storeConfigFilesInSameDirectoryAsProgramByDefault:
|
if storeConfigFilesInSameDirectoryAsProgramByDefault:
|
||||||
# Just use the same directory as the program and forget about
|
# Just use the same directory as the program and forget about
|
||||||
|
|
283
src/namecoin.py
Normal file
283
src/namecoin.py
Normal file
|
@ -0,0 +1,283 @@
|
||||||
|
# Copyright (C) 2013 by Daniel Kraft <d@domob.eu>
|
||||||
|
# This file is part of the Bitmessage project.
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in all
|
||||||
|
# copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
# SOFTWARE.
|
||||||
|
|
||||||
|
import base64
|
||||||
|
import json
|
||||||
|
import socket
|
||||||
|
import sys
|
||||||
|
|
||||||
|
import shared
|
||||||
|
import tr # translate
|
||||||
|
|
||||||
|
configSection = "bitmessagesettings"
|
||||||
|
|
||||||
|
# Error thrown when the RPC call returns an error.
|
||||||
|
class RPCError (Exception):
|
||||||
|
error = None
|
||||||
|
|
||||||
|
def __init__ (self, data):
|
||||||
|
self.error = data
|
||||||
|
|
||||||
|
# This class handles the Namecoin identity integration.
|
||||||
|
class namecoinConnection (object):
|
||||||
|
user = None
|
||||||
|
password = None
|
||||||
|
host = None
|
||||||
|
port = None
|
||||||
|
nmctype = None
|
||||||
|
bufsize = 4096
|
||||||
|
queryid = 1
|
||||||
|
|
||||||
|
# Initialise. If options are given, take the connection settings from
|
||||||
|
# them instead of loading from the configs. This can be used to test
|
||||||
|
# currently entered connection settings in the config dialog without
|
||||||
|
# actually changing the values (yet).
|
||||||
|
def __init__ (self, options = None):
|
||||||
|
if options is None:
|
||||||
|
self.nmctype = shared.config.get (configSection, "namecoinrpctype")
|
||||||
|
self.host = shared.config.get (configSection, "namecoinrpchost")
|
||||||
|
self.port = shared.config.get (configSection, "namecoinrpcport")
|
||||||
|
self.user = shared.config.get (configSection, "namecoinrpcuser")
|
||||||
|
self.password = shared.config.get (configSection,
|
||||||
|
"namecoinrpcpassword")
|
||||||
|
else:
|
||||||
|
self.nmctype = options["type"]
|
||||||
|
self.host = options["host"]
|
||||||
|
self.port = options["port"]
|
||||||
|
self.user = options["user"]
|
||||||
|
self.password = options["password"]
|
||||||
|
|
||||||
|
assert self.nmctype == "namecoind" or self.nmctype == "nmcontrol"
|
||||||
|
|
||||||
|
# Query for the bitmessage address corresponding to the given identity
|
||||||
|
# string. If it doesn't contain a slash, id/ is prepended. We return
|
||||||
|
# the result as (Error, Address) pair, where the Error is an error
|
||||||
|
# message to display or None in case of success.
|
||||||
|
def query (self, string):
|
||||||
|
slashPos = string.find ("/")
|
||||||
|
if slashPos < 0:
|
||||||
|
string = "id/" + string
|
||||||
|
|
||||||
|
try:
|
||||||
|
if self.nmctype == "namecoind":
|
||||||
|
res = self.callRPC ("name_show", [string])
|
||||||
|
res = res["value"]
|
||||||
|
elif self.nmctype == "nmcontrol":
|
||||||
|
res = self.callRPC ("data", ["getValue", string])
|
||||||
|
res = res["reply"]
|
||||||
|
if res == False:
|
||||||
|
raise RPCError ({"code": -4})
|
||||||
|
else:
|
||||||
|
assert False
|
||||||
|
except RPCError as exc:
|
||||||
|
if exc.error["code"] == -4:
|
||||||
|
return (tr.translateText("MainWindow",'The name %1 was not found.').arg(unicode(string)), None)
|
||||||
|
else:
|
||||||
|
return (tr.translateText("MainWindow",'The namecoin query failed (%1)').arg(unicode(exc.error["message"])), None)
|
||||||
|
except Exception as exc:
|
||||||
|
print "Namecoin query exception: %s" % str (exc)
|
||||||
|
return (tr.translateText("MainWindow",'The namecoin query failed.'), None)
|
||||||
|
|
||||||
|
try:
|
||||||
|
val = json.loads (res)
|
||||||
|
except:
|
||||||
|
return (tr.translateText("MainWindow",'The name %1 has no valid JSON data.').arg(unicode(string)), None)
|
||||||
|
|
||||||
|
if "bitmessage" in val:
|
||||||
|
return (None, val["bitmessage"])
|
||||||
|
return (tr.translateText("MainWindow",'The name %1 has no associated Bitmessage address.').arg(unicode(string)), None)
|
||||||
|
|
||||||
|
# Test the connection settings. This routine tries to query a "getinfo"
|
||||||
|
# command, and builds either an error message or a success message with
|
||||||
|
# some info from it.
|
||||||
|
def test (self):
|
||||||
|
try:
|
||||||
|
if self.nmctype == "namecoind":
|
||||||
|
res = self.callRPC ("getinfo", [])
|
||||||
|
vers = res["version"]
|
||||||
|
|
||||||
|
v3 = vers % 100
|
||||||
|
vers = vers / 100
|
||||||
|
v2 = vers % 100
|
||||||
|
vers = vers / 100
|
||||||
|
v1 = vers
|
||||||
|
if v3 == 0:
|
||||||
|
versStr = "0.%d.%d" % (v1, v2)
|
||||||
|
else:
|
||||||
|
versStr = "0.%d.%d.%d" % (v1, v2, v3)
|
||||||
|
return ('success', tr.translateText("MainWindow",'Success! Namecoind version %1 running.').arg(unicode(versStr)) )
|
||||||
|
|
||||||
|
elif self.nmctype == "nmcontrol":
|
||||||
|
res = self.callRPC ("data", ["status"])
|
||||||
|
prefix = "Plugin data running"
|
||||||
|
if ("reply" in res) and res["reply"][:len(prefix)] == prefix:
|
||||||
|
return ('success', tr.translateText("MainWindow",'Success! NMControll is up and running.'))
|
||||||
|
|
||||||
|
print "Unexpected nmcontrol reply: %s" % res
|
||||||
|
return ('failed', tr.translateText("MainWindow",'Couldn\'t understand NMControl.'))
|
||||||
|
|
||||||
|
else:
|
||||||
|
assert False
|
||||||
|
|
||||||
|
except Exception as exc:
|
||||||
|
print "Exception testing the namecoin connection:\n%s" % str (exc)
|
||||||
|
return ('failed', "The connection to namecoin failed.")
|
||||||
|
|
||||||
|
# Helper routine that actually performs an JSON RPC call.
|
||||||
|
def callRPC (self, method, params):
|
||||||
|
data = {"method": method, "params": params, "id": self.queryid}
|
||||||
|
if self.nmctype == "namecoind":
|
||||||
|
resp = self.queryHTTP (json.dumps (data))
|
||||||
|
elif self.nmctype == "nmcontrol":
|
||||||
|
resp = self.queryServer (json.dumps (data))
|
||||||
|
else:
|
||||||
|
assert False
|
||||||
|
val = json.loads (resp)
|
||||||
|
|
||||||
|
if val["id"] != self.queryid:
|
||||||
|
raise Exception ("ID mismatch in JSON RPC answer.")
|
||||||
|
self.queryid = self.queryid + 1
|
||||||
|
|
||||||
|
if val["error"] is not None:
|
||||||
|
raise RPCError (val["error"])
|
||||||
|
|
||||||
|
return val["result"]
|
||||||
|
|
||||||
|
# Query the server via HTTP.
|
||||||
|
def queryHTTP (self, data):
|
||||||
|
header = "POST / HTTP/1.1\n"
|
||||||
|
header += "User-Agent: bitmessage\n"
|
||||||
|
header += "Host: %s\n" % self.host
|
||||||
|
header += "Content-Type: application/json\n"
|
||||||
|
header += "Content-Length: %d\n" % len (data)
|
||||||
|
header += "Accept: application/json\n"
|
||||||
|
authstr = "%s:%s" % (self.user, self.password)
|
||||||
|
header += "Authorization: Basic %s\n" % base64.b64encode (authstr)
|
||||||
|
|
||||||
|
resp = self.queryServer ("%s\n%s" % (header, data))
|
||||||
|
lines = resp.split ("\r\n")
|
||||||
|
result = None
|
||||||
|
body = False
|
||||||
|
for line in lines:
|
||||||
|
if line == "" and not body:
|
||||||
|
body = True
|
||||||
|
elif body:
|
||||||
|
if result is not None:
|
||||||
|
raise Exception ("Expected a single line in HTTP response.")
|
||||||
|
result = line
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
# Helper routine sending data to the RPC server and returning the result.
|
||||||
|
def queryServer (self, data):
|
||||||
|
try:
|
||||||
|
s = socket.socket (socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
s.setsockopt (socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||||
|
s.settimeout(3)
|
||||||
|
s.connect ((self.host, int (self.port)))
|
||||||
|
s.sendall (data)
|
||||||
|
result = ""
|
||||||
|
|
||||||
|
while True:
|
||||||
|
tmp = s.recv (self.bufsize)
|
||||||
|
if not tmp:
|
||||||
|
break
|
||||||
|
result += tmp
|
||||||
|
|
||||||
|
s.close ()
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
except socket.error as exc:
|
||||||
|
raise Exception ("Socket error in RPC connection: %s" % str (exc))
|
||||||
|
|
||||||
|
# Look up the namecoin data folder.
|
||||||
|
# FIXME: Check whether this works on other platforms as well!
|
||||||
|
def lookupNamecoinFolder ():
|
||||||
|
app = "namecoin"
|
||||||
|
from os import path, environ
|
||||||
|
if sys.platform == "darwin":
|
||||||
|
if "HOME" in environ:
|
||||||
|
dataFolder = path.join (os.environ["HOME"],
|
||||||
|
"Library/Application Support/", app) + '/'
|
||||||
|
else:
|
||||||
|
print ("Could not find home folder, please report this message"
|
||||||
|
+ " and your OS X version to the BitMessage Github.")
|
||||||
|
sys.exit()
|
||||||
|
|
||||||
|
elif "win32" in sys.platform or "win64" in sys.platform:
|
||||||
|
dataFolder = path.join(environ["APPDATA"], app) + "\\"
|
||||||
|
else:
|
||||||
|
dataFolder = path.join(environ["HOME"], ".%s" % app) + "/"
|
||||||
|
|
||||||
|
return dataFolder
|
||||||
|
|
||||||
|
# Ensure all namecoin options are set, by setting those to default values
|
||||||
|
# that aren't there.
|
||||||
|
def ensureNamecoinOptions ():
|
||||||
|
if not shared.config.has_option (configSection, "namecoinrpctype"):
|
||||||
|
shared.config.set (configSection, "namecoinrpctype", "namecoind")
|
||||||
|
if not shared.config.has_option (configSection, "namecoinrpchost"):
|
||||||
|
shared.config.set (configSection, "namecoinrpchost", "localhost")
|
||||||
|
|
||||||
|
hasUser = shared.config.has_option (configSection, "namecoinrpcuser")
|
||||||
|
hasPass = shared.config.has_option (configSection, "namecoinrpcpassword")
|
||||||
|
hasPort = shared.config.has_option (configSection, "namecoinrpcport")
|
||||||
|
|
||||||
|
# Try to read user/password from .namecoin configuration file.
|
||||||
|
defaultUser = ""
|
||||||
|
defaultPass = ""
|
||||||
|
try:
|
||||||
|
nmcFolder = lookupNamecoinFolder ()
|
||||||
|
nmcConfig = nmcFolder + "namecoin.conf"
|
||||||
|
nmc = open (nmcConfig, "r")
|
||||||
|
|
||||||
|
while True:
|
||||||
|
line = nmc.readline ()
|
||||||
|
if line == "":
|
||||||
|
break
|
||||||
|
parts = line.split ("=")
|
||||||
|
if len (parts) == 2:
|
||||||
|
key = parts[0]
|
||||||
|
val = parts[1].rstrip ()
|
||||||
|
|
||||||
|
if key == "rpcuser" and not hasUser:
|
||||||
|
defaultUser = val
|
||||||
|
if key == "rpcpassword" and not hasPass:
|
||||||
|
defaultPass = val
|
||||||
|
if key == "rpcport":
|
||||||
|
shared.namecoinDefaultRpcPort = val
|
||||||
|
|
||||||
|
nmc.close ()
|
||||||
|
|
||||||
|
except Exception as exc:
|
||||||
|
print "Failure reading namecoin config file: %s" % str (exc)
|
||||||
|
|
||||||
|
# If still nothing found, set empty at least.
|
||||||
|
if (not hasUser):
|
||||||
|
shared.config.set (configSection, "namecoinrpcuser", defaultUser)
|
||||||
|
if (not hasPass):
|
||||||
|
shared.config.set (configSection, "namecoinrpcpassword", defaultPass)
|
||||||
|
|
||||||
|
# Set default port now, possibly to found value.
|
||||||
|
if (not hasPort):
|
||||||
|
shared.config.set (configSection, "namecoinrpcport",
|
||||||
|
shared.namecoinDefaultRpcPort)
|
|
@ -69,6 +69,11 @@ ackdataForWhichImWatching = {}
|
||||||
networkDefaultProofOfWorkNonceTrialsPerByte = 320 #The amount of work that should be performed (and demanded) per byte of the payload. Double this number to double the work.
|
networkDefaultProofOfWorkNonceTrialsPerByte = 320 #The amount of work that should be performed (and demanded) per byte of the payload. Double this number to double the work.
|
||||||
networkDefaultPayloadLengthExtraBytes = 14000 #To make sending short messages a little more difficult, this value is added to the payload length for use in calculating the proof of work target.
|
networkDefaultPayloadLengthExtraBytes = 14000 #To make sending short messages a little more difficult, this value is added to the payload length for use in calculating the proof of work target.
|
||||||
|
|
||||||
|
# Remember here the RPC port read from namecoin.conf so we can restore to
|
||||||
|
# it as default whenever the user changes the "method" selection for
|
||||||
|
# namecoin integration to "namecoind".
|
||||||
|
namecoinDefaultRpcPort = "8336"
|
||||||
|
|
||||||
def isInSqlInventory(hash):
|
def isInSqlInventory(hash):
|
||||||
t = (hash,)
|
t = (hash,)
|
||||||
shared.sqlLock.acquire()
|
shared.sqlLock.acquire()
|
||||||
|
@ -355,7 +360,7 @@ def checkSensitiveFilePermissions(filename):
|
||||||
return True
|
return True
|
||||||
except:
|
except:
|
||||||
# Swallow exception here, but we might run into trouble later!
|
# Swallow exception here, but we might run into trouble later!
|
||||||
logger.error('Could not determine filesystem type.', filename)
|
logger.error('Could not determine filesystem type. %s', filename)
|
||||||
present_permissions = os.stat(filename)[0]
|
present_permissions = os.stat(filename)[0]
|
||||||
disallowed_permissions = stat.S_IRWXG | stat.S_IRWXO
|
disallowed_permissions = stat.S_IRWXG | stat.S_IRWXO
|
||||||
return present_permissions & disallowed_permissions == 0
|
return present_permissions & disallowed_permissions == 0
|
||||||
|
|
Loading…
Reference in New Issue
Block a user