diff --git a/Makefile b/Makefile index adda5583..72a86ba2 100644 --- a/Makefile +++ b/Makefile @@ -29,7 +29,11 @@ install: install -m 644 desktop/icon24.png ${DESTDIR}${PREFIX}/share/icons/hicolor/24x24/apps/${APP}.png cp -rf src/* ${DESTDIR}${PREFIX}/share/${APP} echo '#!/bin/sh' > ${DESTDIR}${PREFIX}/bin/${APP} - echo 'cd ${PREFIX}/share/pybitmessage' >> ${DESTDIR}${PREFIX}/bin/${APP} + echo 'if [ -d /usr/local/share/${APP} ]; then' >> ${DESTDIR}${PREFIX}/bin/${APP} + echo ' cd /usr/local/share/${APP}' >> ${DESTDIR}${PREFIX}/bin/${APP} + echo 'else' >> ${DESTDIR}${PREFIX}/bin/${APP} + echo ' cd /usr/share/pybitmessage' >> ${DESTDIR}${PREFIX}/bin/${APP} + echo 'fi' >> ${DESTDIR}${PREFIX}/bin/${APP} echo 'LD_LIBRARY_PATH="/opt/openssl-compat-bitcoin/lib/" exec python2 bitmessagemain.py' >> ${DESTDIR}${PREFIX}/bin/${APP} chmod +x ${DESTDIR}${PREFIX}/bin/${APP} uninstall: @@ -38,10 +42,10 @@ uninstall: rm -f ${PREFIX}/bin/${APP} rm -f ${PREFIX}/share/applications/${APP}.desktop rm -f ${PREFIX}/share/icons/hicolor/scalable/apps/${APP}.svg - ${PREFIX}/share/pixmaps/${APP}.svg + rm -f ${PREFIX}/share/pixmaps/${APP}.svg clean: rm -f ${APP} \#* \.#* gnuplot* *.png debian/*.substvars debian/*.log rm -fr deb.* debian/${APP} rpmpackage/${ARCH_TYPE} rm -f ../${APP}*.deb ../${APP}*.changes ../${APP}*.asc ../${APP}*.dsc rm -f rpmpackage/*.src.rpm archpackage/*.gz archpackage/*.xz - rm -f puppypackage/*.gz puppypackage/*.pet slackpackage/*.txz + rm -f puppypackage/*.gz puppypackage/*.pet slackpackage/*.txz diff --git a/debian.sh b/debian.sh old mode 100644 new mode 100755 diff --git a/debian/control b/debian/control index b2ec3268..5e016a1c 100644 --- a/debian/control +++ b/debian/control @@ -4,7 +4,7 @@ Maintainer: Bob Mottram (4096 bits) Build-Depends: debhelper (>= 9.0.0) Standards-Version: 3.9.4 Homepage: https://github.com/Bitmessage/PyBitmessage -Vcs-Git: https://github.com/fuzzgun/packagemonkey.git +Vcs-Git: https://github.com/Bitmessage/PyBitmessage.git Package: pybitmessage Section: mail diff --git a/debian/rules b/debian/rules old mode 100644 new mode 100755 diff --git a/ebuildpackage/pybitmessage-0.3.4-1.ebuild b/ebuildpackage/pybitmessage-0.3.4-1.ebuild index fba11f74..01eddc4f 100755 --- a/ebuildpackage/pybitmessage-0.3.4-1.ebuild +++ b/ebuildpackage/pybitmessage-0.3.4-1.ebuild @@ -9,7 +9,7 @@ PYTHON_REQ_USE="sqlite" REQUIRED_USE="${PYTHON_REQUIRED_USE}" DESCRIPTION="Bitmessage is a P2P communications protocol used to send encrypted messages to another person or to many subscribers. It is decentralized and trustless, meaning that you need-not inherently trust any entities like root certificate authorities. It uses strong authentication which means that the sender of a message cannot be spoofed, and it aims to hide "non-content" data, like the sender and receiver of messages, from passive eavesdroppers like those running warrantless wiretapping programs." HOMEPAGE="https://github.com/Bitmessage/PyBitmessage" -EGIT_REPO_URI="https://github.com/fuzzgun/packagemonkey.git" +EGIT_REPO_URI="https://github.com/Bitmessage/PyBitmessage.git" LICENSE="MIT" SLOT="0" KEYWORDS="x86" diff --git a/generate.sh b/generate.sh index 7aa46e75..173e3c79 100755 --- a/generate.sh +++ b/generate.sh @@ -4,4 +4,4 @@ rm -f Makefile rpmpackage/*.spec -packagemonkey -n "PyBitmessage" --version "0.3.4" --dir "." -l "mit" -e "Bob Mottram (4096 bits) " --brief "Send encrypted messages" --desc "Bitmessage is a P2P communications protocol used to send encrypted messages to another person or to many subscribers. It is decentralized and trustless, meaning that you need-not inherently trust any entities like root certificate authorities. It uses strong authentication which means that the sender of a message cannot be spoofed, and it aims to hide \"non-content\" data, like the sender and receiver of messages, from passive eavesdroppers like those running warrantless wiretapping programs." --homepage "https://github.com/Bitmessage/PyBitmessage" --section "mail" --categories "Office/Email" --dependsdeb "python (>= 2.7.0), openssl, python-qt4, libqt4-dev (>= 4.8.0), python-qt4-dev, sqlite3, libsqlite3-dev, gst123" --dependsrpm "python, PyQt4, openssl-compat-bitcoin-libs, gst123" --mainscript "bitmessagemain.py" --librarypath "/opt/openssl-compat-bitcoin/lib/" --suggestsdeb "libmessaging-menu-dev" --dependspuppy "openssl, python-qt4, sqlite3, sqlite3-dev, python-openssl, python-sip, gst123" --dependsarch "python2, qt4, python2-pyqt4, sqlite, openssl, gst123" --suggestsarch "python2-gevent" --pythonversion 2 --dependsebuild "dev-libs/openssl, dev-python/PyQt4[${PYTHON_USEDEP}]" --buildebuild "\${PYTHON_DEPS}" --pythonreq "sqlite" +packagemonkey -n "PyBitmessage" --version "0.3.4" --dir "." -l "mit" -e "Bob Mottram (4096 bits) " --brief "Send encrypted messages" --desc "Bitmessage is a P2P communications protocol used to send encrypted messages to another person or to many subscribers. It is decentralized and trustless, meaning that you need-not inherently trust any entities like root certificate authorities. It uses strong authentication which means that the sender of a message cannot be spoofed, and it aims to hide \"non-content\" data, like the sender and receiver of messages, from passive eavesdroppers like those running warrantless wiretapping programs." --homepage "https://github.com/Bitmessage/PyBitmessage" --section "mail" --categories "Office/Email" --dependsdeb "python (>= 2.7.0), openssl, python-qt4, libqt4-dev (>= 4.8.0), python-qt4-dev, sqlite3, libsqlite3-dev, gst123" --dependsrpm "python, PyQt4, openssl-compat-bitcoin-libs, gst123" --mainscript "bitmessagemain.py" --librarypath "/opt/openssl-compat-bitcoin/lib/" --suggestsdeb "libmessaging-menu-dev" --dependspuppy "openssl, python-qt4, sqlite3, sqlite3-dev, python-openssl, python-sip, gst123" --dependsarch "python2, qt4, python2-pyqt4, sqlite, openssl, gst123" --suggestsarch "python2-gevent" --pythonversion 2 --dependsebuild "dev-libs/openssl, dev-python/PyQt4[${PYTHON_USEDEP}]" --buildebuild "\${PYTHON_DEPS}" --pythonreq "sqlite" --repository "https://github.com/Bitmessage/PyBitmessage.git" diff --git a/osx.sh b/osx.sh old mode 100644 new mode 100755 diff --git a/puppypackage/pybitmessage-0.3.4.pet.specs b/puppypackage/pybitmessage-0.3.4.pet.specs index 4bcf119b..aac180a9 100644 --- a/puppypackage/pybitmessage-0.3.4.pet.specs +++ b/puppypackage/pybitmessage-0.3.4.pet.specs @@ -1 +1 @@ -pybitmessage-0.3.4-1|PyBitmessage|0.3.4|1|Internet;mailnews;|3.9M||pybitmessage-0.3.4-1.pet|+openssl,+python-qt4,+sqlite3,+sqlite3-dev,+python-openssl,+python-sip,+gst123|Send encrypted messages|ubuntu|precise|5| +pybitmessage-0.3.4-1|PyBitmessage|0.3.4|1|Internet;mailnews;|5.8M||pybitmessage-0.3.4-1.pet|+openssl,+python-qt4,+sqlite3,+sqlite3-dev,+python-openssl,+python-sip,+gst123|Send encrypted messages|ubuntu|precise|5| diff --git a/src/bitmessagemain.py b/src/bitmessagemain.py index 15acf545..c4c2b6db 100644 --- a/src/bitmessagemain.py +++ b/src/bitmessagemain.py @@ -10,12 +10,6 @@ # The software version variable is now held in shared.py #import ctypes -try: - from gevent import monkey - monkey.patch_all() -except ImportError as ex: - print "Not using the gevent module as it was not found. No need to worry." - import signal # Used to capture a Ctrl-C keypress so that Bitmessage can shutdown gracefully. # The next 3 are used for the API from SimpleXMLRPCServer import * @@ -32,15 +26,9 @@ from class_singleListener import * from class_addressGenerator import * # Helper Functions +import helper_startup 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): selfInitiatedConnections[streamNumber] = {} if sys.platform[0:3] == 'win': @@ -471,9 +459,9 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): status, addressVersionNumber, streamNumber, toRipe = decodeAddress( toAddress) if status != 'success': - with shared.printLock: - print 'API Error 0007: Could not decode address:', toAddress, ':', status - + shared.printLock.acquire() + print 'API Error 0007: Could not decode address:', toAddress, ':', status + shared.printLock.release() if status == 'checksumfailed': return 'API Error 0008: Checksum failed for address: ' + toAddress if status == 'invalidcharacters': @@ -488,9 +476,9 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): status, addressVersionNumber, streamNumber, fromRipe = decodeAddress( fromAddress) if status != 'success': - with shared.printLock: - print 'API Error 0007: Could not decode address:', fromAddress, ':', status - + shared.printLock.acquire() + print 'API Error 0007: Could not decode address:', fromAddress, ':', status + shared.printLock.release() if status == 'checksumfailed': return 'API Error 0008: Checksum failed for address: ' + fromAddress if status == 'invalidcharacters': @@ -553,9 +541,9 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): status, addressVersionNumber, streamNumber, fromRipe = decodeAddress( fromAddress) if status != 'success': - with shared.printLock: - print 'API Error 0007: Could not decode address:', fromAddress, ':', status - + shared.printLock.acquire() + print 'API Error 0007: Could not decode address:', fromAddress, ':', status + shared.printLock.release() if status == 'checksumfailed': return 'API Error 0008: Checksum failed for address: ' + fromAddress if status == 'invalidcharacters': @@ -624,9 +612,9 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): status, addressVersionNumber, streamNumber, toRipe = decodeAddress( address) if status != 'success': - with shared.printLock: - print 'API Error 0007: Could not decode address:', address, ':', status - + shared.printLock.acquire() + print 'API Error 0007: Could not decode address:', address, ':', status + shared.printLock.release() if status == 'checksumfailed': return 'API Error 0008: Checksum failed for address: ' + address if status == 'invalidcharacters': @@ -718,8 +706,11 @@ if __name__ == "__main__": signal.signal(signal.SIGINT, helper_generic.signal_handler) # signal.signal(signal.SIGINT, signal.SIG_DFL) + helper_startup.loadConfig() + helper_bootstrap.knownNodes() helper_bootstrap.dns() + # Start the address generation thread addressGeneratorThread = addressGenerator() addressGeneratorThread.daemon = True # close the main program even if there are threads left @@ -750,9 +741,9 @@ if __name__ == "__main__": except: apiNotifyPath = '' if apiNotifyPath != '': - with shared.printLock: - print 'Trying to call', apiNotifyPath - + shared.printLock.acquire() + print 'Trying to call', apiNotifyPath + shared.printLock.release() call([apiNotifyPath, "startingUp"]) singleAPIThread = singleAPI() singleAPIThread.daemon = True # close the main program even if there are threads left @@ -783,9 +774,9 @@ if __name__ == "__main__": import bitmessageqt bitmessageqt.run() else: - with shared.printLock: - print 'Running as a daemon. You can use Ctrl+C to exit.' - + shared.printLock.acquire() + print 'Running as a daemon. You can use Ctrl+C to exit.' + shared.printLock.release() while True: time.sleep(20) diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index 405ea1f8..2c2c7276 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -17,7 +17,6 @@ from bitmessageui import * from newaddressdialog import * from newsubscriptiondialog import * from regenerateaddresses import * -from newchandialog import * from specialaddressbehavior import * from settings import * from about import * @@ -30,12 +29,7 @@ import os from pyelliptic.openssl import OpenSSL import pickle import platform -<<<<<<< HEAD -import debug -from debug import logger -======= import subprocess ->>>>>>> 2af86c8296e0c577f8ac48a56e9a3582ddd87473 try: from PyQt4 import QtCore, QtGui @@ -67,7 +61,6 @@ class MyForm(QtGui.QMainWindow): SOUND_CONNECTION_GREEN = 5 str_broadcast_subscribers = '[Broadcast subscribers]' - str_chan = '[chan]' def __init__(self, parent=None): QtGui.QWidget.__init__(self, parent) @@ -120,8 +113,6 @@ class MyForm(QtGui.QMainWindow): "triggered()"), self.click_actionDeleteAllTrashedMessages) QtCore.QObject.connect(self.ui.actionRegenerateDeterministicAddresses, QtCore.SIGNAL( "triggered()"), self.click_actionRegenerateDeterministicAddresses) - QtCore.QObject.connect(self.ui.actionJoinChan, QtCore.SIGNAL( - "triggered()"), self.click_actionJoinChan) # also used for creating chans. QtCore.QObject.connect(self.ui.pushButtonNewAddress, QtCore.SIGNAL( "clicked()"), self.click_NewAddressDialog) QtCore.QObject.connect(self.ui.comboBoxSendFrom, QtCore.SIGNAL( @@ -310,8 +301,6 @@ class MyForm(QtGui.QMainWindow): newItem = QtGui.QTableWidgetItem(addressInKeysFile) newItem.setFlags( QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) - if shared.safeConfigGetBoolean(addressInKeysFile, 'chan'): - newItem.setTextColor(QtGui.QColor(216, 119, 0)) # orange if not isEnabled: newItem.setTextColor(QtGui.QColor(128, 128, 128)) if shared.safeConfigGetBoolean(addressInKeysFile, 'mailinglist'): @@ -329,10 +318,205 @@ class MyForm(QtGui.QMainWindow): addressInKeysFile) # Load inbox from messages database file - self.loadInbox() + font = QFont() + font.setBold(True) + shared.sqlLock.acquire() + shared.sqlSubmitQueue.put( + '''SELECT msgid, toaddress, fromaddress, subject, received, message, read FROM inbox where folder='inbox' ORDER BY received''') + shared.sqlSubmitQueue.put('') + queryreturn = shared.sqlReturnQueue.get() + shared.sqlLock.release() + for row in queryreturn: + msgid, toAddress, fromAddress, subject, received, message, read = row + subject = shared.fixPotentiallyInvalidUTF8Data(subject) + message = shared.fixPotentiallyInvalidUTF8Data(message) + try: + if toAddress == self.str_broadcast_subscribers: + toLabel = self.str_broadcast_subscribers + else: + toLabel = shared.config.get(toAddress, 'label') + except: + toLabel = '' + if toLabel == '': + toLabel = toAddress + + fromLabel = '' + t = (fromAddress,) + shared.sqlLock.acquire() + shared.sqlSubmitQueue.put( + '''select label from addressbook where address=?''') + shared.sqlSubmitQueue.put(t) + queryreturn = shared.sqlReturnQueue.get() + shared.sqlLock.release() + + if queryreturn != []: + for row in queryreturn: + fromLabel, = row + + if fromLabel == '': # If this address wasn't in our address book... + t = (fromAddress,) + shared.sqlLock.acquire() + shared.sqlSubmitQueue.put( + '''select label from subscriptions where address=?''') + shared.sqlSubmitQueue.put(t) + queryreturn = shared.sqlReturnQueue.get() + shared.sqlLock.release() + + if queryreturn != []: + for row in queryreturn: + fromLabel, = row + + self.ui.tableWidgetInbox.insertRow(0) + newItem = QtGui.QTableWidgetItem(unicode(toLabel, 'utf-8')) + newItem.setToolTip(unicode(toLabel, 'utf-8')) + newItem.setFlags( + QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) + if not read: + newItem.setFont(font) + newItem.setData(Qt.UserRole, str(toAddress)) + if shared.safeConfigGetBoolean(toAddress, 'mailinglist'): + newItem.setTextColor(QtGui.QColor(137, 04, 177)) + self.ui.tableWidgetInbox.setItem(0, 0, newItem) + if fromLabel == '': + newItem = QtGui.QTableWidgetItem( + unicode(fromAddress, 'utf-8')) + newItem.setToolTip(unicode(fromAddress, 'utf-8')) + else: + newItem = QtGui.QTableWidgetItem(unicode(fromLabel, 'utf-8')) + newItem.setToolTip(unicode(fromLabel, 'utf-8')) + newItem.setFlags( + QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) + if not read: + newItem.setFont(font) + newItem.setData(Qt.UserRole, str(fromAddress)) + + self.ui.tableWidgetInbox.setItem(0, 1, newItem) + newItem = QtGui.QTableWidgetItem(unicode(subject, 'utf-8')) + newItem.setToolTip(unicode(subject, 'utf-8')) + newItem.setData(Qt.UserRole, unicode(message, 'utf-8)')) + newItem.setFlags( + QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) + if not read: + newItem.setFont(font) + self.ui.tableWidgetInbox.setItem(0, 2, newItem) + newItem = myTableWidgetItem(unicode(strftime(shared.config.get( + 'bitmessagesettings', 'timeformat'), localtime(int(received))), 'utf-8')) + newItem.setToolTip(unicode(strftime(shared.config.get( + 'bitmessagesettings', 'timeformat'), localtime(int(received))), 'utf-8')) + newItem.setData(Qt.UserRole, QByteArray(msgid)) + newItem.setData(33, int(received)) + newItem.setFlags( + QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) + if not read: + newItem.setFont(font) + self.ui.tableWidgetInbox.setItem(0, 3, newItem) + self.ui.tableWidgetInbox.sortItems(3, Qt.DescendingOrder) + self.ui.tableWidgetInbox.keyPressEvent = self.tableWidgetInboxKeyPressEvent # Load Sent items from database - self.loadSent() + shared.sqlLock.acquire() + shared.sqlSubmitQueue.put( + '''SELECT toaddress, fromaddress, subject, message, status, ackdata, lastactiontime FROM sent where folder = 'sent' ORDER BY lastactiontime''') + shared.sqlSubmitQueue.put('') + queryreturn = shared.sqlReturnQueue.get() + shared.sqlLock.release() + for row in queryreturn: + toAddress, fromAddress, subject, message, status, ackdata, lastactiontime = row + subject = shared.fixPotentiallyInvalidUTF8Data(subject) + message = shared.fixPotentiallyInvalidUTF8Data(message) + try: + fromLabel = shared.config.get(fromAddress, 'label') + except: + fromLabel = '' + if fromLabel == '': + fromLabel = fromAddress + + toLabel = '' + t = (toAddress,) + shared.sqlLock.acquire() + shared.sqlSubmitQueue.put( + '''select label from addressbook where address=?''') + shared.sqlSubmitQueue.put(t) + queryreturn = shared.sqlReturnQueue.get() + shared.sqlLock.release() + + if queryreturn != []: + for row in queryreturn: + toLabel, = row + + self.ui.tableWidgetSent.insertRow(0) + if toLabel == '': + newItem = QtGui.QTableWidgetItem(unicode(toAddress, 'utf-8')) + newItem.setToolTip(unicode(toAddress, 'utf-8')) + else: + newItem = QtGui.QTableWidgetItem(unicode(toLabel, 'utf-8')) + newItem.setToolTip(unicode(toLabel, 'utf-8')) + newItem.setData(Qt.UserRole, str(toAddress)) + newItem.setFlags( + QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) + self.ui.tableWidgetSent.setItem(0, 0, newItem) + if fromLabel == '': + newItem = QtGui.QTableWidgetItem( + unicode(fromAddress, 'utf-8')) + newItem.setToolTip(unicode(fromAddress, 'utf-8')) + else: + newItem = QtGui.QTableWidgetItem(unicode(fromLabel, 'utf-8')) + newItem.setToolTip(unicode(fromLabel, 'utf-8')) + newItem.setData(Qt.UserRole, str(fromAddress)) + newItem.setFlags( + QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) + self.ui.tableWidgetSent.setItem(0, 1, newItem) + newItem = QtGui.QTableWidgetItem(unicode(subject, 'utf-8')) + newItem.setToolTip(unicode(subject, 'utf-8')) + newItem.setData(Qt.UserRole, unicode(message, 'utf-8)')) + newItem.setFlags( + QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) + self.ui.tableWidgetSent.setItem(0, 2, newItem) + if status == 'awaitingpubkey': + statusText = _translate( + "MainWindow", "Waiting on their encryption key. Will request it again soon.") + elif status == 'doingpowforpubkey': + statusText = _translate( + "MainWindow", "Encryption key request queued.") + elif status == 'msgqueued': + statusText = _translate( + "MainWindow", "Queued.") + elif status == 'msgsent': + statusText = _translate("MainWindow", "Message sent. Waiting on acknowledgement. Sent at %1").arg( + unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(lastactiontime)),'utf-8')) + elif status == 'doingmsgpow': + statusText = _translate( + "MainWindow", "Need to do work to send message. Work is queued.") + elif status == 'ackreceived': + statusText = _translate("MainWindow", "Acknowledgement of the message received %1").arg( + unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(lastactiontime)),'utf-8')) + elif status == 'broadcastqueued': + statusText = _translate( + "MainWindow", "Broadcast queued.") + elif status == 'broadcastsent': + statusText = _translate("MainWindow", "Broadcast on %1").arg(unicode(strftime( + shared.config.get('bitmessagesettings', 'timeformat'), localtime(lastactiontime)),'utf-8')) + elif status == 'toodifficult': + statusText = _translate("MainWindow", "Problem: The work demanded by the recipient is more difficult than you are willing to do. %1").arg( + unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(lastactiontime)),'utf-8')) + elif status == 'badkey': + statusText = _translate("MainWindow", "Problem: The recipient\'s encryption key is no good. Could not encrypt message. %1").arg( + unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(lastactiontime)),'utf-8')) + elif status == 'forcepow': + statusText = _translate( + "MainWindow", "Forced difficulty override. Send should start soon.") + else: + statusText = _translate("MainWindow", "Unknown status: %1 %2").arg(status).arg(unicode( + strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(lastactiontime)),'utf-8')) + newItem = myTableWidgetItem(statusText) + newItem.setToolTip(statusText) + newItem.setData(Qt.UserRole, QByteArray(ackdata)) + newItem.setData(33, int(lastactiontime)) + newItem.setFlags( + QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) + self.ui.tableWidgetSent.setItem(0, 3, newItem) + self.ui.tableWidgetSent.sortItems(3, Qt.DescendingOrder) + self.ui.tableWidgetSent.keyPressEvent = self.tableWidgetSentKeyPressEvent # Initialize the address book shared.sqlLock.acquire() @@ -353,14 +537,6 @@ class MyForm(QtGui.QMainWindow): # Initialize the Subscriptions self.rerenderSubscriptions() - # Initialize the inbox search - QtCore.QObject.connect(self.ui.inboxSearchLineEdit, QtCore.SIGNAL( - "returnPressed()"), self.inboxSearchLineEditPressed) - - # Initialize the sent search - QtCore.QObject.connect(self.ui.sentSearchLineEdit, QtCore.SIGNAL( - "returnPressed()"), self.sentSearchLineEditPressed) - # Initialize the Blacklist or Whitelist if shared.config.get('bitmessagesettings', 'blackwhitelist') == 'black': self.loadBlackWhiteList() @@ -520,256 +696,6 @@ class MyForm(QtGui.QMainWindow): self.appIndicatorShow() self.ui.tabWidget.setCurrentIndex(5) - # Load Sent items from database - def loadSent(self, where="", what=""): - what = "%" + what + "%" - if where == "To": - where = "toaddress" - elif where == "From": - where = "fromaddress" - elif where == "Subject": - where = "subject" - elif where == "Message": - where = "message" - else: - where = "toaddress || fromaddress || subject || message" - - sqlQuery = ''' - SELECT toaddress, fromaddress, subject, message, status, ackdata, lastactiontime - FROM sent WHERE folder="sent" AND %s LIKE ? - ORDER BY lastactiontime - ''' % (where,) - - while self.ui.tableWidgetSent.rowCount() > 0: - self.ui.tableWidgetSent.removeRow(0) - - t = (what,) - shared.sqlLock.acquire() - shared.sqlSubmitQueue.put(sqlQuery) - shared.sqlSubmitQueue.put(t) - queryreturn = shared.sqlReturnQueue.get() - shared.sqlLock.release() - for row in queryreturn: - toAddress, fromAddress, subject, message, status, ackdata, lastactiontime = row - subject = shared.fixPotentiallyInvalidUTF8Data(subject) - message = shared.fixPotentiallyInvalidUTF8Data(message) - try: - fromLabel = shared.config.get(fromAddress, 'label') - except: - fromLabel = '' - if fromLabel == '': - fromLabel = fromAddress - - toLabel = '' - t = (toAddress,) - shared.sqlLock.acquire() - shared.sqlSubmitQueue.put( - '''select label from addressbook where address=?''') - shared.sqlSubmitQueue.put(t) - queryreturn = shared.sqlReturnQueue.get() - shared.sqlLock.release() - - if queryreturn != []: - for row in queryreturn: - toLabel, = row - - self.ui.tableWidgetSent.insertRow(0) - if toLabel == '': - newItem = QtGui.QTableWidgetItem(unicode(toAddress, 'utf-8')) - newItem.setToolTip(unicode(toAddress, 'utf-8')) - else: - newItem = QtGui.QTableWidgetItem(unicode(toLabel, 'utf-8')) - newItem.setToolTip(unicode(toLabel, 'utf-8')) - newItem.setData(Qt.UserRole, str(toAddress)) - newItem.setFlags( - QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) - self.ui.tableWidgetSent.setItem(0, 0, newItem) - if fromLabel == '': - newItem = QtGui.QTableWidgetItem( - unicode(fromAddress, 'utf-8')) - newItem.setToolTip(unicode(fromAddress, 'utf-8')) - else: - newItem = QtGui.QTableWidgetItem(unicode(fromLabel, 'utf-8')) - newItem.setToolTip(unicode(fromLabel, 'utf-8')) - newItem.setData(Qt.UserRole, str(fromAddress)) - newItem.setFlags( - QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) - self.ui.tableWidgetSent.setItem(0, 1, newItem) - newItem = QtGui.QTableWidgetItem(unicode(subject, 'utf-8')) - newItem.setToolTip(unicode(subject, 'utf-8')) - newItem.setData(Qt.UserRole, unicode(message, 'utf-8)')) - newItem.setFlags( - QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) - self.ui.tableWidgetSent.setItem(0, 2, newItem) - if status == 'awaitingpubkey': - statusText = _translate( - "MainWindow", "Waiting on their encryption key. Will request it again soon.") - elif status == 'doingpowforpubkey': - statusText = _translate( - "MainWindow", "Encryption key request queued.") - elif status == 'msgqueued': - statusText = _translate( - "MainWindow", "Queued.") - elif status == 'msgsent': - statusText = _translate("MainWindow", "Message sent. Waiting on acknowledgement. Sent at %1").arg( - unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(lastactiontime)),'utf-8')) - elif status == 'msgsentnoackexpected': - statusText = _translate("MainWindow", "Message sent. Sent at %1").arg( - unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(lastactiontime)),'utf-8')) - elif status == 'doingmsgpow': - statusText = _translate( - "MainWindow", "Need to do work to send message. Work is queued.") - elif status == 'ackreceived': - statusText = _translate("MainWindow", "Acknowledgement of the message received %1").arg( - unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(lastactiontime)),'utf-8')) - elif status == 'broadcastqueued': - statusText = _translate( - "MainWindow", "Broadcast queued.") - elif status == 'broadcastsent': - statusText = _translate("MainWindow", "Broadcast on %1").arg(unicode(strftime( - shared.config.get('bitmessagesettings', 'timeformat'), localtime(lastactiontime)),'utf-8')) - elif status == 'toodifficult': - statusText = _translate("MainWindow", "Problem: The work demanded by the recipient is more difficult than you are willing to do. %1").arg( - unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(lastactiontime)),'utf-8')) - elif status == 'badkey': - statusText = _translate("MainWindow", "Problem: The recipient\'s encryption key is no good. Could not encrypt message. %1").arg( - unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(lastactiontime)),'utf-8')) - elif status == 'forcepow': - statusText = _translate( - "MainWindow", "Forced difficulty override. Send should start soon.") - else: - statusText = _translate("MainWindow", "Unknown status: %1 %2").arg(status).arg(unicode( - strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(lastactiontime)),'utf-8')) - newItem = myTableWidgetItem(statusText) - newItem.setToolTip(statusText) - newItem.setData(Qt.UserRole, QByteArray(ackdata)) - newItem.setData(33, int(lastactiontime)) - newItem.setFlags( - QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) - self.ui.tableWidgetSent.setItem(0, 3, newItem) - self.ui.tableWidgetSent.sortItems(3, Qt.DescendingOrder) - self.ui.tableWidgetSent.keyPressEvent = self.tableWidgetSentKeyPressEvent - - # Load inbox from messages database file - def loadInbox(self, where="", what=""): - what = "%" + what + "%" - if where == "To": - where = "toaddress" - elif where == "From": - where = "fromaddress" - elif where == "Subject": - where = "subject" - elif where == "Message": - where = "message" - else: - where = "toaddress || fromaddress || subject || message" - - sqlQuery = ''' - SELECT msgid, toaddress, fromaddress, subject, received, message, read - FROM inbox WHERE folder="inbox" AND %s LIKE ? - ORDER BY received - ''' % (where,) - - while self.ui.tableWidgetInbox.rowCount() > 0: - self.ui.tableWidgetInbox.removeRow(0) - - font = QFont() - font.setBold(True) - t = (what,) - shared.sqlLock.acquire() - shared.sqlSubmitQueue.put(sqlQuery) - shared.sqlSubmitQueue.put(t) - queryreturn = shared.sqlReturnQueue.get() - shared.sqlLock.release() - for row in queryreturn: - msgid, toAddress, fromAddress, subject, received, message, read = row - subject = shared.fixPotentiallyInvalidUTF8Data(subject) - message = shared.fixPotentiallyInvalidUTF8Data(message) - try: - if toAddress == self.str_broadcast_subscribers: - toLabel = self.str_broadcast_subscribers - else: - toLabel = shared.config.get(toAddress, 'label') - except: - toLabel = '' - if toLabel == '': - toLabel = toAddress - - fromLabel = '' - t = (fromAddress,) - shared.sqlLock.acquire() - shared.sqlSubmitQueue.put( - '''select label from addressbook where address=?''') - shared.sqlSubmitQueue.put(t) - queryreturn = shared.sqlReturnQueue.get() - shared.sqlLock.release() - - if queryreturn != []: - for row in queryreturn: - fromLabel, = row - - if fromLabel == '': # If this address wasn't in our address book... - t = (fromAddress,) - shared.sqlLock.acquire() - shared.sqlSubmitQueue.put( - '''select label from subscriptions where address=?''') - shared.sqlSubmitQueue.put(t) - queryreturn = shared.sqlReturnQueue.get() - shared.sqlLock.release() - - if queryreturn != []: - for row in queryreturn: - fromLabel, = row - - self.ui.tableWidgetInbox.insertRow(0) - newItem = QtGui.QTableWidgetItem(unicode(toLabel, 'utf-8')) - newItem.setToolTip(unicode(toLabel, 'utf-8')) - newItem.setFlags( - QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) - if not read: - newItem.setFont(font) - newItem.setData(Qt.UserRole, str(toAddress)) - if shared.safeConfigGetBoolean(toAddress, 'mailinglist'): - newItem.setTextColor(QtGui.QColor(137, 04, 177)) - if shared.safeConfigGetBoolean(str(toAddress), 'chan'): - newItem.setTextColor(QtGui.QColor(216, 119, 0)) # orange - self.ui.tableWidgetInbox.setItem(0, 0, newItem) - if fromLabel == '': - newItem = QtGui.QTableWidgetItem( - unicode(fromAddress, 'utf-8')) - newItem.setToolTip(unicode(fromAddress, 'utf-8')) - else: - newItem = QtGui.QTableWidgetItem(unicode(fromLabel, 'utf-8')) - newItem.setToolTip(unicode(fromLabel, 'utf-8')) - newItem.setFlags( - QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) - if not read: - newItem.setFont(font) - newItem.setData(Qt.UserRole, str(fromAddress)) - - self.ui.tableWidgetInbox.setItem(0, 1, newItem) - newItem = QtGui.QTableWidgetItem(unicode(subject, 'utf-8')) - newItem.setToolTip(unicode(subject, 'utf-8')) - newItem.setData(Qt.UserRole, unicode(message, 'utf-8)')) - newItem.setFlags( - QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) - if not read: - newItem.setFont(font) - self.ui.tableWidgetInbox.setItem(0, 2, newItem) - newItem = myTableWidgetItem(unicode(strftime(shared.config.get( - 'bitmessagesettings', 'timeformat'), localtime(int(received))), 'utf-8')) - newItem.setToolTip(unicode(strftime(shared.config.get( - 'bitmessagesettings', 'timeformat'), localtime(int(received))), 'utf-8')) - newItem.setData(Qt.UserRole, QByteArray(msgid)) - newItem.setData(33, int(received)) - newItem.setFlags( - QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) - if not read: - newItem.setFont(font) - self.ui.tableWidgetInbox.setItem(0, 3, newItem) - self.ui.tableWidgetInbox.sortItems(3, Qt.DescendingOrder) - self.ui.tableWidgetInbox.keyPressEvent = self.tableWidgetInboxKeyPressEvent - # create application indicator def appIndicatorInit(self, app): self.tray = QSystemTrayIcon(QtGui.QIcon( @@ -1110,58 +1036,6 @@ class MyForm(QtGui.QMainWindow): ), self.regenerateAddressesDialogInstance.ui.lineEditPassphrase.text().toUtf8(), self.regenerateAddressesDialogInstance.ui.checkBoxEighteenByteRipe.isChecked())) self.ui.tabWidget.setCurrentIndex(3) - def click_actionJoinChan(self): - self.newChanDialogInstance = newChanDialog(self) - if self.newChanDialogInstance.exec_(): - if self.newChanDialogInstance.ui.radioButtonCreateChan.isChecked(): - if self.newChanDialogInstance.ui.lineEditChanNameCreate.text() == "": - QMessageBox.about(self, _translate("MainWindow", "Chan name needed"), _translate( - "MainWindow", "You didn't enter a chan name.")) - return - shared.apiAddressGeneratorReturnQueue.queue.clear() - shared.addressGeneratorQueue.put(('createChan', 3, 1, self.str_chan + ' ' + str(self.newChanDialogInstance.ui.lineEditChanNameCreate.text().toUtf8()), self.newChanDialogInstance.ui.lineEditChanNameCreate.text().toUtf8())) - addressGeneratorReturnValue = shared.apiAddressGeneratorReturnQueue.get() - print 'addressGeneratorReturnValue', addressGeneratorReturnValue - if len(addressGeneratorReturnValue) == 0: - QMessageBox.about(self, _translate("MainWindow", "Address already present"), _translate( - "MainWindow", "Could not add chan because it appears to already be one of your identities.")) - return - createdAddress = addressGeneratorReturnValue[0] - self.addEntryToAddressBook(createdAddress, self.str_chan + ' ' + str(self.newChanDialogInstance.ui.lineEditChanNameCreate.text().toUtf8())) - QMessageBox.about(self, _translate("MainWindow", "Success"), _translate( - "MainWindow", "Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: %1. This address also appears in 'Your Identities'.").arg(createdAddress)) - self.ui.tabWidget.setCurrentIndex(3) - elif self.newChanDialogInstance.ui.radioButtonJoinChan.isChecked(): - if self.newChanDialogInstance.ui.lineEditChanNameJoin.text() == "": - QMessageBox.about(self, _translate("MainWindow", "Chan name needed"), _translate( - "MainWindow", "You didn't enter a chan name.")) - return - if decodeAddress(self.newChanDialogInstance.ui.lineEditChanBitmessageAddress.text())[0] == 'versiontoohigh': - QMessageBox.about(self, _translate("MainWindow", "Address too new"), _translate( - "MainWindow", "Although that Bitmessage address might be valid, its version number is too new for us to handle. Perhaps you need to upgrade Bitmessage.")) - return - if decodeAddress(self.newChanDialogInstance.ui.lineEditChanBitmessageAddress.text())[0] != 'success': - QMessageBox.about(self, _translate("MainWindow", "Address invalid"), _translate( - "MainWindow", "That Bitmessage address is not valid.")) - return - shared.apiAddressGeneratorReturnQueue.queue.clear() - shared.addressGeneratorQueue.put(('joinChan', addBMIfNotPresent(self.newChanDialogInstance.ui.lineEditChanBitmessageAddress.text()), self.str_chan + ' ' + str(self.newChanDialogInstance.ui.lineEditChanNameJoin.text().toUtf8()), self.newChanDialogInstance.ui.lineEditChanNameJoin.text().toUtf8())) - addressGeneratorReturnValue = shared.apiAddressGeneratorReturnQueue.get() - print 'addressGeneratorReturnValue', addressGeneratorReturnValue - if addressGeneratorReturnValue == 'chan name does not match address': - QMessageBox.about(self, _translate("MainWindow", "Address does not match chan name"), _translate( - "MainWindow", "Although the Bitmessage address you entered was valid, it doesn\'t match the chan name.")) - return - if len(addressGeneratorReturnValue) == 0: - QMessageBox.about(self, _translate("MainWindow", "Address already present"), _translate( - "MainWindow", "Could not add chan because it appears to already be one of your identities.")) - return - createdAddress = addressGeneratorReturnValue[0] - self.addEntryToAddressBook(createdAddress, self.str_chan + ' ' + str(self.newChanDialogInstance.ui.lineEditChanNameJoin.text())) - QMessageBox.about(self, _translate("MainWindow", "Success"), _translate( - "MainWindow", "Successfully joined chan. ")) - self.ui.tabWidget.setCurrentIndex(3) - def openKeysFile(self): if 'linux' in sys.platform: subprocess.call(["xdg-open", shared.appdata + 'keys.dat']) @@ -1408,7 +1282,7 @@ class MyForm(QtGui.QMainWindow): self.ui.tableWidgetInbox.item(i, 0).setTextColor(QtGui.QColor(137, 04, 177)) else: self.ui.tableWidgetInbox.item( - i, 0).setTextColor(QApplication.palette().text().color()) + i, 0).setTextColor(QtGui.QColor(0, 0, 0)) def rerenderSentFromLabels(self): for i in range(self.ui.tableWidgetSent.rowCount()): @@ -1481,9 +1355,9 @@ class MyForm(QtGui.QMainWindow): status, addressVersionNumber, streamNumber, ripe = decodeAddress( toAddress) if status != 'success': - with shared.printLock: - print 'Error: Could not decode', toAddress, ':', status - + shared.printLock.acquire() + print 'Error: Could not decode', toAddress, ':', status + shared.printLock.release() if status == 'missingbm': self.statusBar().showMessage(_translate( "MainWindow", "Error: Bitmessage addresses start with BM- Please check %1").arg(toAddress)) @@ -1512,11 +1386,12 @@ class MyForm(QtGui.QMainWindow): toAddress = addBMIfNotPresent(toAddress) try: shared.config.get(toAddress, 'enabled') - # The toAddress is one owned by me. - if not shared.safeConfigGetBoolean(toAddress, 'chan'): - QMessageBox.about(self, _translate("MainWindow", "Sending to your address"), _translate( - "MainWindow", "Error: One of the addresses to which you are sending a message, %1, is yours. Unfortunately the Bitmessage client cannot process its own messages. Please try running a second client on a different computer or within a VM.").arg(toAddress)) - continue + # The toAddress is one owned by me. We cannot send + # messages to ourselves without significant changes + # to the codebase. + QMessageBox.about(self, _translate("MainWindow", "Sending to your address"), _translate( + "MainWindow", "Error: One of the addresses to which you are sending a message, %1, is yours. Unfortunately the Bitmessage client cannot process its own messages. Please try running a second client on a different computer or within a VM.").arg(toAddress)) + continue except: pass if addressVersionNumber > 3 or addressVersionNumber <= 1: @@ -1649,16 +1524,6 @@ class MyForm(QtGui.QMainWindow): def redrawLabelFrom(self, index): self.ui.labelFrom.setText( self.ui.comboBoxSendFrom.itemData(index).toPyObject()) - self.setBroadcastEnablementDependingOnWhetherThisIsAChanAddress(self.ui.comboBoxSendFrom.itemData(index).toPyObject()) - - def setBroadcastEnablementDependingOnWhetherThisIsAChanAddress(self, address): - # If this is a chan then don't let people broadcast because no one - # should subscribe to chan addresses. - if shared.safeConfigGetBoolean(str(address), 'chan'): - self.ui.radioButtonSpecific.click() - self.ui.radioButtonBroadcast.setEnabled(False) - else: - self.ui.radioButtonBroadcast.setEnabled(True) def rerenderComboBoxSendFrom(self): self.ui.comboBoxSendFrom.clear() @@ -1775,8 +1640,6 @@ class MyForm(QtGui.QMainWindow): newItem.setData(Qt.UserRole, str(toAddress)) if shared.safeConfigGetBoolean(str(toAddress), 'mailinglist'): newItem.setTextColor(QtGui.QColor(137, 04, 177)) - if shared.safeConfigGetBoolean(str(toAddress), 'chan'): - newItem.setTextColor(QtGui.QColor(216, 119, 0)) # orange self.ui.tableWidgetInbox.insertRow(0) self.ui.tableWidgetInbox.setItem(0, 0, newItem) @@ -1816,47 +1679,45 @@ class MyForm(QtGui.QMainWindow): # First we must check to see if the address is already in the # address book. The user cannot add it again or else it will # cause problems when updating and deleting the entry. - address = addBMIfNotPresent(str( - self.NewSubscriptionDialogInstance.ui.lineEditSubscriptionAddress.text())) - label = self.NewSubscriptionDialogInstance.ui.newsubscriptionlabel.text().toUtf8() - self.addEntryToAddressBook(address,label) + shared.sqlLock.acquire() + t = (addBMIfNotPresent(str( + self.NewSubscriptionDialogInstance.ui.lineEditSubscriptionAddress.text())),) + shared.sqlSubmitQueue.put( + '''select * from addressbook where address=?''') + shared.sqlSubmitQueue.put(t) + queryreturn = shared.sqlReturnQueue.get() + shared.sqlLock.release() + if queryreturn == []: + self.ui.tableWidgetAddressBook.setSortingEnabled(False) + self.ui.tableWidgetAddressBook.insertRow(0) + newItem = QtGui.QTableWidgetItem(unicode( + self.NewSubscriptionDialogInstance.ui.newsubscriptionlabel.text().toUtf8(), 'utf-8')) + self.ui.tableWidgetAddressBook.setItem(0, 0, newItem) + newItem = QtGui.QTableWidgetItem(addBMIfNotPresent( + self.NewSubscriptionDialogInstance.ui.lineEditSubscriptionAddress.text())) + newItem.setFlags( + QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) + self.ui.tableWidgetAddressBook.setItem(0, 1, newItem) + self.ui.tableWidgetAddressBook.setSortingEnabled(True) + t = (str(self.NewSubscriptionDialogInstance.ui.newsubscriptionlabel.text().toUtf8()), addBMIfNotPresent( + str(self.NewSubscriptionDialogInstance.ui.lineEditSubscriptionAddress.text()))) + shared.sqlLock.acquire() + shared.sqlSubmitQueue.put( + '''INSERT INTO addressbook VALUES (?,?)''') + shared.sqlSubmitQueue.put(t) + queryreturn = shared.sqlReturnQueue.get() + shared.sqlSubmitQueue.put('commit') + shared.sqlLock.release() + self.rerenderInboxFromLabels() + self.rerenderSentToLabels() + else: + self.statusBar().showMessage(_translate( + "MainWindow", "Error: You cannot add the same address to your address book twice. Try renaming the existing one if you want.")) else: self.statusBar().showMessage(_translate( "MainWindow", "The address you entered was invalid. Ignoring it.")) - def addEntryToAddressBook(self,address,label): - shared.sqlLock.acquire() - t = (address,) - shared.sqlSubmitQueue.put( - '''select * from addressbook where address=?''') - shared.sqlSubmitQueue.put(t) - queryreturn = shared.sqlReturnQueue.get() - shared.sqlLock.release() - if queryreturn == []: - self.ui.tableWidgetAddressBook.setSortingEnabled(False) - self.ui.tableWidgetAddressBook.insertRow(0) - newItem = QtGui.QTableWidgetItem(unicode(label, 'utf-8')) - self.ui.tableWidgetAddressBook.setItem(0, 0, newItem) - newItem = QtGui.QTableWidgetItem(address) - newItem.setFlags( - QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) - self.ui.tableWidgetAddressBook.setItem(0, 1, newItem) - self.ui.tableWidgetAddressBook.setSortingEnabled(True) - t = (str(label), address) - shared.sqlLock.acquire() - shared.sqlSubmitQueue.put( - '''INSERT INTO addressbook VALUES (?,?)''') - shared.sqlSubmitQueue.put(t) - queryreturn = shared.sqlReturnQueue.get() - shared.sqlSubmitQueue.put('commit') - shared.sqlLock.release() - self.rerenderInboxFromLabels() - self.rerenderSentToLabels() - else: - self.statusBar().showMessage(_translate( - "MainWindow", "Error: You cannot add the same address to your address book twice. Try renaming the existing one if you want.")) - - def addSubscription(self, address, label): + def addSubscription(self, label, address): address = addBMIfNotPresent(address) #This should be handled outside of this function, for error displaying and such, but it must also be checked here. if shared.isAddressInMySubscriptionsList(address): @@ -1893,7 +1754,7 @@ class MyForm(QtGui.QMainWindow): self.statusBar().showMessage(_translate("MainWindow", "Error: You cannot add the same address to your subsciptions twice. Perhaps rename the existing one if you want.")) return label = self.NewSubscriptionDialogInstance.ui.newsubscriptionlabel.text().toUtf8() - self.addSubscription(address, label) + self.addSubscription(label, address) def loadBlackWhiteList(self): # Initialize the Blacklist or Whitelist table @@ -1970,8 +1831,6 @@ class MyForm(QtGui.QMainWindow): self.settingsDialogInstance.ui.lineEditSocksUsername.text())) shared.config.set('bitmessagesettings', 'sockspassword', str( self.settingsDialogInstance.ui.lineEditSocksPassword.text())) - shared.config.set('bitmessagesettings', 'sockslisten', str( - self.settingsDialogInstance.ui.checkBoxSocksListen.isChecked())) if float(self.settingsDialogInstance.ui.lineEditTotalDifficulty.text()) >= 1: shared.config.set('bitmessagesettings', 'defaultnoncetrialsperbyte', str(int(float( self.settingsDialogInstance.ui.lineEditTotalDifficulty.text()) * shared.networkDefaultProofOfWorkNonceTrialsPerByte))) @@ -2024,14 +1883,7 @@ class MyForm(QtGui.QMainWindow): shared.knownNodesLock.release() os.remove(shared.appdata + 'keys.dat') os.remove(shared.appdata + 'knownnodes.dat') - previousAppdataLocation = shared.appdata shared.appdata = '' - debug.restartLoggingInUpdatedAppdataLocation() - try: - os.remove(previousAppdataLocation + 'debug.log') - os.remove(previousAppdataLocation + 'debug.log.1') - except: - pass if shared.appdata == '' and not self.settingsDialogInstance.ui.checkBoxPortableMode.isChecked(): # If we ARE using portable mode now but the user selected that we shouldn't... shared.appdata = shared.lookupAppdataFolder() @@ -2051,12 +1903,6 @@ class MyForm(QtGui.QMainWindow): shared.knownNodesLock.release() os.remove('keys.dat') os.remove('knownnodes.dat') - debug.restartLoggingInUpdatedAppdataLocation() - try: - os.remove('debug.log') - os.remove('debug.log.1') - except: - pass def click_radioButtonBlacklist(self): if shared.config.get('bitmessagesettings', 'blackwhitelist') == 'white': @@ -2136,16 +1982,13 @@ class MyForm(QtGui.QMainWindow): currentRow = self.ui.tableWidgetYourIdentities.currentRow() addressAtCurrentRow = str( self.ui.tableWidgetYourIdentities.item(currentRow, 1).text()) - if shared.safeConfigGetBoolean(addressAtCurrentRow, 'chan'): - return if self.dialog.ui.radioButtonBehaveNormalAddress.isChecked(): shared.config.set(str( addressAtCurrentRow), 'mailinglist', 'false') # Set the color to either black or grey if shared.config.getboolean(addressAtCurrentRow, 'enabled'): self.ui.tableWidgetYourIdentities.item( - currentRow, 1).setTextColor(QApplication.palette() - .text().color()) + currentRow, 1).setTextColor(QtGui.QColor(0, 0, 0)) else: self.ui.tableWidgetYourIdentities.item( currentRow, 1).setTextColor(QtGui.QColor(128, 128, 128)) @@ -2172,6 +2015,12 @@ class MyForm(QtGui.QMainWindow): # address.' streamNumberForAddress = addressStream( self.dialog.ui.comboBoxExisting.currentText()) + + # self.addressGenerator = addressGenerator() + # self.addressGenerator.setup(3,streamNumberForAddress,str(self.dialog.ui.newaddresslabel.text().toUtf8()),1,"",self.dialog.ui.checkBoxEighteenByteRipe.isChecked()) + # QtCore.QObject.connect(self.addressGenerator, SIGNAL("writeNewAddressToTable(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"), self.writeNewAddressToTable) + # QtCore.QObject.connect(self.addressGenerator, QtCore.SIGNAL("updateStatusBar(PyQt_PyObject)"), self.updateStatusBar) + # self.addressGenerator.start() shared.addressGeneratorQueue.put(('createRandomAddress', 3, streamNumberForAddress, str( self.dialog.ui.newaddresslabel.text().toUtf8()), 1, "", self.dialog.ui.checkBoxEighteenByteRipe.isChecked())) else: @@ -2183,6 +2032,11 @@ class MyForm(QtGui.QMainWindow): "MainWindow", "Choose a passphrase"), _translate("MainWindow", "You really do need a passphrase.")) else: streamNumberForAddress = 1 # this will eventually have to be replaced by logic to determine the most available stream number. + # self.addressGenerator = addressGenerator() + # self.addressGenerator.setup(3,streamNumberForAddress,"unused address",self.dialog.ui.spinBoxNumberOfAddressesToMake.value(),self.dialog.ui.lineEditPassphrase.text().toUtf8(),self.dialog.ui.checkBoxEighteenByteRipe.isChecked()) + # QtCore.QObject.connect(self.addressGenerator, SIGNAL("writeNewAddressToTable(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"), self.writeNewAddressToTable) + # QtCore.QObject.connect(self.addressGenerator, QtCore.SIGNAL("updateStatusBar(PyQt_PyObject)"), self.updateStatusBar) + # self.addressGenerator.start() shared.addressGeneratorQueue.put(('createDeterministicAddresses', 3, streamNumberForAddress, "unused deterministic address", self.dialog.ui.spinBoxNumberOfAddressesToMake.value( ), self.dialog.ui.lineEditPassphrase.text().toUtf8(), self.dialog.ui.checkBoxEighteenByteRipe.isChecked())) else: @@ -2259,7 +2113,6 @@ class MyForm(QtGui.QMainWindow): self.ui.labelFrom.setText('') else: self.ui.labelFrom.setText(toAddressAtCurrentInboxRow) - self.setBroadcastEnablementDependingOnWhetherThisIsAChanAddress(toAddressAtCurrentInboxRow) self.ui.lineEditTo.setText(str(fromAddressAtCurrentInboxRow)) self.ui.comboBoxSendFrom.setCurrentIndex(0) # self.ui.comboBoxSendFrom.setEditText(str(self.ui.tableWidgetInbox.item(currentInboxRow,0).text)) @@ -2483,7 +2336,7 @@ class MyForm(QtGui.QMainWindow): self.statusBar().showMessage(QtGui.QApplication.translate("MainWindow", "Error: You cannot add the same address to your subsciptions twice. Perhaps rename the existing one if you want.")) continue labelAtCurrentRow = self.ui.tableWidgetAddressBook.item(currentRow,0).text().toUtf8() - self.addSubscription(addressAtCurrentRow, labelAtCurrentRow) + self.addSubscription(labelAtCurrentRow, addressAtCurrentRow) self.ui.tabWidget.setCurrentIndex(4) def on_context_menuAddressBook(self, point): @@ -2535,9 +2388,9 @@ class MyForm(QtGui.QMainWindow): shared.sqlSubmitQueue.put('commit') shared.sqlLock.release() self.ui.tableWidgetSubscriptions.item( - currentRow, 0).setTextColor(QApplication.palette().text().color()) + currentRow, 0).setTextColor(QtGui.QColor(0, 0, 0)) self.ui.tableWidgetSubscriptions.item( - currentRow, 1).setTextColor(QApplication.palette().text().color()) + currentRow, 1).setTextColor(QtGui.QColor(0, 0, 0)) shared.reloadBroadcastSendersForWhichImWatching() def on_action_SubscriptionsDisable(self): @@ -2606,9 +2459,9 @@ class MyForm(QtGui.QMainWindow): addressAtCurrentRow = self.ui.tableWidgetBlacklist.item( currentRow, 1).text() self.ui.tableWidgetBlacklist.item( - currentRow, 0).setTextColor(QApplication.palette().text().color()) + currentRow, 0).setTextColor(QtGui.QColor(0, 0, 0)) self.ui.tableWidgetBlacklist.item( - currentRow, 1).setTextColor(QApplication.palette().text().color()) + currentRow, 1).setTextColor(QtGui.QColor(0, 0, 0)) t = (str(addressAtCurrentRow),) shared.sqlLock.acquire() if shared.config.get('bitmessagesettings', 'blackwhitelist') == 'black': @@ -2659,15 +2512,13 @@ class MyForm(QtGui.QMainWindow): with open(shared.appdata + 'keys.dat', 'wb') as configfile: shared.config.write(configfile) self.ui.tableWidgetYourIdentities.item( - currentRow, 0).setTextColor(QApplication.palette().text().color()) + currentRow, 0).setTextColor(QtGui.QColor(0, 0, 0)) self.ui.tableWidgetYourIdentities.item( - currentRow, 1).setTextColor(QApplication.palette().text().color()) + currentRow, 1).setTextColor(QtGui.QColor(0, 0, 0)) self.ui.tableWidgetYourIdentities.item( - currentRow, 2).setTextColor(QApplication.palette().text().color()) + currentRow, 2).setTextColor(QtGui.QColor(0, 0, 0)) if shared.safeConfigGetBoolean(addressAtCurrentRow, 'mailinglist'): self.ui.tableWidgetYourIdentities.item(currentRow, 1).setTextColor(QtGui.QColor(137, 04, 177)) - if shared.safeConfigGetBoolean(addressAtCurrentRow, 'chan'): - self.ui.tableWidgetYourIdentities.item(currentRow, 1).setTextColor(QtGui.QColor(216, 119, 0)) # orange shared.reloadMyAddressHashes() def on_action_YourIdentitiesDisable(self): @@ -2723,20 +2574,6 @@ class MyForm(QtGui.QMainWindow): self.popMenuSent.addAction(self.actionForceSend) self.popMenuSent.exec_(self.ui.tableWidgetSent.mapToGlobal(point)) - def inboxSearchLineEditPressed(self): - searchKeyword = self.ui.inboxSearchLineEdit.text().toUtf8().data() - searchOption = self.ui.inboxSearchOptionCB.currentText().toUtf8().data() - self.ui.inboxSearchLineEdit.setText(QString("")) - self.ui.textEditInboxMessage.setPlainText(QString("")) - self.loadInbox(searchOption, searchKeyword) - - def sentSearchLineEditPressed(self): - searchKeyword = self.ui.sentSearchLineEdit.text().toUtf8().data() - searchOption = self.ui.sentSearchOptionCB.currentText().toUtf8().data() - self.ui.sentSearchLineEdit.setText(QString("")) - self.ui.textEditInboxMessage.setPlainText(QString("")) - self.loadSent(searchOption, searchKeyword) - def tableWidgetInboxItemClicked(self): currentRow = self.ui.tableWidgetInbox.currentRow() if currentRow >= 0: @@ -2836,14 +2673,11 @@ class MyForm(QtGui.QMainWindow): def writeNewAddressToTable(self, label, address, streamNumber): self.ui.tableWidgetYourIdentities.setSortingEnabled(False) self.ui.tableWidgetYourIdentities.insertRow(0) - newItem = QtGui.QTableWidgetItem(unicode(label, 'utf-8')) self.ui.tableWidgetYourIdentities.setItem( - 0, 0, newItem) + 0, 0, QtGui.QTableWidgetItem(unicode(label, 'utf-8'))) newItem = QtGui.QTableWidgetItem(address) newItem.setFlags( QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) - if shared.safeConfigGetBoolean(address, 'chan'): - newItem.setTextColor(QtGui.QColor(216, 119, 0)) # orange self.ui.tableWidgetYourIdentities.setItem(0, 1, newItem) newItem = QtGui.QTableWidgetItem(streamNumber) newItem.setFlags( @@ -2854,9 +2688,9 @@ class MyForm(QtGui.QMainWindow): def updateStatusBar(self, data): if data != "": - with shared.printLock: - print 'Status bar:', data - + shared.printLock.acquire() + print 'Status bar:', data + shared.printLock.release() self.statusBar().showMessage(data) @@ -2890,6 +2724,7 @@ class regenerateAddressesDialog(QtGui.QDialog): self.parent = parent QtGui.QWidget.resize(self, QtGui.QWidget.sizeHint(self)) + class settingsDialog(QtGui.QDialog): def __init__(self, parent): @@ -2923,8 +2758,6 @@ class settingsDialog(QtGui.QDialog): shared.config.get('bitmessagesettings', 'port'))) self.ui.checkBoxAuthentication.setChecked(shared.config.getboolean( 'bitmessagesettings', 'socksauthentication')) - self.ui.checkBoxSocksListen.setChecked(shared.config.getboolean( - 'bitmessagesettings', 'sockslisten')) if str(shared.config.get('bitmessagesettings', 'socksproxytype')) == 'none': self.ui.comboBoxProxyType.setCurrentIndex(0) self.ui.lineEditSocksHostname.setEnabled(False) @@ -2932,7 +2765,6 @@ class settingsDialog(QtGui.QDialog): self.ui.lineEditSocksUsername.setEnabled(False) self.ui.lineEditSocksPassword.setEnabled(False) self.ui.checkBoxAuthentication.setEnabled(False) - self.ui.checkBoxSocksListen.setEnabled(False) elif str(shared.config.get('bitmessagesettings', 'socksproxytype')) == 'SOCKS4a': self.ui.comboBoxProxyType.setCurrentIndex(1) self.ui.lineEditTCPPort.setEnabled(False) @@ -2989,13 +2821,11 @@ class settingsDialog(QtGui.QDialog): self.ui.lineEditSocksUsername.setEnabled(False) self.ui.lineEditSocksPassword.setEnabled(False) self.ui.checkBoxAuthentication.setEnabled(False) - self.ui.checkBoxSocksListen.setEnabled(False) self.ui.lineEditTCPPort.setEnabled(True) elif comboBoxIndex == 1 or comboBoxIndex == 2: self.ui.lineEditSocksHostname.setEnabled(True) self.ui.lineEditSocksPort.setEnabled(True) self.ui.checkBoxAuthentication.setEnabled(True) - self.ui.checkBoxSocksListen.setEnabled(True) if self.ui.checkBoxAuthentication.isChecked(): self.ui.lineEditSocksUsername.setEnabled(True) self.ui.lineEditSocksPassword.setEnabled(True) @@ -3012,23 +2842,17 @@ class SpecialAddressBehaviorDialog(QtGui.QDialog): currentRow = parent.ui.tableWidgetYourIdentities.currentRow() addressAtCurrentRow = str( parent.ui.tableWidgetYourIdentities.item(currentRow, 1).text()) - if not shared.safeConfigGetBoolean(addressAtCurrentRow, 'chan'): - if shared.safeConfigGetBoolean(addressAtCurrentRow, 'mailinglist'): - self.ui.radioButtonBehaviorMailingList.click() - else: - self.ui.radioButtonBehaveNormalAddress.click() - try: - mailingListName = shared.config.get( - addressAtCurrentRow, 'mailinglistname') - except: - mailingListName = '' - self.ui.lineEditMailingListName.setText( - unicode(mailingListName, 'utf-8')) - else: # if addressAtCurrentRow is a chan address - self.ui.radioButtonBehaviorMailingList.setDisabled(True) - self.ui.lineEditMailingListName.setText(_translate( - "MainWindow", "This is a chan address. You cannot use it as a pseudo-mailing list.")) - + if shared.safeConfigGetBoolean(addressAtCurrentRow, 'mailinglist'): + self.ui.radioButtonBehaviorMailingList.click() + else: + self.ui.radioButtonBehaveNormalAddress.click() + try: + mailingListName = shared.config.get( + addressAtCurrentRow, 'mailinglistname') + except: + mailingListName = '' + self.ui.lineEditMailingListName.setText( + unicode(mailingListName, 'utf-8')) QtGui.QWidget.resize(self, QtGui.QWidget.sizeHint(self)) @@ -3087,11 +2911,11 @@ class NewAddressDialog(QtGui.QDialog): self.ui.groupBoxDeterministic.setHidden(True) QtGui.QWidget.resize(self, QtGui.QWidget.sizeHint(self)) -class newChanDialog(QtGui.QDialog): +class NewChanDialog(QtGui.QDialog): def __init__(self, parent): QtGui.QWidget.__init__(self, parent) - self.ui = Ui_newChanDialog() + self.ui = Ui_NewChanDialog() self.ui.setupUi(self) self.parent = parent self.ui.groupBoxCreateChan.setHidden(True) @@ -3118,90 +2942,66 @@ class myTableWidgetItem(QTableWidgetItem): def __lt__(self, other): return int(self.data(33).toPyObject()) < int(other.data(33).toPyObject()) -from threading import Thread -class UISignaler(Thread,QThread): + +class UISignaler(QThread): def __init__(self, parent=None): - Thread.__init__(self, parent) QThread.__init__(self, parent) def run(self): while True: - try: - command, data = shared.UISignalQueue.get() - if command == 'writeNewAddressToTable': - label, address, streamNumber = data - self.emit(SIGNAL( - "writeNewAddressToTable(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"), label, address, str(streamNumber)) - elif command == 'updateStatusBar': - self.emit(SIGNAL("updateStatusBar(PyQt_PyObject)"), data) - elif command == 'updateSentItemStatusByHash': - hash, message = data - self.emit(SIGNAL( - "updateSentItemStatusByHash(PyQt_PyObject,PyQt_PyObject)"), hash, message) - elif command == 'updateSentItemStatusByAckdata': - ackData, message = data - self.emit(SIGNAL( - "updateSentItemStatusByAckdata(PyQt_PyObject,PyQt_PyObject)"), ackData, message) - elif command == 'displayNewInboxMessage': - inventoryHash, toAddress, fromAddress, subject, body = data - self.emit(SIGNAL( - "displayNewInboxMessage(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"), - inventoryHash, toAddress, fromAddress, subject, body) - elif command == 'displayNewSentMessage': - toAddress, fromLabel, fromAddress, subject, message, ackdata = data - self.emit(SIGNAL( - "displayNewSentMessage(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"), - toAddress, fromLabel, fromAddress, subject, message, ackdata) - elif command == 'updateNetworkStatusTab': - self.emit(SIGNAL("updateNetworkStatusTab()")) - elif command == 'incrementNumberOfMessagesProcessed': - self.emit(SIGNAL("incrementNumberOfMessagesProcessed()")) - elif command == 'incrementNumberOfPubkeysProcessed': - self.emit(SIGNAL("incrementNumberOfPubkeysProcessed()")) - elif command == 'incrementNumberOfBroadcastsProcessed': - self.emit(SIGNAL("incrementNumberOfBroadcastsProcessed()")) - elif command == 'setStatusIcon': - self.emit(SIGNAL("setStatusIcon(PyQt_PyObject)"), data) - elif command == 'rerenderInboxFromLabels': - self.emit(SIGNAL("rerenderInboxFromLabels()")) - elif command == 'rerenderSubscriptions': - self.emit(SIGNAL("rerenderSubscriptions()")) - elif command == 'removeInboxRowByMsgid': - self.emit(SIGNAL("removeInboxRowByMsgid(PyQt_PyObject)"), data) - else: - sys.stderr.write( - 'Command sent to UISignaler not recognized: %s\n' % command) - except Exception,ex: - # uncaught exception will block gevent - import traceback - traceback.print_exc() - traceback.print_stack() - print ex - pass + command, data = shared.UISignalQueue.get() + if command == 'writeNewAddressToTable': + label, address, streamNumber = data + self.emit(SIGNAL( + "writeNewAddressToTable(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"), label, address, str(streamNumber)) + elif command == 'updateStatusBar': + self.emit(SIGNAL("updateStatusBar(PyQt_PyObject)"), data) + elif command == 'updateSentItemStatusByHash': + hash, message = data + self.emit(SIGNAL( + "updateSentItemStatusByHash(PyQt_PyObject,PyQt_PyObject)"), hash, message) + elif command == 'updateSentItemStatusByAckdata': + ackData, message = data + self.emit(SIGNAL( + "updateSentItemStatusByAckdata(PyQt_PyObject,PyQt_PyObject)"), ackData, message) + elif command == 'displayNewInboxMessage': + inventoryHash, toAddress, fromAddress, subject, body = data + self.emit(SIGNAL( + "displayNewInboxMessage(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"), + inventoryHash, toAddress, fromAddress, subject, body) + elif command == 'displayNewSentMessage': + toAddress, fromLabel, fromAddress, subject, message, ackdata = data + self.emit(SIGNAL( + "displayNewSentMessage(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"), + toAddress, fromLabel, fromAddress, subject, message, ackdata) + elif command == 'updateNetworkStatusTab': + self.emit(SIGNAL("updateNetworkStatusTab()")) + elif command == 'incrementNumberOfMessagesProcessed': + self.emit(SIGNAL("incrementNumberOfMessagesProcessed()")) + elif command == 'incrementNumberOfPubkeysProcessed': + self.emit(SIGNAL("incrementNumberOfPubkeysProcessed()")) + elif command == 'incrementNumberOfBroadcastsProcessed': + self.emit(SIGNAL("incrementNumberOfBroadcastsProcessed()")) + elif command == 'setStatusIcon': + self.emit(SIGNAL("setStatusIcon(PyQt_PyObject)"), data) + elif command == 'rerenderInboxFromLabels': + self.emit(SIGNAL("rerenderInboxFromLabels()")) + elif command == 'rerenderSubscriptions': + self.emit(SIGNAL("rerenderSubscriptions()")) + elif command == 'removeInboxRowByMsgid': + self.emit(SIGNAL("removeInboxRowByMsgid(PyQt_PyObject)"), data) + else: + sys.stderr.write( + 'Command sent to UISignaler not recognized: %s\n' % command) -try: - import gevent -except ImportError as ex: - gevent = None -else: - def mainloop(app): - while True: - app.processEvents() - gevent.sleep(0.01) - def testprint(): - #print 'this is running' - gevent.spawn_later(1, testprint) def run(): app = QtGui.QApplication(sys.argv) translator = QtCore.QTranslator() - try: - translator.load("translations/bitmessage_" + str(locale.getlocale()[0])) - except: - # The above is not compatible with all versions of OSX. - translator.load("translations/bitmessage_en_US") # Default to english. + translator.load("translations/bitmessage_" + str(locale.getlocale()[0])) + #translator.load("translations/bitmessage_fr_BE") # Try French instead QtGui.QApplication.installTranslator(translator) app.setStyleSheet("QStatusBar::item { border: 0px solid black }") @@ -3213,8 +3013,5 @@ def run(): myapp.appIndicatorInit(app) myapp.ubuntuMessagingMenuInit() myapp.notifierInit() - if gevent is None: - sys.exit(app.exec_()) - else: - gevent.joinall([gevent.spawn(testprint), gevent.spawn(mainloop, app), gevent.spawn(mainloop, app), gevent.spawn(mainloop, app), gevent.spawn(mainloop, app), gevent.spawn(mainloop, app)]) - print 'done' + + sys.exit(app.exec_()) diff --git a/src/bitmessageqt/bitmessage_icons.qrc b/src/bitmessageqt/bitmessage_icons.qrc index bdd3fd07..a186b01b 100644 --- a/src/bitmessageqt/bitmessage_icons.qrc +++ b/src/bitmessageqt/bitmessage_icons.qrc @@ -1,20 +1,20 @@ - ../images/can-icon-24px-yellow.png - ../images/can-icon-24px-red.png - ../images/can-icon-24px-green.png - ../images/can-icon-24px.png - ../images/can-icon-16px.png - ../images/greenicon.png - ../images/redicon.png - ../images/yellowicon.png - ../images/addressbook.png - ../images/blacklist.png - ../images/identities.png - ../images/networkstatus.png - ../images/sent.png - ../images/subscriptions.png - ../images/send.png - ../images/inbox.png + images/can-icon-24px-yellow.png + images/can-icon-24px-red.png + images/can-icon-24px-green.png + images/can-icon-24px.png + images/can-icon-16px.png + images/greenicon.png + images/redicon.png + images/yellowicon.png + images/addressbook.png + images/blacklist.png + images/identities.png + images/networkstatus.png + images/sent.png + images/subscriptions.png + images/send.png + images/inbox.png diff --git a/src/bitmessageqt/bitmessageui.py b/src/bitmessageqt/bitmessageui.py index 4efecb97..1186e814 100644 --- a/src/bitmessageqt/bitmessageui.py +++ b/src/bitmessageqt/bitmessageui.py @@ -2,8 +2,8 @@ # Form implementation generated from reading ui file 'bitmessageui.ui' # -# Created: Sun Jul 21 17:50:02 2013 -# by: PyQt4 UI code generator 4.10.2 +# Created: Thu Jun 13 01:02:50 2013 +# by: PyQt4 UI code generator 4.10.1 # # WARNING! All changes made in this file will be lost! @@ -54,21 +54,6 @@ class Ui_MainWindow(object): self.inbox.setObjectName(_fromUtf8("inbox")) self.verticalLayout_2 = QtGui.QVBoxLayout(self.inbox) self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2")) - self.horizontalLayoutSearch = QtGui.QHBoxLayout() - self.horizontalLayoutSearch.setContentsMargins(-1, 0, -1, -1) - self.horizontalLayoutSearch.setObjectName(_fromUtf8("horizontalLayoutSearch")) - self.inboxSearchLineEdit = QtGui.QLineEdit(self.inbox) - self.inboxSearchLineEdit.setObjectName(_fromUtf8("inboxSearchLineEdit")) - self.horizontalLayoutSearch.addWidget(self.inboxSearchLineEdit) - self.inboxSearchOptionCB = QtGui.QComboBox(self.inbox) - self.inboxSearchOptionCB.setObjectName(_fromUtf8("inboxSearchOptionCB")) - self.inboxSearchOptionCB.addItem(_fromUtf8("")) - self.inboxSearchOptionCB.addItem(_fromUtf8("")) - self.inboxSearchOptionCB.addItem(_fromUtf8("")) - self.inboxSearchOptionCB.addItem(_fromUtf8("")) - self.inboxSearchOptionCB.addItem(_fromUtf8("")) - self.horizontalLayoutSearch.addWidget(self.inboxSearchOptionCB) - self.verticalLayout_2.addLayout(self.horizontalLayoutSearch) self.tableWidgetInbox = QtGui.QTableWidget(self.inbox) self.tableWidgetInbox.setAlternatingRowColors(True) self.tableWidgetInbox.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection) @@ -172,21 +157,6 @@ class Ui_MainWindow(object): self.sent.setObjectName(_fromUtf8("sent")) self.verticalLayout = QtGui.QVBoxLayout(self.sent) self.verticalLayout.setObjectName(_fromUtf8("verticalLayout")) - self.horizontalLayout = QtGui.QHBoxLayout() - self.horizontalLayout.setContentsMargins(-1, 0, -1, -1) - self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout")) - self.sentSearchLineEdit = QtGui.QLineEdit(self.sent) - self.sentSearchLineEdit.setObjectName(_fromUtf8("sentSearchLineEdit")) - self.horizontalLayout.addWidget(self.sentSearchLineEdit) - self.sentSearchOptionCB = QtGui.QComboBox(self.sent) - self.sentSearchOptionCB.setObjectName(_fromUtf8("sentSearchOptionCB")) - self.sentSearchOptionCB.addItem(_fromUtf8("")) - self.sentSearchOptionCB.addItem(_fromUtf8("")) - self.sentSearchOptionCB.addItem(_fromUtf8("")) - self.sentSearchOptionCB.addItem(_fromUtf8("")) - self.sentSearchOptionCB.addItem(_fromUtf8("")) - self.horizontalLayout.addWidget(self.sentSearchOptionCB) - self.verticalLayout.addLayout(self.horizontalLayout) self.tableWidgetSent = QtGui.QTableWidget(self.sent) self.tableWidgetSent.setDragDropMode(QtGui.QAbstractItemView.DragDrop) self.tableWidgetSent.setAlternatingRowColors(True) @@ -453,12 +423,9 @@ class Ui_MainWindow(object): self.actionRegenerateDeterministicAddresses.setObjectName(_fromUtf8("actionRegenerateDeterministicAddresses")) self.actionDeleteAllTrashedMessages = QtGui.QAction(MainWindow) self.actionDeleteAllTrashedMessages.setObjectName(_fromUtf8("actionDeleteAllTrashedMessages")) - self.actionJoinChan = QtGui.QAction(MainWindow) - self.actionJoinChan.setObjectName(_fromUtf8("actionJoinChan")) self.menuFile.addAction(self.actionManageKeys) self.menuFile.addAction(self.actionDeleteAllTrashedMessages) self.menuFile.addAction(self.actionRegenerateDeterministicAddresses) - self.menuFile.addAction(self.actionJoinChan) self.menuFile.addAction(self.actionExit) self.menuSettings.addAction(self.actionSettings) self.menuHelp.addAction(self.actionHelp) @@ -500,12 +467,6 @@ class Ui_MainWindow(object): def retranslateUi(self, MainWindow): MainWindow.setWindowTitle(_translate("MainWindow", "Bitmessage", None)) - self.inboxSearchLineEdit.setPlaceholderText(_translate("MainWindow", "Search", None)) - self.inboxSearchOptionCB.setItemText(0, _translate("MainWindow", "All", None)) - self.inboxSearchOptionCB.setItemText(1, _translate("MainWindow", "To", None)) - self.inboxSearchOptionCB.setItemText(2, _translate("MainWindow", "From", None)) - self.inboxSearchOptionCB.setItemText(3, _translate("MainWindow", "Subject", None)) - self.inboxSearchOptionCB.setItemText(4, _translate("MainWindow", "Message", None)) self.tableWidgetInbox.setSortingEnabled(True) item = self.tableWidgetInbox.horizontalHeaderItem(0) item.setText(_translate("MainWindow", "To", None)) @@ -531,12 +492,6 @@ class Ui_MainWindow(object): self.pushButtonSend.setText(_translate("MainWindow", "Send", None)) self.labelSendBroadcastWarning.setText(_translate("MainWindow", "Be aware that broadcasts are only encrypted with your address. Anyone who knows your address can read them.", None)) self.tabWidget.setTabText(self.tabWidget.indexOf(self.send), _translate("MainWindow", "Send", None)) - self.sentSearchLineEdit.setPlaceholderText(_translate("MainWindow", "Search", None)) - self.sentSearchOptionCB.setItemText(0, _translate("MainWindow", "All", None)) - self.sentSearchOptionCB.setItemText(1, _translate("MainWindow", "To", None)) - self.sentSearchOptionCB.setItemText(2, _translate("MainWindow", "From", None)) - self.sentSearchOptionCB.setItemText(3, _translate("MainWindow", "Subject", None)) - self.sentSearchOptionCB.setItemText(4, _translate("MainWindow", "Message", None)) self.tableWidgetSent.setSortingEnabled(True) item = self.tableWidgetSent.horizontalHeaderItem(0) item.setText(_translate("MainWindow", "To", None)) @@ -602,6 +557,15 @@ class Ui_MainWindow(object): self.actionSettings.setText(_translate("MainWindow", "Settings", None)) self.actionRegenerateDeterministicAddresses.setText(_translate("MainWindow", "Regenerate deterministic addresses", None)) self.actionDeleteAllTrashedMessages.setText(_translate("MainWindow", "Delete all trashed messages", None)) - self.actionJoinChan.setText(_translate("MainWindow", "Join / Create chan", None)) import bitmessage_icons_rc + +if __name__ == "__main__": + import sys + app = QtGui.QApplication(sys.argv) + MainWindow = QtGui.QMainWindow() + ui = Ui_MainWindow() + ui.setupUi(MainWindow) + MainWindow.show() + sys.exit(app.exec_()) + diff --git a/src/bitmessageqt/bitmessageui.ui b/src/bitmessageqt/bitmessageui.ui index d4478fc8..48f5c224 100644 --- a/src/bitmessageqt/bitmessageui.ui +++ b/src/bitmessageqt/bitmessageui.ui @@ -68,49 +68,6 @@ Inbox - - - - 0 - - - - - Search - - - - - - - - All - - - - - To - - - - - From - - - - - Subject - - - - - Message - - - - - - @@ -353,49 +310,6 @@ p, li { white-space: pre-wrap; } Sent - - - - 0 - - - - - Search - - - - - - - - All - - - - - To - - - - - From - - - - - Subject - - - - - Message - - - - - - @@ -1021,7 +935,6 @@ p, li { white-space: pre-wrap; } - @@ -1095,11 +1008,6 @@ p, li { white-space: pre-wrap; } Delete all trashed messages - - - Join / Create chan - - tabWidget diff --git a/src/bitmessageqt/newchandialog.py b/src/bitmessageqt/newchandialog.py index 43235bfa..5c5e11f2 100644 --- a/src/bitmessageqt/newchandialog.py +++ b/src/bitmessageqt/newchandialog.py @@ -2,7 +2,7 @@ # Form implementation generated from reading ui file 'newchandialog.ui' # -# Created: Mon Jul 22 01:05:35 2013 +# Created: Tue Jun 25 17:03:01 2013 # by: PyQt4 UI code generator 4.10.2 # # WARNING! All changes made in this file will be lost! @@ -23,36 +23,20 @@ except AttributeError: def _translate(context, text, disambig): return QtGui.QApplication.translate(context, text, disambig) -class Ui_newChanDialog(object): - def setupUi(self, newChanDialog): - newChanDialog.setObjectName(_fromUtf8("newChanDialog")) - newChanDialog.resize(530, 422) - newChanDialog.setMinimumSize(QtCore.QSize(0, 0)) - self.formLayout = QtGui.QFormLayout(newChanDialog) +class Ui_NewChanDialog(object): + def setupUi(self, NewChanDialog): + NewChanDialog.setObjectName(_fromUtf8("NewChanDialog")) + NewChanDialog.resize(447, 441) + self.formLayout = QtGui.QFormLayout(NewChanDialog) self.formLayout.setObjectName(_fromUtf8("formLayout")) - self.radioButtonCreateChan = QtGui.QRadioButton(newChanDialog) + self.radioButtonCreateChan = QtGui.QRadioButton(NewChanDialog) self.radioButtonCreateChan.setObjectName(_fromUtf8("radioButtonCreateChan")) self.formLayout.setWidget(0, QtGui.QFormLayout.LabelRole, self.radioButtonCreateChan) - self.radioButtonJoinChan = QtGui.QRadioButton(newChanDialog) + self.radioButtonJoinChan = QtGui.QRadioButton(NewChanDialog) self.radioButtonJoinChan.setChecked(True) self.radioButtonJoinChan.setObjectName(_fromUtf8("radioButtonJoinChan")) self.formLayout.setWidget(1, QtGui.QFormLayout.LabelRole, self.radioButtonJoinChan) - self.groupBoxCreateChan = QtGui.QGroupBox(newChanDialog) - self.groupBoxCreateChan.setObjectName(_fromUtf8("groupBoxCreateChan")) - self.gridLayout = QtGui.QGridLayout(self.groupBoxCreateChan) - self.gridLayout.setObjectName(_fromUtf8("gridLayout")) - self.label_4 = QtGui.QLabel(self.groupBoxCreateChan) - self.label_4.setWordWrap(True) - self.label_4.setObjectName(_fromUtf8("label_4")) - self.gridLayout.addWidget(self.label_4, 0, 0, 1, 1) - self.label_5 = QtGui.QLabel(self.groupBoxCreateChan) - self.label_5.setObjectName(_fromUtf8("label_5")) - self.gridLayout.addWidget(self.label_5, 1, 0, 1, 1) - self.lineEditChanNameCreate = QtGui.QLineEdit(self.groupBoxCreateChan) - self.lineEditChanNameCreate.setObjectName(_fromUtf8("lineEditChanNameCreate")) - self.gridLayout.addWidget(self.lineEditChanNameCreate, 2, 0, 1, 1) - self.formLayout.setWidget(2, QtGui.QFormLayout.SpanningRole, self.groupBoxCreateChan) - self.groupBoxJoinChan = QtGui.QGroupBox(newChanDialog) + self.groupBoxJoinChan = QtGui.QGroupBox(NewChanDialog) self.groupBoxJoinChan.setObjectName(_fromUtf8("groupBoxJoinChan")) self.gridLayout_2 = QtGui.QGridLayout(self.groupBoxJoinChan) self.gridLayout_2.setObjectName(_fromUtf8("gridLayout_2")) @@ -73,30 +57,43 @@ class Ui_newChanDialog(object): self.lineEditChanBitmessageAddress.setObjectName(_fromUtf8("lineEditChanBitmessageAddress")) self.gridLayout_2.addWidget(self.lineEditChanBitmessageAddress, 4, 0, 1, 1) self.formLayout.setWidget(3, QtGui.QFormLayout.SpanningRole, self.groupBoxJoinChan) - spacerItem = QtGui.QSpacerItem(389, 2, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) - self.formLayout.setItem(4, QtGui.QFormLayout.FieldRole, spacerItem) - self.buttonBox = QtGui.QDialogButtonBox(newChanDialog) + self.groupBoxCreateChan = QtGui.QGroupBox(NewChanDialog) + self.groupBoxCreateChan.setObjectName(_fromUtf8("groupBoxCreateChan")) + self.gridLayout = QtGui.QGridLayout(self.groupBoxCreateChan) + self.gridLayout.setObjectName(_fromUtf8("gridLayout")) + self.label_4 = QtGui.QLabel(self.groupBoxCreateChan) + self.label_4.setWordWrap(True) + self.label_4.setObjectName(_fromUtf8("label_4")) + self.gridLayout.addWidget(self.label_4, 0, 0, 1, 1) + self.label_5 = QtGui.QLabel(self.groupBoxCreateChan) + self.label_5.setObjectName(_fromUtf8("label_5")) + self.gridLayout.addWidget(self.label_5, 1, 0, 1, 1) + self.lineEditChanNameCreate = QtGui.QLineEdit(self.groupBoxCreateChan) + self.lineEditChanNameCreate.setObjectName(_fromUtf8("lineEditChanNameCreate")) + self.gridLayout.addWidget(self.lineEditChanNameCreate, 2, 0, 1, 1) + self.formLayout.setWidget(2, QtGui.QFormLayout.SpanningRole, self.groupBoxCreateChan) + self.buttonBox = QtGui.QDialogButtonBox(NewChanDialog) self.buttonBox.setOrientation(QtCore.Qt.Horizontal) self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok) self.buttonBox.setObjectName(_fromUtf8("buttonBox")) - self.formLayout.setWidget(5, QtGui.QFormLayout.FieldRole, self.buttonBox) + self.formLayout.setWidget(4, QtGui.QFormLayout.FieldRole, self.buttonBox) - self.retranslateUi(newChanDialog) - QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("accepted()")), newChanDialog.accept) - QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("rejected()")), newChanDialog.reject) + self.retranslateUi(NewChanDialog) + QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("accepted()")), NewChanDialog.accept) + QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("rejected()")), NewChanDialog.reject) QtCore.QObject.connect(self.radioButtonJoinChan, QtCore.SIGNAL(_fromUtf8("toggled(bool)")), self.groupBoxJoinChan.setShown) QtCore.QObject.connect(self.radioButtonCreateChan, QtCore.SIGNAL(_fromUtf8("toggled(bool)")), self.groupBoxCreateChan.setShown) - QtCore.QMetaObject.connectSlotsByName(newChanDialog) + QtCore.QMetaObject.connectSlotsByName(NewChanDialog) - def retranslateUi(self, newChanDialog): - newChanDialog.setWindowTitle(_translate("newChanDialog", "Dialog", None)) - self.radioButtonCreateChan.setText(_translate("newChanDialog", "Create a new chan", None)) - self.radioButtonJoinChan.setText(_translate("newChanDialog", "Join a chan", None)) - self.groupBoxCreateChan.setTitle(_translate("newChanDialog", "Create a chan", None)) - self.label_4.setText(_translate("newChanDialog", "Enter a name for your chan. If you choose a sufficiently complex chan name (like a strong and unique passphrase) and none of your friends share it publicly then the chan will be secure and private.", None)) - self.label_5.setText(_translate("newChanDialog", "Chan name:", None)) - self.groupBoxJoinChan.setTitle(_translate("newChanDialog", "Join a chan", None)) - self.label.setText(_translate("newChanDialog", "

A chan exists when a group of people share the same decryption keys. The keys and bitmessage address used by a chan are generated from a human-friendly word or phrase (the chan name). To send a message to everyone in the chan, send a normal person-to-person message to the chan address.

Chans are experimental and completely unmoderatable.

", None)) - self.label_2.setText(_translate("newChanDialog", "Chan name:", None)) - self.label_3.setText(_translate("newChanDialog", "Chan bitmessage address:", None)) + def retranslateUi(self, NewChanDialog): + NewChanDialog.setWindowTitle(_translate("NewChanDialog", "Dialog", None)) + self.radioButtonCreateChan.setText(_translate("NewChanDialog", "Create a new chan", None)) + self.radioButtonJoinChan.setText(_translate("NewChanDialog", "Join a chan", None)) + self.groupBoxJoinChan.setTitle(_translate("NewChanDialog", "Join a chan", None)) + self.label.setText(_translate("NewChanDialog", "

A chan is a set of encryption keys that is shared by a group of people. The keys and bitmessage address used by a chan is generated from a human-friendly word or phrase (the chan name).

Chans are experimental and are unmoderatable.

", None)) + self.label_2.setText(_translate("NewChanDialog", "Chan name:", None)) + self.label_3.setText(_translate("NewChanDialog", "Chan bitmessage address:", None)) + self.groupBoxCreateChan.setTitle(_translate("NewChanDialog", "Create a chan", None)) + self.label_4.setText(_translate("NewChanDialog", "Enter a name for your chan. If you choose a sufficiently complex chan name (like a strong and unique passphrase) and none of your friends share it publicly then the chan will be secure and private.", None)) + self.label_5.setText(_translate("NewChanDialog", "Chan name:", None)) diff --git a/src/bitmessageqt/newchandialog.ui b/src/bitmessageqt/newchandialog.ui index 3713c6a3..2e6e4657 100644 --- a/src/bitmessageqt/newchandialog.ui +++ b/src/bitmessageqt/newchandialog.ui @@ -1,21 +1,15 @@ - newChanDialog - + NewChanDialog + 0 0 - 530 - 422 + 447 + 441 - - - 0 - 0 - - Dialog @@ -37,6 +31,45 @@
+ + + + Join a chan + + + + + + <html><head/><body><p>A chan is a set of encryption keys that is shared by a group of people. The keys and bitmessage address used by a chan is generated from a human-friendly word or phrase (the chan name).</p><p>Chans are experimental and are unmoderatable.</p></body></html> + + + true + + + + + + + Chan name: + + + + + + + + + + Chan bitmessage address: + + + + + + + + + @@ -66,59 +99,7 @@
- - - - Join a chan - - - - - - <html><head/><body><p>A chan exists when a group of people share the same decryption keys. The keys and bitmessage address used by a chan are generated from a human-friendly word or phrase (the chan name). To send a message to everyone in the chan, send a normal person-to-person message to the chan address.</p><p>Chans are experimental and completely unmoderatable.</p></body></html> - - - true - - - - - - - Chan name: - - - - - - - - - - Chan bitmessage address: - - - - - - - - - - - - Qt::Vertical - - - - 389 - 2 - - - - - Qt::Horizontal @@ -135,7 +116,7 @@ buttonBox accepted() - newChanDialog + NewChanDialog accept() @@ -151,7 +132,7 @@ buttonBox rejected() - newChanDialog + NewChanDialog reject() diff --git a/src/bitmessageqt/settings.py b/src/bitmessageqt/settings.py index d7672e9d..8c94333c 100644 --- a/src/bitmessageqt/settings.py +++ b/src/bitmessageqt/settings.py @@ -2,8 +2,8 @@ # Form implementation generated from reading ui file 'settings.ui' # -# Created: Fri Jul 12 12:37:53 2013 -# by: PyQt4 UI code generator 4.10.1 +# Created: Mon Jun 10 11:31:56 2013 +# by: PyQt4 UI code generator 4.9.4 # # WARNING! All changes made in this file will be lost! @@ -12,16 +12,7 @@ from PyQt4 import QtCore, QtGui try: _fromUtf8 = QtCore.QString.fromUtf8 except AttributeError: - def _fromUtf8(s): - return s - -try: - _encoding = QtGui.QApplication.UnicodeUTF8 - def _translate(context, text, disambig): - return QtGui.QApplication.translate(context, text, disambig, _encoding) -except AttributeError: - def _translate(context, text, disambig): - return QtGui.QApplication.translate(context, text, disambig) + _fromUtf8 = lambda s: s class Ui_settingsDialog(object): def setupUi(self, settingsDialog): @@ -131,9 +122,6 @@ class Ui_settingsDialog(object): self.lineEditSocksPassword.setEchoMode(QtGui.QLineEdit.Password) self.lineEditSocksPassword.setObjectName(_fromUtf8("lineEditSocksPassword")) self.gridLayout_2.addWidget(self.lineEditSocksPassword, 2, 5, 1, 1) - self.checkBoxSocksListen = QtGui.QCheckBox(self.groupBox_2) - self.checkBoxSocksListen.setObjectName(_fromUtf8("checkBoxSocksListen")) - self.gridLayout_2.addWidget(self.checkBoxSocksListen, 3, 1, 1, 4) self.gridLayout_4.addWidget(self.groupBox_2, 1, 0, 1, 1) spacerItem2 = QtGui.QSpacerItem(20, 70, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) self.gridLayout_4.addItem(spacerItem2, 2, 0, 1, 1) @@ -247,40 +235,38 @@ class Ui_settingsDialog(object): settingsDialog.setTabOrder(self.lineEditSocksPort, self.checkBoxAuthentication) settingsDialog.setTabOrder(self.checkBoxAuthentication, self.lineEditSocksUsername) settingsDialog.setTabOrder(self.lineEditSocksUsername, self.lineEditSocksPassword) - settingsDialog.setTabOrder(self.lineEditSocksPassword, self.checkBoxSocksListen) - settingsDialog.setTabOrder(self.checkBoxSocksListen, self.buttonBox) + settingsDialog.setTabOrder(self.lineEditSocksPassword, self.buttonBox) def retranslateUi(self, settingsDialog): - settingsDialog.setWindowTitle(_translate("settingsDialog", "Settings", None)) - self.checkBoxStartOnLogon.setText(_translate("settingsDialog", "Start Bitmessage on user login", None)) - self.checkBoxStartInTray.setText(_translate("settingsDialog", "Start Bitmessage in the tray (don\'t show main window)", None)) - self.checkBoxMinimizeToTray.setText(_translate("settingsDialog", "Minimize to tray", None)) - self.checkBoxShowTrayNotifications.setText(_translate("settingsDialog", "Show notification when message received", None)) - self.checkBoxPortableMode.setText(_translate("settingsDialog", "Run in Portable Mode", None)) - self.label_7.setText(_translate("settingsDialog", "In Portable Mode, messages and config files are stored in the same directory as the program rather than the normal application-data folder. This makes it convenient to run Bitmessage from a USB thumb drive.", None)) - self.tabWidgetSettings.setTabText(self.tabWidgetSettings.indexOf(self.tabUserInterface), _translate("settingsDialog", "User Interface", None)) - self.groupBox.setTitle(_translate("settingsDialog", "Listening port", None)) - self.label.setText(_translate("settingsDialog", "Listen for connections on port:", None)) - self.groupBox_2.setTitle(_translate("settingsDialog", "Proxy server / Tor", None)) - self.label_2.setText(_translate("settingsDialog", "Type:", None)) - self.comboBoxProxyType.setItemText(0, _translate("settingsDialog", "none", None)) - self.comboBoxProxyType.setItemText(1, _translate("settingsDialog", "SOCKS4a", None)) - self.comboBoxProxyType.setItemText(2, _translate("settingsDialog", "SOCKS5", None)) - self.label_3.setText(_translate("settingsDialog", "Server hostname:", None)) - self.label_4.setText(_translate("settingsDialog", "Port:", None)) - self.checkBoxAuthentication.setText(_translate("settingsDialog", "Authentication", None)) - self.label_5.setText(_translate("settingsDialog", "Username:", None)) - self.label_6.setText(_translate("settingsDialog", "Pass:", None)) - self.checkBoxSocksListen.setText(_translate("settingsDialog", "Listen for incoming connections when using proxy", None)) - self.tabWidgetSettings.setTabText(self.tabWidgetSettings.indexOf(self.tabNetworkSettings), _translate("settingsDialog", "Network Settings", None)) - self.label_8.setText(_translate("settingsDialog", "When someone sends you a message, their computer must first complete some work. The difficulty of this work, by default, is 1. You may raise this default for new addresses you create by changing the values here. Any new addresses you create will require senders to meet the higher difficulty. There is one exception: if you add a friend or acquaintance to your address book, Bitmessage will automatically notify them when you next send a message that they need only complete the minimum amount of work: difficulty 1. ", None)) - self.label_9.setText(_translate("settingsDialog", "Total difficulty:", None)) - self.label_11.setText(_translate("settingsDialog", "Small message difficulty:", None)) - self.label_12.setText(_translate("settingsDialog", "The \'Small message difficulty\' mostly only affects the difficulty of sending small messages. Doubling this value makes it almost twice as difficult to send a small message but doesn\'t really affect large messages.", None)) - self.label_10.setText(_translate("settingsDialog", "The \'Total difficulty\' affects the absolute amount of work the sender must complete. Doubling this value doubles the amount of work.", None)) - self.tabWidgetSettings.setTabText(self.tabWidgetSettings.indexOf(self.tab), _translate("settingsDialog", "Demanded difficulty", None)) - self.label_15.setText(_translate("settingsDialog", "Here you may set the maximum amount of work you are willing to do to send a message to another person. Setting these values to 0 means that any value is acceptable.", 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.tabWidgetSettings.setTabText(self.tabWidgetSettings.indexOf(self.tab_2), _translate("settingsDialog", "Max acceptable difficulty", None)) + settingsDialog.setWindowTitle(QtGui.QApplication.translate("settingsDialog", "Settings", None, QtGui.QApplication.UnicodeUTF8)) + self.checkBoxStartOnLogon.setText(QtGui.QApplication.translate("settingsDialog", "Start Bitmessage on user login", None, QtGui.QApplication.UnicodeUTF8)) + self.checkBoxStartInTray.setText(QtGui.QApplication.translate("settingsDialog", "Start Bitmessage in the tray (don\'t show main window)", None, QtGui.QApplication.UnicodeUTF8)) + self.checkBoxMinimizeToTray.setText(QtGui.QApplication.translate("settingsDialog", "Minimize to tray", None, QtGui.QApplication.UnicodeUTF8)) + self.checkBoxShowTrayNotifications.setText(QtGui.QApplication.translate("settingsDialog", "Show notification when message received", None, QtGui.QApplication.UnicodeUTF8)) + self.checkBoxPortableMode.setText(QtGui.QApplication.translate("settingsDialog", "Run in Portable Mode", None, QtGui.QApplication.UnicodeUTF8)) + self.label_7.setText(QtGui.QApplication.translate("settingsDialog", "In Portable Mode, messages and config files are stored in the same directory as the program rather than the normal application-data folder. This makes it convenient to run Bitmessage from a USB thumb drive.", None, QtGui.QApplication.UnicodeUTF8)) + self.tabWidgetSettings.setTabText(self.tabWidgetSettings.indexOf(self.tabUserInterface), QtGui.QApplication.translate("settingsDialog", "User Interface", None, QtGui.QApplication.UnicodeUTF8)) + self.groupBox.setTitle(QtGui.QApplication.translate("settingsDialog", "Listening port", None, QtGui.QApplication.UnicodeUTF8)) + self.label.setText(QtGui.QApplication.translate("settingsDialog", "Listen for connections on port:", None, QtGui.QApplication.UnicodeUTF8)) + self.groupBox_2.setTitle(QtGui.QApplication.translate("settingsDialog", "Proxy server / Tor", None, QtGui.QApplication.UnicodeUTF8)) + self.label_2.setText(QtGui.QApplication.translate("settingsDialog", "Type:", None, QtGui.QApplication.UnicodeUTF8)) + self.comboBoxProxyType.setItemText(0, QtGui.QApplication.translate("settingsDialog", "none", None, QtGui.QApplication.UnicodeUTF8)) + self.comboBoxProxyType.setItemText(1, QtGui.QApplication.translate("settingsDialog", "SOCKS4a", None, QtGui.QApplication.UnicodeUTF8)) + self.comboBoxProxyType.setItemText(2, QtGui.QApplication.translate("settingsDialog", "SOCKS5", None, QtGui.QApplication.UnicodeUTF8)) + self.label_3.setText(QtGui.QApplication.translate("settingsDialog", "Server hostname:", None, QtGui.QApplication.UnicodeUTF8)) + self.label_4.setText(QtGui.QApplication.translate("settingsDialog", "Port:", None, QtGui.QApplication.UnicodeUTF8)) + self.checkBoxAuthentication.setText(QtGui.QApplication.translate("settingsDialog", "Authentication", None, QtGui.QApplication.UnicodeUTF8)) + self.label_5.setText(QtGui.QApplication.translate("settingsDialog", "Username:", None, QtGui.QApplication.UnicodeUTF8)) + self.label_6.setText(QtGui.QApplication.translate("settingsDialog", "Pass:", None, QtGui.QApplication.UnicodeUTF8)) + self.tabWidgetSettings.setTabText(self.tabWidgetSettings.indexOf(self.tabNetworkSettings), QtGui.QApplication.translate("settingsDialog", "Network Settings", None, QtGui.QApplication.UnicodeUTF8)) + self.label_8.setText(QtGui.QApplication.translate("settingsDialog", "When someone sends you a message, their computer must first complete some work. The difficulty of this work, by default, is 1. You may raise this default for new addresses you create by changing the values here. Any new addresses you create will require senders to meet the higher difficulty. There is one exception: if you add a friend or acquaintance to your address book, Bitmessage will automatically notify them when you next send a message that they need only complete the minimum amount of work: difficulty 1. ", None, QtGui.QApplication.UnicodeUTF8)) + self.label_9.setText(QtGui.QApplication.translate("settingsDialog", "Total difficulty:", None, QtGui.QApplication.UnicodeUTF8)) + self.label_11.setText(QtGui.QApplication.translate("settingsDialog", "Small message difficulty:", None, QtGui.QApplication.UnicodeUTF8)) + self.label_12.setText(QtGui.QApplication.translate("settingsDialog", "The \'Small message difficulty\' mostly only affects the difficulty of sending small messages. Doubling this value makes it almost twice as difficult to send a small message but doesn\'t really affect large messages.", None, QtGui.QApplication.UnicodeUTF8)) + self.label_10.setText(QtGui.QApplication.translate("settingsDialog", "The \'Total difficulty\' affects the absolute amount of work the sender must complete. Doubling this value doubles the amount of work.", None, QtGui.QApplication.UnicodeUTF8)) + self.tabWidgetSettings.setTabText(self.tabWidgetSettings.indexOf(self.tab), QtGui.QApplication.translate("settingsDialog", "Demanded difficulty", None, QtGui.QApplication.UnicodeUTF8)) + self.label_15.setText(QtGui.QApplication.translate("settingsDialog", "Here you may set the maximum amount of work you are willing to do to send a message to another person. Setting these values to 0 means that any value is acceptable.", None, QtGui.QApplication.UnicodeUTF8)) + self.label_13.setText(QtGui.QApplication.translate("settingsDialog", "Maximum acceptable total difficulty:", None, QtGui.QApplication.UnicodeUTF8)) + self.label_14.setText(QtGui.QApplication.translate("settingsDialog", "Maximum acceptable small message difficulty:", None, QtGui.QApplication.UnicodeUTF8)) + self.tabWidgetSettings.setTabText(self.tabWidgetSettings.indexOf(self.tab_2), QtGui.QApplication.translate("settingsDialog", "Max acceptable difficulty", None, QtGui.QApplication.UnicodeUTF8)) diff --git a/src/bitmessageqt/settings.ui b/src/bitmessageqt/settings.ui index 9414e1a4..a1bb7c88 100644 --- a/src/bitmessageqt/settings.ui +++ b/src/bitmessageqt/settings.ui @@ -247,13 +247,6 @@ - - - - Listen for incoming connections when using proxy - - - @@ -515,7 +508,6 @@ checkBoxAuthentication lineEditSocksUsername lineEditSocksPassword - checkBoxSocksListen buttonBox diff --git a/src/class_addressGenerator.py b/src/class_addressGenerator.py index 54582541..08c7773e 100644 --- a/src/class_addressGenerator.py +++ b/src/class_addressGenerator.py @@ -28,8 +28,6 @@ class addressGenerator(threading.Thread): elif queueValue[0] == 'joinChan': command, chanAddress, label, deterministicPassphrase = queueValue eighteenByteRipe = False - addressVersionNumber = decodeAddress(chanAddress)[1] - streamNumber = decodeAddress(chanAddress)[2] numberOfAddressesToMake = 1 elif len(queueValue) == 7: command, addressVersionNumber, streamNumber, label, numberOfAddressesToMake, deterministicPassphrase, eighteenByteRipe = queueValue @@ -37,7 +35,7 @@ class addressGenerator(threading.Thread): command, addressVersionNumber, streamNumber, label, numberOfAddressesToMake, deterministicPassphrase, eighteenByteRipe, nonceTrialsPerByte, payloadLengthExtraBytes = queueValue else: sys.stderr.write( - 'Programming error: A structure with the wrong number of values was passed into the addressGeneratorQueue. Here is the queueValue: %s\n' % repr(queueValue)) + 'Programming error: A structure with the wrong number of values was passed into the addressGeneratorQueue. Here is the queueValue: %s\n' % queueValue) if addressVersionNumber < 3 or addressVersionNumber > 3: sys.stderr.write( 'Program error: For some reason the address generator queue has been given a request to create at least one version %s address which it cannot do.\n' % addressVersionNumber) @@ -119,8 +117,9 @@ class addressGenerator(threading.Thread): with open(shared.appdata + 'keys.dat', 'wb') as configfile: shared.config.write(configfile) - # The API and the join and create Chan functionality - # both need information back from the address generator. + # It may be the case that this address is being generated + # as a result of a call to the API. Let us put the result + # in the necessary queue. shared.apiAddressGeneratorReturnQueue.put(address) shared.UISignalQueue.put(( @@ -129,7 +128,7 @@ class addressGenerator(threading.Thread): label, address, streamNumber))) shared.reloadMyAddressHashes() shared.workerQueue.put(( - 'sendOutOrStoreMyV3Pubkey', ripe.digest())) + 'doPOWForMyV3Pubkey', ripe.digest())) elif command == 'createDeterministicAddresses' or command == 'getDeterministicAddress' or command == 'createChan' or command == 'joinChan': if len(deterministicPassphrase) == 0: @@ -189,7 +188,8 @@ class addressGenerator(threading.Thread): # If we are joining an existing chan, let us check to make sure it matches the provided Bitmessage address if command == 'joinChan': if address != chanAddress: - shared.apiAddressGeneratorReturnQueue.put('chan name does not match address') + #todo: show an error message in the UI + shared.apiAddressGeneratorReturnQueue.put('API Error 0018: Chan name does not match address.') saveAddressToDisk = False if command == 'getDeterministicAddress': saveAddressToDisk = False @@ -210,13 +210,8 @@ class addressGenerator(threading.Thread): privEncryptionKeyWIF = arithmetic.changebase( privEncryptionKey + checksum, 256, 58) - addressAlreadyExists = False try: shared.config.add_section(address) - except: - print address, 'already exists. Not adding it again.' - addressAlreadyExists = True - if not addressAlreadyExists: print 'label:', label shared.config.set(address, 'label', label) shared.config.set(address, 'enabled', 'true') @@ -242,13 +237,17 @@ class addressGenerator(threading.Thread): potentialPrivEncryptionKey.encode('hex')) shared.myAddressesByHash[ ripe.digest()] = address + #todo: don't send out pubkey if dealing with a chan; save in pubkeys table instead. shared.workerQueue.put(( - 'sendOutOrStoreMyV3Pubkey', ripe.digest())) # If this is a chan address, - # the worker thread won't send out the pubkey over the network. - + 'doPOWForMyV3Pubkey', ripe.digest())) + except: + print address, 'already exists. Not adding it again.' # Done generating addresses. - if command == 'createDeterministicAddresses' or command == 'joinChan' or command == 'createChan': + if command == 'createDeterministicAddresses': + # It may be the case that this address is being + # generated as a result of a call to the API. Let us + # put the result in the necessary queue. shared.apiAddressGeneratorReturnQueue.put( listOfNewAddressesToSendOutThroughTheAPI) shared.UISignalQueue.put(( diff --git a/src/class_bgWorker.py b/src/class_bgWorker.py deleted file mode 100644 index c01e26ef..00000000 --- a/src/class_bgWorker.py +++ /dev/null @@ -1,38 +0,0 @@ -#! /usr/bin/python -# -*- coding: utf-8 -*- -# cody by linker.lin@me.com - -__author__ = 'linkerlin' - - -import threading -import Queue -import time - -class bgWorker(threading.Thread): - def __init__(self): - threading.Thread.__init__(self) - self.q = Queue.Queue() - self.setDaemon(True) - - def post(self,job): - self.q.put(job) - - def run(self): - while 1: - job=None - try: - job = self.q.get(block=True) - if job: - job() - except Exception as ex: - print "Error,job exception:",ex.message,type(ex) - time.sleep(0.05) - else: - #print "job: ", job, " done" - pass - finally: - time.sleep(0.05) - -bgworker = bgWorker() -bgworker.start() diff --git a/src/class_outgoingSynSender.py b/src/class_outgoingSynSender.py index 5c21d72c..d547b3e3 100644 --- a/src/class_outgoingSynSender.py +++ b/src/class_outgoingSynSender.py @@ -7,6 +7,7 @@ import socket import sys import tr +#import bitmessagemain from class_sendDataThread import * from class_receiveDataThread import * @@ -60,15 +61,15 @@ class outgoingSynSender(threading.Thread): sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.settimeout(20) if shared.config.get('bitmessagesettings', 'socksproxytype') == 'none' and shared.verbose >= 2: - with shared.printLock: - print 'Trying an outgoing connection to', HOST, ':', PORT - + shared.printLock.acquire() + print 'Trying an outgoing connection to', HOST, ':', PORT + shared.printLock.release() # sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) elif shared.config.get('bitmessagesettings', 'socksproxytype') == 'SOCKS4a': if shared.verbose >= 2: - with shared.printLock: - print '(Using SOCKS4a) Trying an outgoing connection to', HOST, ':', PORT - + shared.printLock.acquire() + print '(Using SOCKS4a) Trying an outgoing connection to', HOST, ':', PORT + shared.printLock.release() proxytype = socks.PROXY_TYPE_SOCKS4 sockshostname = shared.config.get( 'bitmessagesettings', 'sockshostname') @@ -87,9 +88,9 @@ class outgoingSynSender(threading.Thread): proxytype, sockshostname, socksport, rdns) elif shared.config.get('bitmessagesettings', 'socksproxytype') == 'SOCKS5': if shared.verbose >= 2: - with shared.printLock: - print '(Using SOCKS5) Trying an outgoing connection to', HOST, ':', PORT - + shared.printLock.acquire() + print '(Using SOCKS5) Trying an outgoing connection to', HOST, ':', PORT + shared.printLock.release() proxytype = socks.PROXY_TYPE_SOCKS5 sockshostname = shared.config.get( 'bitmessagesettings', 'sockshostname') @@ -115,9 +116,9 @@ class outgoingSynSender(threading.Thread): rd.setup(sock, HOST, PORT, self.streamNumber, someObjectsOfWhichThisRemoteNodeIsAlreadyAware, self.selfInitiatedConnections) rd.start() - with shared.printLock: - print self, 'connected to', HOST, 'during an outgoing attempt.' - + shared.printLock.acquire() + print self, 'connected to', HOST, 'during an outgoing attempt.' + shared.printLock.release() sd = sendDataThread() sd.setup(sock, HOST, PORT, self.streamNumber, @@ -127,18 +128,18 @@ class outgoingSynSender(threading.Thread): except socks.GeneralProxyError as err: if shared.verbose >= 2: - with shared.printLock: - print 'Could NOT connect to', HOST, 'during outgoing attempt.', err - + shared.printLock.acquire() + print 'Could NOT connect to', HOST, 'during outgoing attempt.', err + shared.printLock.release() PORT, timeLastSeen = shared.knownNodes[ self.streamNumber][HOST] if (int(time.time()) - timeLastSeen) > 172800 and len(shared.knownNodes[self.streamNumber]) > 1000: # for nodes older than 48 hours old if we have more than 1000 hosts in our list, delete from the shared.knownNodes data-structure. shared.knownNodesLock.acquire() del shared.knownNodes[self.streamNumber][HOST] shared.knownNodesLock.release() - with shared.printLock: - print 'deleting ', HOST, 'from shared.knownNodes because it is more than 48 hours old and we could not connect to it.' - + shared.printLock.acquire() + print 'deleting ', HOST, 'from shared.knownNodes because it is more than 48 hours old and we could not connect to it.' + shared.printLock.release() except socks.Socks5AuthError as err: shared.UISignalQueue.put(( 'updateStatusBar', tr.translateText( @@ -153,18 +154,18 @@ class outgoingSynSender(threading.Thread): print 'Bitmessage MIGHT be having trouble connecting to the SOCKS server. ' + str(err) else: if shared.verbose >= 1: - with shared.printLock: - print 'Could NOT connect to', HOST, 'during outgoing attempt.', err - + shared.printLock.acquire() + print 'Could NOT connect to', HOST, 'during outgoing attempt.', err + shared.printLock.release() PORT, timeLastSeen = shared.knownNodes[ self.streamNumber][HOST] if (int(time.time()) - timeLastSeen) > 172800 and len(shared.knownNodes[self.streamNumber]) > 1000: # for nodes older than 48 hours old if we have more than 1000 hosts in our list, delete from the knownNodes data-structure. shared.knownNodesLock.acquire() del shared.knownNodes[self.streamNumber][HOST] shared.knownNodesLock.release() - with shared.printLock: - print 'deleting ', HOST, 'from knownNodes because it is more than 48 hours old and we could not connect to it.' - + shared.printLock.acquire() + print 'deleting ', HOST, 'from knownNodes because it is more than 48 hours old and we could not connect to it.' + shared.printLock.release() except Exception as err: sys.stderr.write( 'An exception has occurred in the outgoingSynSender thread that was not caught by other exception types: ') diff --git a/src/class_receiveDataThread.py b/src/class_receiveDataThread.py index 2693b293..ced951b2 100644 --- a/src/class_receiveDataThread.py +++ b/src/class_receiveDataThread.py @@ -61,67 +61,68 @@ class receiveDataThread(threading.Thread): self.someObjectsOfWhichThisRemoteNodeIsAlreadyAware = someObjectsOfWhichThisRemoteNodeIsAlreadyAware def run(self): - with shared.printLock: - print 'ID of the receiveDataThread is', str(id(self)) + '. The size of the shared.connectedHostsList is now', len(shared.connectedHostsList) - + shared.printLock.acquire() + print 'ID of the receiveDataThread is', str(id(self)) + '. The size of the shared.connectedHostsList is now', len(shared.connectedHostsList) + shared.printLock.release() while True: dataLen = len(self.data) try: self.data += self.sock.recv(4096) except socket.timeout: - with shared.printLock: - print 'Timeout occurred waiting for data from', self.HOST + '. Closing receiveData thread. (ID:', str(id(self)) + ')' - + shared.printLock.acquire() + print 'Timeout occurred waiting for data from', self.HOST + '. Closing receiveData thread. (ID:', str(id(self)) + ')' + shared.printLock.release() break except Exception as err: - with shared.printLock: - print 'sock.recv error. Closing receiveData thread (HOST:', self.HOST, 'ID:', str(id(self)) + ').', err - + shared.printLock.acquire() + print 'sock.recv error. Closing receiveData thread (HOST:', self.HOST, 'ID:', str(id(self)) + ').', err + shared.printLock.release() break # print 'Received', repr(self.data) - if len(self.data) == dataLen: # If self.sock.recv returned no data: - with shared.printLock: - print 'Connection to', self.HOST, 'closed. Closing receiveData thread. (ID:', str(id(self)) + ')' + if len(self.data) == dataLen: + shared.printLock.acquire() + print 'Connection to', self.HOST, 'closed. Closing receiveData thread. (ID:', str(id(self)) + ')' + shared.printLock.release() break else: self.processData() try: del self.selfInitiatedConnections[self.streamNumber][self] - with shared.printLock: - print 'removed self (a receiveDataThread) from selfInitiatedConnections' - + shared.printLock.acquire() + print 'removed self (a receiveDataThread) from selfInitiatedConnections' + shared.printLock.release() except: pass shared.broadcastToSendDataQueues((0, 'shutdown', self.HOST)) try: del shared.connectedHostsList[self.HOST] except Exception as err: - with shared.printLock: - print 'Could not delete', self.HOST, 'from shared.connectedHostsList.', err - + shared.printLock.acquire() + print 'Could not delete', self.HOST, 'from shared.connectedHostsList.', err + shared.printLock.release() try: del shared.numberOfObjectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHavePerPeer[ self.HOST] except: pass shared.UISignalQueue.put(('updateNetworkStatusTab', 'no data')) - with shared.printLock: - print 'The size of the connectedHostsList is now:', len(shared.connectedHostsList) - + shared.printLock.acquire() + print 'The size of the connectedHostsList is now:', len(shared.connectedHostsList) + shared.printLock.release() def processData(self): # if shared.verbose >= 3: - # with shared.printLock: - # print 'self.data is currently ', repr(self.data) - # + # shared.printLock.acquire() + # print 'self.data is currently ', repr(self.data) + # shared.printLock.release() if len(self.data) < 20: # if so little of the data has arrived that we can't even unpack the payload length return if self.data[0:4] != '\xe9\xbe\xb4\xd9': if shared.verbose >= 1: - with shared.printLock: - print 'The magic bytes were not correct. First 40 bytes of data: ' + repr(self.data[0:40]) - + shared.printLock.acquire() + print 'The magic bytes were not correct. First 40 bytes of data: ' + repr(self.data[0:40]) + shared.printLock.release() self.data = "" return self.payloadLength, = unpack('>L', self.data[16:20]) @@ -142,9 +143,9 @@ class receiveDataThread(threading.Thread): shared.knownNodesLock.release() if self.payloadLength <= 180000000: # If the size of the message is greater than 180MB, ignore it. (I get memory errors when processing messages much larger than this though it is concievable that this value will have to be lowered if some systems are less tolarant of large messages.) remoteCommand = self.data[4:16] - with shared.printLock: - print 'remoteCommand', repr(remoteCommand.replace('\x00', '')), ' from', self.HOST - + shared.printLock.acquire() + print 'remoteCommand', repr(remoteCommand.replace('\x00', '')), ' from', self.HOST + shared.printLock.release() if remoteCommand == 'version\x00\x00\x00\x00\x00': self.recversion(self.data[24:self.payloadLength + 24]) elif remoteCommand == 'verack\x00\x00\x00\x00\x00\x00': @@ -178,16 +179,16 @@ class receiveDataThread(threading.Thread): objectHash, = random.sample( self.objectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave, 1) if objectHash in shared.inventory: - with shared.printLock: - print 'Inventory (in memory) already has object listed in inv message.' - + shared.printLock.acquire() + print 'Inventory (in memory) already has object listed in inv message.' + shared.printLock.release() del self.objectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave[ objectHash] elif shared.isInSqlInventory(objectHash): if shared.verbose >= 3: - with shared.printLock: - print 'Inventory (SQL on disk) already has object listed in inv message.' - + shared.printLock.acquire() + print 'Inventory (SQL on disk) already has object listed in inv message.' + shared.printLock.release() del self.objectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave[ objectHash] else: @@ -195,9 +196,9 @@ class receiveDataThread(threading.Thread): del self.objectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave[ objectHash] # It is possible that the remote node doesn't respond with the object. In that case, we'll very likely get it from someone else anyway. if len(self.objectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave) == 0: - with shared.printLock: - print '(concerning', self.HOST + ')', 'number of objectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave is now', len(self.objectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave) - + shared.printLock.acquire() + print '(concerning', self.HOST + ')', 'number of objectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave is now', len(self.objectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave) + shared.printLock.release() try: del shared.numberOfObjectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHavePerPeer[ self.HOST] # this data structure is maintained so that we can keep track of how many total objects, across all connections, are currently outstanding. If it goes too high it can indicate that we are under attack by multiple nodes working together. @@ -205,18 +206,18 @@ class receiveDataThread(threading.Thread): pass break if len(self.objectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave) == 0: - with shared.printLock: - print '(concerning', self.HOST + ')', 'number of objectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave is now', len(self.objectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave) - + shared.printLock.acquire() + print '(concerning', self.HOST + ')', 'number of objectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave is now', len(self.objectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave) + shared.printLock.release() try: del shared.numberOfObjectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHavePerPeer[ self.HOST] # this data structure is maintained so that we can keep track of how many total objects, across all connections, are currently outstanding. If it goes too high it can indicate that we are under attack by multiple nodes working together. except: pass if len(self.objectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave) > 0: - with shared.printLock: - print '(concerning', self.HOST + ')', 'number of objectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave is now', len(self.objectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave) - + shared.printLock.acquire() + print '(concerning', self.HOST + ')', 'number of objectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave is now', len(self.objectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave) + shared.printLock.release() shared.numberOfObjectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHavePerPeer[self.HOST] = len( self.objectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave) # this data structure is maintained so that we can keep track of how many total objects, across all connections, are currently outstanding. If it goes too high it can indicate that we are under attack by multiple nodes working together. if len(self.ackDataThatWeHaveYetToSend) > 0: @@ -244,9 +245,9 @@ class receiveDataThread(threading.Thread): '\xE9\xBE\xB4\xD9\x70\x6F\x6E\x67\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcf\x83\xe1\x35') except Exception as err: # if not 'Bad file descriptor' in err: - with shared.printLock: - print 'sock.sendall error:', err - + shared.printLock.acquire() + print 'sock.sendall error:', err + shared.printLock.release() def recverack(self): print 'verack received' @@ -264,19 +265,19 @@ class receiveDataThread(threading.Thread): shared.UISignalQueue.put(('updateNetworkStatusTab', 'no data')) remoteNodeIncomingPort, remoteNodeSeenTime = shared.knownNodes[ self.streamNumber][self.HOST] - with shared.printLock: - print 'Connection fully established with', self.HOST, remoteNodeIncomingPort - print 'The size of the connectedHostsList is now', len(shared.connectedHostsList) - print 'The length of sendDataQueues is now:', len(shared.sendDataQueues) - print 'broadcasting addr from within connectionFullyEstablished function.' - + shared.printLock.acquire() + print 'Connection fully established with', self.HOST, remoteNodeIncomingPort + print 'The size of the connectedHostsList is now', len(shared.connectedHostsList) + print 'The length of sendDataQueues is now:', len(shared.sendDataQueues) + print 'broadcasting addr from within connectionFullyEstablished function.' + shared.printLock.release() self.broadcastaddr([(int(time.time()), self.streamNumber, 1, self.HOST, remoteNodeIncomingPort)]) # This lets all of our peers know about this new node. self.sendaddr() # This is one large addr message to this one peer. if not self.initiatedConnection and len(shared.connectedHostsList) > 200: - with shared.printLock: - print 'We are connected to too many people. Closing connection.' - + shared.printLock.acquire() + print 'We are connected to too many people. Closing connection.' + shared.printLock.release() shared.broadcastToSendDataQueues((0, 'shutdown', self.HOST)) return self.sendBigInv() @@ -328,16 +329,16 @@ class receiveDataThread(threading.Thread): headerData += 'inv\x00\x00\x00\x00\x00\x00\x00\x00\x00' headerData += pack('>L', len(payload)) headerData += hashlib.sha512(payload).digest()[:4] - with shared.printLock: - print 'Sending huge inv message with', numberOfObjects, 'objects to just this one peer' - + shared.printLock.acquire() + print 'Sending huge inv message with', numberOfObjects, 'objects to just this one peer' + shared.printLock.release() try: self.sock.sendall(headerData + payload) except Exception as err: # if not 'Bad file descriptor' in err: - with shared.printLock: - print 'sock.sendall error:', err - + shared.printLock.acquire() + print 'sock.sendall error:', err + shared.printLock.release() # We have received a broadcast message def recbroadcast(self, data): @@ -416,13 +417,13 @@ class receiveDataThread(threading.Thread): sleepTime = lengthOfTimeWeShouldUseToProcessThisMessage - \ (time.time() - self.messageProcessingStartTime) if sleepTime > 0 and doTimingAttackMitigation: - with shared.printLock: - print 'Timing attack mitigation: Sleeping for', sleepTime, 'seconds.' - + shared.printLock.acquire() + print 'Timing attack mitigation: Sleeping for', sleepTime, 'seconds.' + shared.printLock.release() time.sleep(sleepTime) - with shared.printLock: - print 'Total message processing time:', time.time() - self.messageProcessingStartTime, 'seconds.' - + shared.printLock.acquire() + print 'Total message processing time:', time.time() - self.messageProcessingStartTime, 'seconds.' + shared.printLock.release() # A broadcast message has a valid time and POW and requires processing. # The recbroadcast function calls this one. @@ -459,9 +460,9 @@ class receiveDataThread(threading.Thread): sendersHash = data[readPosition:readPosition + 20] if sendersHash not in shared.broadcastSendersForWhichImWatching: # Display timing data - with shared.printLock: - print 'Time spent deciding that we are not interested in this v1 broadcast:', time.time() - self.messageProcessingStartTime - + shared.printLock.acquire() + print 'Time spent deciding that we are not interested in this v1 broadcast:', time.time() - self.messageProcessingStartTime + shared.printLock.release() return # At this point, this message claims to be from sendersHash and # we are interested in it. We still have to hash the public key @@ -524,11 +525,17 @@ class receiveDataThread(threading.Thread): fromAddress = encodeAddress( sendersAddressVersion, sendersStream, ripe.digest()) - with shared.printLock: - print 'fromAddress:', fromAddress - + shared.printLock.acquire() + print 'fromAddress:', fromAddress + shared.printLock.release() if messageEncodingType == 2: - subject, body = self.decodeType2Message(message) + bodyPositionIndex = string.find(message, '\nBody:') + if bodyPositionIndex > 1: + subject = message[8:bodyPositionIndex] + body = message[bodyPositionIndex + 6:] + else: + subject = '' + body = message elif messageEncodingType == 1: body = message subject = '' @@ -561,9 +568,9 @@ class receiveDataThread(threading.Thread): call([apiNotifyPath, "newBroadcast"]) # Display timing data - with shared.printLock: - print 'Time spent processing this interesting broadcast:', time.time() - self.messageProcessingStartTime - + shared.printLock.acquire() + print 'Time spent processing this interesting broadcast:', time.time() - self.messageProcessingStartTime + shared.printLock.release() if broadcastVersion == 2: cleartextStreamNumber, cleartextStreamNumberLength = decodeVarint( data[readPosition:readPosition + 10]) @@ -581,9 +588,9 @@ class receiveDataThread(threading.Thread): # print 'cryptorObject.decrypt Exception:', err if not initialDecryptionSuccessful: # This is not a broadcast I am interested in. - with shared.printLock: - print 'Length of time program spent failing to decrypt this v2 broadcast:', time.time() - self.messageProcessingStartTime, 'seconds.' - + shared.printLock.acquire() + print 'Length of time program spent failing to decrypt this v2 broadcast:', time.time() - self.messageProcessingStartTime, 'seconds.' + shared.printLock.release() return # At this point this is a broadcast I have decrypted and thus am # interested in. @@ -674,11 +681,17 @@ class receiveDataThread(threading.Thread): fromAddress = encodeAddress( sendersAddressVersion, sendersStream, ripe.digest()) - with shared.printLock: - print 'fromAddress:', fromAddress - + shared.printLock.acquire() + print 'fromAddress:', fromAddress + shared.printLock.release() if messageEncodingType == 2: - subject, body = self.decodeType2Message(message) + bodyPositionIndex = string.find(message, '\nBody:') + if bodyPositionIndex > 1: + subject = message[8:bodyPositionIndex] + body = message[bodyPositionIndex + 6:] + else: + subject = '' + body = message elif messageEncodingType == 1: body = message subject = '' @@ -711,9 +724,9 @@ class receiveDataThread(threading.Thread): call([apiNotifyPath, "newBroadcast"]) # Display timing data - with shared.printLock: - print 'Time spent processing this interesting broadcast:', time.time() - self.messageProcessingStartTime - + shared.printLock.acquire() + print 'Time spent processing this interesting broadcast:', time.time() - self.messageProcessingStartTime + shared.printLock.release() # We have received a msg message. def recmsg(self, data): @@ -783,13 +796,13 @@ class receiveDataThread(threading.Thread): sleepTime = lengthOfTimeWeShouldUseToProcessThisMessage - \ (time.time() - self.messageProcessingStartTime) if sleepTime > 0 and doTimingAttackMitigation: - with shared.printLock: - print 'Timing attack mitigation: Sleeping for', sleepTime, 'seconds.' - + shared.printLock.acquire() + print 'Timing attack mitigation: Sleeping for', sleepTime, 'seconds.' + shared.printLock.release() time.sleep(sleepTime) - with shared.printLock: - print 'Total message processing time:', time.time() - self.messageProcessingStartTime, 'seconds.' - + shared.printLock.acquire() + print 'Total message processing time:', time.time() - self.messageProcessingStartTime, 'seconds.' + shared.printLock.release() # A msg message has a valid time and POW and requires processing. The # recmsg function calls this one. @@ -797,9 +810,9 @@ class receiveDataThread(threading.Thread): initialDecryptionSuccessful = False # Let's check whether this is a message acknowledgement bound for us. if encryptedData[readPosition:] in shared.ackdataForWhichImWatching: - with shared.printLock: - print 'This msg IS an acknowledgement bound for me.' - + shared.printLock.acquire() + print 'This msg IS an acknowledgement bound for me.' + shared.printLock.release() del shared.ackdataForWhichImWatching[encryptedData[readPosition:]] t = ('ackreceived', encryptedData[readPosition:]) shared.sqlLock.acquire() @@ -813,10 +826,10 @@ class receiveDataThread(threading.Thread): time.strftime(shared.config.get('bitmessagesettings', 'timeformat'), time.localtime(int(time.time()))), 'utf-8'))))) return else: - with shared.printLock: - print 'This was NOT an acknowledgement bound for me.' + shared.printLock.acquire() + print 'This was NOT an acknowledgement bound for me.' # print 'shared.ackdataForWhichImWatching', shared.ackdataForWhichImWatching - + shared.printLock.release() # This is not an acknowledgement bound for me. See if it is a message # bound for me by trying to decrypt it with my private keys. @@ -826,17 +839,16 @@ class receiveDataThread(threading.Thread): encryptedData[readPosition:]) toRipe = key # This is the RIPE hash of my pubkeys. We need this below to compare to the destination_ripe included in the encrypted data. initialDecryptionSuccessful = True - with shared.printLock: - print 'EC decryption successful using key associated with ripe hash:', key.encode('hex') + print 'EC decryption successful using key associated with ripe hash:', key.encode('hex') break except Exception as err: pass # print 'cryptorObject.decrypt Exception:', err if not initialDecryptionSuccessful: # This is not a message bound for me. - with shared.printLock: - print 'Length of time program spent failing to decrypt this message:', time.time() - self.messageProcessingStartTime, 'seconds.' - + shared.printLock.acquire() + print 'Length of time program spent failing to decrypt this message:', time.time() - self.messageProcessingStartTime, 'seconds.' + shared.printLock.release() else: # This is a message bound for me. toAddress = shared.myAddressesByHash[ @@ -885,12 +897,12 @@ class receiveDataThread(threading.Thread): print 'sender\'s requiredPayloadLengthExtraBytes is', requiredPayloadLengthExtraBytes endOfThePublicKeyPosition = readPosition # needed for when we store the pubkey in our database of pubkeys for later use. if toRipe != decryptedData[readPosition:readPosition + 20]: - with shared.printLock: - print 'The original sender of this message did not send it to you. Someone is attempting a Surreptitious Forwarding Attack.' - print 'See: http://world.std.com/~dtd/sign_encrypt/sign_encrypt7.html' - print 'your toRipe:', toRipe.encode('hex') - print 'embedded destination toRipe:', decryptedData[readPosition:readPosition + 20].encode('hex') - + shared.printLock.acquire() + print 'The original sender of this message did not send it to you. Someone is attempting a Surreptitious Forwarding Attack.' + print 'See: http://world.std.com/~dtd/sign_encrypt/sign_encrypt7.html' + print 'your toRipe:', toRipe.encode('hex') + print 'embedded destination toRipe:', decryptedData[readPosition:readPosition + 20].encode('hex') + shared.printLock.release() return readPosition += 20 messageEncodingType, messageEncodingTypeLength = decodeVarint( @@ -921,9 +933,9 @@ class receiveDataThread(threading.Thread): except Exception as err: print 'ECDSA verify failed', err return - with shared.printLock: - print 'As a matter of intellectual curiosity, here is the Bitcoin address associated with the keys owned by the other person:', helper_bitcoin.calculateBitcoinAddressFromPubkey(pubSigningKey), ' ..and here is the testnet address:', helper_bitcoin.calculateTestnetAddressFromPubkey(pubSigningKey), '. The other person must take their private signing key from Bitmessage and import it into Bitcoin (or a service like Blockchain.info) for it to be of any use. Do not use this unless you know what you are doing.' - + shared.printLock.acquire() + print 'As a matter of intellectual curiosity, here is the Bitcoin address associated with the keys owned by the other person:', helper_bitcoin.calculateBitcoinAddressFromPubkey(pubSigningKey), ' ..and here is the testnet address:', helper_bitcoin.calculateTestnetAddressFromPubkey(pubSigningKey), '. The other person must take their private signing key from Bitmessage and import it into Bitcoin (or a service like Blockchain.info) for it to be of any use. Do not use this unless you know what you are doing.' + shared.printLock.release() # calculate the fromRipe. sha = hashlib.new('sha512') sha.update(pubSigningKey + pubEncryptionKey) @@ -969,9 +981,9 @@ class receiveDataThread(threading.Thread): queryreturn = shared.sqlReturnQueue.get() shared.sqlLock.release() if queryreturn != []: - with shared.printLock: - print 'Message ignored because address is in blacklist.' - + shared.printLock.acquire() + print 'Message ignored because address is in blacklist.' + shared.printLock.release() blockMessage = True else: # We're using a whitelist t = (fromAddress,) @@ -993,7 +1005,15 @@ class receiveDataThread(threading.Thread): toLabel = toAddress if messageEncodingType == 2: - subject, body = self.decodeType2Message(message) + bodyPositionIndex = string.find(message, '\nBody:') + if bodyPositionIndex > 1: + subject = message[8:bodyPositionIndex] + subject = subject[ + :500] # Only save and show the first 500 characters of the subject. Any more is probably an attak. + body = message[bodyPositionIndex + 6:] + else: + subject = '' + body = message elif messageEncodingType == 1: body = message subject = '' @@ -1062,25 +1082,10 @@ class receiveDataThread(threading.Thread): sum = 0 for item in shared.successfullyDecryptMessageTimings: sum += item - with shared.printLock: - print 'Time to decrypt this message successfully:', timeRequiredToAttemptToDecryptMessage - print 'Average time for all message decryption successes since startup:', sum / len(shared.successfullyDecryptMessageTimings) - - def decodeType2Message(self, message): - bodyPositionIndex = string.find(message, '\nBody:') - if bodyPositionIndex > 1: - subject = message[8:bodyPositionIndex] - # Only save and show the first 500 characters of the subject. - # Any more is probably an attack. - subject = subject[:500] - body = message[bodyPositionIndex + 6:] - else: - subject = '' - body = message - # Throw away any extra lines (headers) after the subject. - if subject: - subject = subject.splitlines()[0] - return subject, body + shared.printLock.acquire() + print 'Time to decrypt this message successfully:', timeRequiredToAttemptToDecryptMessage + print 'Average time for all message decryption successes since startup:', sum / len(shared.successfullyDecryptMessageTimings) + shared.printLock.release() def isAckDataValid(self, ackData): if len(ackData) < 24: @@ -1120,9 +1125,9 @@ class receiveDataThread(threading.Thread): shared.sqlLock.release() shared.workerQueue.put(('sendmessage', '')) else: - with shared.printLock: - print 'We don\'t need this pub key. We didn\'t ask for it. Pubkey hash:', toRipe.encode('hex') - + shared.printLock.acquire() + print 'We don\'t need this pub key. We didn\'t ask for it. Pubkey hash:', toRipe.encode('hex') + shared.printLock.release() # We have received a pubkey def recpubkey(self, data): @@ -1146,14 +1151,14 @@ class receiveDataThread(threading.Thread): readPosition += 4 if embeddedTime < int(time.time()) - shared.lengthOfTimeToHoldOnToAllPubkeys: - with shared.printLock: - print 'The embedded time in this pubkey message is too old. Ignoring. Embedded time is:', embeddedTime - + shared.printLock.acquire() + print 'The embedded time in this pubkey message is too old. Ignoring. Embedded time is:', embeddedTime + shared.printLock.release() return if embeddedTime > int(time.time()) + 10800: - with shared.printLock: - print 'The embedded time in this pubkey message more than several hours in the future. This is irrational. Ignoring message.' - + shared.printLock.acquire() + print 'The embedded time in this pubkey message more than several hours in the future. This is irrational. Ignoring message.' + shared.printLock.release() return addressVersion, varintLength = decodeVarint( data[readPosition:readPosition + 10]) @@ -1189,13 +1194,13 @@ class receiveDataThread(threading.Thread): sleepTime = lengthOfTimeWeShouldUseToProcessThisMessage - \ (time.time() - self.pubkeyProcessingStartTime) if sleepTime > 0 and doTimingAttackMitigation: - with shared.printLock: - print 'Timing attack mitigation: Sleeping for', sleepTime, 'seconds.' - + shared.printLock.acquire() + print 'Timing attack mitigation: Sleeping for', sleepTime, 'seconds.' + shared.printLock.release() time.sleep(sleepTime) - with shared.printLock: - print 'Total pubkey processing time:', time.time() - self.pubkeyProcessingStartTime, 'seconds.' - + shared.printLock.acquire() + print 'Total pubkey processing time:', time.time() - self.pubkeyProcessingStartTime, 'seconds.' + shared.printLock.release() def processpubkey(self, data): readPosition = 8 # for the nonce @@ -1219,9 +1224,9 @@ class receiveDataThread(threading.Thread): print '(Within processpubkey) addressVersion of 0 doesn\'t make sense.' return if addressVersion >= 4 or addressVersion == 1: - with shared.printLock: - print 'This version of Bitmessage cannot handle version', addressVersion, 'addresses.' - + shared.printLock.acquire() + print 'This version of Bitmessage cannot handle version', addressVersion, 'addresses.' + shared.printLock.release() return if addressVersion == 2: if len(data) < 146: # sanity check. This is the minimum possible length. @@ -1245,12 +1250,12 @@ class receiveDataThread(threading.Thread): ripeHasher.update(sha.digest()) ripe = ripeHasher.digest() - with shared.printLock: - print 'within recpubkey, addressVersion:', addressVersion, ', streamNumber:', streamNumber - print 'ripe', ripe.encode('hex') - print 'publicSigningKey in hex:', publicSigningKey.encode('hex') - print 'publicEncryptionKey in hex:', publicEncryptionKey.encode('hex') - + shared.printLock.acquire() + print 'within recpubkey, addressVersion:', addressVersion, ', streamNumber:', streamNumber + print 'ripe', ripe.encode('hex') + print 'publicSigningKey in hex:', publicSigningKey.encode('hex') + print 'publicEncryptionKey in hex:', publicEncryptionKey.encode('hex') + shared.printLock.release() t = (ripe,) shared.sqlLock.acquire() @@ -1314,12 +1319,12 @@ class receiveDataThread(threading.Thread): ripeHasher.update(sha.digest()) ripe = ripeHasher.digest() - with shared.printLock: - print 'within recpubkey, addressVersion:', addressVersion, ', streamNumber:', streamNumber - print 'ripe', ripe.encode('hex') - print 'publicSigningKey in hex:', publicSigningKey.encode('hex') - print 'publicEncryptionKey in hex:', publicEncryptionKey.encode('hex') - + shared.printLock.acquire() + print 'within recpubkey, addressVersion:', addressVersion, ', streamNumber:', streamNumber + print 'ripe', ripe.encode('hex') + print 'publicSigningKey in hex:', publicSigningKey.encode('hex') + print 'publicEncryptionKey in hex:', publicEncryptionKey.encode('hex') + shared.printLock.release() t = (ripe,) shared.sqlLock.acquire() @@ -1412,43 +1417,38 @@ class receiveDataThread(threading.Thread): if len(requestedHash) != 20: print 'The length of the requested hash is not 20 bytes. Something is wrong. Ignoring.' return - with shared.printLock: - print 'the hash requested in this getpubkey request is:', requestedHash.encode('hex') + print 'the hash requested in this getpubkey request is:', requestedHash.encode('hex') if requestedHash in shared.myAddressesByHash: # if this address hash is one of mine if decodeAddress(shared.myAddressesByHash[requestedHash])[1] != requestedAddressVersionNumber: - with shared.printLock: - sys.stderr.write( - '(Within the recgetpubkey function) Someone requested one of my pubkeys but the requestedAddressVersionNumber doesn\'t match my actual address version number. They shouldn\'t have done that. Ignoring.\n') + shared.printLock.acquire() + sys.stderr.write( + '(Within the recgetpubkey function) Someone requested one of my pubkeys but the requestedAddressVersionNumber doesn\'t match my actual address version number. That shouldn\'t have happened. Ignoring.\n') + shared.printLock.release() return - if shared.safeConfigGetBoolean(shared.myAddressesByHash[requestedHash], 'chan'): - with shared.printLock: - print 'Ignoring getpubkey request because it is for one of my chan addresses. The other party should already have the pubkey.' - return try: lastPubkeySendTime = int(shared.config.get( shared.myAddressesByHash[requestedHash], 'lastpubkeysendtime')) except: lastPubkeySendTime = 0 - if lastPubkeySendTime > time.time() - shared.lengthOfTimeToHoldOnToAllPubkeys: # If the last time we sent our pubkey was more recent than 28 days ago... - with shared.printLock: - print 'Found getpubkey-requested-hash in my list of EC hashes BUT we already sent it recently. Ignoring request. The lastPubkeySendTime is:', lastPubkeySendTime - return - - with shared.printLock: + if lastPubkeySendTime < time.time() - shared.lengthOfTimeToHoldOnToAllPubkeys: # If the last time we sent our pubkey was at least 28 days ago... + shared.printLock.acquire() print 'Found getpubkey-requested-hash in my list of EC hashes. Telling Worker thread to do the POW for a pubkey message and send it out.' - if requestedAddressVersionNumber == 2: - shared.workerQueue.put(( - 'doPOWForMyV2Pubkey', requestedHash)) - elif requestedAddressVersionNumber == 3: - shared.workerQueue.put(( - 'sendOutOrStoreMyV3Pubkey', requestedHash)) - - + shared.printLock.release() + if requestedAddressVersionNumber == 2: + shared.workerQueue.put(( + 'doPOWForMyV2Pubkey', requestedHash)) + elif requestedAddressVersionNumber == 3: + shared.workerQueue.put(( + 'doPOWForMyV3Pubkey', requestedHash)) + else: + shared.printLock.acquire() + print 'Found getpubkey-requested-hash in my list of EC hashes BUT we already sent it recently. Ignoring request. The lastPubkeySendTime is:', lastPubkeySendTime + shared.printLock.release() else: - with shared.printLock: - print 'This getpubkey request is not for any of my keys.' - + shared.printLock.acquire() + print 'This getpubkey request is not for any of my keys.' + shared.printLock.release() # We have received an inv message def recinv(self, data): @@ -1456,10 +1456,10 @@ class receiveDataThread(threading.Thread): if len(shared.numberOfObjectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHavePerPeer) > 0: for key, value in shared.numberOfObjectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHavePerPeer.items(): totalNumberOfObjectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave += value - with shared.printLock: - print 'number of keys(hosts) in shared.numberOfObjectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHavePerPeer:', len(shared.numberOfObjectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHavePerPeer) - print 'totalNumberOfObjectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave = ', totalNumberOfObjectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave - + shared.printLock.acquire() + print 'number of keys(hosts) in shared.numberOfObjectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHavePerPeer:', len(shared.numberOfObjectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHavePerPeer) + print 'totalNumberOfObjectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave = ', totalNumberOfObjectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave + shared.printLock.release() numberOfItemsInInv, lengthOfVarint = decodeVarint(data[:10]) if numberOfItemsInInv > 50000: sys.stderr.write('Too many items in inv message!') @@ -1469,16 +1469,16 @@ class receiveDataThread(threading.Thread): return if numberOfItemsInInv == 1: # we'll just request this data from the person who advertised the object. if totalNumberOfObjectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave > 200000 and len(self.objectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave) > 1000: # inv flooding attack mitigation - with shared.printLock: - print 'We already have', totalNumberOfObjectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave, 'items yet to retrieve from peers and over 1000 from this node in particular. Ignoring this inv message.' - + shared.printLock.acquire() + print 'We already have', totalNumberOfObjectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave, 'items yet to retrieve from peers and over 1000 from this node in particular. Ignoring this inv message.' + shared.printLock.release() return self.someObjectsOfWhichThisRemoteNodeIsAlreadyAware[ data[lengthOfVarint:32 + lengthOfVarint]] = 0 if data[lengthOfVarint:32 + lengthOfVarint] in shared.inventory: - with shared.printLock: - print 'Inventory (in memory) has inventory item already.' - + shared.printLock.acquire() + print 'Inventory (in memory) has inventory item already.' + shared.printLock.release() elif shared.isInSqlInventory(data[lengthOfVarint:32 + lengthOfVarint]): print 'Inventory (SQL on disk) has inventory item already.' else: @@ -1488,9 +1488,9 @@ class receiveDataThread(threading.Thread): for i in range(numberOfItemsInInv): # upon finishing dealing with an incoming message, the receiveDataThread will request a random object from the peer. This way if we get multiple inv messages from multiple peers which list mostly the same objects, we will make getdata requests for different random objects from the various peers. if len(data[lengthOfVarint + (32 * i):32 + lengthOfVarint + (32 * i)]) == 32: # The length of an inventory hash should be 32. If it isn't 32 then the remote node is either badly programmed or behaving nefariously. if totalNumberOfObjectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave > 200000 and len(self.objectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave) > 1000: # inv flooding attack mitigation - with shared.printLock: - print 'We already have', totalNumberOfObjectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave, 'items yet to retrieve from peers and over', len(self.objectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave), 'from this node in particular. Ignoring the rest of this inv message.' - + shared.printLock.acquire() + print 'We already have', totalNumberOfObjectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave, 'items yet to retrieve from peers and over', len(self.objectsThatWeHaveYetToCheckAndSeeWhetherWeAlreadyHave), 'from this node in particular. Ignoring the rest of this inv message.' + shared.printLock.release() break self.someObjectsOfWhichThisRemoteNodeIsAlreadyAware[data[ lengthOfVarint + (32 * i):32 + lengthOfVarint + (32 * i)]] = 0 @@ -1502,9 +1502,9 @@ class receiveDataThread(threading.Thread): # Send a getdata message to our peer to request the object with the given # hash def sendgetdata(self, hash): - with shared.printLock: - print 'sending getdata to retrieve object with hash:', hash.encode('hex') - + shared.printLock.acquire() + print 'sending getdata to retrieve object with hash:', hash.encode('hex') + shared.printLock.release() payload = '\x01' + hash headerData = '\xe9\xbe\xb4\xd9' # magic bits, slighly different from Bitcoin's magic bits. headerData += 'getdata\x00\x00\x00\x00\x00' @@ -1515,9 +1515,9 @@ class receiveDataThread(threading.Thread): self.sock.sendall(headerData + payload) except Exception as err: # if not 'Bad file descriptor' in err: - with shared.printLock: - print 'sock.sendall error:', err - + shared.printLock.acquire() + print 'sock.sendall error:', err + shared.printLock.release() # We have received a getdata request from our peer def recgetdata(self, data): @@ -1529,9 +1529,9 @@ class receiveDataThread(threading.Thread): for i in xrange(numberOfRequestedInventoryItems): hash = data[lengthOfVarint + ( i * 32):32 + lengthOfVarint + (i * 32)] - with shared.printLock: - print 'received getdata request for item:', hash.encode('hex') - + shared.printLock.acquire() + print 'received getdata request for item:', hash.encode('hex') + shared.printLock.release() # print 'inventory is', shared.inventory if hash in shared.inventory: objectType, streamNumber, payload, receivedTime = shared.inventory[ @@ -1556,24 +1556,24 @@ class receiveDataThread(threading.Thread): def sendData(self, objectType, payload): headerData = '\xe9\xbe\xb4\xd9' # magic bits, slighly different from Bitcoin's magic bits. if objectType == 'pubkey': - with shared.printLock: - print 'sending pubkey' - + shared.printLock.acquire() + print 'sending pubkey' + shared.printLock.release() headerData += 'pubkey\x00\x00\x00\x00\x00\x00' elif objectType == 'getpubkey' or objectType == 'pubkeyrequest': - with shared.printLock: - print 'sending getpubkey' - + shared.printLock.acquire() + print 'sending getpubkey' + shared.printLock.release() headerData += 'getpubkey\x00\x00\x00' elif objectType == 'msg': - with shared.printLock: - print 'sending msg' - + shared.printLock.acquire() + print 'sending msg' + shared.printLock.release() headerData += 'msg\x00\x00\x00\x00\x00\x00\x00\x00\x00' elif objectType == 'broadcast': - with shared.printLock: - print 'sending broadcast' - + shared.printLock.acquire() + print 'sending broadcast' + shared.printLock.release() headerData += 'broadcast\x00\x00\x00' else: sys.stderr.write( @@ -1585,15 +1585,15 @@ class receiveDataThread(threading.Thread): self.sock.sendall(headerData + payload) except Exception as err: # if not 'Bad file descriptor' in err: - with shared.printLock: - print 'sock.sendall error:', err - + shared.printLock.acquire() + print 'sock.sendall error:', err + shared.printLock.release() # Send an inv message with just one hash to all of our peers def broadcastinv(self, hash): - with shared.printLock: - print 'broadcasting inv with hash:', hash.encode('hex') - + shared.printLock.acquire() + print 'broadcasting inv with hash:', hash.encode('hex') + shared.printLock.release() shared.broadcastToSendDataQueues((self.streamNumber, 'sendinv', hash)) # We have received an addr message. @@ -1604,9 +1604,9 @@ class receiveDataThread(threading.Thread): data[:10]) if shared.verbose >= 1: - with shared.printLock: - print 'addr message contains', numberOfAddressesIncluded, 'IP addresses.' - + shared.printLock.acquire() + print 'addr message contains', numberOfAddressesIncluded, 'IP addresses.' + shared.printLock.release() if self.remoteProtocolVersion == 1: if numberOfAddressesIncluded > 1000 or numberOfAddressesIncluded == 0: @@ -1619,25 +1619,25 @@ class receiveDataThread(threading.Thread): for i in range(0, numberOfAddressesIncluded): try: if data[16 + lengthOfNumberOfAddresses + (34 * i):28 + lengthOfNumberOfAddresses + (34 * i)] != '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF': - with shared.printLock: - print 'Skipping IPv6 address.', repr(data[16 + lengthOfNumberOfAddresses + (34 * i):28 + lengthOfNumberOfAddresses + (34 * i)]) - + shared.printLock.acquire() + print 'Skipping IPv6 address.', repr(data[16 + lengthOfNumberOfAddresses + (34 * i):28 + lengthOfNumberOfAddresses + (34 * i)]) + shared.printLock.release() continue except Exception as err: - with shared.printLock: - sys.stderr.write( - 'ERROR TRYING TO UNPACK recaddr (to test for an IPv6 address). Message: %s\n' % str(err)) - + shared.printLock.acquire() + sys.stderr.write( + 'ERROR TRYING TO UNPACK recaddr (to test for an IPv6 address). Message: %s\n' % str(err)) + shared.printLock.release() break # giving up on unpacking any more. We should still be connected however. try: recaddrStream, = unpack('>I', data[4 + lengthOfNumberOfAddresses + ( 34 * i):8 + lengthOfNumberOfAddresses + (34 * i)]) except Exception as err: - with shared.printLock: - sys.stderr.write( - 'ERROR TRYING TO UNPACK recaddr (recaddrStream). Message: %s\n' % str(err)) - + shared.printLock.acquire() + sys.stderr.write( + 'ERROR TRYING TO UNPACK recaddr (recaddrStream). Message: %s\n' % str(err)) + shared.printLock.release() break # giving up on unpacking any more. We should still be connected however. if recaddrStream == 0: continue @@ -1647,20 +1647,20 @@ class receiveDataThread(threading.Thread): recaddrServices, = unpack('>Q', data[8 + lengthOfNumberOfAddresses + ( 34 * i):16 + lengthOfNumberOfAddresses + (34 * i)]) except Exception as err: - with shared.printLock: - sys.stderr.write( - 'ERROR TRYING TO UNPACK recaddr (recaddrServices). Message: %s\n' % str(err)) - + shared.printLock.acquire() + sys.stderr.write( + 'ERROR TRYING TO UNPACK recaddr (recaddrServices). Message: %s\n' % str(err)) + shared.printLock.release() break # giving up on unpacking any more. We should still be connected however. try: recaddrPort, = unpack('>H', data[32 + lengthOfNumberOfAddresses + ( 34 * i):34 + lengthOfNumberOfAddresses + (34 * i)]) except Exception as err: - with shared.printLock: - sys.stderr.write( - 'ERROR TRYING TO UNPACK recaddr (recaddrPort). Message: %s\n' % str(err)) - + shared.printLock.acquire() + sys.stderr.write( + 'ERROR TRYING TO UNPACK recaddr (recaddrPort). Message: %s\n' % str(err)) + shared.printLock.release() break # giving up on unpacking any more. We should still be connected however. # print 'Within recaddr(): IP', recaddrIP, ', Port', # recaddrPort, ', i', i @@ -1709,9 +1709,9 @@ class receiveDataThread(threading.Thread): shared.knownNodesLock.release() self.broadcastaddr( listOfAddressDetailsToBroadcastToPeers) # no longer broadcast - with shared.printLock: - print 'knownNodes currently has', len(shared.knownNodes[self.streamNumber]), 'nodes for this stream.' - + shared.printLock.acquire() + print 'knownNodes currently has', len(shared.knownNodes[self.streamNumber]), 'nodes for this stream.' + shared.printLock.release() elif self.remoteProtocolVersion >= 2: # The difference is that in protocol version 2, network addresses use 64 bit times rather than 32 bit times. if numberOfAddressesIncluded > 1000 or numberOfAddressesIncluded == 0: return @@ -1723,25 +1723,25 @@ class receiveDataThread(threading.Thread): for i in range(0, numberOfAddressesIncluded): try: if data[20 + lengthOfNumberOfAddresses + (38 * i):32 + lengthOfNumberOfAddresses + (38 * i)] != '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF': - with shared.printLock: - print 'Skipping IPv6 address.', repr(data[20 + lengthOfNumberOfAddresses + (38 * i):32 + lengthOfNumberOfAddresses + (38 * i)]) - + shared.printLock.acquire() + print 'Skipping IPv6 address.', repr(data[20 + lengthOfNumberOfAddresses + (38 * i):32 + lengthOfNumberOfAddresses + (38 * i)]) + shared.printLock.release() continue except Exception as err: - with shared.printLock: - sys.stderr.write( - 'ERROR TRYING TO UNPACK recaddr (to test for an IPv6 address). Message: %s\n' % str(err)) - + shared.printLock.acquire() + sys.stderr.write( + 'ERROR TRYING TO UNPACK recaddr (to test for an IPv6 address). Message: %s\n' % str(err)) + shared.printLock.release() break # giving up on unpacking any more. We should still be connected however. try: recaddrStream, = unpack('>I', data[8 + lengthOfNumberOfAddresses + ( 38 * i):12 + lengthOfNumberOfAddresses + (38 * i)]) except Exception as err: - with shared.printLock: - sys.stderr.write( - 'ERROR TRYING TO UNPACK recaddr (recaddrStream). Message: %s\n' % str(err)) - + shared.printLock.acquire() + sys.stderr.write( + 'ERROR TRYING TO UNPACK recaddr (recaddrStream). Message: %s\n' % str(err)) + shared.printLock.release() break # giving up on unpacking any more. We should still be connected however. if recaddrStream == 0: continue @@ -1751,20 +1751,20 @@ class receiveDataThread(threading.Thread): recaddrServices, = unpack('>Q', data[12 + lengthOfNumberOfAddresses + ( 38 * i):20 + lengthOfNumberOfAddresses + (38 * i)]) except Exception as err: - with shared.printLock: - sys.stderr.write( - 'ERROR TRYING TO UNPACK recaddr (recaddrServices). Message: %s\n' % str(err)) - + shared.printLock.acquire() + sys.stderr.write( + 'ERROR TRYING TO UNPACK recaddr (recaddrServices). Message: %s\n' % str(err)) + shared.printLock.release() break # giving up on unpacking any more. We should still be connected however. try: recaddrPort, = unpack('>H', data[36 + lengthOfNumberOfAddresses + ( 38 * i):38 + lengthOfNumberOfAddresses + (38 * i)]) except Exception as err: - with shared.printLock: - sys.stderr.write( - 'ERROR TRYING TO UNPACK recaddr (recaddrPort). Message: %s\n' % str(err)) - + shared.printLock.acquire() + sys.stderr.write( + 'ERROR TRYING TO UNPACK recaddr (recaddrPort). Message: %s\n' % str(err)) + shared.printLock.release() break # giving up on unpacking any more. We should still be connected however. # print 'Within recaddr(): IP', recaddrIP, ', Port', # recaddrPort, ', i', i @@ -1792,9 +1792,9 @@ class receiveDataThread(threading.Thread): shared.knownNodes[recaddrStream][hostFromAddrMessage] = ( recaddrPort, timeSomeoneElseReceivedMessageFromThisNode) shared.knownNodesLock.release() - with shared.printLock: - print 'added new node', hostFromAddrMessage, 'to knownNodes in stream', recaddrStream - + shared.printLock.acquire() + print 'added new node', hostFromAddrMessage, 'to knownNodes in stream', recaddrStream + shared.printLock.release() needToWriteKnownNodesToDisk = True hostDetails = ( timeSomeoneElseReceivedMessageFromThisNode, @@ -1818,9 +1818,9 @@ class receiveDataThread(threading.Thread): output.close() shared.knownNodesLock.release() self.broadcastaddr(listOfAddressDetailsToBroadcastToPeers) - with shared.printLock: - print 'knownNodes currently has', len(shared.knownNodes[self.streamNumber]), 'nodes for this stream.' - + shared.printLock.acquire() + print 'knownNodes currently has', len(shared.knownNodes[self.streamNumber]), 'nodes for this stream.' + shared.printLock.release() # Function runs when we want to broadcast an addr message to all of our # peers. Runs when we learn of nodes that we didn't previously know about @@ -1847,9 +1847,9 @@ class receiveDataThread(threading.Thread): datatosend = datatosend + payload if shared.verbose >= 1: - with shared.printLock: - print 'Broadcasting addr with', numberOfAddressesInAddrMessage, 'entries.' - + shared.printLock.acquire() + print 'Broadcasting addr with', numberOfAddressesInAddrMessage, 'entries.' + shared.printLock.release() shared.broadcastToSendDataQueues(( self.streamNumber, 'sendaddr', datatosend)) @@ -1939,14 +1939,14 @@ class receiveDataThread(threading.Thread): try: self.sock.sendall(datatosend) if shared.verbose >= 1: - with shared.printLock: - print 'Sending addr with', numberOfAddressesInAddrMessage, 'entries.' - + shared.printLock.acquire() + print 'Sending addr with', numberOfAddressesInAddrMessage, 'entries.' + shared.printLock.release() except Exception as err: # if not 'Bad file descriptor' in err: - with shared.printLock: - print 'sock.sendall error:', err - + shared.printLock.acquire() + print 'sock.sendall error:', err + shared.printLock.release() # We have received a version message def recversion(self, data): @@ -1957,9 +1957,9 @@ class receiveDataThread(threading.Thread): self.remoteProtocolVersion, = unpack('>L', data[:4]) if self.remoteProtocolVersion <= 1: shared.broadcastToSendDataQueues((0, 'shutdown', self.HOST)) - with shared.printLock: - print 'Closing connection to old protocol version 1 node: ', self.HOST - + shared.printLock.acquire() + print 'Closing connection to old protocol version 1 node: ', self.HOST + shared.printLock.release() return # print 'remoteProtocolVersion', self.remoteProtocolVersion self.myExternalIP = socket.inet_ntoa(data[40:44]) @@ -1976,14 +1976,14 @@ class receiveDataThread(threading.Thread): readPosition += lengthOfNumberOfStreamsInVersionMessage self.streamNumber, lengthOfRemoteStreamNumber = decodeVarint( data[readPosition:]) - with shared.printLock: - print 'Remote node useragent:', useragent, ' stream number:', self.streamNumber - + shared.printLock.acquire() + print 'Remote node useragent:', useragent, ' stream number:', self.streamNumber + shared.printLock.release() if self.streamNumber != 1: shared.broadcastToSendDataQueues((0, 'shutdown', self.HOST)) - with shared.printLock: - print 'Closed connection to', self.HOST, 'because they are interested in stream', self.streamNumber, '.' - + shared.printLock.acquire() + print 'Closed connection to', self.HOST, 'because they are interested in stream', self.streamNumber, '.' + shared.printLock.release() return shared.connectedHostsList[ self.HOST] = 1 # We use this data structure to not only keep track of what hosts we are connected to so that we don't try to connect to them again, but also to list the connections count on the Network Status tab. @@ -1994,9 +1994,9 @@ class receiveDataThread(threading.Thread): 0, 'setStreamNumber', (self.HOST, self.streamNumber))) if data[72:80] == shared.eightBytesOfRandomDataUsedToDetectConnectionsToSelf: shared.broadcastToSendDataQueues((0, 'shutdown', self.HOST)) - with shared.printLock: - print 'Closing connection to myself: ', self.HOST - + shared.printLock.acquire() + print 'Closing connection to myself: ', self.HOST + shared.printLock.release() return shared.broadcastToSendDataQueues((0, 'setRemoteProtocolVersion', ( self.HOST, self.remoteProtocolVersion))) @@ -2015,31 +2015,31 @@ class receiveDataThread(threading.Thread): # Sends a version message def sendversion(self): - with shared.printLock: - print 'Sending version message' - + shared.printLock.acquire() + print 'Sending version message' + shared.printLock.release() try: self.sock.sendall(shared.assembleVersionMessage( self.HOST, self.PORT, self.streamNumber)) except Exception as err: # if not 'Bad file descriptor' in err: - with shared.printLock: - print 'sock.sendall error:', err - + shared.printLock.acquire() + print 'sock.sendall error:', err + shared.printLock.release() # Sends a verack message def sendverack(self): - with shared.printLock: - print 'Sending verack' - + shared.printLock.acquire() + print 'Sending verack' + shared.printLock.release() try: self.sock.sendall( '\xE9\xBE\xB4\xD9\x76\x65\x72\x61\x63\x6B\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcf\x83\xe1\x35') except Exception as err: # if not 'Bad file descriptor' in err: - with shared.printLock: - print 'sock.sendall error:', err - + shared.printLock.acquire() + print 'sock.sendall error:', err + shared.printLock.release() # cf # 83 # e1 diff --git a/src/class_sendDataThread.py b/src/class_sendDataThread.py index dec436e9..c1992067 100644 --- a/src/class_sendDataThread.py +++ b/src/class_sendDataThread.py @@ -18,9 +18,9 @@ class sendDataThread(threading.Thread): threading.Thread.__init__(self) self.mailbox = Queue.Queue() shared.sendDataQueues.append(self.mailbox) - with shared.printLock: - print 'The length of sendDataQueues at sendDataThread init is:', len(shared.sendDataQueues) - + shared.printLock.acquire() + print 'The length of sendDataQueues at sendDataThread init is:', len(shared.sendDataQueues) + shared.printLock.release() self.data = '' def setup( @@ -39,48 +39,48 @@ class sendDataThread(threading.Thread): self.lastTimeISentData = int( time.time()) # If this value increases beyond five minutes ago, we'll send a pong message to keep the connection alive. self.someObjectsOfWhichThisRemoteNodeIsAlreadyAware = someObjectsOfWhichThisRemoteNodeIsAlreadyAware - with shared.printLock: - print 'The streamNumber of this sendDataThread (ID:', str(id(self)) + ') at setup() is', self.streamNumber - + shared.printLock.acquire() + print 'The streamNumber of this sendDataThread (ID:', str(id(self)) + ') at setup() is', self.streamNumber + shared.printLock.release() def sendVersionMessage(self): datatosend = shared.assembleVersionMessage( self.HOST, self.PORT, self.streamNumber) # the IP and port of the remote host, and my streamNumber. - with shared.printLock: - print 'Sending version packet: ', repr(datatosend) - + shared.printLock.acquire() + print 'Sending version packet: ', repr(datatosend) + shared.printLock.release() try: self.sock.sendall(datatosend) except Exception as err: # if not 'Bad file descriptor' in err: - with shared.printLock: - sys.stderr.write('sock.sendall error: %s\n' % err) - + shared.printLock.acquire() + sys.stderr.write('sock.sendall error: %s\n' % err) + shared.printLock.release() self.versionSent = 1 def run(self): while True: deststream, command, data = self.mailbox.get() - # with shared.printLock: - # print 'sendDataThread, destream:', deststream, ', Command:', command, ', ID:',id(self), ', HOST:', self.HOST - # + # shared.printLock.acquire() + # print 'sendDataThread, destream:', deststream, ', Command:', command, ', ID:',id(self), ', HOST:', self.HOST + # shared.printLock.release() if deststream == self.streamNumber or deststream == 0: if command == 'shutdown': if data == self.HOST or data == 'all': - with shared.printLock: - print 'sendDataThread (associated with', self.HOST, ') ID:', id(self), 'shutting down now.' - + shared.printLock.acquire() + print 'sendDataThread (associated with', self.HOST, ') ID:', id(self), 'shutting down now.' + shared.printLock.release() try: self.sock.shutdown(socket.SHUT_RDWR) self.sock.close() except: pass shared.sendDataQueues.remove(self.mailbox) - with shared.printLock: - print 'len of sendDataQueues', len(shared.sendDataQueues) - + shared.printLock.acquire() + print 'len of sendDataQueues', len(shared.sendDataQueues) + shared.printLock.release() break # When you receive an incoming connection, a sendDataThread is # created even though you don't yet know what stream number the @@ -91,16 +91,16 @@ class sendDataThread(threading.Thread): elif command == 'setStreamNumber': hostInMessage, specifiedStreamNumber = data if hostInMessage == self.HOST: - with shared.printLock: - print 'setting the stream number in the sendData thread (ID:', id(self), ') to', specifiedStreamNumber - + shared.printLock.acquire() + print 'setting the stream number in the sendData thread (ID:', id(self), ') to', specifiedStreamNumber + shared.printLock.release() self.streamNumber = specifiedStreamNumber elif command == 'setRemoteProtocolVersion': hostInMessage, specifiedRemoteProtocolVersion = data if hostInMessage == self.HOST: - with shared.printLock: - print 'setting the remote node\'s protocol version in the sendData thread (ID:', id(self), ') to', specifiedRemoteProtocolVersion - + shared.printLock.acquire() + print 'setting the remote node\'s protocol version in the sendData thread (ID:', id(self), ') to', specifiedRemoteProtocolVersion + shared.printLock.release() self.remoteProtocolVersion = specifiedRemoteProtocolVersion elif command == 'sendaddr': try: @@ -150,9 +150,9 @@ class sendDataThread(threading.Thread): self.someObjectsOfWhichThisRemoteNodeIsAlreadyAware.clear() # To save memory, let us clear this data structure from time to time. As its function is to help us keep from sending inv messages to peers which sent us the same inv message mere seconds earlier, it will be fine to clear this data structure from time to time. if self.lastTimeISentData < (int(time.time()) - 298): # Send out a pong message to keep the connection alive. - with shared.printLock: - print 'Sending pong to', self.HOST, 'to keep connection alive.' - + shared.printLock.acquire() + print 'Sending pong to', self.HOST, 'to keep connection alive.' + shared.printLock.release() try: self.sock.sendall( '\xE9\xBE\xB4\xD9\x70\x6F\x6E\x67\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcf\x83\xe1\x35') @@ -168,7 +168,7 @@ class sendDataThread(threading.Thread): print 'sendDataThread thread', self, 'ending now. Was connected to', self.HOST break else: - with shared.printLock: - print 'sendDataThread ID:', id(self), 'ignoring command', command, 'because the thread is not in stream', deststream - + shared.printLock.acquire() + print 'sendDataThread ID:', id(self), 'ignoring command', command, 'because the thread is not in stream', deststream + shared.printLock.release() diff --git a/src/class_singleCleaner.py b/src/class_singleCleaner.py index 6fed68a5..5b77fdd4 100644 --- a/src/class_singleCleaner.py +++ b/src/class_singleCleaner.py @@ -78,11 +78,11 @@ class singleCleaner(threading.Thread): queryreturn = shared.sqlReturnQueue.get() for row in queryreturn: if len(row) < 5: - with shared.printLock: - sys.stderr.write( - 'Something went wrong in the singleCleaner thread: a query did not return the requested fields. ' + repr(row)) + shared.printLock.acquire() + sys.stderr.write( + 'Something went wrong in the singleCleaner thread: a query did not return the requested fields. ' + repr(row)) time.sleep(3) - + shared.printLock.release() break toaddress, toripe, fromaddress, subject, message, ackdata, lastactiontime, status, pubkeyretrynumber, msgretrynumber = row if status == 'awaitingpubkey': diff --git a/src/class_singleListener.py b/src/class_singleListener.py index d6b46643..fff351bf 100644 --- a/src/class_singleListener.py +++ b/src/class_singleListener.py @@ -21,16 +21,15 @@ class singleListener(threading.Thread): self.selfInitiatedConnections = selfInitiatedConnections def run(self): - # We typically don't want to accept incoming connections if the user is using a - # SOCKS proxy, unless they have configured otherwise. If they eventually select - # proxy 'none' or configure SOCKS listening then this will start listening for - # connections. - while shared.config.get('bitmessagesettings', 'socksproxytype')[0:5] == 'SOCKS' and not shared.config.getboolean('bitmessagesettings', 'sockslisten'): + # We don't want to accept incoming connections if the user is using a + # SOCKS proxy. If they eventually select proxy 'none' then this will + # start listening for connections. + while shared.config.get('bitmessagesettings', 'socksproxytype')[0:5] == 'SOCKS': time.sleep(300) - with shared.printLock: - print 'Listening for incoming connections.' - + shared.printLock.acquire() + print 'Listening for incoming connections.' + shared.printLock.release() HOST = '' # Symbolic name meaning all available interfaces PORT = shared.config.getint('bitmessagesettings', 'port') sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) @@ -41,16 +40,15 @@ class singleListener(threading.Thread): sock.listen(2) while True: - # We typically don't want to accept incoming connections if the user is using a - # SOCKS proxy, unless they have configured otherwise. If they eventually select - # proxy 'none' or configure SOCKS listening then this will start listening for - # connections. - while shared.config.get('bitmessagesettings', 'socksproxytype')[0:5] == 'SOCKS' and not shared.config.getboolean('bitmessagesettings', 'sockslisten'): + # We don't want to accept incoming connections if the user is using + # a SOCKS proxy. If the user eventually select proxy 'none' then + # this will start listening for connections. + while shared.config.get('bitmessagesettings', 'socksproxytype')[0:5] == 'SOCKS': time.sleep(10) while len(shared.connectedHostsList) > 220: - with shared.printLock: - print 'We are connected to too many people. Not accepting further incoming connections for ten seconds.' - + shared.printLock.acquire() + print 'We are connected to too many people. Not accepting further incoming connections for ten seconds.' + shared.printLock.release() time.sleep(10) a, (HOST, PORT) = sock.accept() @@ -59,9 +57,9 @@ class singleListener(threading.Thread): # because the two computers will share the same external IP. This # is here to prevent connection flooding. while HOST in shared.connectedHostsList: - with shared.printLock: - print 'We are already connected to', HOST + '. Ignoring connection.' - + shared.printLock.acquire() + print 'We are already connected to', HOST + '. Ignoring connection.' + shared.printLock.release() a.close() a, (HOST, PORT) = sock.accept() someObjectsOfWhichThisRemoteNodeIsAlreadyAware = {} # This is not necessairly a complete list; we clear it from time to time to save memory. @@ -78,6 +76,6 @@ class singleListener(threading.Thread): a, HOST, PORT, -1, someObjectsOfWhichThisRemoteNodeIsAlreadyAware, self.selfInitiatedConnections) rd.start() - with shared.printLock: - print self, 'connected to', HOST, 'during INCOMING request.' - + shared.printLock.acquire() + print self, 'connected to', HOST, 'during INCOMING request.' + shared.printLock.release() diff --git a/src/class_singleWorker.py b/src/class_singleWorker.py index 2ba34eeb..13cceb9e 100644 --- a/src/class_singleWorker.py +++ b/src/class_singleWorker.py @@ -72,8 +72,8 @@ class singleWorker(threading.Thread): self.sendBroadcast() elif command == 'doPOWForMyV2Pubkey': self.doPOWForMyV2Pubkey(data) - elif command == 'sendOutOrStoreMyV3Pubkey': - self.sendOutOrStoreMyV3Pubkey(data) + elif command == 'doPOWForMyV3Pubkey': + self.doPOWForMyV3Pubkey(data) """elif command == 'newpubkey': toAddressVersion,toStreamNumber,toRipe = data if toRipe in shared.neededPubkeys: @@ -88,14 +88,14 @@ class singleWorker(threading.Thread): shared.sqlLock.release() self.sendMsg() else: - with shared.printLock: - print 'We don\'t need this pub key. We didn\'t ask for it. Pubkey hash:', toRipe.encode('hex') - """ + shared.printLock.acquire() + print 'We don\'t need this pub key. We didn\'t ask for it. Pubkey hash:', toRipe.encode('hex') + shared.printLock.release()""" else: - with shared.printLock: - sys.stderr.write( - 'Probable programming error: The command sent to the workerThread is weird. It is: %s\n' % command) - + shared.printLock.acquire() + sys.stderr.write( + 'Probable programming error: The command sent to the workerThread is weird. It is: %s\n' % command) + shared.printLock.release() shared.workerQueue.task_done() def doPOWForMyV2Pubkey(self, hash): # This function also broadcasts out the pubkey message once it is done with the POW @@ -123,10 +123,10 @@ class singleWorker(threading.Thread): privEncryptionKeyBase58 = shared.config.get( myAddress, 'privencryptionkey') except Exception as err: - with shared.printLock: - sys.stderr.write( - 'Error within doPOWForMyV2Pubkey. Could not read the keys from the keys.dat file for a requested address. %s\n' % err) - + shared.printLock.acquire() + sys.stderr.write( + 'Error within doPOWForMyV2Pubkey. Could not read the keys from the keys.dat file for a requested address. %s\n' % err) + shared.printLock.release() return privSigningKeyHex = shared.decodeWalletImportFormat( @@ -162,9 +162,9 @@ class singleWorker(threading.Thread): shared.inventory[inventoryHash] = ( objectType, streamNumber, payload, embeddedTime) - with shared.printLock: - print 'broadcasting inv with hash:', inventoryHash.encode('hex') - + shared.printLock.acquire() + print 'broadcasting inv with hash:', inventoryHash.encode('hex') + shared.printLock.release() shared.broadcastToSendDataQueues(( streamNumber, 'sendinv', inventoryHash)) shared.UISignalQueue.put(('updateStatusBar', '')) @@ -173,11 +173,7 @@ class singleWorker(threading.Thread): with open(shared.appdata + 'keys.dat', 'wb') as configfile: shared.config.write(configfile) - # If this isn't a chan address, this function assembles the pubkey data, - # does the necessary POW and sends it out. If it *is* a chan then it - # assembles the pubkey and stores is in the pubkey table so that we can - # send messages to "ourselves". - def sendOutOrStoreMyV3Pubkey(self, hash): + def doPOWForMyV3Pubkey(self, hash): # This function also broadcasts out the pubkey message once it is done with the POW myAddress = shared.myAddressesByHash[hash] status, addressVersionNumber, streamNumber, hash = decodeAddress( myAddress) @@ -194,10 +190,10 @@ class singleWorker(threading.Thread): privEncryptionKeyBase58 = shared.config.get( myAddress, 'privencryptionkey') except Exception as err: - with shared.printLock: - sys.stderr.write( - 'Error within sendOutOrStoreMyV3Pubkey. Could not read the keys from the keys.dat file for a requested address. %s\n' % err) - + shared.printLock.acquire() + sys.stderr.write( + 'Error within doPOWForMyV3Pubkey. Could not read the keys from the keys.dat file for a requested address. %s\n' % err) + shared.printLock.release() return privSigningKeyHex = shared.decodeWalletImportFormat( @@ -220,40 +216,34 @@ class singleWorker(threading.Thread): payload += encodeVarint(len(signature)) payload += signature - if not shared.safeConfigGetBoolean(myAddress, 'chan'): - # Do the POW for this pubkey message - target = 2 ** 64 / ((len(payload) + shared.networkDefaultPayloadLengthExtraBytes + - 8) * shared.networkDefaultProofOfWorkNonceTrialsPerByte) - print '(For pubkey message) Doing proof of work...' - initialHash = hashlib.sha512(payload).digest() - trialValue, nonce = proofofwork.run(target, initialHash) - print '(For pubkey message) Found proof of work', trialValue, 'Nonce:', nonce + # Do the POW for this pubkey message + target = 2 ** 64 / ((len(payload) + shared.networkDefaultPayloadLengthExtraBytes + + 8) * shared.networkDefaultProofOfWorkNonceTrialsPerByte) + print '(For pubkey message) Doing proof of work...' + initialHash = hashlib.sha512(payload).digest() + trialValue, nonce = proofofwork.run(target, initialHash) + print '(For pubkey message) Found proof of work', trialValue, 'Nonce:', nonce - payload = pack('>Q', nonce) + payload - inventoryHash = calculateInventoryHash(payload) - objectType = 'pubkey' - shared.inventory[inventoryHash] = ( - objectType, streamNumber, payload, embeddedTime) + payload = pack('>Q', nonce) + payload + """t = (hash,payload,embeddedTime,'no') + shared.sqlLock.acquire() + shared.sqlSubmitQueue.put('''INSERT INTO pubkeys VALUES (?,?,?,?)''') + shared.sqlSubmitQueue.put(t) + queryreturn = shared.sqlReturnQueue.get() + shared.sqlSubmitQueue.put('commit') + shared.sqlLock.release()""" - with shared.printLock: - print 'broadcasting inv with hash:', inventoryHash.encode('hex') + inventoryHash = calculateInventoryHash(payload) + objectType = 'pubkey' + shared.inventory[inventoryHash] = ( + objectType, streamNumber, payload, embeddedTime) - shared.broadcastToSendDataQueues(( - streamNumber, 'sendinv', inventoryHash)) - shared.UISignalQueue.put(('updateStatusBar', '')) - # If this is a chan address then we won't send out the pubkey over the - # network but rather will only store it in our pubkeys table so that - # we can send messages to "ourselves". - if shared.safeConfigGetBoolean(myAddress, 'chan'): - payload = '\x00' * 8 + payload # Attach a fake nonce on the front - # just so that it is in the correct format. - t = (hash,payload,embeddedTime,'yes') - shared.sqlLock.acquire() - shared.sqlSubmitQueue.put('''INSERT INTO pubkeys VALUES (?,?,?,?)''') - shared.sqlSubmitQueue.put(t) - shared.sqlReturnQueue.get() - shared.sqlSubmitQueue.put('commit') - shared.sqlLock.release() + shared.printLock.acquire() + print 'broadcasting inv with hash:', inventoryHash.encode('hex') + shared.printLock.release() + shared.broadcastToSendDataQueues(( + streamNumber, 'sendinv', inventoryHash)) + shared.UISignalQueue.put(('updateStatusBar', '')) shared.config.set( myAddress, 'lastpubkeysendtime', str(int(time.time()))) with open(shared.appdata + 'keys.dat', 'wb') as configfile: @@ -424,19 +414,19 @@ class singleWorker(threading.Thread): # Update the status of the message in the 'sent' table to have # a 'broadcastsent' status shared.sqlLock.acquire() - t = (inventoryHash,'broadcastsent', int( + t = ('broadcastsent', int( time.time()), fromaddress, subject, body, 'broadcastqueued') shared.sqlSubmitQueue.put( - 'UPDATE sent SET msgid=?, status=?, lastactiontime=? WHERE fromaddress=? AND subject=? AND message=? AND status=?') + 'UPDATE sent SET status=?, lastactiontime=? WHERE fromaddress=? AND subject=? AND message=? AND status=?') shared.sqlSubmitQueue.put(t) queryreturn = shared.sqlReturnQueue.get() shared.sqlSubmitQueue.put('commit') shared.sqlLock.release() else: - with shared.printLock: - sys.stderr.write( - 'Error: In the singleWorker thread, the sendBroadcast function doesn\'t understand the address version.\n') - + shared.printLock.acquire() + sys.stderr.write( + 'Error: In the singleWorker thread, the sendBroadcast function doesn\'t understand the address version.\n') + shared.printLock.release() def sendMsg(self): # Check to see if there are any messages queued to be sent @@ -517,10 +507,10 @@ class singleWorker(threading.Thread): if queryreturn == [] and toripe not in shared.neededPubkeys: # We no longer have the needed pubkey and we haven't requested # it. - with shared.printLock: - sys.stderr.write( - 'For some reason, the status of a message in our outbox is \'doingmsgpow\' even though we lack the pubkey. Here is the RIPE hash of the needed pubkey: %s\n' % toripe.encode('hex')) - + shared.printLock.acquire() + sys.stderr.write( + 'For some reason, the status of a message in our outbox is \'doingmsgpow\' even though we lack the pubkey. Here is the RIPE hash of the needed pubkey: %s\n' % toripe.encode('hex')) + shared.printLock.release() t = (toaddress,) shared.sqlLock.acquire() shared.sqlSubmitQueue.put( @@ -540,10 +530,10 @@ class singleWorker(threading.Thread): fromaddress) shared.UISignalQueue.put(('updateSentItemStatusByAckdata', ( ackdata, tr.translateText("MainWindow", "Looking up the receiver\'s public key")))) - with shared.printLock: - print 'Found a message in our database that needs to be sent with this pubkey.' - print 'First 150 characters of message:', repr(message[:150]) - + shared.printLock.acquire() + print 'Found a message in our database that needs to be sent with this pubkey.' + print 'First 150 characters of message:', repr(message[:150]) + shared.printLock.release() # mark the pubkey as 'usedpersonally' so that we don't ever delete # it. @@ -563,10 +553,10 @@ class singleWorker(threading.Thread): queryreturn = shared.sqlReturnQueue.get() shared.sqlLock.release() if queryreturn == []: - with shared.printLock: - sys.stderr.write( - '(within sendMsg) The needed pubkey was not found. This should never happen. Aborting send.\n') - + shared.printLock.acquire() + sys.stderr.write( + '(within sendMsg) The needed pubkey was not found. This should never happen. Aborting send.\n') + shared.printLock.release() return for row in queryreturn: pubkeyPayload, = row @@ -732,13 +722,8 @@ class singleWorker(threading.Thread): subject + '\n' + 'Body:' + message payload += encodeVarint(len(messageToTransmit)) payload += messageToTransmit - if shared.safeConfigGetBoolean(toaddress, 'chan'): - with shared.printLock: - print 'Not bothering to generate ackdata because we are sending to a chan.' - fullAckPayload = '' - else: - fullAckPayload = self.generateFullAckMessage( - ackdata, toStreamNumber, embeddedTime) # The fullAckPayload is a normal msg protocol message with the proof of work already completed that the receiver of this message can easily send out. + fullAckPayload = self.generateFullAckMessage( + ackdata, toStreamNumber, embeddedTime) # The fullAckPayload is a normal msg protocol message with the proof of work already completed that the receiver of this message can easily send out. payload += encodeVarint(len(fullAckPayload)) payload += fullAckPayload signature = highlevelcrypto.sign(payload, privSigningKeyHex) @@ -761,45 +746,36 @@ class singleWorker(threading.Thread): continue encryptedPayload = embeddedTime + encodeVarint(toStreamNumber) + encrypted target = 2**64 / ((len(encryptedPayload)+requiredPayloadLengthExtraBytes+8) * requiredAverageProofOfWorkNonceTrialsPerByte) - with shared.printLock: - print '(For msg message) Doing proof of work. Total required difficulty:', float(requiredAverageProofOfWorkNonceTrialsPerByte) / shared.networkDefaultProofOfWorkNonceTrialsPerByte, 'Required small message difficulty:', float(requiredPayloadLengthExtraBytes) / shared.networkDefaultPayloadLengthExtraBytes - + shared.printLock.acquire() + print '(For msg message) Doing proof of work. Total required difficulty:', float(requiredAverageProofOfWorkNonceTrialsPerByte) / shared.networkDefaultProofOfWorkNonceTrialsPerByte, 'Required small message difficulty:', float(requiredPayloadLengthExtraBytes) / shared.networkDefaultPayloadLengthExtraBytes + shared.printLock.release() powStartTime = time.time() initialHash = hashlib.sha512(encryptedPayload).digest() trialValue, nonce = proofofwork.run(target, initialHash) - with shared.printLock: - print '(For msg message) Found proof of work', trialValue, 'Nonce:', nonce - try: - print 'POW took', int(time.time() - powStartTime), 'seconds.', nonce / (time.time() - powStartTime), 'nonce trials per second.' - except: - pass - + shared.printLock.acquire() + print '(For msg message) Found proof of work', trialValue, 'Nonce:', nonce + try: + print 'POW took', int(time.time() - powStartTime), 'seconds.', nonce / (time.time() - powStartTime), 'nonce trials per second.' + except: + pass + shared.printLock.release() encryptedPayload = pack('>Q', nonce) + encryptedPayload inventoryHash = calculateInventoryHash(encryptedPayload) objectType = 'msg' shared.inventory[inventoryHash] = ( objectType, toStreamNumber, encryptedPayload, int(time.time())) - if shared.safeConfigGetBoolean(toaddress, 'chan'): - shared.UISignalQueue.put(('updateSentItemStatusByAckdata', (ackdata, tr.translateText("MainWindow", "Message sent. Sent on %1").arg(unicode( - strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(int(time.time()))), 'utf-8'))))) - else: - # not sending to a chan - shared.UISignalQueue.put(('updateSentItemStatusByAckdata', (ackdata, tr.translateText("MainWindow", "Message sent. Waiting on acknowledgement. Sent on %1").arg(unicode( - strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(int(time.time()))), 'utf-8'))))) + shared.UISignalQueue.put(('updateSentItemStatusByAckdata', (ackdata, tr.translateText("MainWindow", "Message sent. Waiting on acknowledgement. Sent on %1").arg(unicode( + strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(int(time.time()))), 'utf-8'))))) print 'Broadcasting inv for my msg(within sendmsg function):', inventoryHash.encode('hex') shared.broadcastToSendDataQueues(( streamNumber, 'sendinv', inventoryHash)) # Update the status of the message in the 'sent' table to have a - # 'msgsent' status or 'msgsentnoackexpected' status. - if shared.safeConfigGetBoolean(toaddress, 'chan'): - newStatus = 'msgsentnoackexpected' - else: - newStatus = 'msgsent' + # 'msgsent' status shared.sqlLock.acquire() - t = (inventoryHash,newStatus,ackdata,) - shared.sqlSubmitQueue.put('''UPDATE sent SET msgid=?, status=? WHERE ackdata=?''') + t = (ackdata,) + shared.sqlSubmitQueue.put('''UPDATE sent SET status='msgsent' WHERE ackdata=?''') shared.sqlSubmitQueue.put(t) queryreturn = shared.sqlReturnQueue.get() shared.sqlSubmitQueue.put('commit') @@ -809,10 +785,10 @@ class singleWorker(threading.Thread): toStatus, addressVersionNumber, streamNumber, ripe = decodeAddress( toAddress) if toStatus != 'success': - with shared.printLock: - sys.stderr.write('Very abnormal error occurred in requestPubKey. toAddress is: ' + repr( - toAddress) + '. Please report this error to Atheros.') - + shared.printLock.acquire() + sys.stderr.write('Very abnormal error occurred in requestPubKey. toAddress is: ' + repr( + toAddress) + '. Please report this error to Atheros.') + shared.printLock.release() return shared.neededPubkeys[ripe] = 0 payload = pack('>Q', (int(time.time()) + random.randrange( @@ -820,9 +796,9 @@ class singleWorker(threading.Thread): payload += encodeVarint(addressVersionNumber) payload += encodeVarint(streamNumber) payload += ripe - with shared.printLock: - print 'making request for pubkey with ripe:', ripe.encode('hex') - + shared.printLock.acquire() + print 'making request for pubkey with ripe:', ripe.encode('hex') + shared.printLock.release() # print 'trial value', trialValue statusbar = 'Doing the computations necessary to request the recipient\'s public key.' shared.UISignalQueue.put(('updateStatusBar', statusbar)) @@ -832,9 +808,9 @@ class singleWorker(threading.Thread): 8) * shared.networkDefaultProofOfWorkNonceTrialsPerByte) initialHash = hashlib.sha512(payload).digest() trialValue, nonce = proofofwork.run(target, initialHash) - with shared.printLock: - print 'Found proof of work', trialValue, 'Nonce:', nonce - + shared.printLock.acquire() + print 'Found proof of work', trialValue, 'Nonce:', nonce + shared.printLock.release() payload = pack('>Q', nonce) + payload inventoryHash = calculateInventoryHash(payload) @@ -863,19 +839,19 @@ class singleWorker(threading.Thread): payload = embeddedTime + encodeVarint(toStreamNumber) + ackdata target = 2 ** 64 / ((len(payload) + shared.networkDefaultPayloadLengthExtraBytes + 8) * shared.networkDefaultProofOfWorkNonceTrialsPerByte) - with shared.printLock: - print '(For ack message) Doing proof of work...' - + shared.printLock.acquire() + print '(For ack message) Doing proof of work...' + shared.printLock.release() powStartTime = time.time() initialHash = hashlib.sha512(payload).digest() trialValue, nonce = proofofwork.run(target, initialHash) - with shared.printLock: - print '(For ack message) Found proof of work', trialValue, 'Nonce:', nonce - try: - print 'POW took', int(time.time() - powStartTime), 'seconds.', nonce / (time.time() - powStartTime), 'nonce trials per second.' - except: - pass - + shared.printLock.acquire() + print '(For ack message) Found proof of work', trialValue, 'Nonce:', nonce + try: + print 'POW took', int(time.time() - powStartTime), 'seconds.', nonce / (time.time() - powStartTime), 'nonce trials per second.' + except: + pass + shared.printLock.release() payload = pack('>Q', nonce) + payload headerData = '\xe9\xbe\xb4\xd9' # magic bits, slighly different from Bitcoin's magic bits. headerData += 'msg\x00\x00\x00\x00\x00\x00\x00\x00\x00' diff --git a/src/class_sqlThread.py b/src/class_sqlThread.py index f1a428d2..ebe6a7ff 100644 --- a/src/class_sqlThread.py +++ b/src/class_sqlThread.py @@ -5,7 +5,6 @@ import time import shutil # used for moving the messages.dat file import sys import os -from debug import logger # 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 @@ -62,9 +61,9 @@ class sqlThread(threading.Thread): print 'Created messages database file' except Exception as err: if str(err) == 'table inbox already exists': - with shared.printLock: - print 'Database file already exists.' - + shared.printLock.acquire() + print 'Database file already exists.' + shared.printLock.release() else: sys.stderr.write( 'ERROR trying to create database file (message.dat). Error message: %s\n' % str(err)) @@ -81,7 +80,6 @@ class sqlThread(threading.Thread): shared.config.set('bitmessagesettings', 'socksauthentication', 'false') shared.config.set('bitmessagesettings', 'socksusername', '') shared.config.set('bitmessagesettings', 'sockspassword', '') - shared.config.set('bitmessagesettings', 'sockslisten', 'false') shared.config.set('bitmessagesettings', 'keysencrypted', 'false') shared.config.set('bitmessagesettings', 'messagesencrypted', 'false') with open(shared.appdata + 'keys.dat', 'wb') as configfile: @@ -227,14 +225,14 @@ class sqlThread(threading.Thread): self.conn.commit() elif item == 'exit': self.conn.close() - with shared.printLock: - print 'sqlThread exiting gracefully.' - + shared.printLock.acquire() + print 'sqlThread exiting gracefully.' + shared.printLock.release() return elif item == 'movemessagstoprog': - with shared.printLock: - print 'the sqlThread is moving the messages.dat file to the local program directory.' - + shared.printLock.acquire() + print 'the sqlThread is moving the messages.dat file to the local program directory.' + shared.printLock.release() self.conn.commit() self.conn.close() shutil.move( @@ -243,9 +241,9 @@ class sqlThread(threading.Thread): self.conn.text_factory = str self.cur = self.conn.cursor() elif item == 'movemessagstoappdata': - with shared.printLock: - print 'the sqlThread is moving the messages.dat file to the Appdata folder.' - + shared.printLock.acquire() + print 'the sqlThread is moving the messages.dat file to the Appdata folder.' + shared.printLock.release() self.conn.commit() self.conn.close() shutil.move( @@ -265,11 +263,11 @@ class sqlThread(threading.Thread): try: self.cur.execute(item, parameters) except Exception as err: - with shared.printLock: - sys.stderr.write('\nMajor error occurred when trying to execute a SQL statement within the sqlThread. Please tell Atheros about this error message or post it in the forum! Error occurred while trying to execute statement: "' + str( - item) + '" Here are the parameters; you might want to censor this data with asterisks (***) as it can contain private information: ' + str(repr(parameters)) + '\nHere is the actual error message thrown by the sqlThread: ' + str(err) + '\n') - sys.stderr.write('This program shall now abruptly exit!\n') - + shared.printLock.acquire() + sys.stderr.write('\nMajor error occurred when trying to execute a SQL statement within the sqlThread. Please tell Atheros about this error message or post it in the forum! Error occurred while trying to execute statement: "' + str( + item) + '" Here are the parameters; you might want to censor this data with asterisks (***) as it can contain private information: ' + str(repr(parameters)) + '\nHere is the actual error message thrown by the sqlThread: ' + str(err) + '\n') + sys.stderr.write('This program shall now abruptly exit!\n') + shared.printLock.release() os._exit(0) shared.sqlReturnQueue.put(self.cur.fetchall()) diff --git a/src/debug.py b/src/debug.py deleted file mode 100644 index fe7815e7..00000000 --- a/src/debug.py +++ /dev/null @@ -1,81 +0,0 @@ -# -*- coding: utf-8 -*- -''' -Logging and debuging facility -============================= - -Levels: - DEBUG Detailed information, typically of interest only when diagnosing problems. - INFO Confirmation that things are working as expected. - WARNING An indication that something unexpected happened, or indicative of some problem in the - near future (e.g. ‘disk space low’). The software is still working as expected. - ERROR Due to a more serious problem, the software has not been able to perform some function. - CRITICAL A serious error, indicating that the program itself may be unable to continue running. - -There are three loggers: `console_only`, `file_only` and `both`. - -Use: `from debug import logger` to import this facility into whatever module you wish to log messages from. - Logging is thread-safe so you don't have to worry about locks, just import and log. -''' -import logging -import logging.config -import shared - -# TODO(xj9): Get from a config file. -log_level = 'DEBUG' - -def configureLogging(): - logging.config.dictConfig({ - 'version': 1, - 'formatters': { - 'default': { - 'format': '%(asctime)s - %(levelname)s - %(message)s', - }, - }, - 'handlers': { - 'console': { - 'class': 'logging.StreamHandler', - 'formatter': 'default', - 'level': log_level, - 'stream': 'ext://sys.stdout' - }, - 'file': { - 'class': 'logging.handlers.RotatingFileHandler', - 'formatter': 'default', - 'level': log_level, - 'filename': shared.appdata + 'debug.log', - 'maxBytes': 2097152, # 2 MiB - 'backupCount': 1, - } - }, - 'loggers': { - 'console_only': { - 'handlers': ['console'], - 'propagate' : 0 - }, - 'file_only': { - 'handlers': ['file'], - 'propagate' : 0 - }, - 'both': { - 'handlers': ['console', 'file'], - 'propagate' : 0 - }, - }, - 'root': { - 'level': log_level, - 'handlers': ['console'], - }, - }) -# TODO (xj9): Get from a config file. -#logger = logging.getLogger('console_only') -configureLogging() -logger = logging.getLogger('both') - -def restartLoggingInUpdatedAppdataLocation(): - global logger - for i in list(logger.handlers): - logger.removeHandler(i) - i.flush() - i.close() - configureLogging() - logger = logging.getLogger('both') \ No newline at end of file diff --git a/src/helper_bootstrap.py b/src/helper_bootstrap.py index c3d5c1fd..296dda6b 100644 --- a/src/helper_bootstrap.py +++ b/src/helper_bootstrap.py @@ -33,7 +33,7 @@ def dns(): print 'Adding', item[4][0], 'to knownNodes based on DNS boostrap method' shared.knownNodes[1][item[4][0]] = (8080, int(time.time())) except: - print 'bootstrap8080.bitmessage.org DNS bootstrapping failed.' + print 'bootstrap8080.bitmessage.org DNS bootstraping failed.' try: for item in socket.getaddrinfo('bootstrap8444.bitmessage.org', 80): print 'Adding', item[4][0], 'to knownNodes based on DNS boostrap method' diff --git a/src/helper_startup.py b/src/helper_startup.py index 46150d4d..e6590b0e 100644 --- a/src/helper_startup.py +++ b/src/helper_startup.py @@ -50,8 +50,6 @@ def loadConfig(): shared.config.set('bitmessagesettings', 'socksport', '9050') shared.config.set( 'bitmessagesettings', 'socksauthentication', 'false') - shared.config.set( - 'bitmessagesettings', 'sockslisten', 'false') shared.config.set('bitmessagesettings', 'socksusername', '') shared.config.set('bitmessagesettings', 'sockspassword', '') shared.config.set('bitmessagesettings', 'keysencrypted', 'false') @@ -76,13 +74,5 @@ def loadConfig(): print 'Creating new config files in', shared.appdata if not os.path.exists(shared.appdata): os.makedirs(shared.appdata) - if not sys.platform.startswith('win'): - os.umask(0o077) with open(shared.appdata + 'keys.dat', 'wb') as configfile: shared.config.write(configfile) - - # Initialize settings that may be missing due to upgrades and could - # cause errors if missing. - if not shared.config.has_option('bitmessagesettings', 'sockslisten'): - shared.config.set('bitmessagesettings', 'sockslisten', 'false') - diff --git a/src/message_data_reader.py b/src/message_data_reader.py index c600935d..90f4bedc 100644 --- a/src/message_data_reader.py +++ b/src/message_data_reader.py @@ -107,8 +107,8 @@ def vacuum(): #takeInboxMessagesOutOfTrash() #takeSentMessagesOutOfTrash() #markAllInboxMessagesAsUnread() -readInbox() -#readSent() +#readInbox() +readSent() #readPubkeys() #readSubscriptions() #readInventory() diff --git a/src/pyelliptic/openssl.py b/src/pyelliptic/openssl.py index ee75f90a..09df5ca4 100644 --- a/src/pyelliptic/openssl.py +++ b/src/pyelliptic/openssl.py @@ -289,12 +289,7 @@ class _OpenSSL: self.HMAC.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_int, ctypes.c_void_p, ctypes.c_int, ctypes.c_void_p, ctypes.c_void_p] - try: - self.PKCS5_PBKDF2_HMAC = self._lib.PKCS5_PBKDF2_HMAC - except: - # The above is not compatible with all versions of OSX. - self.PKCS5_PBKDF2_HMAC = self._lib.PKCS5_PBKDF2_HMAC_SHA1 - + self.PKCS5_PBKDF2_HMAC = self._lib.PKCS5_PBKDF2_HMAC self.PKCS5_PBKDF2_HMAC.restype = ctypes.c_int self.PKCS5_PBKDF2_HMAC.argtypes = [ctypes.c_void_p, ctypes.c_int, ctypes.c_void_p, ctypes.c_int, diff --git a/src/shared.py b/src/shared.py index aead1f8a..4b3ef73b 100644 --- a/src/shared.py +++ b/src/shared.py @@ -8,25 +8,19 @@ maximumAgeOfNodesThatIAdvertiseToOthers = 10800 # Equals three hours useVeryEasyProofOfWorkForTesting = False # If you set this to True while on the normal network, you won't be able to send or sometimes receive messages. -# Libraries. -import ConfigParser -import os -import pickle -import Queue -import random -import socket -import sys -import stat import threading -import time - -# Project imports. +import sys from addresses import * import highlevelcrypto +import Queue +import pickle +import os +import time +import ConfigParser +import socket +import random +import highlevelcrypto import shared -import helper_startup - - config = ConfigParser.SafeConfigParser() myECCryptorObjects = {} @@ -68,6 +62,8 @@ 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. 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. + + def isInSqlInventory(hash): t = (hash,) shared.sqlLock.acquire() @@ -122,11 +118,7 @@ def lookupAppdataFolder(): if "HOME" in environ: dataFolder = path.join(os.environ["HOME"], "Library/Application Support/", APPNAME) + '/' else: - stringToLog = 'Could not find home folder, please report this message and your OS X version to the BitMessage Github.' - if 'logger' in globals(): - logger.critical(stringToLog) - else: - print stringToLog + 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: @@ -137,19 +129,13 @@ def lookupAppdataFolder(): dataFolder = path.join(environ["XDG_CONFIG_HOME"], APPNAME) except KeyError: dataFolder = path.join(environ["HOME"], ".config", APPNAME) - # Migrate existing data to the proper location if this is an existing install try: + print "Moving data folder to ~/.config/%s" % APPNAME move(path.join(environ["HOME"], ".%s" % APPNAME), dataFolder) - stringToLog = "Moving data folder to %s" % (dataFolder) - if 'logger' in globals(): - logger.info(stringToLog) - else: - print stringToLog + dataFolder = dataFolder + '/' except IOError: - # Old directory may not exist. - pass - dataFolder = dataFolder + '/' + dataFolder = dataFolder + '/' return dataFolder def isAddressInMyAddressBook(address): @@ -193,63 +179,51 @@ def isAddressInMyAddressBookSubscriptionsListOrWhitelist(address): return False def safeConfigGetBoolean(section,field): - try: - return config.getboolean(section,field) - except Exception, err: - return False + try: + return config.getboolean(section,field) + except: + return False def decodeWalletImportFormat(WIFstring): fullString = arithmetic.changebase(WIFstring,58,256) privkey = fullString[:-4] if fullString[-4:] != hashlib.sha256(hashlib.sha256(privkey).digest()).digest()[:4]: - logger.error('Major problem! When trying to decode one of your private keys, the checksum ' - 'failed. Here is the PRIVATE key: %s\n' % str(WIFstring)) + sys.stderr.write('Major problem! When trying to decode one of your private keys, the checksum failed. Here is the PRIVATE key: %s\n' % str(WIFstring)) return "" else: #checksum passed if privkey[0] == '\x80': return privkey[1:] else: - logger.error('Major problem! When trying to decode one of your private keys, the ' - 'checksum passed but the key doesn\'t begin with hex 80. Here is the ' - 'PRIVATE key: %s\n' % str(WIFstring)) + sys.stderr.write('Major problem! When trying to decode one of your private keys, the checksum passed but the key doesn\'t begin with hex 80. Here is the PRIVATE key: %s\n' % str(WIFstring)) return "" def reloadMyAddressHashes(): - logger.debug('reloading keys from keys.dat file') + printLock.acquire() + print 'reloading keys from keys.dat file' + printLock.release() myECCryptorObjects.clear() myAddressesByHash.clear() #myPrivateKeys.clear() - - keyfileSecure = checkSensitiveFilePermissions(appdata + 'keys.dat') configSections = config.sections() - hasEnabledKeys = False for addressInKeysFile in configSections: if addressInKeysFile <> 'bitmessagesettings': isEnabled = config.getboolean(addressInKeysFile, 'enabled') if isEnabled: - hasEnabledKeys = True status,addressVersionNumber,streamNumber,hash = decodeAddress(addressInKeysFile) if addressVersionNumber == 2 or addressVersionNumber == 3: - # Returns a simple 32 bytes of information encoded in 64 Hex characters, - # or null if there was an error. - privEncryptionKey = decodeWalletImportFormat( - config.get(addressInKeysFile, 'privencryptionkey')).encode('hex') - + privEncryptionKey = decodeWalletImportFormat(config.get(addressInKeysFile, 'privencryptionkey')).encode('hex') #returns a simple 32 bytes of information encoded in 64 Hex characters, or null if there was an error if len(privEncryptionKey) == 64:#It is 32 bytes encoded as 64 hex characters myECCryptorObjects[hash] = highlevelcrypto.makeCryptor(privEncryptionKey) myAddressesByHash[hash] = addressInKeysFile - else: - logger.error('Error in reloadMyAddressHashes: Can\'t handle address ' - 'versions other than 2 or 3.\n') - - if not keyfileSecure: - fixSensitiveFilePermissions(appdata + 'keys.dat', hasEnabledKeys) + sys.stderr.write('Error in reloadMyAddressHashes: Can\'t handle address versions other than 2 or 3.\n') def reloadBroadcastSendersForWhichImWatching(): - logger.debug('reloading subscriptions...') + printLock.acquire() + print 'reloading subscriptions...' + printLock.release() broadcastSendersForWhichImWatching.clear() MyECSubscriptionCryptorObjects.clear() sqlLock.acquire() @@ -272,45 +246,46 @@ def doCleanShutdown(): knownNodesLock.acquire() UISignalQueue.put(('updateStatusBar','Saving the knownNodes list of peers to disk...')) output = open(appdata + 'knownnodes.dat', 'wb') - logger.info('finished opening knownnodes.dat. Now pickle.dump') + print 'finished opening knownnodes.dat. Now pickle.dump' pickle.dump(knownNodes, output) - logger.info('Completed pickle.dump. Closing output...') + print 'Completed pickle.dump. Closing output...' output.close() knownNodesLock.release() - logger.info('Finished closing knownnodes.dat output file.') + printLock.acquire() + print 'Finished closing knownnodes.dat output file.' + printLock.release() UISignalQueue.put(('updateStatusBar','Done saving the knownNodes list of peers to disk.')) broadcastToSendDataQueues((0, 'shutdown', 'all')) - logger.info('Flushing inventory in memory out to disk...') - UISignalQueue.put(( - 'updateStatusBar', - 'Flushing inventory in memory out to disk. This should normally only take a second...')) + printLock.acquire() + print 'Flushing inventory in memory out to disk...' + printLock.release() + UISignalQueue.put(('updateStatusBar','Flushing inventory in memory out to disk. This should normally only take a second...')) flushInventory() - # This one last useless query will guarantee that the previous flush committed before we close - # the program. + #This one last useless query will guarantee that the previous flush committed before we close the program. sqlLock.acquire() sqlSubmitQueue.put('SELECT address FROM subscriptions') sqlSubmitQueue.put('') sqlReturnQueue.get() sqlSubmitQueue.put('exit') sqlLock.release() - logger.info('Finished flushing inventory.') + printLock.acquire() + print 'Finished flushing inventory.' + printLock.release() - # Wait long enough to guarantee that any running proof of work worker threads will check the - # shutdown variable and exit. If the main thread closes before they do then they won't stop. - time.sleep(.25) + time.sleep(.25) #Wait long enough to guarantee that any running proof of work worker threads will check the shutdown variable and exit. If the main thread closes before they do then they won't stop. if safeConfigGetBoolean('bitmessagesettings','daemon'): - logger.info('Clean shutdown complete.') + printLock.acquire() + print 'Done.' + printLock.release() os._exit(0) -# When you want to command a sendDataThread to do something, like shutdown or send some data, this -# function puts your data into the queues for each of the sendDataThreads. The sendDataThreads are -# responsible for putting their queue into (and out of) the sendDataQueues list. +#When you want to command a sendDataThread to do something, like shutdown or send some data, this function puts your data into the queues for each of the sendDataThreads. The sendDataThreads are responsible for putting their queue into (and out of) the sendDataQueues list. def broadcastToSendDataQueues(data): - # logger.debug('running broadcastToSendDataQueues') + #print 'running broadcastToSendDataQueues' for q in sendDataQueues: q.put((data)) @@ -334,41 +309,3 @@ def fixPotentiallyInvalidUTF8Data(text): except: output = 'Part of the message is corrupt. The message cannot be displayed the normal way.\n\n' + repr(text) return output - -# Checks sensitive file permissions for inappropriate umask during keys.dat creation. -# (Or unwise subsequent chmod.) -# -# Returns true iff file appears to have appropriate permissions. -def checkSensitiveFilePermissions(filename): - if sys.platform == 'win32': - # TODO: This might deserve extra checks by someone familiar with - # Windows systems. - return True - else: - present_permissions = os.stat(filename)[0] - disallowed_permissions = stat.S_IRWXG | stat.S_IRWXO - return present_permissions & disallowed_permissions == 0 - -# Fixes permissions on a sensitive file. -def fixSensitiveFilePermissions(filename, hasEnabledKeys): - if hasEnabledKeys: - logger.warning('Keyfile had insecure permissions, and there were enabled keys. ' - 'The truly paranoid should stop using them immediately.') - else: - logger.warning('Keyfile had insecure permissions, but there were no enabled keys.') - try: - present_permissions = os.stat(filename)[0] - disallowed_permissions = stat.S_IRWXG | stat.S_IRWXO - allowed_permissions = ((1<<32)-1) ^ disallowed_permissions - new_permissions = ( - allowed_permissions & present_permissions) - os.chmod(filename, new_permissions) - - logger.info('Keyfile permissions automatically fixed.') - - except Exception, e: - logger.exception('Keyfile permissions could not be fixed.') - raise - -helper_startup.loadConfig() -from debug import logger \ No newline at end of file diff --git a/src/translations/bitmessage_ru_RU.pro b/src/translations/bitmessage_ru_RU.pro deleted file mode 100644 index 71cac3ae..00000000 --- a/src/translations/bitmessage_ru_RU.pro +++ /dev/null @@ -1,30 +0,0 @@ -SOURCES += ../addresses.py -SOURCES += ../bitmessagemain.py -SOURCES += ../class_addressGenerator.py -SOURCES += ../class_outgoingSynSender.py -SOURCES += ../class_receiveDataThread.py -SOURCES += ../class_sendDataThread.py -SOURCES += ../class_singleCleaner.py -SOURCES += ../class_singleListener.py -SOURCES += ../class_singleWorker.py -SOURCES += ../class_sqlThread.py -SOURCES += ../helper_bitcoin.py -SOURCES += ../helper_bootstrap.py -SOURCES += ../helper_generic.py -SOURCES += ../helper_inbox.py -SOURCES += ../helper_sent.py -SOURCES += ../helper_startup.py -SOURCES += ../shared.py -SOURCES += ../bitmessageqt/__init__.py -SOURCES += ../bitmessageqt/about.py -SOURCES += ../bitmessageqt/bitmessageui.py -SOURCES += ../bitmessageqt/help.py -SOURCES += ../bitmessageqt/iconglossary.py -SOURCES += ../bitmessageqt/newaddressdialog.py -SOURCES += ../bitmessageqt/newchandialog.py -SOURCES += ../bitmessageqt/newsubscriptiondialog.py -SOURCES += ../bitmessageqt/regenerateaddresses.py -SOURCES += ../bitmessageqt/settings.py -SOURCES += ../bitmessageqt/specialaddressbehavior.py - -TRANSLATIONS = bitmessage_ru_RU.ts diff --git a/src/translations/bitmessage_ru_RU.qm b/src/translations/bitmessage_ru_RU.qm deleted file mode 100644 index e917c3b0..00000000 Binary files a/src/translations/bitmessage_ru_RU.qm and /dev/null differ diff --git a/src/translations/bitmessage_ru_RU.ts b/src/translations/bitmessage_ru_RU.ts deleted file mode 100644 index e6337bf0..00000000 --- a/src/translations/bitmessage_ru_RU.ts +++ /dev/null @@ -1,1260 +0,0 @@ - - - - - MainWindow - - - One of your addresses, %1, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? - Один из Ваших адресов, %1, является устаревшим адресом версии 1. Адреса версии 1 больше не поддерживаются. Хотите ли Вы удалить его сейчас? - - - - Reply - Ответить - - - - Add sender to your Address Book - Добавить отправителя в адресную книгу - - - - Move to Trash - Поместить в корзину - - - - View HTML code as formatted text - Просмотреть HTML код как отформатированный текст - - - - Save message as... - Сохранить сообщение как ... - - - - New - Новый адрес - - - - Enable - Включить - - - - Disable - Выключить - - - - Copy address to clipboard - Скопировать адрес в буфер обмена - - - - Special address behavior... - Особое поведение адресов... - - - - Send message to this address - Отправить сообщение на этот адрес - - - - Subscribe to this address - Подписаться на рассылку с этого адреса - - - - Add New Address - Добавить новый адрес - - - - Delete - Удалить - - - - Copy destination address to clipboard - Скопировать адрес отправки в буфер обмена - - - - Force send - Форсировать отправку - - - - Add new entry - Добавить новую запись - - - - Waiting on their encryption key. Will request it again soon. - Ожидаем ключ шифрования от Вашего собеседника. Запрос будет повторен через некоторое время. - - - - Encryption key request queued. - Запрос ключа шифрования поставлен в очередь. - - - - Queued. - В очереди. - - - - Message sent. Waiting on acknowledgement. Sent at %1 - Сообщение отправлено. Ожидаем подтверждения. Отправлено в %1 - - - - Need to do work to send message. Work is queued. - Нужно провести требуемые вычисления, чтобы отправить сообщение. Вычисления ожидают очереди. - - - - Acknowledgement of the message received %1 - Сообщение получено %1 - - - - Broadcast queued. - Рассылка ожидает очереди. - - - - Broadcast on %1 - Рассылка на %1 - - - - Problem: The work demanded by the recipient is more difficult than you are willing to do. %1 - Проблема: Ваш получатель требует более сложных вычислений, чем максимум, указанный в Ваших настройках. %1 - - - - Problem: The recipient's encryption key is no good. Could not encrypt message. %1 - Проблема: ключ получателя неправильный. Невозможно зашифровать сообщение. %1 - - - - Forced difficulty override. Send should start soon. - Форсирована смена сложности. Отправляем через некоторое время. - - - - Unknown status: %1 %2 - Неизвестный статус: %1 %2 - - - - Since startup on %1 - С начала работы %1 - - - - Not Connected - Не соединено - - - - Show Bitmessage - Показать Bitmessage - - - - Send - Отправка - - - - Subscribe - Подписки - - - - Address Book - Адресная книга - - - - Quit - Выйти - - - - You may manage your keys by editing the keys.dat file stored in the same directory as this program. It is important that you back up this file. - Вы можете управлять Вашими ключами, отредактировав файл keys.dat, находящийся в той же папке, что и эта программа. -Создайте резервную копию этого файла перед тем как будете его редактировать. - - - - You may manage your keys by editing the keys.dat file stored in - %1 -It is important that you back up this file. - Вы можете управлять Вашими ключами, отредактировав файл keys.dat, находящийся в - %1 -Создайте резервную копию этого файла перед тем как будете его редактировать. - - - - Open keys.dat? - Открыть файл keys.dat? - - - - You may manage your keys by editing the keys.dat file stored in the same directory as this program. It is important that you back up this file. Would you like to open the file now? (Be sure to close Bitmessage before making any changes.) - Вы можете управлять Вашими ключами, отредактировав файл keys.dat, находящийся в той же папке, что и эта программа. -Создайте резервную копию этого файла перед тем как будете его редактировать. Хотели бы Вы открыть этот файл сейчас? -(пожалуйста, закройте Bitmessage до того как Вы внесете в этот файл какие-либо изменения.) - - - - You may manage your keys by editing the keys.dat file stored in - %1 -It is important that you back up this file. Would you like to open the file now? (Be sure to close Bitmessage before making any changes.) - Вы можете управлять Вашими ключами, отредактировав файл keys.dat, находящийся в - %1 -Создайте резервную копию этого файла перед тем как будете его редактировать. Хотели бы Вы открыть этот файл сейчас? -(пожалуйста, закройте Bitmessage до того как Вы внесете в этот файл какие-либо изменения.) - - - - Delete trash? - Очистить корзину? - - - - Are you sure you want to delete all trashed messages? - Вы уверены, что хотите очистить корзину? - - - - bad passphrase - Неподходящая секретная фраза - - - - You must type your passphrase. If you don't have one then this is not the form for you. - Вы должны ввести секретную фразу. Если Вы не хотите это делать, то Вы выбрали неправильную опцию. - - - - Processed %1 person-to-person messages. - Обработано %1 сообщений. - - - - Processed %1 broadcast messages. - Обработано %1 рассылок. - - - - Processed %1 public keys. - Обработано %1 открытых ключей. - - - - Total Connections: %1 - Всего соединений: %1 - - - - Connection lost - Соединение потеряно - - - - Connected - Соединено - - - - Message trashed - Сообщение удалено - - - - Error: Bitmessage addresses start with BM- Please check %1 - Ошибка: Bitmessage адреса начинаются с BM- Пожалуйста, проверьте %1 - - - - Error: The address %1 is not typed or copied correctly. Please check it. - Ошибка: адрес %1 внесен или скопирован неправильно. Пожалуйста, перепроверьте. - - - - Error: The address %1 contains invalid characters. Please check it. - Ошибка: адрес %1 содержит запрещенные символы. Пожалуйста, перепроверьте. - - - - Error: The address version in %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - Ошибка: версия адреса в %1 слишком новая. Либо Вам нужно обновить Bitmessage, либо Ваш собеседник дал неправильный адрес. - - - - Error: Some data encoded in the address %1 is too short. There might be something wrong with the software of your acquaintance. - Ошибка: некоторые данные, закодированные в адресе %1, слишком короткие. Возможно, что-то не так с программой Вашего собеседника. - - - - Error: Some data encoded in the address %1 is too long. There might be something wrong with the software of your acquaintance. - Ошибка: некоторые данные, закодированные в адресе %1, слишком длинные. Возможно, что-то не так с программой Вашего собеседника. - - - - Error: Something is wrong with the address %1. - Ошибка: что-то не так с адресом %1. - - - - Error: You must specify a From address. If you don't have one, go to the 'Your Identities' tab. - Вы должны указать адрес в поле "От кого". Вы можете найти Ваш адрес во вкладе "Ваши Адреса". - - - - Sending to your address - Отправка на Ваш собственный адрес - - - - Error: One of the addresses to which you are sending a message, %1, is yours. Unfortunately the Bitmessage client cannot process its own messages. Please try running a second client on a different computer or within a VM. - Ошибка: Один из адресов, на который Вы отправляете сообщение, %1, принадлежит Вам. К сожалению, Bitmessage не может отправлять сообщения самому себе. Попробуйте запустить второго клиента на другом компьютере или на виртуальной машине. - - - - Address version number - Версия адреса - - - - Concerning the address %1, Bitmessage cannot understand address version numbers of %2. Perhaps upgrade Bitmessage to the latest version. - По поводу адреса %1: Bitmessage не поддерживаем адреса версии %2. Возможно, Вам нужно обновить клиент Bitmessage. - - - - Stream number - Номер потока - - - - Concerning the address %1, Bitmessage cannot handle stream numbers of %2. Perhaps upgrade Bitmessage to the latest version. - По поводу адреса %1: Bitmessage не поддерживаем стрим номер %2. Возможно, Вам нужно обновить клиент Bitmessage. - - - - Warning: You are currently not connected. Bitmessage will do the work necessary to send the message but it won't send until you connect. - Внимание: Вы не подключены к сети. Bitmessage проделает необходимые вычисления, чтобы отправить сообщение, но не отправит его до тех пор, пока Вы не подсоединитесь к сети. - - - - Your 'To' field is empty. - Вы не заполнили поле 'Кому'. - - - - Work is queued. - Вычисления поставлены в очередь. - - - - Right click one or more entries in your address book and select 'Send message to this address'. - Нажмите правую кнопку мышки на каком-либо адресе и выберите "Отправить сообщение на этот адрес". - - - - Work is queued. %1 - Вычисления поставлены в очередь. %1 - - - - New Message - Новое сообщение - - - - From - От - - - - Address is valid. - Адрес введен правильно. - - - - Error: You cannot add the same address to your address book twice. Try renaming the existing one if you want. - Ошибка: Вы не можете добавлять один и тот же адрес в Адресную Книгу несколько раз. Просто переименуйте существующий адрес. - - - - The address you entered was invalid. Ignoring it. - Вы ввели неправильный адрес. Это адрес проигнорирован. - - - - Error: You cannot add the same address to your subsciptions twice. Perhaps rename the existing one if you want. - Ошибка: Вы не можете добавлять один и тот же адрес в подписку несколько раз. Просто переименуйте существующую подписку. - - - - Restart - Перезапустить - - - - You must restart Bitmessage for the port number change to take effect. - Вы должны перезапустить Bitmessage, чтобы смена номера порта имела эффект. - - - - Bitmessage will use your proxy from now on but you may want to manually restart Bitmessage now to close existing connections. - Bitmessage будет использовать Ваш прокси в дальнейшем, тем не менее, мы рекомендуем перезапустить Bitmessage в ручную, чтобы закрыть уже существующие соединения. - - - - Error: You cannot add the same address to your list twice. Perhaps rename the existing one if you want. - Ошибка: Вы не можете добавлять один и тот же адрес в список несколько раз. Просто переименуйте существующий адрес. - - - - Passphrase mismatch - Секретная фраза не подходит - - - - The passphrase you entered twice doesn't match. Try again. - Вы ввели две разные секретные фразы. Пожалуйста, повторите заново. - - - - Choose a passphrase - Придумайте секретную фразу - - - - You really do need a passphrase. - Вы действительно должны ввести секретную фразу. - - - - All done. Closing user interface... - Программа завершена. Закрываем пользовательский интерфейс... - - - - Address is gone - Адрес утерян - - - - Bitmessage cannot find your address %1. Perhaps you removed it? - Bitmessage не может найти Ваш адрес %1. Возможно Вы удалили его? - - - - Address disabled - Адрес выключен - - - - Error: The address from which you are trying to send is disabled. You'll have to enable it on the 'Your Identities' tab before using it. - Ошибка: адрес, с которого Вы пытаетесь отправить, выключен. Вам нужно будет включить этот адрес во вкладке "Ваши адреса". - - - - Entry added to the Address Book. Edit the label to your liking. - Запись добавлена в Адресную Книгу. Вы можете ее отредактировать. - - - - Moved items to trash. There is no user interface to view your trash, but it is still on disk if you are desperate to get it back. - Удалено в корзину. Чтобы попасть в корзину, Вам нужно будет найти файл корзины на диске. - - - - Save As... - Сохранить как ... - - - - Write error. - Ошибка записи. - - - - No addresses selected. - Вы не выбрали адрес. - - - - Options have been disabled because they either aren't applicable or because they haven't yet been implemented for your operating system. - Опции были отключены, потому что ли они либо не подходят, либо еще не выполнены под Вашу операционную систему. - - - - The address should start with ''BM-'' - Адрес должен начинаться с "BM-" - - - - The address is not typed or copied correctly (the checksum failed). - Адрес введен или скопирован неверно (контрольная сумма не сходится). - - - - The version number of this address is higher than this software can support. Please upgrade Bitmessage. - Версия этого адреса более поздняя, чем Ваша программа. Пожалуйста, обновите программу Bitmessage. - - - - The address contains invalid characters. - Адрес содержит запрещенные символы. - - - - Some data encoded in the address is too short. - Данные, закодированные в адресе, слишком короткие. - - - - Some data encoded in the address is too long. - Данные, закодированные в адресе, слишком длинные. - - - - You are using TCP port %1. (This can be changed in the settings). - Вы используете TCP порт %1 (Его можно поменять в настройках). - - - - Bitmessage - Bitmessage - - - - To - Кому - - - - From - От кого - - - - Subject - Тема - - - - Received - Получено - - - - Inbox - Входящие - - - - Load from Address book - Взять из адресной книги - - - - Message: - Сообщение: - - - - Subject: - Тема: - - - - Send to one or more specific people - Отправить одному или нескольким указанным получателям - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'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;"><br /></p></body></html> - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'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;"><br /></p></body></html> - - - - To: - Кому: - - - - From: - От: - - - - Broadcast to everyone who is subscribed to your address - Рассылка всем, кто подписался на Ваш адрес - - - - Be aware that broadcasts are only encrypted with your address. Anyone who knows your address can read them. - Пожалуйста, учитывайте, что рассылки шифруются лишь Вашим адресом. Любой человек, который знает Ваш адрес, сможет прочитать Вашу рассылку. - - - - Status - Статус - - - - Sent - Отправленные - - - - Label (not shown to anyone) - Название (не показывается никому) - - - - Address - Адрес - - - - Stream - Поток - - - - Your Identities - Ваши Адреса - - - - Here you can subscribe to 'broadcast messages' that are sent by other users. Messages will appear in your Inbox. Addresses here override those on the Blacklist tab. - Здесь Вы можете подписаться на рассылки от других пользователей. Все рассылки будут появляться у Вас во Входящих. Вы будете следить за всеми адресами, указанными здесь, даже если они в черном списке. - - - - Add new Subscription - Добавить новую подписку - - - - Label - Название - - - - Subscriptions - Подписки - - - - The Address book is useful for adding names or labels to other people's Bitmessage addresses so that you can recognize them more easily in your inbox. You can add entries here using the 'Add' button, or from your inbox by right-clicking on a message. - Адресная книга удобна для присвоения осмысленных имен Bitmessage адресам Ваших друзей. Вы можете добавлять новые записи с помощью кнопки "Добавить новую запись", или же правым кликом мышки на сообщении. - - - - Name or Label - Название - - - - Use a Blacklist (Allow all incoming messages except those on the Blacklist) - Использовать черный список (Разрешить все входящие сообщения, кроме указанных в черном списке) - - - - Use a Whitelist (Block all incoming messages except those on the Whitelist) - Использовать белый список (блокировать все входящие сообщения, кроме указанных в белом списке) - - - - Blacklist - Черный список - - - - Stream # - № потока - - - - Connections - Соединений - - - - Total connections: 0 - Всего соединений: 0 - - - - Since startup at asdf: - С начала работы программы в asdf: - - - - Processed 0 person-to-person message. - Обработано 0 сообщений. - - - - Processed 0 public key. - Обработано 0 открытых ключей. - - - - Processed 0 broadcast. - Обработано 0 рассылок. - - - - Network Status - Статус сети - - - - File - Файл - - - - Settings - Настройки - - - - Help - Помощь - - - - Import keys - Импортировать ключи - - - - Manage keys - Управлять ключами - - - - About - О программе - - - - Regenerate deterministic addresses - Сгенерировать заново все адреса - - - - Delete all trashed messages - Стереть все сообщения из корзины - - - - NewAddressDialog - - - Create new Address - Создать новый адрес - - - - Here you may generate as many addresses as you like. Indeed, creating and abandoning addresses is encouraged. You may generate addresses by using either random numbers or by using a passphrase. If you use a passphrase, the address is called a "deterministic" address. -The 'Random Number' option is selected by default but deterministic addresses have several pros and cons: - Здесь Вы сможете сгенерировать столько адресов сколько хотите. На самом деле, создание и выкидывание адресов даже поощряется. Вы можете сгенерировать адреса используя либо генератор случайных чисел либо придумав секретную фразу. Если Вы используете секретную фразу, то адреса будут называться "детерминистическими". Генератор случайных чисел выбран по умолчанию, однако детерминистические адреса имеют следующие плюсы и минусы по сравнению с ними: - - - - <html><head/><body><p><span style=" font-weight:600;">Pros:<br/></span>You can recreate your addresses on any computer from memory. <br/>You need-not worry about backing up your keys.dat file as long as you can remember your passphrase. <br/><span style=" font-weight:600;">Cons:<br/></span>You must remember (or write down) your passphrase if you expect to be able to recreate your keys if they are lost. <br/>You must remember the address version number and the stream number along with your passphrase. <br/>If you choose a weak passphrase and someone on the Internet can brute-force it, they can read your messages and send messages as you.</p></body></html> - <html><head/><body><p><span style=" font-weight:600;">Плюсы:<br/></span>Вы сможете восстановить адрес по памяти на любом компьютере<br/>Вам не нужно беспокоиться о сохранении файла keys.dat, если Вы запомнили секретную фразу<br/><span style=" font-weight:600;">Минусы:<br/></span>Вы должны запомнить (или записать) секретную фразу, если Вы хотите когда-либо восстановить Ваш адрес на другом компьютере <br/>Вы должны также запомнить версию адреса и номер потока вместе с секретной фразой<br/>Если Вы выберите слишком короткую секретную фразу, кто-нибудь в интернете сможет подобрать ключ и, как следствие, читать и отправлять от Вашего имени сообщения.</p></body></html> - - - - Use a random number generator to make an address - Использовать генератор случайных чисел для создания адреса - - - - Use a passphrase to make addresses - Использовать секретную фразу для создания адресов - - - - Spend several minutes of extra computing time to make the address(es) 1 or 2 characters shorter - Потратить несколько лишних минут, чтобы сделать адрес(а) короче на 1 или 2 символа - - - - Make deterministic addresses - Создать детерминистический адрес - - - - Address version number: 3 - Версия адреса: 3 - - - - In addition to your passphrase, you must remember these numbers: - В дополнение к секретной фразе, Вам необходимо запомнить эти числа: - - - - Passphrase - Придумайте секретную фразу - - - - Number of addresses to make based on your passphrase: - Кол-во адресов, которые Вы хотите получить из секретной фразы: - - - - Stream number: 1 - Номер потока: 1 - - - - Retype passphrase - Повторите секретную фразу - - - - Randomly generate address - Сгенерировать случайный адрес - - - - Label (not shown to anyone except you) - Название (не показывается никому кроме Вас) - - - - Use the most available stream - Использовать наиболее доступный поток - - - - (best if this is the first of many addresses you will create) - (выберите этот вариант, если это лишь первый из многих адресов, которые Вы планируете создать) - - - - Use the same stream as an existing address - Использовать тот же поток, что и указанный существующий адрес - - - - (saves you some bandwidth and processing power) - (немного сэкономит Вам пропускную способность сети и вычислительную мощь) - - - - NewChanDialog - - - Dialog - Новый chan - - - - Create a new chan - Создать новый chan - - - - Join a chan - Присоединиться к chan - - - - <html><head/><body><p>A chan is a set of encryption keys that is shared by a group of people. The keys and bitmessage address used by a chan is generated from a human-friendly word or phrase (the chan name).</p><p>Chans are experimental and are unmoderatable.</p></body></html> - <html><head/><body><p>Chan - это набор ключей шифрования, которые известны некоторой группе людей. Ключи и Bitmessage-адрес используемый chan-ом генерируется из слова или фразы (имя chan-а).</p><p>Chan-ы - это экспериментальная новинка.</p></body></html> - - - - Chan name: - Имя chan: - - - - Chan bitmessage address: - Bitmessage адрес chan: - - - - Create a chan - Создать chan - - - - Enter a name for your chan. If you choose a sufficiently complex chan name (like a strong and unique passphrase) and none of your friends share it publicly then the chan will be secure and private. - Введите имя Вашего chan-a. Если Вы выберете достаточно сложное имя для chan-а (например, сложную и необычную секретную фразу) и никто из Ваших друзей не опубликует эту фразу, то Вам chan будет надежно зашифрован. - - - - NewSubscriptionDialog - - - Add new entry - Добавить новую запись - - - - Label - Название - - - - Address - Адрес - - - - SpecialAddressBehaviorDialog - - - Special Address Behavior - Особое поведение адреса - - - - Behave as a normal address - Вести себя как обычный адрес - - - - Behave as a pseudo-mailing-list address - Вести себя как адрес псевдо-рассылки - - - - Mail received to a pseudo-mailing-list address will be automatically broadcast to subscribers (and thus will be public). - Почта, полученная на адрес псевдо-рассылки, будет автоматически разослана всем подписчикам (и поэтому будет доступна общей публике). - - - - Name of the pseudo-mailing-list: - Имя псевдо-рассылки: - - - - aboutDialog - - - About - О программе - - - - PyBitmessage - PyBitmessage - - - - version ? - версия ? - - - - Copyright © 2013 Jonathan Warren - Копирайт © 2013 Джонатан Уоррен - - - - <html><head/><body><p>Distributed under the MIT/X11 software license; see <a href="http://www.opensource.org/licenses/mit-license.php"><span style=" text-decoration: underline; color:#0000ff;">http://www.opensource.org/licenses/mit-license.php</span></a></p></body></html> - <html><head/><body><p>Программа распространяется в соответствии с лицензией MIT/X11; см. <a href="http://www.opensource.org/licenses/mit-license.php"><span style=" text-decoration: underline; color:#0000ff;">http://www.opensource.org/licenses/mit-license.php</span></a></p></body></html> - - - - This is Beta software. - Это бета версия программы. - - - - helpDialog - - - Help - Помощь - - - - <a href="http://Bitmessage.org/wiki/PyBitmessage_Help">http://Bitmessage.org/wiki/PyBitmessage_Help</a> - <a href="http://Bitmessage.org/wiki/PyBitmessage_Help">http://Bitmessage.org/wiki/PyBitmessage_Help</a> - - - - As Bitmessage is a collaborative project, help can be found online in the Bitmessage Wiki: - Bitmessage - общественный проект. Вы можете найти подсказки и советы на Wiki-страничке Bitmessage: - - - - iconGlossaryDialog - - - Icon Glossary - Описание значков - - - - You have no connections with other peers. - Нет соединения с другими участниками сети. - - - - You have made at least one connection to a peer using an outgoing connection but you have not yet received any incoming connections. Your firewall or home router probably isn't configured to forward incoming TCP connections to your computer. Bitmessage will work just fine but it would help the Bitmessage network if you allowed for incoming connections and will help you be a better-connected node. - На текущий момент Вы установили по-крайней мере одно исходящее соединение, но пока ни одного входящего. Ваш файрвол или маршрутизатор скорее всего не настроен на переброс входящих TCP соединений к Вашему компьютеру. Bitmessage будет прекрасно работать и без этого, но Вы могли бы помочь сети если бы разрешили и входящие соединения тоже. Это помогло бы Вам стать более важным узлом сети. - - - - You are using TCP port ?. (This can be changed in the settings). - Вы используете TCP порт ?. (Его можно поменять в настройках). - - - - You do have connections with other peers and your firewall is correctly configured. - Вы установили соединение с другими участниками сети и ваш файрвол настроен правильно. - - - - regenerateAddressesDialog - - - Regenerate Existing Addresses - Сгенерировать заново существующие адреса - - - - Regenerate existing addresses - Сгенерировать заново существующие адреса - - - - Passphrase - Секретная фраза - - - - Number of addresses to make based on your passphrase: - Кол-во адресов, которые Вы хотите получить из Вашей секретной фразы: - - - - Address version Number: - Версия адреса: - - - - 3 - 3 - - - - Stream number: - Номер потока: - - - - 1 - 1 - - - - Spend several minutes of extra computing time to make the address(es) 1 or 2 characters shorter - Потратить несколько лишних минут, чтобы сделать адрес(а) короче на 1 или 2 символа - - - - You must check (or not check) this box just like you did (or didn't) when you made your addresses the first time. - Вы должны кликнуть эту галочку (или не кликать) точно также как Вы сделали в самый первый раз, когда создавали Ваши адреса. - - - - If you have previously made deterministic addresses but lost them due to an accident (like hard drive failure), you can regenerate them here. If you used the random number generator to make your addresses then this form will be of no use to you. - Если Вы ранее делали детерминистические адреса, но случайно потеряли их, Вы можете их восстановить здесь. Если же Вы использовали генератор случайных чисел, чтобы создать Ваши адреса, то Вы не сможете их здесь восстановить. - - - - settingsDialog - - - Settings - Настройки - - - - Start Bitmessage on user login - Запускать Bitmessage при входе в систему - - - - Start Bitmessage in the tray (don't show main window) - Запускать Bitmessage в свернутом виде (не показывать главное окно) - - - - Minimize to tray - Сворачивать в трей - - - - Show notification when message received - Показывать уведомления при получении новых сообщений - - - - Run in Portable Mode - Запустить в переносном режиме - - - - In Portable Mode, messages and config files are stored in the same directory as the program rather than the normal application-data folder. This makes it convenient to run Bitmessage from a USB thumb drive. - В переносном режиме, все сообщения и конфигурационные файлы сохраняются в той же самой папке что и сама программа. Это делает более удобным использование Bitmessage с USB-флэшки. - - - - User Interface - Пользовательские - - - - Listening port - Порт прослушивания - - - - Listen for connections on port: - Прослушивать соединения на порту: - - - - Proxy server / Tor - Прокси сервер / Tor - - - - Type: - Тип: - - - - none - отсутствует - - - - SOCKS4a - SOCKS4a - - - - SOCKS5 - SOCKS5 - - - - Server hostname: - Адрес сервера: - - - - Port: - Порт: - - - - Authentication - Авторизация - - - - Username: - Имя пользователя: - - - - Pass: - Прль: - - - - Network Settings - Сетевые настройки - - - - When someone sends you a message, their computer must first complete some work. The difficulty of this work, by default, is 1. You may raise this default for new addresses you create by changing the values here. Any new addresses you create will require senders to meet the higher difficulty. There is one exception: if you add a friend or acquaintance to your address book, Bitmessage will automatically notify them when you next send a message that they need only complete the minimum amount of work: difficulty 1. - Когда кто-либо отправляет Вам сообщение, его компьютер должен сперва решить определенную вычислительную задачу. Сложность этой задачи по умолчанию равна 1. Вы можете повысить эту сложность для новых адресов, которые Вы создадите, здесь. Таким образом, любые новые адреса, которые Вы создадите, могут требовать от отправителей сложность большую чем 1. Однако, есть одно исключение: если Вы специально добавите Вашего собеседника в адресную книгу, то Bitmessage автоматически уведомит его о том, что для него минимальная сложность будет составлять всегда всего лишь 1. - - - - Total difficulty: - Общая сложность: - - - - Small message difficulty: - Сложность для маленьких сообщений: - - - - The 'Small message difficulty' mostly only affects the difficulty of sending small messages. Doubling this value makes it almost twice as difficult to send a small message but doesn't really affect large messages. - "Сложность для маленьких сообщений" влияет исключительно на небольшие сообщения. Увеличив это число в два раза, вы сделаете отправку маленьких сообщений в два раза сложнее, в то время как сложность отправки больших сообщений не изменится. - - - - The 'Total difficulty' affects the absolute amount of work the sender must complete. Doubling this value doubles the amount of work. - "Общая сложность" влияет на абсолютное количество вычислений, которые отправитель должен провести, чтобы отправить сообщение. Увеличив это число в два раза, вы увеличите в два раза объем требуемых вычислений. - - - - Demanded difficulty - Требуемая сложность - - - - Here you may set the maximum amount of work you are willing to do to send a message to another person. Setting these values to 0 means that any value is acceptable. - Здесь Вы можете установить максимальную вычислительную работу, которую Вы согласны проделать, чтобы отправить сообщение другому пользователю. Ноль означает, чтобы любое значение допустимо. - - - - Maximum acceptable total difficulty: - Макс допустимая общая сложность: - - - - Maximum acceptable small message difficulty: - Макс допустимая сложность для маленький сообщений: - - - - Max acceptable difficulty - Макс допустимая сложность - - -