Merge pull request #409 from Atheros1/domob1812-namecoin-id2

Domob1812 namecoin id2
This commit is contained in:
Jonathan Warren 2013-08-14 16:19:20 -07:00
commit 6ec4d5c73a
9 changed files with 697 additions and 15 deletions

0
src/bitmessagemain.py Normal file → Executable file
View File

View File

@ -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,22 @@ 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.
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()
# 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 +1713,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 +2053,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)))
@ -3057,6 +3094,37 @@ 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
ensureNamecoinOptions()
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 +3164,47 @@ 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)
responseStatus = nc.test()[1]
self.ui.labelNamecoinTestResult.setText(responseStatus)
if nc.test()[0]== 'success':
self.parent.ui.pushButtonFetchNamecoinID.show()
class SpecialAddressBehaviorDialog(QtGui.QDialog): class SpecialAddressBehaviorDialog(QtGui.QDialog):

View File

@ -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))

View File

@ -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>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt; <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt; &lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; } p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Droid Sans'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt; &lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot;-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';&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> &lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</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">

View File

@ -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))

View File

@ -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>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;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 &lt;span style=&quot; font-style:italic;&quot;&gt;test. &lt;/span&gt;&lt;/p&gt;&lt;p&gt;(Getting your own Bitmessage address into Namecoin is still rather difficult).&lt;/p&gt;&lt;p&gt;Bitmessage can use either namecoind directly or a running nmcontrol instance.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</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>

View File

@ -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

284
src/namecoin.py Normal file
View File

@ -0,0 +1,284 @@
# 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:
ensureNamecoinOptions ()
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)

View File

@ -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()