Added new deterministic address and subscription-related commands
This commit is contained in:
parent
eb9339052d
commit
a293cef8d1
2
Makefile
2
Makefile
|
@ -1,5 +1,5 @@
|
||||||
APP=pybitmessage
|
APP=pybitmessage
|
||||||
VERSION=0.3.0
|
VERSION=0.3.1
|
||||||
DEST_SHARE=/usr/share
|
DEST_SHARE=/usr/share
|
||||||
DEST_APP=$(DEST_SHARE)/$(APP)
|
DEST_APP=$(DEST_SHARE)/$(APP)
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
APP=pybitmessage
|
APP=pybitmessage
|
||||||
VERSION=0.3.0
|
VERSION=0.3.1
|
||||||
ARCH_TYPE=all
|
ARCH_TYPE=all
|
||||||
|
|
||||||
# Create a source archive
|
# Create a source archive
|
||||||
|
|
|
@ -25,7 +25,7 @@ print jsonAddresses
|
||||||
print 'Now that we have our address data in a nice Python data structure, let\'s look at the first address (index 0) and print its label:'
|
print 'Now that we have our address data in a nice Python data structure, let\'s look at the first address (index 0) and print its label:'
|
||||||
print jsonAddresses['addresses'][0]['label']
|
print jsonAddresses['addresses'][0]['label']
|
||||||
|
|
||||||
print 'Uncomment the next two lines to create a new random address with slightly a slightly higher difficulty setting than normal.'
|
print 'Uncomment the next two lines to create a new random address with a slightly higher difficulty setting than normal.'
|
||||||
#addressLabel = 'new address label'.encode('base64')
|
#addressLabel = 'new address label'.encode('base64')
|
||||||
#print api.createRandomAddress(addressLabel,False,1.05,1.1111)
|
#print api.createRandomAddress(addressLabel,False,1.05,1.1111)
|
||||||
|
|
||||||
|
@ -35,6 +35,15 @@ print 'Uncomment these next four lines to create new deterministic addresses.'
|
||||||
#print jsonDeterministicAddresses
|
#print jsonDeterministicAddresses
|
||||||
#print json.loads(jsonDeterministicAddresses)
|
#print json.loads(jsonDeterministicAddresses)
|
||||||
|
|
||||||
|
#print 'Uncomment this next line to print the first deterministic address that would be generated with the given passphrase. This will Not add it to the Bitmessage interface or the keys.dat file.'
|
||||||
|
#print api.getDeterministicAddress('asdfasdfqwser'.encode('base64'),3,1)
|
||||||
|
|
||||||
|
#print 'Uncomment this line to subscribe to an address. (You must use your own address, this one is invalid).'
|
||||||
|
#print api.addSubscription('2D94G5d8yp237GGqAheoecBYpdehdT3dha','test sub'.encode('base64'))
|
||||||
|
|
||||||
|
#print 'Uncomment this line to unsubscribe from an address.'
|
||||||
|
#print api.deleteSubscription('2D94G5d8yp237GGqAheoecBYpdehdT3dha')
|
||||||
|
|
||||||
print 'Let\'s now print all of our inbox messages:'
|
print 'Let\'s now print all of our inbox messages:'
|
||||||
print api.getAllInboxMessages()
|
print api.getAllInboxMessages()
|
||||||
inboxMessages = json.loads(api.getAllInboxMessages())
|
inboxMessages = json.loads(api.getAllInboxMessages())
|
||||||
|
|
|
@ -18,7 +18,6 @@ useVeryEasyProofOfWorkForTesting = False #If you set this to True while on the n
|
||||||
encryptedBroadcastSwitchoverTime = 1369735200
|
encryptedBroadcastSwitchoverTime = 1369735200
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
import ConfigParser
|
import ConfigParser
|
||||||
import Queue
|
import Queue
|
||||||
from addresses import *
|
from addresses import *
|
||||||
|
@ -3221,10 +3220,10 @@ class addressGenerator(threading.Thread):
|
||||||
queueValue = shared.addressGeneratorQueue.get()
|
queueValue = shared.addressGeneratorQueue.get()
|
||||||
nonceTrialsPerByte = 0
|
nonceTrialsPerByte = 0
|
||||||
payloadLengthExtraBytes = 0
|
payloadLengthExtraBytes = 0
|
||||||
if len(queueValue) == 6:
|
if len(queueValue) == 7:
|
||||||
addressVersionNumber,streamNumber,label,numberOfAddressesToMake,deterministicPassphrase,eighteenByteRipe = queueValue
|
command,addressVersionNumber,streamNumber,label,numberOfAddressesToMake,deterministicPassphrase,eighteenByteRipe = queueValue
|
||||||
elif len(queueValue) == 8:
|
elif len(queueValue) == 9:
|
||||||
addressVersionNumber,streamNumber,label,numberOfAddressesToMake,deterministicPassphrase,eighteenByteRipe,nonceTrialsPerByte,payloadLengthExtraBytes = queueValue
|
command,addressVersionNumber,streamNumber,label,numberOfAddressesToMake,deterministicPassphrase,eighteenByteRipe,nonceTrialsPerByte,payloadLengthExtraBytes = queueValue
|
||||||
else:
|
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' % queueValue)
|
sys.stderr.write('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:
|
if addressVersionNumber < 3 or addressVersionNumber > 3:
|
||||||
|
@ -3238,7 +3237,7 @@ class addressGenerator(threading.Thread):
|
||||||
if payloadLengthExtraBytes < shared.networkDefaultPayloadLengthExtraBytes:
|
if payloadLengthExtraBytes < shared.networkDefaultPayloadLengthExtraBytes:
|
||||||
payloadLengthExtraBytes = shared.networkDefaultPayloadLengthExtraBytes
|
payloadLengthExtraBytes = shared.networkDefaultPayloadLengthExtraBytes
|
||||||
if addressVersionNumber == 3: #currently the only one supported.
|
if addressVersionNumber == 3: #currently the only one supported.
|
||||||
if deterministicPassphrase == "":
|
if command == 'createRandomAddress':
|
||||||
shared.UISignalQueue.put(('updateStatusBar','Generating one new address'))
|
shared.UISignalQueue.put(('updateStatusBar','Generating one new address'))
|
||||||
#This next section is a little bit strange. We're going to generate keys over and over until we
|
#This next section is a little bit strange. We're going to generate keys over and over until we
|
||||||
#find one that starts with either \x00 or \x00\x00. Then when we pack them into a Bitmessage address,
|
#find one that starts with either \x00 or \x00\x00. Then when we pack them into a Bitmessage address,
|
||||||
|
@ -3301,10 +3300,12 @@ class addressGenerator(threading.Thread):
|
||||||
shared.reloadMyAddressHashes()
|
shared.reloadMyAddressHashes()
|
||||||
shared.workerQueue.put(('doPOWForMyV3Pubkey',ripe.digest()))
|
shared.workerQueue.put(('doPOWForMyV3Pubkey',ripe.digest()))
|
||||||
|
|
||||||
else: #There is something in the deterministicPassphrase variable thus we are going to do this deterministically.
|
elif command == 'createDeterministicAddresses' or command == 'getDeterministicAddress':
|
||||||
statusbar = 'Generating '+str(numberOfAddressesToMake) + ' new addresses.'
|
if len(deterministicPassphrase) == 0:
|
||||||
#self.emit(SIGNAL("updateStatusBar(PyQt_PyObject)"),statusbar)
|
sys.stderr.write('WARNING: You are creating deterministic address(es) using a blank passphrase. Bitmessage will do it but it is rather stupid.')
|
||||||
shared.UISignalQueue.put(('updateStatusBar',statusbar))
|
if command == 'createDeterministicAddresses':
|
||||||
|
statusbar = 'Generating '+str(numberOfAddressesToMake) + ' new addresses.'
|
||||||
|
shared.UISignalQueue.put(('updateStatusBar',statusbar))
|
||||||
signingKeyNonce = 0
|
signingKeyNonce = 0
|
||||||
encryptionKeyNonce = 1
|
encryptionKeyNonce = 1
|
||||||
listOfNewAddressesToSendOutThroughTheAPI = [] #We fill out this list no matter what although we only need it if we end up passing the info to the API.
|
listOfNewAddressesToSendOutThroughTheAPI = [] #We fill out this list no matter what although we only need it if we end up passing the info to the API.
|
||||||
|
@ -3340,44 +3341,49 @@ class addressGenerator(threading.Thread):
|
||||||
print 'ripe.digest', ripe.digest().encode('hex')
|
print 'ripe.digest', ripe.digest().encode('hex')
|
||||||
print 'Address generator calculated', numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix, 'addresses at', numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix/(time.time()-startTime),'keys per second.'
|
print 'Address generator calculated', numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix, 'addresses at', numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix/(time.time()-startTime),'keys per second.'
|
||||||
address = encodeAddress(3,streamNumber,ripe.digest())
|
address = encodeAddress(3,streamNumber,ripe.digest())
|
||||||
#self.emit(SIGNAL("updateStatusBar(PyQt_PyObject)"),'Finished generating address. Writing to keys.dat')
|
|
||||||
|
|
||||||
#An excellent way for us to store our keys is in Wallet Import Format. Let us convert now.
|
if command == 'createDeterministicAddresses':
|
||||||
#https://en.bitcoin.it/wiki/Wallet_import_format
|
#An excellent way for us to store our keys is in Wallet Import Format. Let us convert now.
|
||||||
privSigningKey = '\x80'+potentialPrivSigningKey
|
#https://en.bitcoin.it/wiki/Wallet_import_format
|
||||||
checksum = hashlib.sha256(hashlib.sha256(privSigningKey).digest()).digest()[0:4]
|
privSigningKey = '\x80'+potentialPrivSigningKey
|
||||||
privSigningKeyWIF = arithmetic.changebase(privSigningKey + checksum,256,58)
|
checksum = hashlib.sha256(hashlib.sha256(privSigningKey).digest()).digest()[0:4]
|
||||||
|
privSigningKeyWIF = arithmetic.changebase(privSigningKey + checksum,256,58)
|
||||||
|
|
||||||
privEncryptionKey = '\x80'+potentialPrivEncryptionKey
|
privEncryptionKey = '\x80'+potentialPrivEncryptionKey
|
||||||
checksum = hashlib.sha256(hashlib.sha256(privEncryptionKey).digest()).digest()[0:4]
|
checksum = hashlib.sha256(hashlib.sha256(privEncryptionKey).digest()).digest()[0:4]
|
||||||
privEncryptionKeyWIF = arithmetic.changebase(privEncryptionKey + checksum,256,58)
|
privEncryptionKeyWIF = arithmetic.changebase(privEncryptionKey + checksum,256,58)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
shared.config.add_section(address)
|
shared.config.add_section(address)
|
||||||
print 'label:', label
|
print 'label:', label
|
||||||
shared.config.set(address,'label',label)
|
shared.config.set(address,'label',label)
|
||||||
shared.config.set(address,'enabled','true')
|
shared.config.set(address,'enabled','true')
|
||||||
shared.config.set(address,'decoy','false')
|
shared.config.set(address,'decoy','false')
|
||||||
shared.config.set(address,'noncetrialsperbyte',str(nonceTrialsPerByte))
|
shared.config.set(address,'noncetrialsperbyte',str(nonceTrialsPerByte))
|
||||||
shared.config.set(address,'payloadlengthextrabytes',str(payloadLengthExtraBytes))
|
shared.config.set(address,'payloadlengthextrabytes',str(payloadLengthExtraBytes))
|
||||||
shared.config.set(address,'privSigningKey',privSigningKeyWIF)
|
shared.config.set(address,'privSigningKey',privSigningKeyWIF)
|
||||||
shared.config.set(address,'privEncryptionKey',privEncryptionKeyWIF)
|
shared.config.set(address,'privEncryptionKey',privEncryptionKeyWIF)
|
||||||
with open(shared.appdata + 'keys.dat', 'wb') as configfile:
|
with open(shared.appdata + 'keys.dat', 'wb') as configfile:
|
||||||
shared.config.write(configfile)
|
shared.config.write(configfile)
|
||||||
|
|
||||||
#self.emit(SIGNAL("writeNewAddressToTable(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"),self.label,address,str(self.streamNumber))
|
#self.emit(SIGNAL("writeNewAddressToTable(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"),self.label,address,str(self.streamNumber))
|
||||||
shared.UISignalQueue.put(('writeNewAddressToTable',(label,address,str(streamNumber))))
|
shared.UISignalQueue.put(('writeNewAddressToTable',(label,address,str(streamNumber))))
|
||||||
listOfNewAddressesToSendOutThroughTheAPI.append(address)
|
listOfNewAddressesToSendOutThroughTheAPI.append(address)
|
||||||
if eighteenByteRipe:
|
if eighteenByteRipe:
|
||||||
shared.reloadMyAddressHashes()#This is necessary here (rather than just at the end) because otherwise if the human generates a large number of new addresses and uses one before they are done generating, the program will receive a getpubkey message and will ignore it.
|
shared.reloadMyAddressHashes()#This is necessary here (rather than just at the end) because otherwise if the human generates a large number of new addresses and uses one before they are done generating, the program will receive a getpubkey message and will ignore it.
|
||||||
except:
|
except:
|
||||||
print address,'already exists. Not adding it again.'
|
print address,'already exists. Not adding it again.'
|
||||||
|
|
||||||
|
#Done generating addresses.
|
||||||
#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.
|
#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.
|
||||||
apiAddressGeneratorReturnQueue.put(listOfNewAddressesToSendOutThroughTheAPI)
|
if command == 'createDeterministicAddresses':
|
||||||
#self.emit(SIGNAL("updateStatusBar(PyQt_PyObject)"),'Done generating address')
|
apiAddressGeneratorReturnQueue.put(listOfNewAddressesToSendOutThroughTheAPI)
|
||||||
shared.UISignalQueue.put(('updateStatusBar','Done generating address'))
|
shared.UISignalQueue.put(('updateStatusBar','Done generating address'))
|
||||||
shared.reloadMyAddressHashes()
|
shared.reloadMyAddressHashes()
|
||||||
|
elif command == 'getDeterministicAddress':
|
||||||
|
apiAddressGeneratorReturnQueue.put(address)
|
||||||
|
else:
|
||||||
|
raise Exception("Error in the addressGenerator thread. Thread was given a command it could not understand: "+command)
|
||||||
|
|
||||||
#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).
|
||||||
|
@ -3512,7 +3518,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
||||||
label = label.decode('base64')
|
label = label.decode('base64')
|
||||||
apiAddressGeneratorReturnQueue.queue.clear()
|
apiAddressGeneratorReturnQueue.queue.clear()
|
||||||
streamNumberForAddress = 1
|
streamNumberForAddress = 1
|
||||||
shared.addressGeneratorQueue.put((3,streamNumberForAddress,label,1,"",eighteenByteRipe,nonceTrialsPerByte,payloadLengthExtraBytes))
|
shared.addressGeneratorQueue.put(('createRandomAddress',3,streamNumberForAddress,label,1,"",eighteenByteRipe,nonceTrialsPerByte,payloadLengthExtraBytes))
|
||||||
return apiAddressGeneratorReturnQueue.get()
|
return apiAddressGeneratorReturnQueue.get()
|
||||||
elif method == 'createDeterministicAddresses':
|
elif method == 'createDeterministicAddresses':
|
||||||
if len(params) == 0:
|
if len(params) == 0:
|
||||||
|
@ -3563,7 +3569,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
||||||
if addressVersionNumber == 0: #0 means "just use the proper addressVersionNumber"
|
if addressVersionNumber == 0: #0 means "just use the proper addressVersionNumber"
|
||||||
addressVersionNumber = 3
|
addressVersionNumber = 3
|
||||||
if addressVersionNumber != 3:
|
if addressVersionNumber != 3:
|
||||||
return 'API Error 0002: The address version number currently must be 3 (or 0 which means auto-select).', addressVersionNumber,' isn\'t supported.'
|
return 'API Error 0002: The address version number currently must be 3 (or 0 which means auto-select). '+ addressVersionNumber+' isn\'t supported.'
|
||||||
if streamNumber == 0: #0 means "just use the most available stream"
|
if streamNumber == 0: #0 means "just use the most available stream"
|
||||||
streamNumber = 1
|
streamNumber = 1
|
||||||
if streamNumber != 1:
|
if streamNumber != 1:
|
||||||
|
@ -3574,7 +3580,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
||||||
return 'API Error 0005: You have (accidentally?) specified too many addresses to make. Maximum 999. This check only exists to prevent mischief; if you really want to create more addresses than this, contact the Bitmessage developers and we can modify the check or you can do it yourself by searching the source code for this message.'
|
return 'API Error 0005: You have (accidentally?) specified too many addresses to make. Maximum 999. This check only exists to prevent mischief; if you really want to create more addresses than this, contact the Bitmessage developers and we can modify the check or you can do it yourself by searching the source code for this message.'
|
||||||
apiAddressGeneratorReturnQueue.queue.clear()
|
apiAddressGeneratorReturnQueue.queue.clear()
|
||||||
print 'Requesting that the addressGenerator create', numberOfAddresses, 'addresses.'
|
print 'Requesting that the addressGenerator create', numberOfAddresses, 'addresses.'
|
||||||
shared.addressGeneratorQueue.put((addressVersionNumber,streamNumber,'unused API address',numberOfAddresses,passphrase,eighteenByteRipe,nonceTrialsPerByte,payloadLengthExtraBytes))
|
shared.addressGeneratorQueue.put(('createDeterministicAddresses',addressVersionNumber,streamNumber,'unused API address',numberOfAddresses,passphrase,eighteenByteRipe,nonceTrialsPerByte,payloadLengthExtraBytes))
|
||||||
data = '{"addresses":['
|
data = '{"addresses":['
|
||||||
queueReturn = apiAddressGeneratorReturnQueue.get()
|
queueReturn = apiAddressGeneratorReturnQueue.get()
|
||||||
for item in queueReturn:
|
for item in queueReturn:
|
||||||
|
@ -3583,6 +3589,23 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
||||||
data += "\""+item+ "\""
|
data += "\""+item+ "\""
|
||||||
data += ']}'
|
data += ']}'
|
||||||
return data
|
return data
|
||||||
|
elif method == 'getDeterministicAddress':
|
||||||
|
if len(params) != 3:
|
||||||
|
return 'API Error 0000: I need exactly 3 parameters.'
|
||||||
|
passphrase, addressVersionNumber, streamNumber = params
|
||||||
|
numberOfAddresses = 1
|
||||||
|
eighteenByteRipe = False
|
||||||
|
if len(passphrase) == 0:
|
||||||
|
return 'API Error 0001: The specified passphrase is blank.'
|
||||||
|
passphrase = passphrase.decode('base64')
|
||||||
|
if addressVersionNumber != 3:
|
||||||
|
return 'API Error 0002: The address version number currently must be 3. '+ addressVersionNumber +' isn\'t supported.'
|
||||||
|
if streamNumber != 1:
|
||||||
|
return 'API Error 0003: The stream number must be 1. Others aren\'t supported.'
|
||||||
|
apiAddressGeneratorReturnQueue.queue.clear()
|
||||||
|
print 'Requesting that the addressGenerator create', numberOfAddresses, 'addresses.'
|
||||||
|
shared.addressGeneratorQueue.put(('getDeterministicAddress',addressVersionNumber,streamNumber,'unused API address',numberOfAddresses,passphrase,eighteenByteRipe))
|
||||||
|
return apiAddressGeneratorReturnQueue.get()
|
||||||
elif method == 'getAllInboxMessages':
|
elif method == 'getAllInboxMessages':
|
||||||
shared.sqlLock.acquire()
|
shared.sqlLock.acquire()
|
||||||
shared.sqlSubmitQueue.put('''SELECT msgid, toaddress, fromaddress, subject, received, message FROM inbox where folder='inbox' ORDER BY received''')
|
shared.sqlSubmitQueue.put('''SELECT msgid, toaddress, fromaddress, subject, received, message FROM inbox where folder='inbox' ORDER BY received''')
|
||||||
|
@ -3633,6 +3656,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
||||||
return 'API Error 0009: Invalid characters in address: '+ toAddress
|
return 'API Error 0009: Invalid characters in address: '+ toAddress
|
||||||
if status == 'versiontoohigh':
|
if status == 'versiontoohigh':
|
||||||
return 'API Error 0010: Address version number too high (or zero) in address: ' + toAddress
|
return 'API Error 0010: Address version number too high (or zero) in address: ' + toAddress
|
||||||
|
return 'API Error 0007: Could not decode address: ' + toAddress+ ' : '+ status
|
||||||
if addressVersionNumber < 2 or addressVersionNumber > 3:
|
if addressVersionNumber < 2 or addressVersionNumber > 3:
|
||||||
return 'API Error 0011: The address version number currently must be 2 or 3. Others aren\'t supported. Check the toAddress.'
|
return 'API Error 0011: The address version number currently must be 2 or 3. Others aren\'t supported. Check the toAddress.'
|
||||||
if streamNumber != 1:
|
if streamNumber != 1:
|
||||||
|
@ -3648,6 +3672,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
||||||
return 'API Error 0009: Invalid characters in address: '+ fromAddress
|
return 'API Error 0009: Invalid characters in address: '+ fromAddress
|
||||||
if status == 'versiontoohigh':
|
if status == 'versiontoohigh':
|
||||||
return 'API Error 0010: Address version number too high (or zero) in address: ' + fromAddress
|
return 'API Error 0010: Address version number too high (or zero) in address: ' + fromAddress
|
||||||
|
return 'API Error 0007: Could not decode address: ' + fromAddress+ ' : '+ status
|
||||||
if addressVersionNumber < 2 or addressVersionNumber > 3:
|
if addressVersionNumber < 2 or addressVersionNumber > 3:
|
||||||
return 'API Error 0011: The address version number currently must be 2 or 3. Others aren\'t supported. Check the fromAddress.'
|
return 'API Error 0011: The address version number currently must be 2 or 3. Others aren\'t supported. Check the fromAddress.'
|
||||||
if streamNumber != 1:
|
if streamNumber != 1:
|
||||||
|
@ -3711,6 +3736,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
||||||
return 'API Error 0009: Invalid characters in address: '+ fromAddress
|
return 'API Error 0009: Invalid characters in address: '+ fromAddress
|
||||||
if status == 'versiontoohigh':
|
if status == 'versiontoohigh':
|
||||||
return 'API Error 0010: Address version number too high (or zero) in address: ' + fromAddress
|
return 'API Error 0010: Address version number too high (or zero) in address: ' + fromAddress
|
||||||
|
return 'API Error 0007: Could not decode address: ' + fromAddress+ ' : '+ status
|
||||||
if addressVersionNumber < 2 or addressVersionNumber > 3:
|
if addressVersionNumber < 2 or addressVersionNumber > 3:
|
||||||
return 'API Error 0011: the address version number currently must be 2 or 3. Others aren\'t supported. Check the fromAddress.'
|
return 'API Error 0011: the address version number currently must be 2 or 3. Others aren\'t supported. Check the fromAddress.'
|
||||||
if streamNumber != 1:
|
if streamNumber != 1:
|
||||||
|
@ -3764,6 +3790,71 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
||||||
return 'ackReceived'
|
return 'ackReceived'
|
||||||
else:
|
else:
|
||||||
return 'otherStatus: '+status
|
return 'otherStatus: '+status
|
||||||
|
elif method == 'addSubscription':
|
||||||
|
if len(params) == 0:
|
||||||
|
return 'API Error 0000: I need parameters!'
|
||||||
|
if len(params) == 1:
|
||||||
|
address, = params
|
||||||
|
label == ''
|
||||||
|
if len(params) == 2:
|
||||||
|
address, label = params
|
||||||
|
label = label.decode('base64')
|
||||||
|
if len(params) >2:
|
||||||
|
return 'API Error 0000: I need either 1 or 2 parameters!'
|
||||||
|
address = addBMIfNotPresent(address)
|
||||||
|
status,addressVersionNumber,streamNumber,toRipe = decodeAddress(address)
|
||||||
|
if status <> 'success':
|
||||||
|
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':
|
||||||
|
return 'API Error 0009: Invalid characters in address: '+ address
|
||||||
|
if status == 'versiontoohigh':
|
||||||
|
return 'API Error 0010: Address version number too high (or zero) in address: ' + address
|
||||||
|
return 'API Error 0007: Could not decode address: ' + address+ ' : '+ status
|
||||||
|
if addressVersionNumber < 2 or addressVersionNumber > 3:
|
||||||
|
return 'API Error 0011: The address version number currently must be 2 or 3. Others aren\'t supported.'
|
||||||
|
if streamNumber != 1:
|
||||||
|
return 'API Error 0012: The stream number must be 1. Others aren\'t supported.'
|
||||||
|
#First we must check to see if the address is already in the subscriptions list.
|
||||||
|
shared.sqlLock.acquire()
|
||||||
|
t = (address,)
|
||||||
|
shared.sqlSubmitQueue.put('''select * from subscriptions where address=?''')
|
||||||
|
shared.sqlSubmitQueue.put(t)
|
||||||
|
queryreturn = shared.sqlReturnQueue.get()
|
||||||
|
shared.sqlLock.release()
|
||||||
|
if queryreturn != []:
|
||||||
|
return 'API Error 0016: You are already subscribed to that address.'
|
||||||
|
t = (label,address,True)
|
||||||
|
shared.sqlLock.acquire()
|
||||||
|
shared.sqlSubmitQueue.put('''INSERT INTO subscriptions VALUES (?,?,?)''')
|
||||||
|
shared.sqlSubmitQueue.put(t)
|
||||||
|
queryreturn = shared.sqlReturnQueue.get()
|
||||||
|
shared.sqlSubmitQueue.put('commit')
|
||||||
|
shared.sqlLock.release()
|
||||||
|
shared.reloadBroadcastSendersForWhichImWatching()
|
||||||
|
shared.UISignalQueue.put(('rerenderInboxFromLabels',''))
|
||||||
|
shared.UISignalQueue.put(('rerenderSubscriptions',''))
|
||||||
|
return 'Added subscription.'
|
||||||
|
|
||||||
|
elif method == 'deleteSubscription':
|
||||||
|
if len(params) != 1:
|
||||||
|
return 'API Error 0000: I need 1 parameter!'
|
||||||
|
address, = params
|
||||||
|
address = addBMIfNotPresent(address)
|
||||||
|
t = (address,)
|
||||||
|
shared.sqlLock.acquire()
|
||||||
|
shared.sqlSubmitQueue.put('''DELETE FROM subscriptions WHERE address=?''')
|
||||||
|
shared.sqlSubmitQueue.put(t)
|
||||||
|
shared.sqlReturnQueue.get()
|
||||||
|
shared.sqlSubmitQueue.put('commit')
|
||||||
|
shared.sqlLock.release()
|
||||||
|
shared.reloadBroadcastSendersForWhichImWatching()
|
||||||
|
shared.UISignalQueue.put(('rerenderInboxFromLabels',''))
|
||||||
|
shared.UISignalQueue.put(('rerenderSubscriptions',''))
|
||||||
|
return 'Deleted subscription if it existed.'
|
||||||
else:
|
else:
|
||||||
return 'Invalid Method: %s'%method
|
return 'Invalid Method: %s'%method
|
||||||
|
|
||||||
|
@ -3777,37 +3868,6 @@ class singleAPI(threading.Thread):
|
||||||
se.register_introspection_functions()
|
se.register_introspection_functions()
|
||||||
se.serve_forever()
|
se.serve_forever()
|
||||||
|
|
||||||
|
|
||||||
#The MySimpleXMLRPCRequestHandler class cannot emit signals (or at least I don't know how) because it is not a QT thread. It therefore puts data in a queue which this thread monitors and emits the signals on its behalf.
|
|
||||||
"""class singleAPISignalHandler(QThread):
|
|
||||||
def __init__(self, parent = None):
|
|
||||||
QThread.__init__(self, parent)
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
while True:
|
|
||||||
command, data = apiSignalQueue.get()
|
|
||||||
if command == 'updateStatusBar':
|
|
||||||
self.emit(SIGNAL("updateStatusBar(PyQt_PyObject)"),data)
|
|
||||||
elif command == 'createRandomAddress':
|
|
||||||
label, eighteenByteRipe = data
|
|
||||||
streamNumberForAddress = 1
|
|
||||||
#self.addressGenerator = addressGenerator()
|
|
||||||
#self.addressGenerator.setup(3,streamNumberForAddress,label,1,"",eighteenByteRipe)
|
|
||||||
#self.emit(SIGNAL("passAddressGeneratorObjectThrough(PyQt_PyObject)"),self.addressGenerator)
|
|
||||||
#self.addressGenerator.start()
|
|
||||||
shared.addressGeneratorQueue.put((3,streamNumberForAddress,label,1,"",eighteenByteRipe))
|
|
||||||
elif command == 'createDeterministicAddresses':
|
|
||||||
passphrase, numberOfAddresses, addressVersionNumber, streamNumber, eighteenByteRipe = data
|
|
||||||
#self.addressGenerator = addressGenerator()
|
|
||||||
#self.addressGenerator.setup(addressVersionNumber,streamNumber,'unused API address',numberOfAddresses,passphrase,eighteenByteRipe)
|
|
||||||
#self.emit(SIGNAL("passAddressGeneratorObjectThrough(PyQt_PyObject)"),self.addressGenerator)
|
|
||||||
#self.addressGenerator.start()
|
|
||||||
shared.addressGeneratorQueue.put((addressVersionNumber,streamNumber,'unused API address',numberOfAddresses,passphrase,eighteenByteRipe))
|
|
||||||
elif command == 'displayNewSentMessage':
|
|
||||||
toAddress,toLabel,fromAddress,subject,message,ackdata = data
|
|
||||||
self.emit(SIGNAL("displayNewSentMessage(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"),toAddress,toLabel,fromAddress,subject,message,ackdata)"""
|
|
||||||
|
|
||||||
|
|
||||||
selfInitiatedConnections = {} #This is a list of current connections (the thread pointers at least)
|
selfInitiatedConnections = {} #This is a list of current connections (the thread pointers at least)
|
||||||
alreadyAttemptedConnectionsList = {} #This is a list of nodes to which we have already attempted a connection
|
alreadyAttemptedConnectionsList = {} #This is a list of nodes to which we have already attempted a connection
|
||||||
ackdataForWhichImWatching = {}
|
ackdataForWhichImWatching = {}
|
||||||
|
|
|
@ -393,23 +393,7 @@ class MyForm(QtGui.QMainWindow):
|
||||||
self.ui.tableWidgetAddressBook.setItem(0,1,newItem)
|
self.ui.tableWidgetAddressBook.setItem(0,1,newItem)
|
||||||
|
|
||||||
#Initialize the Subscriptions
|
#Initialize the Subscriptions
|
||||||
shared.sqlLock.acquire()
|
self.rerenderSubscriptions()
|
||||||
shared.sqlSubmitQueue.put('SELECT label, address, enabled FROM subscriptions')
|
|
||||||
shared.sqlSubmitQueue.put('')
|
|
||||||
queryreturn = shared.sqlReturnQueue.get()
|
|
||||||
shared.sqlLock.release()
|
|
||||||
for row in queryreturn:
|
|
||||||
label, address, enabled = row
|
|
||||||
self.ui.tableWidgetSubscriptions.insertRow(0)
|
|
||||||
newItem = QtGui.QTableWidgetItem(unicode(label,'utf-8'))
|
|
||||||
if not enabled:
|
|
||||||
newItem.setTextColor(QtGui.QColor(128,128,128))
|
|
||||||
self.ui.tableWidgetSubscriptions.setItem(0,0,newItem)
|
|
||||||
newItem = QtGui.QTableWidgetItem(address)
|
|
||||||
newItem.setFlags( QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled )
|
|
||||||
if not enabled:
|
|
||||||
newItem.setTextColor(QtGui.QColor(128,128,128))
|
|
||||||
self.ui.tableWidgetSubscriptions.setItem(0,1,newItem)
|
|
||||||
|
|
||||||
#Initialize the Blacklist or Whitelist
|
#Initialize the Blacklist or Whitelist
|
||||||
if shared.config.get('bitmessagesettings', 'blackwhitelist') == 'black':
|
if shared.config.get('bitmessagesettings', 'blackwhitelist') == 'black':
|
||||||
|
@ -447,6 +431,8 @@ class MyForm(QtGui.QMainWindow):
|
||||||
QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL("incrementNumberOfPubkeysProcessed()"), self.incrementNumberOfPubkeysProcessed)
|
QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL("incrementNumberOfPubkeysProcessed()"), self.incrementNumberOfPubkeysProcessed)
|
||||||
QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL("incrementNumberOfBroadcastsProcessed()"), self.incrementNumberOfBroadcastsProcessed)
|
QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL("incrementNumberOfBroadcastsProcessed()"), self.incrementNumberOfBroadcastsProcessed)
|
||||||
QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL("setStatusIcon(PyQt_PyObject)"), self.setStatusIcon)
|
QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL("setStatusIcon(PyQt_PyObject)"), self.setStatusIcon)
|
||||||
|
QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL("rerenderInboxFromLabels()"), self.rerenderInboxFromLabels)
|
||||||
|
QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL("rerenderSubscriptions()"), self.rerenderSubscriptions)
|
||||||
self.UISignalThread.start()
|
self.UISignalThread.start()
|
||||||
|
|
||||||
#Below this point, it would be good if all of the necessary global data structures were initialized.
|
#Below this point, it would be good if all of the necessary global data structures were initialized.
|
||||||
|
@ -795,7 +781,7 @@ class MyForm(QtGui.QMainWindow):
|
||||||
#QtCore.QObject.connect(self.addressGenerator, SIGNAL("writeNewAddressToTable(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"), self.writeNewAddressToTable)
|
#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)
|
#QtCore.QObject.connect(self.addressGenerator, QtCore.SIGNAL("updateStatusBar(PyQt_PyObject)"), self.updateStatusBar)
|
||||||
#self.addressGenerator.start()
|
#self.addressGenerator.start()
|
||||||
shared.addressGeneratorQueue.put((addressVersionNumber,streamNumberForAddress,"regenerated deterministic address",self.regenerateAddressesDialogInstance.ui.spinBoxNumberOfAddressesToMake.value(),self.regenerateAddressesDialogInstance.ui.lineEditPassphrase.text().toUtf8(),self.regenerateAddressesDialogInstance.ui.checkBoxEighteenByteRipe.isChecked()))
|
shared.addressGeneratorQueue.put(('createDeterministicAddresses',addressVersionNumber,streamNumberForAddress,"regenerated deterministic address",self.regenerateAddressesDialogInstance.ui.spinBoxNumberOfAddressesToMake.value(),self.regenerateAddressesDialogInstance.ui.lineEditPassphrase.text().toUtf8(),self.regenerateAddressesDialogInstance.ui.checkBoxEighteenByteRipe.isChecked()))
|
||||||
self.ui.tabWidget.setCurrentIndex(3)
|
self.ui.tabWidget.setCurrentIndex(3)
|
||||||
|
|
||||||
def openKeysFile(self):
|
def openKeysFile(self):
|
||||||
|
@ -1031,6 +1017,26 @@ class MyForm(QtGui.QMainWindow):
|
||||||
toLabel, = row
|
toLabel, = row
|
||||||
self.ui.tableWidgetSent.item(i,0).setText(unicode(toLabel,'utf-8'))
|
self.ui.tableWidgetSent.item(i,0).setText(unicode(toLabel,'utf-8'))
|
||||||
|
|
||||||
|
def rerenderSubscriptions(self):
|
||||||
|
self.ui.tableWidgetSubscriptions.setRowCount(0)
|
||||||
|
shared.sqlLock.acquire()
|
||||||
|
shared.sqlSubmitQueue.put('SELECT label, address, enabled FROM subscriptions')
|
||||||
|
shared.sqlSubmitQueue.put('')
|
||||||
|
queryreturn = shared.sqlReturnQueue.get()
|
||||||
|
shared.sqlLock.release()
|
||||||
|
for row in queryreturn:
|
||||||
|
label, address, enabled = row
|
||||||
|
self.ui.tableWidgetSubscriptions.insertRow(0)
|
||||||
|
newItem = QtGui.QTableWidgetItem(unicode(label,'utf-8'))
|
||||||
|
if not enabled:
|
||||||
|
newItem.setTextColor(QtGui.QColor(128,128,128))
|
||||||
|
self.ui.tableWidgetSubscriptions.setItem(0,0,newItem)
|
||||||
|
newItem = QtGui.QTableWidgetItem(address)
|
||||||
|
newItem.setFlags( QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled )
|
||||||
|
if not enabled:
|
||||||
|
newItem.setTextColor(QtGui.QColor(128,128,128))
|
||||||
|
self.ui.tableWidgetSubscriptions.setItem(0,1,newItem)
|
||||||
|
|
||||||
def click_pushButtonSend(self):
|
def click_pushButtonSend(self):
|
||||||
self.statusBar().showMessage('')
|
self.statusBar().showMessage('')
|
||||||
toAddresses = str(self.ui.lineEditTo.text())
|
toAddresses = str(self.ui.lineEditTo.text())
|
||||||
|
@ -1358,7 +1364,7 @@ class MyForm(QtGui.QMainWindow):
|
||||||
|
|
||||||
if self.NewSubscriptionDialogInstance.exec_():
|
if self.NewSubscriptionDialogInstance.exec_():
|
||||||
if self.NewSubscriptionDialogInstance.ui.labelSubscriptionAddressCheck.text() == 'Address is valid.':
|
if self.NewSubscriptionDialogInstance.ui.labelSubscriptionAddressCheck.text() == 'Address is valid.':
|
||||||
#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.
|
#First we must check to see if the address is already in the subscriptions list. The user cannot add it again or else it will cause problems when updating and deleting the entry.
|
||||||
shared.sqlLock.acquire()
|
shared.sqlLock.acquire()
|
||||||
t = (addBMIfNotPresent(str(self.NewSubscriptionDialogInstance.ui.lineEditSubscriptionAddress.text())),)
|
t = (addBMIfNotPresent(str(self.NewSubscriptionDialogInstance.ui.lineEditSubscriptionAddress.text())),)
|
||||||
shared.sqlSubmitQueue.put('''select * from subscriptions where address=?''')
|
shared.sqlSubmitQueue.put('''select * from subscriptions where address=?''')
|
||||||
|
@ -1605,7 +1611,7 @@ class MyForm(QtGui.QMainWindow):
|
||||||
#QtCore.QObject.connect(self.addressGenerator, SIGNAL("writeNewAddressToTable(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"), self.writeNewAddressToTable)
|
#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)
|
#QtCore.QObject.connect(self.addressGenerator, QtCore.SIGNAL("updateStatusBar(PyQt_PyObject)"), self.updateStatusBar)
|
||||||
#self.addressGenerator.start()
|
#self.addressGenerator.start()
|
||||||
shared.addressGeneratorQueue.put((3,streamNumberForAddress,str(self.dialog.ui.newaddresslabel.text().toUtf8()),1,"",self.dialog.ui.checkBoxEighteenByteRipe.isChecked()))
|
shared.addressGeneratorQueue.put(('createRandomAddress',3,streamNumberForAddress,str(self.dialog.ui.newaddresslabel.text().toUtf8()),1,"",self.dialog.ui.checkBoxEighteenByteRipe.isChecked()))
|
||||||
else:
|
else:
|
||||||
if self.dialog.ui.lineEditPassphrase.text() != self.dialog.ui.lineEditPassphraseAgain.text():
|
if self.dialog.ui.lineEditPassphrase.text() != self.dialog.ui.lineEditPassphraseAgain.text():
|
||||||
QMessageBox.about(self, "Passphrase mismatch", "The passphrase you entered twice doesn\'t match. Try again.")
|
QMessageBox.about(self, "Passphrase mismatch", "The passphrase you entered twice doesn\'t match. Try again.")
|
||||||
|
@ -1618,7 +1624,7 @@ class MyForm(QtGui.QMainWindow):
|
||||||
#QtCore.QObject.connect(self.addressGenerator, SIGNAL("writeNewAddressToTable(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"), self.writeNewAddressToTable)
|
#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)
|
#QtCore.QObject.connect(self.addressGenerator, QtCore.SIGNAL("updateStatusBar(PyQt_PyObject)"), self.updateStatusBar)
|
||||||
#self.addressGenerator.start()
|
#self.addressGenerator.start()
|
||||||
shared.addressGeneratorQueue.put((3,streamNumberForAddress,"unused deterministic address",self.dialog.ui.spinBoxNumberOfAddressesToMake.value(),self.dialog.ui.lineEditPassphrase.text().toUtf8(),self.dialog.ui.checkBoxEighteenByteRipe.isChecked()))
|
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:
|
else:
|
||||||
print 'new address dialog box rejected'
|
print 'new address dialog box rejected'
|
||||||
|
|
||||||
|
@ -2287,6 +2293,10 @@ class UISignaler(QThread):
|
||||||
self.emit(SIGNAL("incrementNumberOfBroadcastsProcessed()"))
|
self.emit(SIGNAL("incrementNumberOfBroadcastsProcessed()"))
|
||||||
elif command == 'setStatusIcon':
|
elif command == 'setStatusIcon':
|
||||||
self.emit(SIGNAL("setStatusIcon(PyQt_PyObject)"),data)
|
self.emit(SIGNAL("setStatusIcon(PyQt_PyObject)"),data)
|
||||||
|
elif command == 'rerenderInboxFromLabels':
|
||||||
|
self.emit(SIGNAL("rerenderInboxFromLabels()"))
|
||||||
|
elif command == 'rerenderSubscriptions':
|
||||||
|
self.emit(SIGNAL("rerenderSubscriptions()"))
|
||||||
else:
|
else:
|
||||||
sys.stderr.write('Command sent to UISignaler not recognized: %s\n' % command)
|
sys.stderr.write('Command sent to UISignaler not recognized: %s\n' % command)
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
softwareVersion = '0.3.0'
|
softwareVersion = '0.3.1'
|
||||||
|
|
||||||
import threading
|
import threading
|
||||||
import sys
|
import sys
|
||||||
|
|
Reference in New Issue
Block a user