Merge branch 'master' of github.com:Atheros1/PyBitmessage

This commit is contained in:
Jonathan Warren 2013-06-10 23:43:11 -04:00
commit 999e6e6ccd
5 changed files with 399 additions and 187 deletions

View File

@ -60,8 +60,9 @@ class outgoingSynSender(threading.Thread):
time.sleep(1) time.sleep(1)
global alreadyAttemptedConnectionsListResetTime global alreadyAttemptedConnectionsListResetTime
while True: while True:
#time.sleep(999999)#I sometimes use this to prevent connections for testing. if len(selfInitiatedConnections[self.streamNumber]) >= 8: #maximum number of outgoing connections = 8
if len(selfInitiatedConnections[self.streamNumber]) < 8: #maximum number of outgoing connections = 8 time.sleep(10)
else:
random.seed() random.seed()
HOST, = random.sample(shared.knownNodes[self.streamNumber], 1) HOST, = random.sample(shared.knownNodes[self.streamNumber], 1)
alreadyAttemptedConnectionsListLock.acquire() alreadyAttemptedConnectionsListLock.acquire()
@ -123,7 +124,6 @@ class outgoingSynSender(threading.Thread):
sock.connect((HOST, PORT)) sock.connect((HOST, PORT))
rd = receiveDataThread() rd = receiveDataThread()
rd.daemon = True # close the main program even if there are threads left rd.daemon = True # close the main program even if there are threads left
#self.emit(SIGNAL("passObjectThrough(PyQt_PyObject)"),rd)
objectsOfWhichThisRemoteNodeIsAlreadyAware = {} objectsOfWhichThisRemoteNodeIsAlreadyAware = {}
rd.setup(sock,HOST,PORT,self.streamNumber,objectsOfWhichThisRemoteNodeIsAlreadyAware) rd.setup(sock,HOST,PORT,self.streamNumber,objectsOfWhichThisRemoteNodeIsAlreadyAware)
rd.start() rd.start()
@ -150,19 +150,15 @@ class outgoingSynSender(threading.Thread):
print 'deleting ', HOST, 'from shared.knownNodes because it is more than 48 hours old and we could not connect to it.' print 'deleting ', HOST, 'from shared.knownNodes because it is more than 48 hours old and we could not connect to it.'
shared.printLock.release() shared.printLock.release()
except socks.Socks5AuthError, err: except socks.Socks5AuthError, err:
#self.emit(SIGNAL("updateStatusBar(PyQt_PyObject)"),"SOCKS5 Authentication problem: "+str(err))
shared.UISignalQueue.put(('updateStatusBar',"SOCKS5 Authentication problem: "+str(err))) shared.UISignalQueue.put(('updateStatusBar',"SOCKS5 Authentication problem: "+str(err)))
except socks.Socks5Error, err: except socks.Socks5Error, err:
pass pass
print 'SOCKS5 error. (It is possible that the server wants authentication).)' ,str(err) print 'SOCKS5 error. (It is possible that the server wants authentication).)' ,str(err)
#self.emit(SIGNAL("updateStatusBar(PyQt_PyObject)"),"SOCKS5 error. Server might require authentication. "+str(err))
except socks.Socks4Error, err: except socks.Socks4Error, err:
print 'Socks4Error:', err print 'Socks4Error:', err
#self.emit(SIGNAL("updateStatusBar(PyQt_PyObject)"),"SOCKS4 error: "+str(err))
except socket.error, err: except socket.error, err:
if shared.config.get('bitmessagesettings', 'socksproxytype')[0:5] == 'SOCKS': if shared.config.get('bitmessagesettings', 'socksproxytype')[0:5] == 'SOCKS':
print 'Bitmessage MIGHT be having trouble connecting to the SOCKS server. '+str(err) print 'Bitmessage MIGHT be having trouble connecting to the SOCKS server. '+str(err)
#self.emit(SIGNAL("updateStatusBar(PyQt_PyObject)"),"Problem: Bitmessage can not connect to the SOCKS server. "+str(err))
else: else:
if verbose >= 1: if verbose >= 1:
shared.printLock.acquire() shared.printLock.acquire()
@ -178,7 +174,7 @@ class outgoingSynSender(threading.Thread):
shared.printLock.release() shared.printLock.release()
except Exception, err: except Exception, err:
sys.stderr.write('An exception has occurred in the outgoingSynSender thread that was not caught by other exception types: %s\n' % err) sys.stderr.write('An exception has occurred in the outgoingSynSender thread that was not caught by other exception types: %s\n' % err)
time.sleep(0.1) time.sleep(0.1)
#Only one singleListener thread will ever exist. It creates the receiveDataThread and sendDataThread for each incoming connection. Note that it cannot set the stream number because it is not known yet- the other node will have to tell us its stream number in a version message. If we don't care about their stream, we will close the connection (within the recversion function of the recieveData thread) #Only one singleListener thread will ever exist. It creates the receiveDataThread and sendDataThread for each incoming connection. Note that it cannot set the stream number because it is not known yet- the other node will have to tell us its stream number in a version message. If we don't care about their stream, we will close the connection (within the recversion function of the recieveData thread)
class singleListener(threading.Thread): class singleListener(threading.Thread):
@ -449,7 +445,6 @@ class receiveDataThread(threading.Thread):
def connectionFullyEstablished(self): def connectionFullyEstablished(self):
self.connectionIsOrWasFullyEstablished = True self.connectionIsOrWasFullyEstablished = True
if not self.initiatedConnection: if not self.initiatedConnection:
#self.emit(SIGNAL("setStatusIcon(PyQt_PyObject)"),'green')
shared.UISignalQueue.put(('setStatusIcon','green')) shared.UISignalQueue.put(('setStatusIcon','green'))
self.sock.settimeout(600) #We'll send out a pong every 5 minutes to make sure the connection stays alive if there has been no other traffic to send lately. self.sock.settimeout(600) #We'll send out a pong every 5 minutes to make sure the connection stays alive if there has been no other traffic to send lately.
shared.UISignalQueue.put(('updateNetworkStatusTab','no data')) shared.UISignalQueue.put(('updateNetworkStatusTab','no data'))
@ -569,7 +564,6 @@ class receiveDataThread(threading.Thread):
shared.inventory[self.inventoryHash] = (objectType, self.streamNumber, data, embeddedTime) shared.inventory[self.inventoryHash] = (objectType, self.streamNumber, data, embeddedTime)
shared.inventoryLock.release() shared.inventoryLock.release()
self.broadcastinv(self.inventoryHash) self.broadcastinv(self.inventoryHash)
#self.emit(SIGNAL("incrementNumberOfBroadcastsProcessed()"))
shared.UISignalQueue.put(('incrementNumberOfBroadcastsProcessed','no data')) shared.UISignalQueue.put(('incrementNumberOfBroadcastsProcessed','no data'))
@ -701,7 +695,6 @@ class receiveDataThread(threading.Thread):
shared.sqlReturnQueue.get() shared.sqlReturnQueue.get()
shared.sqlSubmitQueue.put('commit') shared.sqlSubmitQueue.put('commit')
shared.sqlLock.release() shared.sqlLock.release()
#self.emit(SIGNAL("displayNewInboxMessage(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"),self.inventoryHash,toAddress,fromAddress,subject,body)
shared.UISignalQueue.put(('displayNewInboxMessage',(self.inventoryHash,toAddress,fromAddress,subject,body))) shared.UISignalQueue.put(('displayNewInboxMessage',(self.inventoryHash,toAddress,fromAddress,subject,body)))
#If we are behaving as an API then we might need to run an outside command to let some program know that a new message has arrived. #If we are behaving as an API then we might need to run an outside command to let some program know that a new message has arrived.
@ -836,7 +829,6 @@ class receiveDataThread(threading.Thread):
shared.sqlReturnQueue.get() shared.sqlReturnQueue.get()
shared.sqlSubmitQueue.put('commit') shared.sqlSubmitQueue.put('commit')
shared.sqlLock.release() shared.sqlLock.release()
#self.emit(SIGNAL("displayNewInboxMessage(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"),self.inventoryHash,toAddress,fromAddress,subject,body)
shared.UISignalQueue.put(('displayNewInboxMessage',(self.inventoryHash,toAddress,fromAddress,subject,body))) shared.UISignalQueue.put(('displayNewInboxMessage',(self.inventoryHash,toAddress,fromAddress,subject,body)))
#If we are behaving as an API then we might need to run an outside command to let some program know that a new message has arrived. #If we are behaving as an API then we might need to run an outside command to let some program know that a new message has arrived.
@ -898,7 +890,6 @@ class receiveDataThread(threading.Thread):
shared.inventory[self.inventoryHash] = (objectType, self.streamNumber, data, embeddedTime) shared.inventory[self.inventoryHash] = (objectType, self.streamNumber, data, embeddedTime)
shared.inventoryLock.release() shared.inventoryLock.release()
self.broadcastinv(self.inventoryHash) self.broadcastinv(self.inventoryHash)
#self.emit(SIGNAL("incrementNumberOfMessagesProcessed()"))
shared.UISignalQueue.put(('incrementNumberOfMessagesProcessed','no data')) shared.UISignalQueue.put(('incrementNumberOfMessagesProcessed','no data'))
@ -1119,7 +1110,6 @@ class receiveDataThread(threading.Thread):
shared.sqlReturnQueue.get() shared.sqlReturnQueue.get()
shared.sqlSubmitQueue.put('commit') shared.sqlSubmitQueue.put('commit')
shared.sqlLock.release() shared.sqlLock.release()
#self.emit(SIGNAL("displayNewInboxMessage(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"),self.inventoryHash,toAddress,fromAddress,subject,body)
shared.UISignalQueue.put(('displayNewInboxMessage',(self.inventoryHash,toAddress,fromAddress,subject,body))) shared.UISignalQueue.put(('displayNewInboxMessage',(self.inventoryHash,toAddress,fromAddress,subject,body)))
#If we are behaving as an API then we might need to run an outside command to let some program know that a new message has arrived. #If we are behaving as an API then we might need to run an outside command to let some program know that a new message has arrived.
@ -1153,7 +1143,6 @@ class receiveDataThread(threading.Thread):
shared.sqlSubmitQueue.put('commit') shared.sqlSubmitQueue.put('commit')
shared.sqlLock.release() shared.sqlLock.release()
#self.emit(SIGNAL("displayNewSentMessage(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"),toAddress,'[Broadcast subscribers]',fromAddress,subject,message,ackdata)
shared.UISignalQueue.put(('displayNewSentMessage',(toAddress,'[Broadcast subscribers]',fromAddress,subject,message,ackdata))) shared.UISignalQueue.put(('displayNewSentMessage',(toAddress,'[Broadcast subscribers]',fromAddress,subject,message,ackdata)))
shared.workerQueue.put(('sendbroadcast','')) shared.workerQueue.put(('sendbroadcast',''))
@ -1264,7 +1253,6 @@ class receiveDataThread(threading.Thread):
shared.inventory[inventoryHash] = (objectType, self.streamNumber, data, embeddedTime) shared.inventory[inventoryHash] = (objectType, self.streamNumber, data, embeddedTime)
shared.inventoryLock.release() shared.inventoryLock.release()
self.broadcastinv(inventoryHash) self.broadcastinv(inventoryHash)
#self.emit(SIGNAL("incrementNumberOfPubkeysProcessed()"))
shared.UISignalQueue.put(('incrementNumberOfPubkeysProcessed','no data')) shared.UISignalQueue.put(('incrementNumberOfPubkeysProcessed','no data'))
self.processpubkey(data) self.processpubkey(data)
@ -1897,10 +1885,7 @@ class receiveDataThread(threading.Thread):
PORT, timeLastReceivedMessageFromThisNode = value PORT, timeLastReceivedMessageFromThisNode = value
if timeLastReceivedMessageFromThisNode > (int(time.time())- maximumAgeOfNodesThatIAdvertiseToOthers): #If it is younger than 3 hours old.. if timeLastReceivedMessageFromThisNode > (int(time.time())- maximumAgeOfNodesThatIAdvertiseToOthers): #If it is younger than 3 hours old..
numberOfAddressesInAddrMessage += 1 numberOfAddressesInAddrMessage += 1
if self.remoteProtocolVersion == 1: payload += pack('>Q',timeLastReceivedMessageFromThisNode) #64-bit time
payload += pack('>I',timeLastReceivedMessageFromThisNode) #32-bit time
else:
payload += pack('>Q',timeLastReceivedMessageFromThisNode) #64-bit time
payload += pack('>I',self.streamNumber) payload += pack('>I',self.streamNumber)
payload += pack('>q',1) #service bit flags offered by this node payload += pack('>q',1) #service bit flags offered by this node
payload += '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF' + socket.inet_aton(HOST) payload += '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF' + socket.inet_aton(HOST)
@ -1909,10 +1894,7 @@ class receiveDataThread(threading.Thread):
PORT, timeLastReceivedMessageFromThisNode = value PORT, timeLastReceivedMessageFromThisNode = value
if timeLastReceivedMessageFromThisNode > (int(time.time())- maximumAgeOfNodesThatIAdvertiseToOthers): #If it is younger than 3 hours old.. if timeLastReceivedMessageFromThisNode > (int(time.time())- maximumAgeOfNodesThatIAdvertiseToOthers): #If it is younger than 3 hours old..
numberOfAddressesInAddrMessage += 1 numberOfAddressesInAddrMessage += 1
if self.remoteProtocolVersion == 1: payload += pack('>Q',timeLastReceivedMessageFromThisNode) #64-bit time
payload += pack('>I',timeLastReceivedMessageFromThisNode) #32-bit time
else:
payload += pack('>Q',timeLastReceivedMessageFromThisNode) #64-bit time
payload += pack('>I',self.streamNumber*2) payload += pack('>I',self.streamNumber*2)
payload += pack('>q',1) #service bit flags offered by this node payload += pack('>q',1) #service bit flags offered by this node
payload += '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF' + socket.inet_aton(HOST) payload += '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF' + socket.inet_aton(HOST)
@ -1921,10 +1903,7 @@ class receiveDataThread(threading.Thread):
PORT, timeLastReceivedMessageFromThisNode = value PORT, timeLastReceivedMessageFromThisNode = value
if timeLastReceivedMessageFromThisNode > (int(time.time())- maximumAgeOfNodesThatIAdvertiseToOthers): #If it is younger than 3 hours old.. if timeLastReceivedMessageFromThisNode > (int(time.time())- maximumAgeOfNodesThatIAdvertiseToOthers): #If it is younger than 3 hours old..
numberOfAddressesInAddrMessage += 1 numberOfAddressesInAddrMessage += 1
if self.remoteProtocolVersion == 1: payload += pack('>Q',timeLastReceivedMessageFromThisNode) #64-bit time
payload += pack('>I',timeLastReceivedMessageFromThisNode) #32-bit time
else:
payload += pack('>Q',timeLastReceivedMessageFromThisNode) #64-bit time
payload += pack('>I',(self.streamNumber*2)+1) payload += pack('>I',(self.streamNumber*2)+1)
payload += pack('>q',1) #service bit flags offered by this node payload += pack('>q',1) #service bit flags offered by this node
payload += '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF' + socket.inet_aton(HOST) payload += '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF' + socket.inet_aton(HOST)
@ -1954,6 +1933,12 @@ class receiveDataThread(threading.Thread):
return return
elif not self.verackSent: elif not self.verackSent:
self.remoteProtocolVersion, = unpack('>L',data[:4]) self.remoteProtocolVersion, = unpack('>L',data[:4])
if self.remoteProtocolVersion <= 1:
shared.broadcastToSendDataQueues((0, 'shutdown', self.HOST))
shared.printLock.acquire()
print 'Closing connection to old protocol version 1 node: ', self.HOST
shared.printLock.release()
return
#print 'remoteProtocolVersion', self.remoteProtocolVersion #print 'remoteProtocolVersion', self.remoteProtocolVersion
self.myExternalIP = socket.inet_ntoa(data[40:44]) self.myExternalIP = socket.inet_ntoa(data[40:44])
#print 'myExternalIP', self.myExternalIP #print 'myExternalIP', self.myExternalIP
@ -2107,27 +2092,22 @@ class sendDataThread(threading.Thread):
shared.printLock.release() shared.printLock.release()
self.remoteProtocolVersion = specifiedRemoteProtocolVersion self.remoteProtocolVersion = specifiedRemoteProtocolVersion
elif command == 'sendaddr': elif command == 'sendaddr':
if self.remoteProtocolVersion == 1: try:
shared.printLock.acquire() #To prevent some network analysis, 'leak' the data out to our peer after waiting a random amount of time unless we have a long list of messages in our queue to send.
print 'a sendData thread is not sending an addr message to this particular peer ('+self.HOST+') because their protocol version is 1.' random.seed()
shared.printLock.release() time.sleep(random.randrange(0, 10))
else: self.sock.sendall(data)
self.lastTimeISentData = int(time.time())
except:
print 'self.sock.sendall failed'
try: try:
#To prevent some network analysis, 'leak' the data out to our peer after waiting a random amount of time unless we have a long list of messages in our queue to send. self.sock.shutdown(socket.SHUT_RDWR)
random.seed() self.sock.close()
time.sleep(random.randrange(0, 10))
self.sock.sendall(data)
self.lastTimeISentData = int(time.time())
except: except:
print 'self.sock.sendall failed' pass
try: shared.sendDataQueues.remove(self.mailbox)
self.sock.shutdown(socket.SHUT_RDWR) print 'sendDataThread thread (ID:',str(id(self))+') ending now. Was connected to', self.HOST
self.sock.close() break
except:
pass
shared.sendDataQueues.remove(self.mailbox)
print 'sendDataThread thread (ID:',str(id(self))+') ending now. Was connected to', self.HOST
break
elif command == 'sendinv': elif command == 'sendinv':
if data not in self.objectsOfWhichThisRemoteNodeIsAlreadyAware: if data not in self.objectsOfWhichThisRemoteNodeIsAlreadyAware:
payload = '\x01' + data payload = '\x01' + data
@ -2507,6 +2487,11 @@ class sqlThread(threading.Thread):
self.conn = sqlite3.connect(shared.appdata + 'messages.dat' ) self.conn = sqlite3.connect(shared.appdata + 'messages.dat' )
self.conn.text_factory = str self.conn.text_factory = str
self.cur = self.conn.cursor() self.cur = self.conn.cursor()
elif item == 'deleteandvacuume':
self.cur.execute('''delete from inbox where folder='trash' ''')
self.cur.execute('''delete from sent where folder='trash' ''')
self.conn.commit()
self.cur.execute( ''' VACUUM ''')
else: else:
parameters = shared.sqlSubmitQueue.get() parameters = shared.sqlSubmitQueue.get()
#print 'item', item #print 'item', item
@ -2547,7 +2532,6 @@ class singleCleaner(threading.Thread):
while True: while True:
shared.sqlLock.acquire() shared.sqlLock.acquire()
#self.emit(SIGNAL("updateStatusBar(PyQt_PyObject)"),"Doing housekeeping (Flushing inventory in memory to disk...)")
shared.UISignalQueue.put(('updateStatusBar','Doing housekeeping (Flushing inventory in memory to disk...)')) shared.UISignalQueue.put(('updateStatusBar','Doing housekeeping (Flushing inventory in memory to disk...)'))
for hash, storedValue in shared.inventory.items(): for hash, storedValue in shared.inventory.items():
objectType, streamNumber, payload, receivedTime = storedValue objectType, streamNumber, payload, receivedTime = storedValue
@ -2601,7 +2585,6 @@ class singleCleaner(threading.Thread):
except: except:
pass pass
#self.emit(SIGNAL("updateStatusBar(PyQt_PyObject)"),"Doing work necessary to again attempt to request a public key...")
shared.UISignalQueue.put(('updateStatusBar','Doing work necessary to again attempt to request a public key...')) shared.UISignalQueue.put(('updateStatusBar','Doing work necessary to again attempt to request a public key...'))
t = (int(time.time()),pubkeyretrynumber+1,toripe) t = (int(time.time()),pubkeyretrynumber+1,toripe)
shared.sqlSubmitQueue.put('''UPDATE sent SET lastactiontime=?, pubkeyretrynumber=?, status='msgqueued' WHERE toripe=?''') shared.sqlSubmitQueue.put('''UPDATE sent SET lastactiontime=?, pubkeyretrynumber=?, status='msgqueued' WHERE toripe=?''')
@ -2618,7 +2601,6 @@ class singleCleaner(threading.Thread):
shared.sqlReturnQueue.get() shared.sqlReturnQueue.get()
shared.sqlSubmitQueue.put('commit') shared.sqlSubmitQueue.put('commit')
shared.workerQueue.put(('sendmessage','')) shared.workerQueue.put(('sendmessage',''))
#self.emit(SIGNAL("updateStatusBar(PyQt_PyObject)"),"Doing work necessary to again attempt to deliver a message...")
shared.UISignalQueue.put(('updateStatusBar','Doing work necessary to again attempt to deliver a message...')) shared.UISignalQueue.put(('updateStatusBar','Doing work necessary to again attempt to deliver a message...'))
shared.sqlSubmitQueue.put('commit') shared.sqlSubmitQueue.put('commit')
shared.sqlLock.release() shared.sqlLock.release()
@ -2755,7 +2737,6 @@ class singleWorker(threading.Thread):
print 'broadcasting inv with hash:', inventoryHash.encode('hex') print 'broadcasting inv with hash:', inventoryHash.encode('hex')
shared.printLock.release() shared.printLock.release()
shared.broadcastToSendDataQueues((streamNumber, 'sendinv', inventoryHash)) shared.broadcastToSendDataQueues((streamNumber, 'sendinv', inventoryHash))
#self.emit(SIGNAL("updateStatusBar(PyQt_PyObject)"),"")
shared.UISignalQueue.put(('updateStatusBar','')) shared.UISignalQueue.put(('updateStatusBar',''))
shared.config.set(myAddress,'lastpubkeysendtime',str(int(time.time()))) shared.config.set(myAddress,'lastpubkeysendtime',str(int(time.time())))
with open(shared.appdata + 'keys.dat', 'wb') as configfile: with open(shared.appdata + 'keys.dat', 'wb') as configfile:
@ -2817,7 +2798,6 @@ class singleWorker(threading.Thread):
print 'broadcasting inv with hash:', inventoryHash.encode('hex') print 'broadcasting inv with hash:', inventoryHash.encode('hex')
shared.printLock.release() shared.printLock.release()
shared.broadcastToSendDataQueues((streamNumber, 'sendinv', inventoryHash)) shared.broadcastToSendDataQueues((streamNumber, 'sendinv', inventoryHash))
#self.emit(SIGNAL("updateStatusBar(PyQt_PyObject)"),"")
shared.UISignalQueue.put(('updateStatusBar','')) shared.UISignalQueue.put(('updateStatusBar',''))
shared.config.set(myAddress,'lastpubkeysendtime',str(int(time.time()))) shared.config.set(myAddress,'lastpubkeysendtime',str(int(time.time())))
with open(shared.appdata + 'keys.dat', 'wb') as configfile: with open(shared.appdata + 'keys.dat', 'wb') as configfile:
@ -2839,7 +2819,6 @@ class singleWorker(threading.Thread):
privSigningKeyBase58 = shared.config.get(fromaddress, 'privsigningkey') privSigningKeyBase58 = shared.config.get(fromaddress, 'privsigningkey')
privEncryptionKeyBase58 = shared.config.get(fromaddress, 'privencryptionkey') privEncryptionKeyBase58 = shared.config.get(fromaddress, 'privencryptionkey')
except: except:
#self.emit(SIGNAL("updateSentItemStatusByAckdata(PyQt_PyObject,PyQt_PyObject)"),ackdata,'Error! Could not find sender address (your address) in the keys.dat file.')
shared.UISignalQueue.put(('updateSentItemStatusByAckdata',(ackdata,'Error! Could not find sender address (your address) in the keys.dat file.'))) shared.UISignalQueue.put(('updateSentItemStatusByAckdata',(ackdata,'Error! Could not find sender address (your address) in the keys.dat file.')))
continue continue
@ -2849,7 +2828,7 @@ class singleWorker(threading.Thread):
pubSigningKey = highlevelcrypto.privToPub(privSigningKeyHex).decode('hex') #At this time these pubkeys are 65 bytes long because they include the encoding byte which we won't be sending in the broadcast message. pubSigningKey = highlevelcrypto.privToPub(privSigningKeyHex).decode('hex') #At this time these pubkeys are 65 bytes long because they include the encoding byte which we won't be sending in the broadcast message.
pubEncryptionKey = highlevelcrypto.privToPub(privEncryptionKeyHex).decode('hex') pubEncryptionKey = highlevelcrypto.privToPub(privEncryptionKeyHex).decode('hex')
payload = pack('>I',(int(time.time())+random.randrange(-300, 300)))#the current time plus or minus five minutes payload = pack('>Q',(int(time.time())+random.randrange(-300, 300)))#the current time plus or minus five minutes
payload += encodeVarint(1) #broadcast version payload += encodeVarint(1) #broadcast version
payload += encodeVarint(addressVersionNumber) payload += encodeVarint(addressVersionNumber)
payload += encodeVarint(streamNumber) payload += encodeVarint(streamNumber)
@ -2867,7 +2846,6 @@ class singleWorker(threading.Thread):
target = 2**64 / ((len(payload)+shared.networkDefaultPayloadLengthExtraBytes+8) * shared.networkDefaultProofOfWorkNonceTrialsPerByte) target = 2**64 / ((len(payload)+shared.networkDefaultPayloadLengthExtraBytes+8) * shared.networkDefaultProofOfWorkNonceTrialsPerByte)
print '(For broadcast message) Doing proof of work...' print '(For broadcast message) Doing proof of work...'
#self.emit(SIGNAL("updateSentItemStatusByAckdata(PyQt_PyObject,PyQt_PyObject)"),ackdata,'Doing work necessary to send broadcast...')
shared.UISignalQueue.put(('updateSentItemStatusByAckdata',(ackdata,'Doing work necessary to send broadcast...'))) shared.UISignalQueue.put(('updateSentItemStatusByAckdata',(ackdata,'Doing work necessary to send broadcast...')))
initialHash = hashlib.sha512(payload).digest() initialHash = hashlib.sha512(payload).digest()
trialValue, nonce = proofofwork.run(target, initialHash) trialValue, nonce = proofofwork.run(target, initialHash)
@ -2881,7 +2859,6 @@ class singleWorker(threading.Thread):
print 'Broadcasting inv for my broadcast (within sendBroadcast function):', inventoryHash.encode('hex') print 'Broadcasting inv for my broadcast (within sendBroadcast function):', inventoryHash.encode('hex')
shared.broadcastToSendDataQueues((streamNumber, 'sendinv', inventoryHash)) shared.broadcastToSendDataQueues((streamNumber, 'sendinv', inventoryHash))
#self.emit(SIGNAL("updateSentItemStatusByAckdata(PyQt_PyObject,PyQt_PyObject)"),ackdata,'Broadcast sent on '+unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'),localtime(int(time.time()))),'utf-8'))
shared.UISignalQueue.put(('updateSentItemStatusByAckdata',(ackdata,'Broadcast sent on '+unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'),localtime(int(time.time()))),'utf-8')))) shared.UISignalQueue.put(('updateSentItemStatusByAckdata',(ackdata,'Broadcast sent on '+unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'),localtime(int(time.time()))),'utf-8'))))
#Update the status of the message in the 'sent' table to have a 'broadcastsent' status #Update the status of the message in the 'sent' table to have a 'broadcastsent' status
@ -2898,7 +2875,6 @@ class singleWorker(threading.Thread):
privSigningKeyBase58 = shared.config.get(fromaddress, 'privsigningkey') privSigningKeyBase58 = shared.config.get(fromaddress, 'privsigningkey')
privEncryptionKeyBase58 = shared.config.get(fromaddress, 'privencryptionkey') privEncryptionKeyBase58 = shared.config.get(fromaddress, 'privencryptionkey')
except: except:
#self.emit(SIGNAL("updateSentItemStatusByAckdata(PyQt_PyObject,PyQt_PyObject)"),ackdata,'Error! Could not find sender address (your address) in the keys.dat file.')
shared.UISignalQueue.put(('updateSentItemStatusByAckdata',(ackdata,'Error! Could not find sender address (your address) in the keys.dat file.'))) shared.UISignalQueue.put(('updateSentItemStatusByAckdata',(ackdata,'Error! Could not find sender address (your address) in the keys.dat file.')))
continue continue
@ -2908,7 +2884,7 @@ class singleWorker(threading.Thread):
pubSigningKey = highlevelcrypto.privToPub(privSigningKeyHex).decode('hex') #At this time these pubkeys are 65 bytes long because they include the encoding byte which we won't be sending in the broadcast message. pubSigningKey = highlevelcrypto.privToPub(privSigningKeyHex).decode('hex') #At this time these pubkeys are 65 bytes long because they include the encoding byte which we won't be sending in the broadcast message.
pubEncryptionKey = highlevelcrypto.privToPub(privEncryptionKeyHex).decode('hex') pubEncryptionKey = highlevelcrypto.privToPub(privEncryptionKeyHex).decode('hex')
payload = pack('>I',(int(time.time())+random.randrange(-300, 300)))#the current time plus or minus five minutes payload = pack('>Q',(int(time.time())+random.randrange(-300, 300)))#the current time plus or minus five minutes
payload += encodeVarint(2) #broadcast version payload += encodeVarint(2) #broadcast version
payload += encodeVarint(streamNumber) payload += encodeVarint(streamNumber)
@ -2933,7 +2909,6 @@ class singleWorker(threading.Thread):
target = 2**64 / ((len(payload)+shared.networkDefaultPayloadLengthExtraBytes+8) * shared.networkDefaultProofOfWorkNonceTrialsPerByte) target = 2**64 / ((len(payload)+shared.networkDefaultPayloadLengthExtraBytes+8) * shared.networkDefaultProofOfWorkNonceTrialsPerByte)
print '(For broadcast message) Doing proof of work...' print '(For broadcast message) Doing proof of work...'
#self.emit(SIGNAL("updateSentItemStatusByAckdata(PyQt_PyObject,PyQt_PyObject)"),ackdata,'Doing work necessary to send broadcast...')
shared.UISignalQueue.put(('updateSentItemStatusByAckdata',(ackdata,'Doing work necessary to send broadcast...'))) shared.UISignalQueue.put(('updateSentItemStatusByAckdata',(ackdata,'Doing work necessary to send broadcast...')))
initialHash = hashlib.sha512(payload).digest() initialHash = hashlib.sha512(payload).digest()
trialValue, nonce = proofofwork.run(target, initialHash) trialValue, nonce = proofofwork.run(target, initialHash)
@ -2947,7 +2922,6 @@ class singleWorker(threading.Thread):
print 'sending inv (within sendBroadcast function)' print 'sending inv (within sendBroadcast function)'
shared.broadcastToSendDataQueues((streamNumber, 'sendinv', inventoryHash)) shared.broadcastToSendDataQueues((streamNumber, 'sendinv', inventoryHash))
#self.emit(SIGNAL("updateSentItemStatusByAckdata(PyQt_PyObject,PyQt_PyObject)"),ackdata,'Broadcast sent on '+unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'),localtime(int(time.time()))),'utf-8'))
shared.UISignalQueue.put(('updateSentItemStatusByAckdata',(ackdata,'Broadcast sent on '+unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'),localtime(int(time.time()))),'utf-8')))) shared.UISignalQueue.put(('updateSentItemStatusByAckdata',(ackdata,'Broadcast sent on '+unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'),localtime(int(time.time()))),'utf-8'))))
#Update the status of the message in the 'sent' table to have a 'broadcastsent' status #Update the status of the message in the 'sent' table to have a 'broadcastsent' status
@ -3009,12 +2983,12 @@ class singleWorker(threading.Thread):
shared.UISignalQueue.put(('updateSentItemStatusByHash',(toripe,'Sending a request for the recipient\'s encryption key.'))) shared.UISignalQueue.put(('updateSentItemStatusByHash',(toripe,'Sending a request for the recipient\'s encryption key.')))
self.requestPubKey(toaddress) self.requestPubKey(toaddress)
shared.sqlLock.acquire() shared.sqlLock.acquire()
shared.sqlSubmitQueue.put('''SELECT toaddress, toripe, fromaddress, subject, message, ackdata FROM sent WHERE status='doingmsgpow' and folder='sent' ''') shared.sqlSubmitQueue.put('''SELECT toaddress, toripe, fromaddress, subject, message, ackdata, status FROM sent WHERE (status='doingmsgpow' or status='forcepow' or (status='toodifficult' and lastactiontime>?)) and folder='sent' ''')
shared.sqlSubmitQueue.put('') shared.sqlSubmitQueue.put((int(time.time())-2419200,))
queryreturn = shared.sqlReturnQueue.get() queryreturn = shared.sqlReturnQueue.get()
shared.sqlLock.release() shared.sqlLock.release()
for row in queryreturn: for row in queryreturn:
toaddress, toripe, fromaddress, subject, message, ackdata = row toaddress, toripe, fromaddress, subject, message, ackdata, status = row
#Evidently there is a remote possibility that we may no longer have the recipient's pubkey. Let us make sure we still have it or else the sendMsg function will appear to freeze. #Evidently there is a remote possibility that we may no longer have the recipient's pubkey. Let us make sure we still have it or else the sendMsg function will appear to freeze.
shared.sqlLock.acquire() shared.sqlLock.acquire()
@ -3045,7 +3019,72 @@ class singleWorker(threading.Thread):
print 'Found a message in our database that needs to be sent with this pubkey.' print 'Found a message in our database that needs to be sent with this pubkey.'
print 'First 150 characters of message:', repr(message[:150]) print 'First 150 characters of message:', repr(message[:150])
shared.printLock.release() shared.printLock.release()
embeddedTime = pack('>I',(int(time.time())+random.randrange(-300, 300)))#the current time plus or minus five minutes. We will use this time both for our message and for the ackdata packed within our message.
#Now let us fetch the recipient's public key out of our database. If the required proof of work difficulty is too hard then we'll abort.
shared.sqlLock.acquire()
shared.sqlSubmitQueue.put('SELECT transmitdata FROM pubkeys WHERE hash=?')
shared.sqlSubmitQueue.put((toripe,))
queryreturn = shared.sqlReturnQueue.get()
#also mark the pubkey as 'usedpersonally' so that we don't delete it.
t = (toripe,)
shared.sqlSubmitQueue.put('''UPDATE pubkeys SET usedpersonally='yes' WHERE hash=?''')
shared.sqlSubmitQueue.put(t)
shared.sqlReturnQueue.get()
shared.sqlSubmitQueue.put('commit')
shared.sqlLock.release()
if queryreturn == []:
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
#The pubkey is stored the way we originally received it which means that we need to read beyond things like the nonce and time to get to the public keys.
readPosition = 8 #to bypass the nonce
pubkeyEmbeddedTime, = unpack('>I',pubkeyPayload[readPosition:readPosition+4])
#This section is used for the transition from 32 bit time to 64 bit time in the protocol.
if pubkeyEmbeddedTime == 0:
pubkeyEmbeddedTime, = unpack('>Q',pubkeyPayload[readPosition:readPosition+8])
readPosition += 8
else:
readPosition += 4
readPosition += 1 #to bypass the address version whose length is definitely 1
streamNumber, streamNumberLength = decodeVarint(pubkeyPayload[readPosition:readPosition+10])
readPosition += streamNumberLength
behaviorBitfield = pubkeyPayload[readPosition:readPosition+4]
readPosition += 4 #to bypass the bitfield of behaviors
#pubSigningKeyBase256 = pubkeyPayload[readPosition:readPosition+64] #We don't use this key for anything here.
readPosition += 64
pubEncryptionKeyBase256 = pubkeyPayload[readPosition:readPosition+64]
readPosition += 64
if toAddressVersionNumber == 2:
requiredAverageProofOfWorkNonceTrialsPerByte = shared.networkDefaultProofOfWorkNonceTrialsPerByte
requiredPayloadLengthExtraBytes = shared.networkDefaultPayloadLengthExtraBytes
elif toAddressVersionNumber == 3:
requiredAverageProofOfWorkNonceTrialsPerByte, varintLength = decodeVarint(pubkeyPayload[readPosition:readPosition+10])
readPosition += varintLength
requiredPayloadLengthExtraBytes, varintLength = decodeVarint(pubkeyPayload[readPosition:readPosition+10])
readPosition += varintLength
if requiredAverageProofOfWorkNonceTrialsPerByte < shared.networkDefaultProofOfWorkNonceTrialsPerByte: #We still have to meet a minimum POW difficulty regardless of what they say is allowed in order to get our message to propagate through the network.
requiredAverageProofOfWorkNonceTrialsPerByte = shared.networkDefaultProofOfWorkNonceTrialsPerByte
if requiredPayloadLengthExtraBytes < shared.networkDefaultPayloadLengthExtraBytes:
requiredPayloadLengthExtraBytes = shared.networkDefaultPayloadLengthExtraBytes
if status != 'forcepow':
if (requiredAverageProofOfWorkNonceTrialsPerByte > shared.config.getint('bitmessagesettings','maxacceptablenoncetrialsperbyte') and shared.config.getint('bitmessagesettings','maxacceptablenoncetrialsperbyte') != 0) or (requiredPayloadLengthExtraBytes > shared.config.getint('bitmessagesettings','maxacceptablepayloadlengthextrabytes') and shared.config.getint('bitmessagesettings','maxacceptablepayloadlengthextrabytes') != 0):
#The demanded difficulty is more than we are willing to do.
shared.sqlLock.acquire()
t = (ackdata,)
shared.sqlSubmitQueue.put('''UPDATE sent SET status='toodifficult' WHERE ackdata=? AND status='doingmsgpow' ''')
shared.sqlSubmitQueue.put(t)
shared.sqlReturnQueue.get()
shared.sqlSubmitQueue.put('commit')
shared.sqlLock.release()
shared.UISignalQueue.put(('updateSentItemStatusByAckdata',(ackdata,'Problem: The work demanded by the recipient (' + str(float(requiredAverageProofOfWorkNonceTrialsPerByte) / shared.networkDefaultProofOfWorkNonceTrialsPerByte) + ' and ' + str(float(requiredPayloadLengthExtraBytes) / shared.networkDefaultPayloadLengthExtraBytes) + ') is more difficult than you are willing to do. ' + unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'),localtime(int(time.time()))),'utf-8'))))
continue
embeddedTime = pack('>Q',(int(time.time())+random.randrange(-300, 300)))#the current time plus or minus five minutes. We will use this time both for our message and for the ackdata packed within our message.
if fromAddressVersionNumber == 2: if fromAddressVersionNumber == 2:
payload = '\x01' #Message version. payload = '\x01' #Message version.
payload += encodeVarint(fromAddressVersionNumber) payload += encodeVarint(fromAddressVersionNumber)
@ -3057,7 +3096,6 @@ class singleWorker(threading.Thread):
privSigningKeyBase58 = shared.config.get(fromaddress, 'privsigningkey') privSigningKeyBase58 = shared.config.get(fromaddress, 'privsigningkey')
privEncryptionKeyBase58 = shared.config.get(fromaddress, 'privencryptionkey') privEncryptionKeyBase58 = shared.config.get(fromaddress, 'privencryptionkey')
except: except:
#self.emit(SIGNAL("updateSentItemStatusByAckdata(PyQt_PyObject,PyQt_PyObject)"),ackdata,'Error! Could not find sender address (your address) in the keys.dat file.')
shared.UISignalQueue.put(('updateSentItemStatusByAckdata',(ackdata,'Error! Could not find sender address (your address) in the keys.dat file.'))) shared.UISignalQueue.put(('updateSentItemStatusByAckdata',(ackdata,'Error! Could not find sender address (your address) in the keys.dat file.')))
continue continue
@ -3093,7 +3131,6 @@ class singleWorker(threading.Thread):
privSigningKeyBase58 = shared.config.get(fromaddress, 'privsigningkey') privSigningKeyBase58 = shared.config.get(fromaddress, 'privsigningkey')
privEncryptionKeyBase58 = shared.config.get(fromaddress, 'privencryptionkey') privEncryptionKeyBase58 = shared.config.get(fromaddress, 'privencryptionkey')
except: except:
#self.emit(SIGNAL("updateSentItemStatusByAckdata(PyQt_PyObject,PyQt_PyObject)"),ackdata,'Error! Could not find sender address (your address) in the keys.dat file.')
shared.UISignalQueue.put(('updateSentItemStatusByAckdata',(ackdata,'Error! Could not find sender address (your address) in the keys.dat file.'))) shared.UISignalQueue.put(('updateSentItemStatusByAckdata',(ackdata,'Error! Could not find sender address (your address) in the keys.dat file.')))
continue continue
@ -3125,71 +3162,9 @@ class singleWorker(threading.Thread):
payload += encodeVarint(len(signature)) payload += encodeVarint(len(signature))
payload += signature payload += signature
#We have assembled the data that will be encrypted.
#We have assembled the data that will be encrypted. Now let us fetch the recipient's public key out of our database and do the encryption. encrypted = highlevelcrypto.encrypt(payload,"04"+pubEncryptionKeyBase256.encode('hex'))
#We will now drop the unencrypted data in payload since it has already been encrypted and replace it with the encrypted payload that we will send out.
if toAddressVersionNumber == 2 or toAddressVersionNumber == 3:
shared.sqlLock.acquire()
shared.sqlSubmitQueue.put('SELECT transmitdata FROM pubkeys WHERE hash=?')
shared.sqlSubmitQueue.put((toripe,))
queryreturn = shared.sqlReturnQueue.get()
shared.sqlLock.release()
if queryreturn == []:
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
#The pubkey is stored the way we originally received it which means that we need to read beyond things like the nonce and time to get to the public keys.
readPosition = 8 #to bypass the nonce
pubkeyEmbeddedTime, = unpack('>I',pubkeyPayload[readPosition:readPosition+4])
#This section is used for the transition from 32 bit time to 64 bit time in the protocol.
if pubkeyEmbeddedTime == 0:
pubkeyEmbeddedTime, = unpack('>Q',pubkeyPayload[readPosition:readPosition+8])
readPosition += 8
else:
readPosition += 4
readPosition += 1 #to bypass the address version whose length is definitely 1
streamNumber, streamNumberLength = decodeVarint(pubkeyPayload[readPosition:readPosition+10])
readPosition += streamNumberLength
behaviorBitfield = pubkeyPayload[readPosition:readPosition+4]
readPosition += 4 #to bypass the bitfield of behaviors
#pubSigningKeyBase256 = pubkeyPayload[readPosition:readPosition+64] #We don't use this key for anything here.
readPosition += 64
pubEncryptionKeyBase256 = pubkeyPayload[readPosition:readPosition+64]
readPosition += 64
if toAddressVersionNumber == 2:
requiredAverageProofOfWorkNonceTrialsPerByte = shared.networkDefaultProofOfWorkNonceTrialsPerByte
requiredPayloadLengthExtraBytes = shared.networkDefaultPayloadLengthExtraBytes
elif toAddressVersionNumber == 3:
requiredAverageProofOfWorkNonceTrialsPerByte, varintLength = decodeVarint(pubkeyPayload[readPosition:readPosition+10])
readPosition += varintLength
requiredPayloadLengthExtraBytes, varintLength = decodeVarint(pubkeyPayload[readPosition:readPosition+10])
readPosition += varintLength
if requiredAverageProofOfWorkNonceTrialsPerByte < shared.networkDefaultProofOfWorkNonceTrialsPerByte: #We still have to meet a minimum POW difficulty regardless of what they say is allowed in order to get our message to propagate through the network.
requiredAverageProofOfWorkNonceTrialsPerByte = shared.networkDefaultProofOfWorkNonceTrialsPerByte
if requiredPayloadLengthExtraBytes < shared.networkDefaultPayloadLengthExtraBytes:
requiredPayloadLengthExtraBytes = shared.networkDefaultPayloadLengthExtraBytes
if (requiredAverageProofOfWorkNonceTrialsPerByte > shared.config.getint('bitmessagesettings','maxacceptablenoncetrialsperbyte') and shared.config.getint('bitmessagesettings','maxacceptablenoncetrialsperbyte') != 0) or (requiredPayloadLengthExtraBytes > shared.config.getint('bitmessagesettings','maxacceptablepayloadlengthextrabytes') and shared.config.getint('bitmessagesettings','maxacceptablepayloadlengthextrabytes') != 0):
#The demanded difficulty is more than we are willing to do.
shared.sqlLock.acquire()
t = (ackdata,)
shared.sqlSubmitQueue.put('''UPDATE sent SET status='toodifficult' WHERE ackdata=? AND status='doingmsgpow' ''')
shared.sqlSubmitQueue.put(t)
shared.sqlReturnQueue.get()
shared.sqlSubmitQueue.put('commit')
shared.sqlLock.release()
shared.UISignalQueue.put(('updateSentItemStatusByAckdata',(ackdata,'Problem: The work demanded by the recipient (' + str(requiredAverageProofOfWorkNonceTrialsPerByte / shared.networkDefaultProofOfWorkNonceTrialsPerByte) + ' and ' + str(requiredPayloadLengthExtraBytes / shared.networkDefaultPayloadLengthExtraBytes) + ') is more difficult than you are willing to do. ' + unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'),localtime(int(time.time()))),'utf-8'))))
continue
encrypted = highlevelcrypto.encrypt(payload,"04"+pubEncryptionKeyBase256.encode('hex'))
#We are now dropping the unencrypted data in payload since it has already been encrypted and replacing it with the encrypted payload that we will send out.
payload = embeddedTime + encodeVarint(toStreamNumber) + encrypted payload = embeddedTime + encodeVarint(toStreamNumber) + encrypted
target = 2**64 / ((len(payload)+requiredPayloadLengthExtraBytes+8) * requiredAverageProofOfWorkNonceTrialsPerByte) target = 2**64 / ((len(payload)+requiredPayloadLengthExtraBytes+8) * requiredAverageProofOfWorkNonceTrialsPerByte)
shared.printLock.acquire() shared.printLock.acquire()
@ -3208,20 +3183,14 @@ class singleWorker(threading.Thread):
inventoryHash = calculateInventoryHash(payload) inventoryHash = calculateInventoryHash(payload)
objectType = 'msg' objectType = 'msg'
shared.inventory[inventoryHash] = (objectType, toStreamNumber, payload, int(time.time())) shared.inventory[inventoryHash] = (objectType, toStreamNumber, payload, int(time.time()))
#self.emit(SIGNAL("updateSentItemStatusByAckdata(PyQt_PyObject,PyQt_PyObject)"),ackdata,'Message sent. Waiting on acknowledgement. Sent on ' + unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'),localtime(int(time.time()))),'utf-8'))
shared.UISignalQueue.put(('updateSentItemStatusByAckdata',(ackdata,'Message sent. Waiting on acknowledgement. Sent on ' + unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'),localtime(int(time.time()))),'utf-8')))) shared.UISignalQueue.put(('updateSentItemStatusByAckdata',(ackdata,'Message sent. Waiting on acknowledgement. Sent on ' + 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') print 'Broadcasting inv for my msg(within sendmsg function):', inventoryHash.encode('hex')
shared.broadcastToSendDataQueues((streamNumber, 'sendinv', inventoryHash)) shared.broadcastToSendDataQueues((streamNumber, 'sendinv', inventoryHash))
#Update the status of the message in the 'sent' table to have a 'msgsent' status #Update the status of the message in the 'sent' table to have a 'msgsent' status
shared.sqlLock.acquire() shared.sqlLock.acquire()
t = ('msgsent',toaddress, fromaddress, subject, message,'doingmsgpow') t = (toaddress, fromaddress, subject, message)
shared.sqlSubmitQueue.put('UPDATE sent SET status=? WHERE toaddress=? AND fromaddress=? AND subject=? AND message=? AND status=?') shared.sqlSubmitQueue.put('''UPDATE sent SET status='msgsent' WHERE toaddress=? AND fromaddress=? AND subject=? AND message=? AND status='doingmsgpow' or status='forcepow' ''')
shared.sqlSubmitQueue.put(t)
queryreturn = shared.sqlReturnQueue.get()
t = (toripe,)
shared.sqlSubmitQueue.put('''UPDATE pubkeys SET usedpersonally='yes' WHERE hash=?''')
shared.sqlSubmitQueue.put(t) shared.sqlSubmitQueue.put(t)
queryreturn = shared.sqlReturnQueue.get() queryreturn = shared.sqlReturnQueue.get()
shared.sqlSubmitQueue.put('commit') shared.sqlSubmitQueue.put('commit')
@ -3236,7 +3205,7 @@ class singleWorker(threading.Thread):
shared.printLock.release() shared.printLock.release()
return return
neededPubkeys[ripe] = 0 neededPubkeys[ripe] = 0
payload = pack('>I',(int(time.time())+random.randrange(-300, 300)))#the current time plus or minus five minutes. payload = pack('>Q',(int(time.time())+random.randrange(-300, 300)))#the current time plus or minus five minutes.
payload += encodeVarint(addressVersionNumber) payload += encodeVarint(addressVersionNumber)
payload += encodeVarint(streamNumber) payload += encodeVarint(streamNumber)
payload += ripe payload += ripe
@ -3247,7 +3216,6 @@ class singleWorker(threading.Thread):
statusbar = 'Doing the computations necessary to request the recipient\'s public key.' statusbar = 'Doing the computations necessary to request the recipient\'s public key.'
shared.UISignalQueue.put(('updateStatusBar',statusbar)) shared.UISignalQueue.put(('updateStatusBar',statusbar))
shared.UISignalQueue.put(('updateSentItemStatusByHash',(ripe,'Doing work necessary to request encryption key.'))) shared.UISignalQueue.put(('updateSentItemStatusByHash',(ripe,'Doing work necessary to request encryption key.')))
print 'Doing proof-of-work necessary to send getpubkey message.'
target = 2**64 / ((len(payload)+shared.networkDefaultPayloadLengthExtraBytes+8) * shared.networkDefaultProofOfWorkNonceTrialsPerByte) target = 2**64 / ((len(payload)+shared.networkDefaultPayloadLengthExtraBytes+8) * shared.networkDefaultProofOfWorkNonceTrialsPerByte)
initialHash = hashlib.sha512(payload).digest() initialHash = hashlib.sha512(payload).digest()
trialValue, nonce = proofofwork.run(target, initialHash) trialValue, nonce = proofofwork.run(target, initialHash)
@ -3379,9 +3347,7 @@ class addressGenerator(threading.Thread):
#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(address) apiAddressGeneratorReturnQueue.put(address)
#self.emit(SIGNAL("updateStatusBar(PyQt_PyObject)"),'Done generating address. Doing work necessary to broadcast it...')
shared.UISignalQueue.put(('updateStatusBar','Done generating address. Doing work necessary to broadcast it...')) shared.UISignalQueue.put(('updateStatusBar','Done generating address. Doing work necessary to broadcast it...'))
#self.emit(SIGNAL("writeNewAddressToTable(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"),self.label,address,str(streamNumber))
shared.UISignalQueue.put(('writeNewAddressToTable',(label,address,streamNumber))) shared.UISignalQueue.put(('writeNewAddressToTable',(label,address,streamNumber)))
shared.reloadMyAddressHashes() shared.reloadMyAddressHashes()
shared.workerQueue.put(('doPOWForMyV3Pubkey',ripe.digest())) shared.workerQueue.put(('doPOWForMyV3Pubkey',ripe.digest()))
@ -3452,20 +3418,22 @@ class addressGenerator(threading.Thread):
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))
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.
shared.myECCryptorObjects[ripe.digest()] = highlevelcrypto.makeCryptor(potentialPrivEncryptionKey.encode('hex'))
shared.myAddressesByHash[ripe.digest()] = address
shared.workerQueue.put(('doPOWForMyV3Pubkey',ripe.digest()))
except: except:
print address,'already exists. Not adding it again.' print address,'already exists. Not adding it again.'
#Done generating addresses. #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.
if command == 'createDeterministicAddresses': 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.
apiAddressGeneratorReturnQueue.put(listOfNewAddressesToSendOutThroughTheAPI) apiAddressGeneratorReturnQueue.put(listOfNewAddressesToSendOutThroughTheAPI)
shared.UISignalQueue.put(('updateStatusBar','Done generating address')) shared.UISignalQueue.put(('updateStatusBar','Done generating address'))
shared.reloadMyAddressHashes() #shared.reloadMyAddressHashes()
elif command == 'getDeterministicAddress': elif command == 'getDeterministicAddress':
apiAddressGeneratorReturnQueue.put(address) apiAddressGeneratorReturnQueue.put(address)
else: else:
@ -3602,6 +3570,10 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
else: else:
return 'API Error 0000: Too many parameters!' return 'API Error 0000: Too many parameters!'
label = label.decode('base64') label = label.decode('base64')
try:
unicode(label,'utf-8')
except:
return 'API Error 0017: Label is not valid UTF-8 data.'
apiAddressGeneratorReturnQueue.queue.clear() apiAddressGeneratorReturnQueue.queue.clear()
streamNumberForAddress = 1 streamNumberForAddress = 1
shared.addressGeneratorQueue.put(('createRandomAddress',3,streamNumberForAddress,label,1,"",eighteenByteRipe,nonceTrialsPerByte,payloadLengthExtraBytes)) shared.addressGeneratorQueue.put(('createRandomAddress',3,streamNumberForAddress,label,1,"",eighteenByteRipe,nonceTrialsPerByte,payloadLengthExtraBytes))
@ -3701,6 +3673,8 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
data = '{"inboxMessages":[' data = '{"inboxMessages":['
for row in queryreturn: for row in queryreturn:
msgid, toAddress, fromAddress, subject, received, message, = row msgid, toAddress, fromAddress, subject, received, message, = row
subject = shared.fixPotentiallyInvalidUTF8Data(subject)
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':2,'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':2,'receivedTime':received},indent=4, separators=(',', ': '))
@ -3845,8 +3819,6 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
shared.sqlLock.release() shared.sqlLock.release()
toLabel = '[Broadcast subscribers]' toLabel = '[Broadcast subscribers]'
#apiSignalQueue.put(('displayNewSentMessage',(toAddress,toLabel,fromAddress,subject,message,ackdata)))
#self.emit(SIGNAL("displayNewSentMessage(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"),toAddress,toLabel,fromAddress,subject,message,ackdata)
shared.UISignalQueue.put(('displayNewSentMessage',(toAddress,toLabel,fromAddress,subject,message,ackdata))) shared.UISignalQueue.put(('displayNewSentMessage',(toAddress,toLabel,fromAddress,subject,message,ackdata)))
shared.workerQueue.put(('sendbroadcast','')) shared.workerQueue.put(('sendbroadcast',''))
@ -3877,8 +3849,8 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
address, label = params address, label = params
label = label.decode('base64') label = label.decode('base64')
try: try:
label.decode('utf-8') unicode(label,'utf-8')
except UnicodeDecodeError: except:
return 'API Error 0017: Label is not valid UTF-8 data.' return 'API Error 0017: Label is not valid UTF-8 data.'
if len(params) >2: if len(params) >2:
return 'API Error 0000: I need either 1 or 2 parameters!' return 'API Error 0000: I need either 1 or 2 parameters!'

View File

@ -169,11 +169,12 @@ class MyForm(QtGui.QMainWindow):
# Actions # Actions
self.actionTrashSentMessage = self.ui.sentContextMenuToolbar.addAction("Move to Trash", self.on_action_SentTrash) self.actionTrashSentMessage = self.ui.sentContextMenuToolbar.addAction("Move to Trash", self.on_action_SentTrash)
self.actionSentClipboard = self.ui.sentContextMenuToolbar.addAction("Copy destination address to clipboard", self.on_action_SentClipboard) self.actionSentClipboard = self.ui.sentContextMenuToolbar.addAction("Copy destination address to clipboard", self.on_action_SentClipboard)
self.actionForceSend = self.ui.sentContextMenuToolbar.addAction("Force send", self.on_action_ForceSend)
self.ui.tableWidgetSent.setContextMenuPolicy( QtCore.Qt.CustomContextMenu ) self.ui.tableWidgetSent.setContextMenuPolicy( QtCore.Qt.CustomContextMenu )
self.connect(self.ui.tableWidgetSent, QtCore.SIGNAL('customContextMenuRequested(const QPoint&)'), self.on_context_menuSent) self.connect(self.ui.tableWidgetSent, QtCore.SIGNAL('customContextMenuRequested(const QPoint&)'), self.on_context_menuSent)
self.popMenuSent = QtGui.QMenu( self ) #self.popMenuSent = QtGui.QMenu( self )
self.popMenuSent.addAction( self.actionSentClipboard ) #self.popMenuSent.addAction( self.actionSentClipboard )
self.popMenuSent.addAction( self.actionTrashSentMessage ) #self.popMenuSent.addAction( self.actionTrashSentMessage )
#Popup menu for the Blacklist page #Popup menu for the Blacklist page
@ -220,10 +221,9 @@ class MyForm(QtGui.QMainWindow):
if isEnabled: if isEnabled:
status,addressVersionNumber,streamNumber,hash = decodeAddress(addressInKeysFile) status,addressVersionNumber,streamNumber,hash = decodeAddress(addressInKeysFile)
self.ui.tableWidgetSent.keyPressEvent = self.tableWidgetSentKeyPressEvent #Load inbox from messages database file
font = QFont() font = QFont()
font.setBold(True) font.setBold(True)
#Load inbox from messages database file
shared.sqlLock.acquire() 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('''SELECT msgid, toaddress, fromaddress, subject, received, message, read FROM inbox where folder='inbox' ORDER BY received''')
shared.sqlSubmitQueue.put('') shared.sqlSubmitQueue.put('')
@ -231,7 +231,8 @@ class MyForm(QtGui.QMainWindow):
shared.sqlLock.release() shared.sqlLock.release()
for row in queryreturn: for row in queryreturn:
msgid, toAddress, fromAddress, subject, received, message, read = row msgid, toAddress, fromAddress, subject, received, message, read = row
subject = shared.fixPotentiallyInvalidUTF8Data(subject)
message = shared.fixPotentiallyInvalidUTF8Data(message)
try: try:
if toAddress == self.str_broadcast_subscribers: if toAddress == self.str_broadcast_subscribers:
toLabel = self.str_broadcast_subscribers toLabel = self.str_broadcast_subscribers
@ -268,6 +269,7 @@ class MyForm(QtGui.QMainWindow):
self.ui.tableWidgetInbox.insertRow(0) self.ui.tableWidgetInbox.insertRow(0)
newItem = QtGui.QTableWidgetItem(unicode(toLabel,'utf-8')) newItem = QtGui.QTableWidgetItem(unicode(toLabel,'utf-8'))
newItem.setToolTip(unicode(toLabel,'utf-8'))
newItem.setFlags( QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled ) newItem.setFlags( QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled )
if not read: if not read:
newItem.setFont(font) newItem.setFont(font)
@ -277,8 +279,10 @@ class MyForm(QtGui.QMainWindow):
self.ui.tableWidgetInbox.setItem(0,0,newItem) self.ui.tableWidgetInbox.setItem(0,0,newItem)
if fromLabel == '': if fromLabel == '':
newItem = QtGui.QTableWidgetItem(unicode(fromAddress,'utf-8')) newItem = QtGui.QTableWidgetItem(unicode(fromAddress,'utf-8'))
newItem.setToolTip(unicode(fromAddress,'utf-8'))
else: else:
newItem = QtGui.QTableWidgetItem(unicode(fromLabel,'utf-8')) newItem = QtGui.QTableWidgetItem(unicode(fromLabel,'utf-8'))
newItem.setToolTip(unicode(fromLabel,'utf-8'))
newItem.setFlags( QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled ) newItem.setFlags( QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled )
if not read: if not read:
newItem.setFont(font) newItem.setFont(font)
@ -286,12 +290,14 @@ class MyForm(QtGui.QMainWindow):
self.ui.tableWidgetInbox.setItem(0,1,newItem) self.ui.tableWidgetInbox.setItem(0,1,newItem)
newItem = QtGui.QTableWidgetItem(unicode(subject,'utf-8')) newItem = QtGui.QTableWidgetItem(unicode(subject,'utf-8'))
newItem.setToolTip(unicode(subject,'utf-8'))
newItem.setData(Qt.UserRole,unicode(message,'utf-8)')) newItem.setData(Qt.UserRole,unicode(message,'utf-8)'))
newItem.setFlags( QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled ) newItem.setFlags( QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled )
if not read: if not read:
newItem.setFont(font) newItem.setFont(font)
self.ui.tableWidgetInbox.setItem(0,2,newItem) self.ui.tableWidgetInbox.setItem(0,2,newItem)
newItem = myTableWidgetItem(unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'),localtime(int(received))),'utf-8')) 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(Qt.UserRole,QByteArray(msgid))
newItem.setData(33,int(received)) newItem.setData(33,int(received))
newItem.setFlags( QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled ) newItem.setFlags( QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled )
@ -299,8 +305,8 @@ class MyForm(QtGui.QMainWindow):
newItem.setFont(font) newItem.setFont(font)
self.ui.tableWidgetInbox.setItem(0,3,newItem) self.ui.tableWidgetInbox.setItem(0,3,newItem)
self.ui.tableWidgetInbox.sortItems(3,Qt.DescendingOrder) self.ui.tableWidgetInbox.sortItems(3,Qt.DescendingOrder)
self.ui.tableWidgetInbox.keyPressEvent = self.tableWidgetInboxKeyPressEvent self.ui.tableWidgetInbox.keyPressEvent = self.tableWidgetInboxKeyPressEvent
#Load Sent items from database #Load Sent items from database
shared.sqlLock.acquire() 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('''SELECT toaddress, fromaddress, subject, message, status, ackdata, lastactiontime FROM sent where folder = 'sent' ORDER BY lastactiontime''')
@ -309,6 +315,8 @@ class MyForm(QtGui.QMainWindow):
shared.sqlLock.release() shared.sqlLock.release()
for row in queryreturn: for row in queryreturn:
toAddress, fromAddress, subject, message, status, ackdata, lastactiontime = row toAddress, fromAddress, subject, message, status, ackdata, lastactiontime = row
subject = shared.fixPotentiallyInvalidUTF8Data(subject)
message = shared.fixPotentiallyInvalidUTF8Data(message)
try: try:
fromLabel = shared.config.get(fromAddress, 'label') fromLabel = shared.config.get(fromAddress, 'label')
except: except:
@ -331,47 +339,57 @@ class MyForm(QtGui.QMainWindow):
self.ui.tableWidgetSent.insertRow(0) self.ui.tableWidgetSent.insertRow(0)
if toLabel == '': if toLabel == '':
newItem = QtGui.QTableWidgetItem(unicode(toAddress,'utf-8')) newItem = QtGui.QTableWidgetItem(unicode(toAddress,'utf-8'))
newItem.setToolTip(unicode(toAddress,'utf-8'))
else: else:
newItem = QtGui.QTableWidgetItem(unicode(toLabel,'utf-8')) newItem = QtGui.QTableWidgetItem(unicode(toLabel,'utf-8'))
newItem.setToolTip(unicode(toLabel,'utf-8'))
newItem.setData(Qt.UserRole,str(toAddress)) newItem.setData(Qt.UserRole,str(toAddress))
newItem.setFlags( QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled ) newItem.setFlags( QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled )
self.ui.tableWidgetSent.setItem(0,0,newItem) self.ui.tableWidgetSent.setItem(0,0,newItem)
if fromLabel == '': if fromLabel == '':
newItem = QtGui.QTableWidgetItem(unicode(fromAddress,'utf-8')) newItem = QtGui.QTableWidgetItem(unicode(fromAddress,'utf-8'))
newItem.setToolTip(unicode(fromAddress,'utf-8'))
else: else:
newItem = QtGui.QTableWidgetItem(unicode(fromLabel,'utf-8')) newItem = QtGui.QTableWidgetItem(unicode(fromLabel,'utf-8'))
newItem.setToolTip(unicode(fromLabel,'utf-8'))
newItem.setData(Qt.UserRole,str(fromAddress)) newItem.setData(Qt.UserRole,str(fromAddress))
newItem.setFlags( QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled ) newItem.setFlags( QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled )
self.ui.tableWidgetSent.setItem(0,1,newItem) self.ui.tableWidgetSent.setItem(0,1,newItem)
newItem = QtGui.QTableWidgetItem(unicode(subject,'utf-8')) newItem = QtGui.QTableWidgetItem(unicode(subject,'utf-8'))
newItem.setToolTip(unicode(subject,'utf-8'))
newItem.setData(Qt.UserRole,unicode(message,'utf-8)')) newItem.setData(Qt.UserRole,unicode(message,'utf-8)'))
newItem.setFlags( QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled ) newItem.setFlags( QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled )
self.ui.tableWidgetSent.setItem(0,2,newItem) self.ui.tableWidgetSent.setItem(0,2,newItem)
if status == 'awaitingpubkey': if status == 'awaitingpubkey':
newItem = myTableWidgetItem('Waiting on their encryption key. Will request it again soon.') statusText = 'Waiting on their encryption key. Will request it again soon.'
elif status == 'doingpowforpubkey': elif status == 'doingpowforpubkey':
newItem = myTableWidgetItem('Encryption key request queued.') statusText = 'Encryption key request queued.'
elif status == 'msgqueued': elif status == 'msgqueued':
newItem = myTableWidgetItem('Queued.') statusText = 'Queued.'
elif status == 'msgsent': elif status == 'msgsent':
newItem = myTableWidgetItem('Message sent. Waiting on acknowledgement. Sent at ' + unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'),localtime(lastactiontime)),'utf-8')) statusText = 'Message sent. Waiting on acknowledgement. Sent at ' + unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'),localtime(lastactiontime)),'utf-8')
elif status == 'doingmsgpow': elif status == 'doingmsgpow':
newItem = myTableWidgetItem('Need to do work to send message. Work is queued.') statusText = 'Need to do work to send message. Work is queued.'
elif status == 'ackreceived': elif status == 'ackreceived':
newItem = myTableWidgetItem('Acknowledgement of the message received ' + unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'),localtime(int(lastactiontime))),'utf-8')) statusText = 'Acknowledgement of the message received ' + unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'),localtime(int(lastactiontime))),'utf-8')
elif status == 'broadcastqueued': elif status == 'broadcastqueued':
newItem = myTableWidgetItem('Broadcast queued.') statusText = 'Broadcast queued.'
elif status == 'broadcastsent': elif status == 'broadcastsent':
newItem = myTableWidgetItem('Broadcast on ' + unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'),localtime(int(lastactiontime))),'utf-8')) statusText = 'Broadcast on ' + unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'),localtime(int(lastactiontime))),'utf-8')
elif status == 'toodifficult': elif status == 'toodifficult':
newItem = myTableWidgetItem('Problem: The work demanded by the recipient is more difficult than you are willing to do. ' + unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'),localtime(int(lastactiontime))),'utf-8')) statusText = 'Problem: The work demanded by the recipient is more difficult than you are willing to do. ' + unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'),localtime(int(lastactiontime))),'utf-8')
elif status == 'forcepow':
statusText = 'Forced difficulty override. Send should start soon.'
else: else:
newItem = myTableWidgetItem('Unknown status: ' + status + ' ' + unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'),localtime(int(lastactiontime))),'utf-8')) statusText = 'Unknown status: ' + status + ' ' + unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'),localtime(int(lastactiontime))),'utf-8')
newItem = myTableWidgetItem(statusText)
newItem.setToolTip(statusText)
newItem.setData(Qt.UserRole,QByteArray(ackdata)) newItem.setData(Qt.UserRole,QByteArray(ackdata))
newItem.setData(33,int(lastactiontime)) newItem.setData(33,int(lastactiontime))
newItem.setFlags( QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled ) newItem.setFlags( QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled )
self.ui.tableWidgetSent.setItem(0,3,newItem) self.ui.tableWidgetSent.setItem(0,3,newItem)
self.ui.tableWidgetSent.sortItems(3,Qt.DescendingOrder) self.ui.tableWidgetSent.sortItems(3,Qt.DescendingOrder)
self.ui.tableWidgetSent.keyPressEvent = self.tableWidgetSentKeyPressEvent
#Initialize the address book #Initialize the address book
shared.sqlLock.acquire() shared.sqlLock.acquire()
@ -766,19 +784,8 @@ class MyForm(QtGui.QMainWindow):
def click_actionDeleteAllTrashedMessages(self): def click_actionDeleteAllTrashedMessages(self):
if QtGui.QMessageBox.question(self, 'Delete trash?',"Are you sure you want to delete all trashed messages?", QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) == QtGui.QMessageBox.No: if QtGui.QMessageBox.question(self, 'Delete trash?',"Are you sure you want to delete all trashed messages?", QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) == QtGui.QMessageBox.No:
return return
self.statusBar().showMessage('Deleting messages and freeing empty space...')
shared.sqlLock.acquire() shared.sqlLock.acquire()
shared.sqlSubmitQueue.put('''delete from inbox where folder='trash' ''') shared.sqlSubmitQueue.put('deleteandvacuume')
shared.sqlSubmitQueue.put('')
shared.sqlReturnQueue.get()
shared.sqlSubmitQueue.put('''delete from sent where folder='trash' ''')
shared.sqlSubmitQueue.put('')
shared.sqlReturnQueue.get()
shared.sqlSubmitQueue.put('commit') #Commit takes no parameters and returns nothing
shared.sqlSubmitQueue.put('vacuum')
shared.sqlSubmitQueue.put('')
shared.sqlReturnQueue.get()
self.statusBar().showMessage('')
shared.sqlLock.release() shared.sqlLock.release()
def click_actionRegenerateDeterministicAddresses(self): def click_actionRegenerateDeterministicAddresses(self):
@ -928,8 +935,8 @@ class MyForm(QtGui.QMainWindow):
toAddress = str(self.ui.tableWidgetSent.item(i,0).data(Qt.UserRole).toPyObject()) toAddress = str(self.ui.tableWidgetSent.item(i,0).data(Qt.UserRole).toPyObject())
status,addressVersionNumber,streamNumber,ripe = decodeAddress(toAddress) status,addressVersionNumber,streamNumber,ripe = decodeAddress(toAddress)
if ripe == toRipe: if ripe == toRipe:
#self.ui.tableWidgetSent.item(i,3).setText(unicode(textToDisplay,'utf-8'))
self.ui.tableWidgetSent.item(i,3).setText(textToDisplay) self.ui.tableWidgetSent.item(i,3).setText(textToDisplay)
self.ui.tableWidgetSent.item(i,3).setToolTip(textToDisplay)
def updateSentItemStatusByAckdata(self,ackdata,textToDisplay): def updateSentItemStatusByAckdata(self,ackdata,textToDisplay):
for i in range(self.ui.tableWidgetSent.rowCount()): for i in range(self.ui.tableWidgetSent.rowCount()):
@ -939,6 +946,7 @@ class MyForm(QtGui.QMainWindow):
if ackdata == tableAckdata: if ackdata == tableAckdata:
#self.ui.tableWidgetSent.item(i,3).setText(unicode(textToDisplay,'utf-8')) #self.ui.tableWidgetSent.item(i,3).setText(unicode(textToDisplay,'utf-8'))
self.ui.tableWidgetSent.item(i,3).setText(textToDisplay) self.ui.tableWidgetSent.item(i,3).setText(textToDisplay)
self.ui.tableWidgetSent.item(i,3).setToolTip(textToDisplay)
def removeInboxRowByMsgid(self,msgid):#msgid and inventoryHash are the same thing def removeInboxRowByMsgid(self,msgid):#msgid and inventoryHash are the same thing
for i in range(self.ui.tableWidgetInbox.rowCount()): for i in range(self.ui.tableWidgetInbox.rowCount()):
@ -1080,7 +1088,7 @@ class MyForm(QtGui.QMainWindow):
continue continue
except: except:
pass pass
if addressVersionNumber > 3 or addressVersionNumber == 0: if addressVersionNumber > 3 or addressVersionNumber <= 1:
QMessageBox.about(self, "Address version number", "Concerning the address "+toAddress+", Bitmessage cannot understand address version numbers of "+str(addressVersionNumber)+". Perhaps upgrade Bitmessage to the latest version.") QMessageBox.about(self, "Address version number", "Concerning the address "+toAddress+", Bitmessage cannot understand address version numbers of "+str(addressVersionNumber)+". Perhaps upgrade Bitmessage to the latest version.")
continue continue
if streamNumber > 1 or streamNumber == 0: if streamNumber > 1 or streamNumber == 0:
@ -1210,6 +1218,8 @@ class MyForm(QtGui.QMainWindow):
#This function is called by the processmsg function when that function receives a message to an address that is acting as a pseudo-mailing-list. The message will be broadcast out. This function puts the message on the 'Sent' tab. #This function is called by the processmsg function when that function receives a message to an address that is acting as a pseudo-mailing-list. The message will be broadcast out. This function puts the message on the 'Sent' tab.
def displayNewSentMessage(self,toAddress,toLabel,fromAddress,subject,message,ackdata): def displayNewSentMessage(self,toAddress,toLabel,fromAddress,subject,message,ackdata):
subject = shared.fixPotentiallyInvalidUTF8Data(subject)
message = shared.fixPotentiallyInvalidUTF8Data(message)
try: try:
fromLabel = shared.config.get(fromAddress, 'label') fromLabel = shared.config.get(fromAddress, 'label')
except: except:
@ -1221,21 +1231,27 @@ class MyForm(QtGui.QMainWindow):
self.ui.tableWidgetSent.insertRow(0) self.ui.tableWidgetSent.insertRow(0)
if toLabel == '': if toLabel == '':
newItem = QtGui.QTableWidgetItem(unicode(toAddress,'utf-8')) newItem = QtGui.QTableWidgetItem(unicode(toAddress,'utf-8'))
newItem.setToolTip(unicode(toAddress,'utf-8'))
else: else:
newItem = QtGui.QTableWidgetItem(unicode(toLabel,'utf-8')) newItem = QtGui.QTableWidgetItem(unicode(toLabel,'utf-8'))
newItem.setToolTip(unicode(toLabel,'utf-8'))
newItem.setData(Qt.UserRole,str(toAddress)) newItem.setData(Qt.UserRole,str(toAddress))
self.ui.tableWidgetSent.setItem(0,0,newItem) self.ui.tableWidgetSent.setItem(0,0,newItem)
if fromLabel == '': if fromLabel == '':
newItem = QtGui.QTableWidgetItem(unicode(fromAddress,'utf-8')) newItem = QtGui.QTableWidgetItem(unicode(fromAddress,'utf-8'))
newItem.setToolTip(unicode(fromAddress,'utf-8'))
else: else:
newItem = QtGui.QTableWidgetItem(unicode(fromLabel,'utf-8')) newItem = QtGui.QTableWidgetItem(unicode(fromLabel,'utf-8'))
newItem.setToolTip(unicode(fromLabel,'utf-8'))
newItem.setData(Qt.UserRole,str(fromAddress)) newItem.setData(Qt.UserRole,str(fromAddress))
self.ui.tableWidgetSent.setItem(0,1,newItem) self.ui.tableWidgetSent.setItem(0,1,newItem)
newItem = QtGui.QTableWidgetItem(unicode(subject,'utf-8)')) newItem = QtGui.QTableWidgetItem(unicode(subject,'utf-8)'))
newItem.setToolTip(unicode(subject,'utf-8)'))
newItem.setData(Qt.UserRole,unicode(message,'utf-8)')) newItem.setData(Qt.UserRole,unicode(message,'utf-8)'))
self.ui.tableWidgetSent.setItem(0,2,newItem) self.ui.tableWidgetSent.setItem(0,2,newItem)
#newItem = QtGui.QTableWidgetItem('Doing work necessary to send broadcast...'+ unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'),localtime(int(time.time()))),'utf-8')) #newItem = QtGui.QTableWidgetItem('Doing work necessary to send broadcast...'+ unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'),localtime(int(time.time()))),'utf-8'))
newItem = myTableWidgetItem('Work is queued. '+ unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'),localtime(int(time.time()))),'utf-8')) newItem = myTableWidgetItem('Work is queued. '+ unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'),localtime(int(time.time()))),'utf-8'))
newItem.setToolTip('Work is queued. '+ unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'),localtime(int(time.time()))),'utf-8'))
newItem.setData(Qt.UserRole,QByteArray(ackdata)) newItem.setData(Qt.UserRole,QByteArray(ackdata))
newItem.setData(33,int(time.time())) newItem.setData(33,int(time.time()))
self.ui.tableWidgetSent.setItem(0,3,newItem) self.ui.tableWidgetSent.setItem(0,3,newItem)
@ -1243,6 +1259,8 @@ class MyForm(QtGui.QMainWindow):
self.ui.tableWidgetSent.setSortingEnabled(True) self.ui.tableWidgetSent.setSortingEnabled(True)
def displayNewInboxMessage(self,inventoryHash,toAddress,fromAddress,subject,message): def displayNewInboxMessage(self,inventoryHash,toAddress,fromAddress,subject,message):
subject = shared.fixPotentiallyInvalidUTF8Data(subject)
message = shared.fixPotentiallyInvalidUTF8Data(message)
fromLabel = '' fromLabel = ''
shared.sqlLock.acquire() shared.sqlLock.acquire()
t = (fromAddress,) t = (fromAddress,)
@ -1279,6 +1297,7 @@ class MyForm(QtGui.QMainWindow):
font.setBold(True) font.setBold(True)
self.ui.tableWidgetInbox.setSortingEnabled(False) self.ui.tableWidgetInbox.setSortingEnabled(False)
newItem = QtGui.QTableWidgetItem(unicode(toLabel,'utf-8')) newItem = QtGui.QTableWidgetItem(unicode(toLabel,'utf-8'))
newItem.setToolTip(unicode(toLabel,'utf-8'))
newItem.setFont(font) newItem.setFont(font)
newItem.setData(Qt.UserRole,str(toAddress)) newItem.setData(Qt.UserRole,str(toAddress))
if shared.safeConfigGetBoolean(str(toAddress),'mailinglist'): if shared.safeConfigGetBoolean(str(toAddress),'mailinglist'):
@ -1288,20 +1307,24 @@ class MyForm(QtGui.QMainWindow):
if fromLabel == '': if fromLabel == '':
newItem = QtGui.QTableWidgetItem(unicode(fromAddress,'utf-8')) newItem = QtGui.QTableWidgetItem(unicode(fromAddress,'utf-8'))
newItem.setToolTip(unicode(fromAddress,'utf-8'))
if shared.config.getboolean('bitmessagesettings', 'showtraynotifications'): if shared.config.getboolean('bitmessagesettings', 'showtraynotifications'):
self.notifierShow('New Message', 'From '+ fromAddress) self.notifierShow('New Message', 'From '+ fromAddress)
else: else:
newItem = QtGui.QTableWidgetItem(unicode(fromLabel,'utf-8')) newItem = QtGui.QTableWidgetItem(unicode(fromLabel,'utf-8'))
newItem.setToolTip(unicode(unicode(fromLabel,'utf-8')))
if shared.config.getboolean('bitmessagesettings', 'showtraynotifications'): if shared.config.getboolean('bitmessagesettings', 'showtraynotifications'):
self.notifierShow('New Message', 'From ' + fromLabel) self.notifierShow('New Message', 'From ' + fromLabel)
newItem.setData(Qt.UserRole,str(fromAddress)) newItem.setData(Qt.UserRole,str(fromAddress))
newItem.setFont(font) newItem.setFont(font)
self.ui.tableWidgetInbox.setItem(0,1,newItem) self.ui.tableWidgetInbox.setItem(0,1,newItem)
newItem = QtGui.QTableWidgetItem(unicode(subject,'utf-8)')) newItem = QtGui.QTableWidgetItem(unicode(subject,'utf-8)'))
newItem.setToolTip(unicode(subject,'utf-8)'))
newItem.setData(Qt.UserRole,unicode(message,'utf-8)')) newItem.setData(Qt.UserRole,unicode(message,'utf-8)'))
newItem.setFont(font) newItem.setFont(font)
self.ui.tableWidgetInbox.setItem(0,2,newItem) self.ui.tableWidgetInbox.setItem(0,2,newItem)
newItem = myTableWidgetItem(unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'),localtime(int(time.time()))),'utf-8')) newItem = myTableWidgetItem(unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'),localtime(int(time.time()))),'utf-8'))
newItem.setToolTip(unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'),localtime(int(time.time()))),'utf-8'))
newItem.setData(Qt.UserRole,QByteArray(inventoryHash)) newItem.setData(Qt.UserRole,QByteArray(inventoryHash))
newItem.setData(33,int(time.time())) newItem.setData(33,int(time.time()))
newItem.setFont(font) newItem.setFont(font)
@ -1441,6 +1464,11 @@ class MyForm(QtGui.QMainWindow):
shared.config.set('bitmessagesettings', 'defaultnoncetrialsperbyte',str(int(float(self.settingsDialogInstance.ui.lineEditTotalDifficulty.text())*shared.networkDefaultProofOfWorkNonceTrialsPerByte))) shared.config.set('bitmessagesettings', 'defaultnoncetrialsperbyte',str(int(float(self.settingsDialogInstance.ui.lineEditTotalDifficulty.text())*shared.networkDefaultProofOfWorkNonceTrialsPerByte)))
if float(self.settingsDialogInstance.ui.lineEditSmallMessageDifficulty.text()) >= 1: if float(self.settingsDialogInstance.ui.lineEditSmallMessageDifficulty.text()) >= 1:
shared.config.set('bitmessagesettings', 'defaultpayloadlengthextrabytes',str(int(float(self.settingsDialogInstance.ui.lineEditSmallMessageDifficulty.text())*shared.networkDefaultPayloadLengthExtraBytes))) shared.config.set('bitmessagesettings', 'defaultpayloadlengthextrabytes',str(int(float(self.settingsDialogInstance.ui.lineEditSmallMessageDifficulty.text())*shared.networkDefaultPayloadLengthExtraBytes)))
if float(self.settingsDialogInstance.ui.lineEditMaxAcceptableTotalDifficulty.text()) >= 1 or float(self.settingsDialogInstance.ui.lineEditMaxAcceptableTotalDifficulty.text()) == 0:
shared.config.set('bitmessagesettings', 'maxacceptablenoncetrialsperbyte',str(int(float(self.settingsDialogInstance.ui.lineEditMaxAcceptableTotalDifficulty.text())*shared.networkDefaultProofOfWorkNonceTrialsPerByte)))
if float(self.settingsDialogInstance.ui.lineEditMaxAcceptableSmallMessageDifficulty.text()) >= 1 or float(self.settingsDialogInstance.ui.lineEditMaxAcceptableSmallMessageDifficulty.text()) == 0:
shared.config.set('bitmessagesettings', 'maxacceptablepayloadlengthextrabytes',str(int(float(self.settingsDialogInstance.ui.lineEditMaxAcceptableSmallMessageDifficulty.text())*shared.networkDefaultPayloadLengthExtraBytes)))
#if str(self.settingsDialogInstance.ui.comboBoxMaxCores.currentText()) == 'All': #if str(self.settingsDialogInstance.ui.comboBoxMaxCores.currentText()) == 'All':
# shared.config.set('bitmessagesettings', 'maxcores', '99999') # shared.config.set('bitmessagesettings', 'maxcores', '99999')
#else: #else:
@ -1766,6 +1794,25 @@ class MyForm(QtGui.QMainWindow):
else: else:
self.ui.tableWidgetSent.selectRow(currentRow-1) self.ui.tableWidgetSent.selectRow(currentRow-1)
def on_action_ForceSend(self):
currentRow = self.ui.tableWidgetSent.currentRow()
addressAtCurrentRow = str(self.ui.tableWidgetSent.item(currentRow,0).data(Qt.UserRole).toPyObject())
toRipe = decodeAddress(addressAtCurrentRow)[3]
t = (toRipe,)
shared.sqlLock.acquire()
shared.sqlSubmitQueue.put('''UPDATE sent SET status='forcepow' WHERE toripe=? AND status='toodifficult' and folder='sent' ''')
shared.sqlSubmitQueue.put(t)
shared.sqlReturnQueue.get()
shared.sqlSubmitQueue.put('commit')
shared.sqlSubmitQueue.put('''select ackdata FROM sent WHERE status='forcepow' ''')
shared.sqlSubmitQueue.put('')
queryreturn = shared.sqlReturnQueue.get()
shared.sqlLock.release()
for row in queryreturn:
ackdata, = row
shared.UISignalQueue.put(('updateSentItemStatusByAckdata',(ackdata,'Overriding maximum-difficulty setting. Work queued.')))
shared.workerQueue.put(('sendmessage',''))
def on_action_SentClipboard(self): def on_action_SentClipboard(self):
currentRow = self.ui.tableWidgetSent.currentRow() currentRow = self.ui.tableWidgetSent.currentRow()
addressAtCurrentRow = str(self.ui.tableWidgetSent.item(currentRow,0).data(Qt.UserRole).toPyObject()) addressAtCurrentRow = str(self.ui.tableWidgetSent.item(currentRow,0).data(Qt.UserRole).toPyObject())
@ -1975,6 +2022,22 @@ class MyForm(QtGui.QMainWindow):
def on_context_menuInbox(self, point): def on_context_menuInbox(self, point):
self.popMenuInbox.exec_( self.ui.tableWidgetInbox.mapToGlobal(point) ) self.popMenuInbox.exec_( self.ui.tableWidgetInbox.mapToGlobal(point) )
def on_context_menuSent(self, point): def on_context_menuSent(self, point):
self.popMenuSent = QtGui.QMenu( self )
self.popMenuSent.addAction( self.actionSentClipboard )
self.popMenuSent.addAction( self.actionTrashSentMessage )
#Check to see if this item is toodifficult and display an additional menu option (Force Send) if it is.
currentRow = self.ui.tableWidgetSent.currentRow()
ackData = str(self.ui.tableWidgetSent.item(currentRow,3).data(Qt.UserRole).toPyObject())
shared.sqlLock.acquire()
shared.sqlSubmitQueue.put('''SELECT status FROM sent where ackdata=?''')
shared.sqlSubmitQueue.put((ackData,))
queryreturn = shared.sqlReturnQueue.get()
shared.sqlLock.release()
for row in queryreturn:
status, = row
if status == 'toodifficult':
self.popMenuSent.addAction( self.actionForceSend )
self.popMenuSent.exec_( self.ui.tableWidgetSent.mapToGlobal(point) ) self.popMenuSent.exec_( self.ui.tableWidgetSent.mapToGlobal(point) )
def tableWidgetInboxItemClicked(self): def tableWidgetInboxItemClicked(self):
@ -2152,6 +2215,10 @@ class settingsDialog(QtGui.QDialog):
self.ui.lineEditTotalDifficulty.setText(str((float(shared.config.getint('bitmessagesettings', 'defaultnoncetrialsperbyte'))/shared.networkDefaultProofOfWorkNonceTrialsPerByte))) self.ui.lineEditTotalDifficulty.setText(str((float(shared.config.getint('bitmessagesettings', 'defaultnoncetrialsperbyte'))/shared.networkDefaultProofOfWorkNonceTrialsPerByte)))
self.ui.lineEditSmallMessageDifficulty.setText(str((float(shared.config.getint('bitmessagesettings', 'defaultpayloadlengthextrabytes'))/shared.networkDefaultPayloadLengthExtraBytes))) self.ui.lineEditSmallMessageDifficulty.setText(str((float(shared.config.getint('bitmessagesettings', 'defaultpayloadlengthextrabytes'))/shared.networkDefaultPayloadLengthExtraBytes)))
#Max acceptable difficulty tab
self.ui.lineEditMaxAcceptableTotalDifficulty.setText(str((float(shared.config.getint('bitmessagesettings', 'maxacceptablenoncetrialsperbyte'))/shared.networkDefaultProofOfWorkNonceTrialsPerByte)))
self.ui.lineEditMaxAcceptableSmallMessageDifficulty.setText(str((float(shared.config.getint('bitmessagesettings', 'maxacceptablepayloadlengthextrabytes'))/shared.networkDefaultPayloadLengthExtraBytes)))
#'System' tab removed for now. #'System' tab removed for now.
"""try: """try:
maxCores = shared.config.getint('bitmessagesettings', 'maxcores') maxCores = shared.config.getint('bitmessagesettings', 'maxcores')

View File

@ -2,8 +2,8 @@
# Form implementation generated from reading ui file 'settings.ui' # Form implementation generated from reading ui file 'settings.ui'
# #
# Created: Mon Jun 03 23:09:01 2013 # Created: Mon Jun 10 11:31:56 2013
# by: PyQt4 UI code generator 4.9.5 # by: PyQt4 UI code generator 4.9.4
# #
# WARNING! All changes made in this file will be lost! # WARNING! All changes made in this file will be lost!
@ -74,6 +74,7 @@ class Ui_settingsDialog(object):
self.label.setObjectName(_fromUtf8("label")) self.label.setObjectName(_fromUtf8("label"))
self.gridLayout_3.addWidget(self.label, 0, 1, 1, 1) self.gridLayout_3.addWidget(self.label, 0, 1, 1, 1)
self.lineEditTCPPort = QtGui.QLineEdit(self.groupBox) self.lineEditTCPPort = QtGui.QLineEdit(self.groupBox)
self.lineEditTCPPort.setMaximumSize(QtCore.QSize(70, 16777215))
self.lineEditTCPPort.setObjectName(_fromUtf8("lineEditTCPPort")) self.lineEditTCPPort.setObjectName(_fromUtf8("lineEditTCPPort"))
self.gridLayout_3.addWidget(self.lineEditTCPPort, 0, 2, 1, 1) self.gridLayout_3.addWidget(self.lineEditTCPPort, 0, 2, 1, 1)
self.gridLayout_4.addWidget(self.groupBox, 0, 0, 1, 1) self.gridLayout_4.addWidget(self.groupBox, 0, 0, 1, 1)
@ -172,6 +173,48 @@ class Ui_settingsDialog(object):
self.label_10.setObjectName(_fromUtf8("label_10")) self.label_10.setObjectName(_fromUtf8("label_10"))
self.gridLayout_6.addWidget(self.label_10, 2, 0, 1, 3) self.gridLayout_6.addWidget(self.label_10, 2, 0, 1, 3)
self.tabWidgetSettings.addTab(self.tab, _fromUtf8("")) self.tabWidgetSettings.addTab(self.tab, _fromUtf8(""))
self.tab_2 = QtGui.QWidget()
self.tab_2.setObjectName(_fromUtf8("tab_2"))
self.gridLayout_7 = QtGui.QGridLayout(self.tab_2)
self.gridLayout_7.setObjectName(_fromUtf8("gridLayout_7"))
self.label_15 = QtGui.QLabel(self.tab_2)
self.label_15.setWordWrap(True)
self.label_15.setObjectName(_fromUtf8("label_15"))
self.gridLayout_7.addWidget(self.label_15, 0, 0, 1, 3)
spacerItem5 = QtGui.QSpacerItem(102, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
self.gridLayout_7.addItem(spacerItem5, 1, 0, 1, 1)
self.label_13 = QtGui.QLabel(self.tab_2)
self.label_13.setLayoutDirection(QtCore.Qt.LeftToRight)
self.label_13.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.label_13.setObjectName(_fromUtf8("label_13"))
self.gridLayout_7.addWidget(self.label_13, 1, 1, 1, 1)
self.lineEditMaxAcceptableTotalDifficulty = QtGui.QLineEdit(self.tab_2)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.lineEditMaxAcceptableTotalDifficulty.sizePolicy().hasHeightForWidth())
self.lineEditMaxAcceptableTotalDifficulty.setSizePolicy(sizePolicy)
self.lineEditMaxAcceptableTotalDifficulty.setMaximumSize(QtCore.QSize(70, 16777215))
self.lineEditMaxAcceptableTotalDifficulty.setObjectName(_fromUtf8("lineEditMaxAcceptableTotalDifficulty"))
self.gridLayout_7.addWidget(self.lineEditMaxAcceptableTotalDifficulty, 1, 2, 1, 1)
spacerItem6 = QtGui.QSpacerItem(102, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
self.gridLayout_7.addItem(spacerItem6, 2, 0, 1, 1)
self.label_14 = QtGui.QLabel(self.tab_2)
self.label_14.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.label_14.setObjectName(_fromUtf8("label_14"))
self.gridLayout_7.addWidget(self.label_14, 2, 1, 1, 1)
self.lineEditMaxAcceptableSmallMessageDifficulty = QtGui.QLineEdit(self.tab_2)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.lineEditMaxAcceptableSmallMessageDifficulty.sizePolicy().hasHeightForWidth())
self.lineEditMaxAcceptableSmallMessageDifficulty.setSizePolicy(sizePolicy)
self.lineEditMaxAcceptableSmallMessageDifficulty.setMaximumSize(QtCore.QSize(70, 16777215))
self.lineEditMaxAcceptableSmallMessageDifficulty.setObjectName(_fromUtf8("lineEditMaxAcceptableSmallMessageDifficulty"))
self.gridLayout_7.addWidget(self.lineEditMaxAcceptableSmallMessageDifficulty, 2, 2, 1, 1)
spacerItem7 = QtGui.QSpacerItem(20, 147, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
self.gridLayout_7.addItem(spacerItem7, 3, 1, 1, 1)
self.tabWidgetSettings.addTab(self.tab_2, _fromUtf8(""))
self.gridLayout.addWidget(self.tabWidgetSettings, 0, 0, 1, 1) self.gridLayout.addWidget(self.tabWidgetSettings, 0, 0, 1, 1)
self.retranslateUi(settingsDialog) self.retranslateUi(settingsDialog)
@ -222,4 +265,8 @@ class Ui_settingsDialog(object):
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_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.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.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))

View File

@ -142,7 +142,14 @@
</widget> </widget>
</item> </item>
<item row="0" column="2"> <item row="0" column="2">
<widget class="QLineEdit" name="lineEditTCPPort"/> <widget class="QLineEdit" name="lineEditTCPPort">
<property name="maximumSize">
<size>
<width>70</width>
<height>16777215</height>
</size>
</property>
</widget>
</item> </item>
</layout> </layout>
</widget> </widget>
@ -373,6 +380,117 @@
</item> </item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="tab_2">
<attribute name="title">
<string>Max acceptable difficulty</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_7">
<item row="0" column="0" colspan="3">
<widget class="QLabel" name="label_15">
<property name="text">
<string>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.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>102</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="1">
<widget class="QLabel" name="label_13">
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<property name="text">
<string>Maximum acceptable total difficulty:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLineEdit" name="lineEditMaxAcceptableTotalDifficulty">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>70</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
<item row="2" column="0">
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>102</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="1">
<widget class="QLabel" name="label_14">
<property name="text">
<string>Maximum acceptable small message difficulty:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QLineEdit" name="lineEditMaxAcceptableSmallMessageDifficulty">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>70</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
<item row="3" column="1">
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>147</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget> </widget>
</item> </item>
</layout> </layout>

View File

@ -202,4 +202,12 @@ def flushInventory():
sqlReturnQueue.get() sqlReturnQueue.get()
del inventory[hash] del inventory[hash]
sqlSubmitQueue.put('commit') sqlSubmitQueue.put('commit')
sqlLock.release() sqlLock.release()
def fixPotentiallyInvalidUTF8Data(text):
try:
unicode(text,'utf-8')
return text
except:
output = 'Part of the message is corrupt. The message cannot be displayed the normal way.\n\n' + repr(text)
return output