Merge pull request #333 from Atheros1/master

Further work to implement the Connect dialog on startup
This commit is contained in:
Jonathan Warren 2013-07-24 09:45:07 -07:00
commit 63b201e6a8
5 changed files with 44 additions and 54 deletions

View File

@ -9,7 +9,7 @@
# The software version variable is now held in shared.py # The software version variable is now held in shared.py
#import ctypes # import ctypes
try: try:
from gevent import monkey from gevent import monkey
monkey.patch_all() monkey.patch_all()
@ -36,7 +36,7 @@ import helper_bootstrap
import sys import sys
if sys.platform == 'darwin': if sys.platform == 'darwin':
if float( "{1}.{2}".format(*sys.version_info) ) < 7.5: if float("{1}.{2}".format(*sys.version_info)) < 7.5:
print "You should use python 2.7.5 or greater." print "You should use python 2.7.5 or greater."
print "Your version: {0}.{1}.{2}".format(*sys.version_info) print "Your version: {0}.{1}.{2}".format(*sys.version_info)
sys.exit(0) sys.exit(0)
@ -56,8 +56,6 @@ def connectToStream(streamNumber):
# This is one of several classes that constitute the API # This is one of several classes that constitute the API
# This class was written by Vaibhav Bhatia. Modified by Jonathan Warren (Atheros). # This class was written by Vaibhav Bhatia. Modified by Jonathan Warren (Atheros).
# http://code.activestate.com/recipes/501148-xmlrpc-serverclient-which-does-cookie-handling-and/ # http://code.activestate.com/recipes/501148-xmlrpc-serverclient-which-does-cookie-handling-and/
class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
def do_POST(self): def do_POST(self):
@ -342,7 +340,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
msgid, toAddress, fromAddress, subject, received, message, encodingtype = row msgid, toAddress, fromAddress, subject, received, message, encodingtype = row
subject = shared.fixPotentiallyInvalidUTF8Data(subject) subject = shared.fixPotentiallyInvalidUTF8Data(subject)
message = shared.fixPotentiallyInvalidUTF8Data(message) message = shared.fixPotentiallyInvalidUTF8Data(message)
data += json.dumps({'msgid':msgid.encode('hex'),'toAddress':toAddress,'fromAddress':fromAddress,'subject':subject.encode('base64'),'message':message.encode('base64'),'encodingType':encodingtype,'receivedTime':received},indent=4, separators=(',', ': ')) data += json.dumps({'msgid':msgid.encode('hex'), 'toAddress':toAddress, 'fromAddress':fromAddress, 'subject':subject.encode('base64'), 'message':message.encode('base64'), 'encodingType':encodingtype, 'receivedTime':received}, indent=4, separators=(',', ': '))
data += ']}' data += ']}'
return data return data
elif method == 'getAllSentMessages': elif method == 'getAllSentMessages':
@ -358,7 +356,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
message = shared.fixPotentiallyInvalidUTF8Data(message) message = shared.fixPotentiallyInvalidUTF8Data(message)
if len(data) > 25: if len(data) > 25:
data += ',' data += ','
data += json.dumps({'msgid':msgid.encode('hex'),'toAddress':toAddress,'fromAddress':fromAddress,'subject':subject.encode('base64'),'message':message.encode('base64'),'encodingType':encodingtype,'lastActionTime':lastactiontime,'status':status,'ackData':ackdata.encode('hex')},indent=4, separators=(',', ': ')) data += json.dumps({'msgid':msgid.encode('hex'), 'toAddress':toAddress, 'fromAddress':fromAddress, 'subject':subject.encode('base64'), 'message':message.encode('base64'), 'encodingType':encodingtype, 'lastActionTime':lastactiontime, 'status':status, 'ackData':ackdata.encode('hex')}, indent=4, separators=(',', ': '))
data += ']}' data += ']}'
return data return data
elif method == 'getInboxMessagesByAddress': elif method == 'getInboxMessagesByAddress':
@ -373,12 +371,12 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
shared.sqlLock.release() shared.sqlLock.release()
data = '{"inboxMessages":[' data = '{"inboxMessages":['
for row in queryreturn: for row in queryreturn:
msgid, toAddress, fromAddress, subject, received, message, encodingtype= row msgid, toAddress, fromAddress, subject, received, message, encodingtype = row
subject = shared.fixPotentiallyInvalidUTF8Data(subject) subject = shared.fixPotentiallyInvalidUTF8Data(subject)
message = shared.fixPotentiallyInvalidUTF8Data(message) message = shared.fixPotentiallyInvalidUTF8Data(message)
if len(data) > 25: if len(data) > 25:
data += ',' data += ','
data += json.dumps({'msgid':msgid.encode('hex'),'toAddress':toAddress,'fromAddress':fromAddress,'subject':subject.encode('base64'),'message':message.encode('base64'),'encodingType':encodingtype,'receivedTime':received},indent=4, separators=(',', ': ')) data += json.dumps({'msgid':msgid.encode('hex'), 'toAddress':toAddress, 'fromAddress':fromAddress, 'subject':subject.encode('base64'), 'message':message.encode('base64'), 'encodingType':encodingtype, 'receivedTime':received}, indent=4, separators=(',', ': '))
data += ']}' data += ']}'
return data return data
elif method == 'getSentMessageById': elif method == 'getSentMessageById':
@ -396,7 +394,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
msgid, toAddress, fromAddress, subject, lastactiontime, message, encodingtype, status, ackdata = row msgid, toAddress, fromAddress, subject, lastactiontime, message, encodingtype, status, ackdata = row
subject = shared.fixPotentiallyInvalidUTF8Data(subject) subject = shared.fixPotentiallyInvalidUTF8Data(subject)
message = shared.fixPotentiallyInvalidUTF8Data(message) message = shared.fixPotentiallyInvalidUTF8Data(message)
data += json.dumps({'msgid':msgid.encode('hex'),'toAddress':toAddress,'fromAddress':fromAddress,'subject':subject.encode('base64'),'message':message.encode('base64'),'encodingType':encodingtype,'lastActionTime':lastactiontime,'status':status,'ackData':ackdata.encode('hex')},indent=4, separators=(',', ': ')) data += json.dumps({'msgid':msgid.encode('hex'), 'toAddress':toAddress, 'fromAddress':fromAddress, 'subject':subject.encode('base64'), 'message':message.encode('base64'), 'encodingType':encodingtype, 'lastActionTime':lastactiontime, 'status':status, 'ackData':ackdata.encode('hex')}, indent=4, separators=(',', ': '))
data += ']}' data += ']}'
return data return data
elif method == 'getSentMessagesByAddress': elif method == 'getSentMessagesByAddress':
@ -416,7 +414,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
message = shared.fixPotentiallyInvalidUTF8Data(message) message = shared.fixPotentiallyInvalidUTF8Data(message)
if len(data) > 25: if len(data) > 25:
data += ',' data += ','
data += json.dumps({'msgid':msgid.encode('hex'),'toAddress':toAddress,'fromAddress':fromAddress,'subject':subject.encode('base64'),'message':message.encode('base64'),'encodingType':encodingtype,'lastActionTime':lastactiontime,'status':status,'ackData':ackdata.encode('hex')},indent=4, separators=(',', ': ')) data += json.dumps({'msgid':msgid.encode('hex'), 'toAddress':toAddress, 'fromAddress':fromAddress, 'subject':subject.encode('base64'), 'message':message.encode('base64'), 'encodingType':encodingtype, 'lastActionTime':lastactiontime, 'status':status, 'ackData':ackdata.encode('hex')}, indent=4, separators=(',', ': '))
data += ']}' data += ']}'
return data return data
elif method == 'getSentMessageByAckData': elif method == 'getSentMessageByAckData':
@ -434,7 +432,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
msgid, toAddress, fromAddress, subject, lastactiontime, message, encodingtype, status, ackdata = row msgid, toAddress, fromAddress, subject, lastactiontime, message, encodingtype, status, ackdata = row
subject = shared.fixPotentiallyInvalidUTF8Data(subject) subject = shared.fixPotentiallyInvalidUTF8Data(subject)
message = shared.fixPotentiallyInvalidUTF8Data(message) message = shared.fixPotentiallyInvalidUTF8Data(message)
data += json.dumps({'msgid':msgid.encode('hex'),'toAddress':toAddress,'fromAddress':fromAddress,'subject':subject.encode('base64'),'message':message.encode('base64'),'encodingType':encodingtype,'lastActionTime':lastactiontime,'status':status,'ackData':ackdata.encode('hex')},indent=4, separators=(',', ': ')) data += json.dumps({'msgid':msgid.encode('hex'), 'toAddress':toAddress, 'fromAddress':fromAddress, 'subject':subject.encode('base64'), 'message':message.encode('base64'), 'encodingType':encodingtype, 'lastActionTime':lastactiontime, 'status':status, 'ackData':ackdata.encode('hex')}, indent=4, separators=(',', ': '))
data += ']}' data += ']}'
return data return data
elif (method == 'trashMessage') or (method == 'trashInboxMessage'): elif (method == 'trashMessage') or (method == 'trashInboxMessage'):
@ -454,7 +452,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
shared.sqlReturnQueue.get() shared.sqlReturnQueue.get()
shared.sqlSubmitQueue.put('commit') shared.sqlSubmitQueue.put('commit')
shared.sqlLock.release() shared.sqlLock.release()
#shared.UISignalQueue.put(('removeSentRowByMsgid',msgid)) This function doesn't exist yet. # shared.UISignalQueue.put(('removeSentRowByMsgid',msgid)) This function doesn't exist yet.
return 'Trashed sent message (assuming message existed).' return 'Trashed sent message (assuming message existed).'
elif method == 'sendMessage': elif method == 'sendMessage':
if len(params) == 0: if len(params) == 0:
@ -719,7 +717,6 @@ if __name__ == "__main__":
# signal.signal(signal.SIGINT, signal.SIG_DFL) # signal.signal(signal.SIGINT, signal.SIG_DFL)
helper_bootstrap.knownNodes() helper_bootstrap.knownNodes()
helper_bootstrap.dns()
# Start the address generation thread # Start the address generation thread
addressGeneratorThread = addressGenerator() addressGeneratorThread = addressGenerator()
addressGeneratorThread.daemon = True # close the main program even if there are threads left addressGeneratorThread.daemon = True # close the main program even if there are threads left
@ -757,13 +754,6 @@ if __name__ == "__main__":
singleAPIThread = singleAPI() singleAPIThread = singleAPI()
singleAPIThread.daemon = True # close the main program even if there are threads left singleAPIThread.daemon = True # close the main program even if there are threads left
singleAPIThread.start() singleAPIThread.start()
# self.singleAPISignalHandlerThread = singleAPISignalHandler()
# self.singleAPISignalHandlerThread.start()
# QtCore.QObject.connect(self.singleAPISignalHandlerThread, QtCore.SIGNAL("updateStatusBar(PyQt_PyObject)"), self.updateStatusBar)
# QtCore.QObject.connect(self.singleAPISignalHandlerThread, QtCore.SIGNAL("passAddressGeneratorObjectThrough(PyQt_PyObject)"), self.connectObjectToAddressGeneratorSignals)
# QtCore.QObject.connect(self.singleAPISignalHandlerThread,
# QtCore.SIGNAL("displayNewSentMessage(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"),
# self.displayNewSentMessage)
connectToStream(1) connectToStream(1)
@ -783,6 +773,7 @@ if __name__ == "__main__":
import bitmessageqt import bitmessageqt
bitmessageqt.run() bitmessageqt.run()
else: else:
shared.config.remove_option('bitmessagesettings', 'dontconnect')
with shared.printLock: with shared.printLock:
print 'Running as a daemon. You can use Ctrl+C to exit.' print 'Running as a daemon. You can use Ctrl+C to exit.'

View File

@ -2,7 +2,7 @@
# Form implementation generated from reading ui file 'connect.ui' # Form implementation generated from reading ui file 'connect.ui'
# #
# Created: Wed Jul 24 10:41:58 2013 # Created: Wed Jul 24 12:42:01 2013
# by: PyQt4 UI code generator 4.10 # by: PyQt4 UI code generator 4.10
# #
# WARNING! All changes made in this file will be lost! # WARNING! All changes made in this file will be lost!
@ -36,9 +36,9 @@ class Ui_connectDialog(object):
self.radioButtonConnectNow.setChecked(True) self.radioButtonConnectNow.setChecked(True)
self.radioButtonConnectNow.setObjectName(_fromUtf8("radioButtonConnectNow")) self.radioButtonConnectNow.setObjectName(_fromUtf8("radioButtonConnectNow"))
self.gridLayout.addWidget(self.radioButtonConnectNow, 1, 0, 1, 2) self.gridLayout.addWidget(self.radioButtonConnectNow, 1, 0, 1, 2)
self.radioButton = QtGui.QRadioButton(connectDialog) self.radioButtonConfigureNetwork = QtGui.QRadioButton(connectDialog)
self.radioButton.setObjectName(_fromUtf8("radioButton")) self.radioButtonConfigureNetwork.setObjectName(_fromUtf8("radioButtonConfigureNetwork"))
self.gridLayout.addWidget(self.radioButton, 2, 0, 1, 2) self.gridLayout.addWidget(self.radioButtonConfigureNetwork, 2, 0, 1, 2)
spacerItem = QtGui.QSpacerItem(185, 24, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) spacerItem = QtGui.QSpacerItem(185, 24, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
self.gridLayout.addItem(spacerItem, 3, 0, 1, 1) self.gridLayout.addItem(spacerItem, 3, 0, 1, 1)
self.buttonBox = QtGui.QDialogButtonBox(connectDialog) self.buttonBox = QtGui.QDialogButtonBox(connectDialog)
@ -53,8 +53,8 @@ class Ui_connectDialog(object):
QtCore.QMetaObject.connectSlotsByName(connectDialog) QtCore.QMetaObject.connectSlotsByName(connectDialog)
def retranslateUi(self, connectDialog): def retranslateUi(self, connectDialog):
connectDialog.setWindowTitle(_translate("connectDialog", "Dialog", None)) connectDialog.setWindowTitle(_translate("connectDialog", "Bitmessage", None))
self.label.setText(_translate("connectDialog", "Bitmessage won\'t connect to anyone until you let it. ", None)) self.label.setText(_translate("connectDialog", "Bitmessage won\'t connect to anyone until you let it. ", None))
self.radioButtonConnectNow.setText(_translate("connectDialog", "Connect now", None)) self.radioButtonConnectNow.setText(_translate("connectDialog", "Connect now", None))
self.radioButton.setText(_translate("connectDialog", "Let me configure special network settings first", None)) self.radioButtonConfigureNetwork.setText(_translate("connectDialog", "Let me configure special network settings first", None))

View File

@ -11,7 +11,7 @@
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>Dialog</string> <string>Bitmessage</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout"> <layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" colspan="2"> <item row="0" column="0" colspan="2">
@ -32,7 +32,7 @@
</widget> </widget>
</item> </item>
<item row="2" column="0" colspan="2"> <item row="2" column="0" colspan="2">
<widget class="QRadioButton" name="radioButton"> <widget class="QRadioButton" name="radioButtonConfigureNetwork">
<property name="text"> <property name="text">
<string>Let me configure special network settings first</string> <string>Let me configure special network settings first</string>
</property> </property>

View File

@ -3,6 +3,7 @@ import shared
import socket import socket
from class_sendDataThread import * from class_sendDataThread import *
from class_receiveDataThread import * from class_receiveDataThread import *
import helper_bootstrap
# Only one singleListener thread will ever exist. It creates the # Only one singleListener thread will ever exist. It creates the
# receiveDataThread and sendDataThread for each incoming connection. Note # receiveDataThread and sendDataThread for each incoming connection. Note
@ -21,14 +22,15 @@ class singleListener(threading.Thread):
self.selfInitiatedConnections = selfInitiatedConnections self.selfInitiatedConnections = selfInitiatedConnections
def run(self): def run(self):
while shared.safeConfigGetBoolean('bitmessagesettings', 'dontconnect'):
time.sleep(1)
helper_bootstrap.dns()
# We typically don't want to accept incoming connections if the user is using a # 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 # SOCKS proxy, unless they have configured otherwise. If they eventually select
# proxy 'none' or configure SOCKS listening then this will start listening for # proxy 'none' or configure SOCKS listening then this will start listening for
# connections. # connections.
while shared.config.get('bitmessagesettings', 'socksproxytype')[0:5] == 'SOCKS' and not shared.config.getboolean('bitmessagesettings', 'sockslisten'): while shared.config.get('bitmessagesettings', 'socksproxytype')[0:5] == 'SOCKS' and not shared.config.getboolean('bitmessagesettings', 'sockslisten'):
time.sleep(10) time.sleep(5)
while shared.safeConfigGetBoolean('bitmessagesettings', 'dontconnect'):
time.sleep(1)
with shared.printLock: with shared.printLock:
print 'Listening for incoming connections.' print 'Listening for incoming connections.'

View File

@ -12,34 +12,31 @@ def knownNodes():
shared.knownNodes = pickle.load(pickleFile) shared.knownNodes = pickle.load(pickleFile)
pickleFile.close() pickleFile.close()
except: except:
defaultKnownNodes.createDefaultKnownNodes(shared.appdata) shared.knownNodes = defaultKnownNodes.createDefaultKnownNodes(shared.appdata)
pickleFile = open(shared.appdata + 'knownnodes.dat', 'rb')
shared.knownNodes = pickle.load(pickleFile)
pickleFile.close()
if shared.config.getint('bitmessagesettings', 'settingsversion') > 6: if shared.config.getint('bitmessagesettings', 'settingsversion') > 6:
print 'Bitmessage cannot read future versions of the keys file (keys.dat). Run the newer version of Bitmessage.' print 'Bitmessage cannot read future versions of the keys file (keys.dat). Run the newer version of Bitmessage.'
raise SystemExit raise SystemExit
def dns(): def dns():
# DNS bootstrap. This could be programmed to use the SOCKS proxy to do the # DNS bootstrap. This could be programmed to use the SOCKS proxy to do the
# DNS lookup some day but for now we will just rely on the entries in # DNS lookup some day but for now we will just rely on the entries in
# defaultKnownNodes.py. Hopefully either they are up to date or the user # defaultKnownNodes.py. Hopefully either they are up to date or the user
# has run Bitmessage recently without SOCKS turned on and received good # has run Bitmessage recently without SOCKS turned on and received good
# bootstrap nodes using that method. # bootstrap nodes using that method.
if shared.config.get('bitmessagesettings', 'socksproxytype') == 'none': with shared.printLock:
try: if shared.config.get('bitmessagesettings', 'socksproxytype') == 'none':
for item in socket.getaddrinfo('bootstrap8080.bitmessage.org', 80): try:
print 'Adding', item[4][0], 'to knownNodes based on DNS boostrap method' for item in socket.getaddrinfo('bootstrap8080.bitmessage.org', 80):
shared.knownNodes[1][item[4][0]] = (8080, int(time.time())) print 'Adding', item[4][0], 'to knownNodes based on DNS boostrap method'
except: shared.knownNodes[1][item[4][0]] = (8080, int(time.time()))
print 'bootstrap8080.bitmessage.org DNS bootstrapping failed.' except:
try: print 'bootstrap8080.bitmessage.org DNS bootstrapping failed.'
for item in socket.getaddrinfo('bootstrap8444.bitmessage.org', 80): try:
print 'Adding', item[4][0], 'to knownNodes based on DNS boostrap method' for item in socket.getaddrinfo('bootstrap8444.bitmessage.org', 80):
shared.knownNodes[1][item[4][0]] = (8444, int(time.time())) print 'Adding', item[4][0], 'to knownNodes based on DNS boostrap method'
except: shared.knownNodes[1][item[4][0]] = (8444, int(time.time()))
print 'bootstrap8444.bitmessage.org DNS bootstrapping failed.' except:
else: print 'bootstrap8444.bitmessage.org DNS bootstrapping failed.'
print 'DNS bootstrap skipped because SOCKS is used.' else:
print 'DNS bootstrap skipped because SOCKS is used.'