Refactored the code in api.py by extracting the handler code for each request to separate methods

This should result in code that is easier to understand, modify and maintain
This commit is contained in:
Timothy 2015-03-21 19:53:09 +08:00
parent 08f2c3bfc0
commit 2dfce7f5e7

View File

@ -149,17 +149,10 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
return (status, addressVersionNumber, streamNumber, ripe) return (status, addressVersionNumber, streamNumber, ripe)
def _handle_request(self, method, params):
if method == 'helloWorld': #Request Handlers
(a, b) = params
return a + '-' + b def HandleListAddresses(self, method):
elif method == 'add':
(a, b) = params
return a + b
elif method == 'statusBar':
message, = params
shared.UISignalQueue.put(('updateStatusBar', message))
elif method == 'listAddresses' or method == 'listAddresses2':
data = '{"addresses":[' data = '{"addresses":['
configSections = shared.config.sections() configSections = shared.config.sections()
for addressInKeysFile in configSections: for addressInKeysFile in configSections:
@ -179,7 +172,8 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
streamNumber, 'enabled': shared.config.getboolean(addressInKeysFile, 'enabled'), 'chan': chan}, indent=4, separators=(',', ': ')) streamNumber, 'enabled': shared.config.getboolean(addressInKeysFile, 'enabled'), 'chan': chan}, indent=4, separators=(',', ': '))
data += ']}' data += ']}'
return data return data
elif method == 'listAddressBookEntries' or method == 'listAddressbook': # the listAddressbook alias should be removed eventually.
def HandleListAddressBookEntries(self, params):
queryreturn = sqlQuery('''SELECT label, address from addressbook''') queryreturn = sqlQuery('''SELECT label, address from addressbook''')
data = '{"addresses":[' data = '{"addresses":['
for row in queryreturn: for row in queryreturn:
@ -190,7 +184,8 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
data += json.dumps({'label':label.encode('base64'), 'address': address}, indent=4, separators=(',', ': ')) data += json.dumps({'label':label.encode('base64'), 'address': address}, indent=4, separators=(',', ': '))
data += ']}' data += ']}'
return data return data
elif method == 'addAddressBookEntry' or method == 'addAddressbook': # the addAddressbook alias should be deleted eventually.
def HandleAddAddressBookEntry(self, params):
if len(params) != 2: if len(params) != 2:
raise APIError(0, "I need label and address") raise APIError(0, "I need label and address")
address, label = params address, label = params
@ -206,7 +201,8 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
shared.UISignalQueue.put(('rerenderSentToLabels','')) shared.UISignalQueue.put(('rerenderSentToLabels',''))
shared.UISignalQueue.put(('rerenderAddressBook','')) shared.UISignalQueue.put(('rerenderAddressBook',''))
return "Added address %s to address book" % address return "Added address %s to address book" % address
elif method == 'deleteAddressBookEntry' or method == 'deleteAddressbook': # The deleteAddressbook alias should be deleted eventually.
def HandleDeleteAddressBookEntry(self, params):
if len(params) != 1: if len(params) != 1:
raise APIError(0, "I need an address") raise APIError(0, "I need an address")
address, = params address, = params
@ -217,7 +213,8 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
shared.UISignalQueue.put(('rerenderSentToLabels','')) shared.UISignalQueue.put(('rerenderSentToLabels',''))
shared.UISignalQueue.put(('rerenderAddressBook','')) shared.UISignalQueue.put(('rerenderAddressBook',''))
return "Deleted address book entry for %s if it existed" % address return "Deleted address book entry for %s if it existed" % address
elif method == 'createRandomAddress':
def HandleCreateRandomAddress(self, params):
if len(params) == 0: if len(params) == 0:
raise APIError(0, 'I need parameters!') raise APIError(0, 'I need parameters!')
elif len(params) == 1: elif len(params) == 1:
@ -257,7 +254,8 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
shared.addressGeneratorQueue.put(( shared.addressGeneratorQueue.put((
'createRandomAddress', 4, streamNumberForAddress, label, 1, "", eighteenByteRipe, nonceTrialsPerByte, payloadLengthExtraBytes)) 'createRandomAddress', 4, streamNumberForAddress, label, 1, "", eighteenByteRipe, nonceTrialsPerByte, payloadLengthExtraBytes))
return shared.apiAddressGeneratorReturnQueue.get() return shared.apiAddressGeneratorReturnQueue.get()
elif method == 'createDeterministicAddresses':
def HandleCreateDeterministicAddresses(self, params):
if len(params) == 0: if len(params) == 0:
raise APIError(0, 'I need parameters!') raise APIError(0, 'I need parameters!')
elif len(params) == 1: elif len(params) == 1:
@ -344,7 +342,8 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
data += "\"" + item + "\"" data += "\"" + item + "\""
data += ']}' data += ']}'
return data return data
elif method == 'getDeterministicAddress':
def HandleGetDeterministicAddress(self, params):
if len(params) != 3: if len(params) != 3:
raise APIError(0, 'I need exactly 3 parameters.') raise APIError(0, 'I need exactly 3 parameters.')
passphrase, addressVersionNumber, streamNumber = params passphrase, addressVersionNumber, streamNumber = params
@ -364,7 +363,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
streamNumber, 'unused API address', numberOfAddresses, passphrase, eighteenByteRipe)) streamNumber, 'unused API address', numberOfAddresses, passphrase, eighteenByteRipe))
return shared.apiAddressGeneratorReturnQueue.get() return shared.apiAddressGeneratorReturnQueue.get()
elif method == 'createChan': def HandleCreateChan(self, params):
if len(params) == 0: if len(params) == 0:
raise APIError(0, 'I need parameters.') raise APIError(0, 'I need parameters.')
elif len(params) == 1: elif len(params) == 1:
@ -390,7 +389,8 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
raise APIError(24, 'Chan address is already present.') raise APIError(24, 'Chan address is already present.')
address = queueReturn[0] address = queueReturn[0]
return address return address
elif method == 'joinChan':
def HandleJoinChan(self, params):
if len(params) < 2: if len(params) < 2:
raise APIError(0, 'I need two parameters.') raise APIError(0, 'I need two parameters.')
elif len(params) == 2: elif len(params) == 2:
@ -419,7 +419,8 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
#TODO: this variable is not used to anything #TODO: this variable is not used to anything
createdAddress = addressGeneratorReturnValue[0] # in case we ever want it for anything. createdAddress = addressGeneratorReturnValue[0] # in case we ever want it for anything.
return "success" return "success"
elif method == 'leaveChan':
def HandleLeaveChan(self, params):
if len(params) == 0: if len(params) == 0:
raise APIError(0, 'I need parameters.') raise APIError(0, 'I need parameters.')
elif len(params) == 1: elif len(params) == 1:
@ -431,10 +432,11 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
if not shared.safeConfigGetBoolean(address, 'chan'): if not shared.safeConfigGetBoolean(address, 'chan'):
raise APIError(25, 'Specified address is not a chan address. Use deleteAddress API call instead.') raise APIError(25, 'Specified address is not a chan address. Use deleteAddress API call instead.')
shared.config.remove_section(address) shared.config.remove_section(address)
shared.writeKeysFile() with open(shared.appdata + 'keys.dat', 'wb') as configfile:
shared.config.write(configfile)
return 'success' return 'success'
elif method == 'deleteAddress': def HandleDeleteAddress(self, params):
if len(params) == 0: if len(params) == 0:
raise APIError(0, 'I need parameters.') raise APIError(0, 'I need parameters.')
elif len(params) == 1: elif len(params) == 1:
@ -444,13 +446,14 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
if not shared.config.has_section(address): if not shared.config.has_section(address):
raise APIError(13, 'Could not find this address in your keys.dat file.') raise APIError(13, 'Could not find this address in your keys.dat file.')
shared.config.remove_section(address) shared.config.remove_section(address)
shared.writeKeysFile() with open(shared.appdata + 'keys.dat', 'wb') as configfile:
shared.config.write(configfile)
shared.UISignalQueue.put(('rerenderInboxFromLabels','')) shared.UISignalQueue.put(('rerenderInboxFromLabels',''))
shared.UISignalQueue.put(('rerenderSentToLabels','')) shared.UISignalQueue.put(('rerenderSentToLabels',''))
shared.reloadMyAddressHashes() shared.reloadMyAddressHashes()
return 'success' return 'success'
elif method == 'getAllInboxMessages': def HandleGetAllInboxMessages(self, params):
queryreturn = sqlQuery( queryreturn = sqlQuery(
'''SELECT msgid, toaddress, fromaddress, subject, received, message, encodingtype, read FROM inbox where folder='inbox' ORDER BY received''') '''SELECT msgid, toaddress, fromaddress, subject, received, message, encodingtype, read FROM inbox where folder='inbox' ORDER BY received''')
data = '{"inboxMessages":[' data = '{"inboxMessages":['
@ -464,7 +467,8 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
'base64'), 'message': message.encode('base64'), 'encodingType': encodingtype, 'receivedTime': received, 'read': read}, indent=4, separators=(',', ': ')) 'base64'), 'message': message.encode('base64'), 'encodingType': encodingtype, 'receivedTime': received, 'read': read}, indent=4, separators=(',', ': '))
data += ']}' data += ']}'
return data return data
elif method == 'getAllInboxMessageIds' or method == 'getAllInboxMessageIDs':
def HandleGetAllInboxMessageIds(self, params):
queryreturn = sqlQuery( queryreturn = sqlQuery(
'''SELECT msgid FROM inbox where folder='inbox' ORDER BY received''') '''SELECT msgid FROM inbox where folder='inbox' ORDER BY received''')
data = '{"inboxMessageIds":[' data = '{"inboxMessageIds":['
@ -475,7 +479,8 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
data += json.dumps({'msgid': msgid.encode('hex')}, indent=4, separators=(',', ': ')) data += json.dumps({'msgid': msgid.encode('hex')}, indent=4, separators=(',', ': '))
data += ']}' data += ']}'
return data return data
elif method == 'getInboxMessageById' or method == 'getInboxMessageByID':
def HandleGetInboxMessageById(self, params):
if len(params) == 0: if len(params) == 0:
raise APIError(0, 'I need parameters!') raise APIError(0, 'I need parameters!')
elif len(params) == 1: elif len(params) == 1:
@ -499,7 +504,8 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
data += json.dumps({'msgid':msgid.encode('hex'), 'toAddress':toAddress, 'fromAddress':fromAddress, 'subject':subject.encode('base64'), 'message':message.encode('base64'), 'encodingType':encodingtype, 'receivedTime':received, 'read': read}, indent=4, separators=(',', ': ')) data += json.dumps({'msgid':msgid.encode('hex'), 'toAddress':toAddress, 'fromAddress':fromAddress, 'subject':subject.encode('base64'), 'message':message.encode('base64'), 'encodingType':encodingtype, 'receivedTime':received, 'read': read}, indent=4, separators=(',', ': '))
data += ']}' data += ']}'
return data return data
elif method == 'getAllSentMessages':
def HandleGetAllSentMessages(self, params):
queryreturn = sqlQuery('''SELECT msgid, toaddress, fromaddress, subject, lastactiontime, message, encodingtype, status, ackdata FROM sent where folder='sent' ORDER BY lastactiontime''') queryreturn = sqlQuery('''SELECT msgid, toaddress, fromaddress, subject, lastactiontime, message, encodingtype, status, ackdata FROM sent where folder='sent' ORDER BY lastactiontime''')
data = '{"sentMessages":[' data = '{"sentMessages":['
for row in queryreturn: for row in queryreturn:
@ -511,7 +517,8 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
data += json.dumps({'msgid':msgid.encode('hex'), 'toAddress':toAddress, 'fromAddress':fromAddress, 'subject':subject.encode('base64'), 'message':message.encode('base64'), 'encodingType':encodingtype, 'lastActionTime':lastactiontime, 'status':status, 'ackData':ackdata.encode('hex')}, indent=4, separators=(',', ': ')) data += json.dumps({'msgid':msgid.encode('hex'), 'toAddress':toAddress, 'fromAddress':fromAddress, 'subject':subject.encode('base64'), 'message':message.encode('base64'), 'encodingType':encodingtype, 'lastActionTime':lastactiontime, 'status':status, 'ackData':ackdata.encode('hex')}, indent=4, separators=(',', ': '))
data += ']}' data += ']}'
return data return data
elif method == 'getAllSentMessageIds' or method == 'getAllSentMessageIDs':
def HandleGetAllSentMessageIds(self, params):
queryreturn = sqlQuery('''SELECT msgid FROM sent where folder='sent' ORDER BY lastactiontime''') queryreturn = sqlQuery('''SELECT msgid FROM sent where folder='sent' ORDER BY lastactiontime''')
data = '{"sentMessageIds":[' data = '{"sentMessageIds":['
for row in queryreturn: for row in queryreturn:
@ -521,7 +528,8 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
data += json.dumps({'msgid':msgid.encode('hex')}, indent=4, separators=(',', ': ')) data += json.dumps({'msgid':msgid.encode('hex')}, indent=4, separators=(',', ': '))
data += ']}' data += ']}'
return data return data
elif method == 'getInboxMessagesByReceiver' or method == 'getInboxMessagesByAddress': #after some time getInboxMessagesByAddress should be removed
def HandleInboxMessagesByReceiver(self, params):
if len(params) == 0: if len(params) == 0:
raise APIError(0, 'I need parameters!') raise APIError(0, 'I need parameters!')
toAddress = params[0] toAddress = params[0]
@ -536,7 +544,8 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
data += json.dumps({'msgid':msgid.encode('hex'), 'toAddress':toAddress, 'fromAddress':fromAddress, 'subject':subject.encode('base64'), 'message':message.encode('base64'), 'encodingType':encodingtype, 'receivedTime':received}, indent=4, separators=(',', ': ')) data += json.dumps({'msgid':msgid.encode('hex'), 'toAddress':toAddress, 'fromAddress':fromAddress, 'subject':subject.encode('base64'), 'message':message.encode('base64'), 'encodingType':encodingtype, 'receivedTime':received}, indent=4, separators=(',', ': '))
data += ']}' data += ']}'
return data return data
elif method == 'getSentMessageById' or method == 'getSentMessageByID':
def HandleGetSentMessageById(self, params):
if len(params) == 0: if len(params) == 0:
raise APIError(0, 'I need parameters!') raise APIError(0, 'I need parameters!')
msgid = self._decode(params[0], "hex") msgid = self._decode(params[0], "hex")
@ -549,7 +558,8 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
data += json.dumps({'msgid':msgid.encode('hex'), 'toAddress':toAddress, 'fromAddress':fromAddress, 'subject':subject.encode('base64'), 'message':message.encode('base64'), 'encodingType':encodingtype, 'lastActionTime':lastactiontime, 'status':status, 'ackData':ackdata.encode('hex')}, indent=4, separators=(',', ': ')) data += json.dumps({'msgid':msgid.encode('hex'), 'toAddress':toAddress, 'fromAddress':fromAddress, 'subject':subject.encode('base64'), 'message':message.encode('base64'), 'encodingType':encodingtype, 'lastActionTime':lastactiontime, 'status':status, 'ackData':ackdata.encode('hex')}, indent=4, separators=(',', ': '))
data += ']}' data += ']}'
return data return data
elif method == 'getSentMessagesByAddress' or method == 'getSentMessagesBySender':
def HandleGetSentMessagesByAddress(self, params):
if len(params) == 0: if len(params) == 0:
raise APIError(0, 'I need parameters!') raise APIError(0, 'I need parameters!')
fromAddress = params[0] fromAddress = params[0]
@ -565,7 +575,8 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
data += json.dumps({'msgid':msgid.encode('hex'), 'toAddress':toAddress, 'fromAddress':fromAddress, 'subject':subject.encode('base64'), 'message':message.encode('base64'), 'encodingType':encodingtype, 'lastActionTime':lastactiontime, 'status':status, 'ackData':ackdata.encode('hex')}, indent=4, separators=(',', ': ')) data += json.dumps({'msgid':msgid.encode('hex'), 'toAddress':toAddress, 'fromAddress':fromAddress, 'subject':subject.encode('base64'), 'message':message.encode('base64'), 'encodingType':encodingtype, 'lastActionTime':lastactiontime, 'status':status, 'ackData':ackdata.encode('hex')}, indent=4, separators=(',', ': '))
data += ']}' data += ']}'
return data return data
elif method == 'getSentMessageByAckData':
def HandleGetSentMessagesByAckData(self, params):
if len(params) == 0: if len(params) == 0:
raise APIError(0, 'I need parameters!') raise APIError(0, 'I need parameters!')
ackData = self._decode(params[0], "hex") ackData = self._decode(params[0], "hex")
@ -579,7 +590,8 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
data += json.dumps({'msgid':msgid.encode('hex'), 'toAddress':toAddress, 'fromAddress':fromAddress, 'subject':subject.encode('base64'), 'message':message.encode('base64'), 'encodingType':encodingtype, 'lastActionTime':lastactiontime, 'status':status, 'ackData':ackdata.encode('hex')}, indent=4, separators=(',', ': ')) data += json.dumps({'msgid':msgid.encode('hex'), 'toAddress':toAddress, 'fromAddress':fromAddress, 'subject':subject.encode('base64'), 'message':message.encode('base64'), 'encodingType':encodingtype, 'lastActionTime':lastactiontime, 'status':status, 'ackData':ackdata.encode('hex')}, indent=4, separators=(',', ': '))
data += ']}' data += ']}'
return data return data
elif method == 'trashMessage':
def HandleTrashMessage(self, params):
if len(params) == 0: if len(params) == 0:
raise APIError(0, 'I need parameters!') raise APIError(0, 'I need parameters!')
msgid = self._decode(params[0], "hex") msgid = self._decode(params[0], "hex")
@ -589,48 +601,35 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
# Trash if in sent table # Trash if in sent table
sqlExecute('''UPDATE sent SET folder='trash' WHERE msgid=?''', msgid) sqlExecute('''UPDATE sent SET folder='trash' WHERE msgid=?''', msgid)
return 'Trashed message (assuming message existed).' return 'Trashed message (assuming message existed).'
elif method == 'trashInboxMessage':
def HandleTrashInboxMessage(self, params):
if len(params) == 0: if len(params) == 0:
raise APIError(0, 'I need parameters!') raise APIError(0, 'I need parameters!')
msgid = self._decode(params[0], "hex") msgid = self._decode(params[0], "hex")
helper_inbox.trash(msgid) helper_inbox.trash(msgid)
return 'Trashed inbox message (assuming message existed).' return 'Trashed inbox message (assuming message existed).'
elif method == 'trashSentMessage':
def HandleTrashSentMessage(self, params):
if len(params) == 0: if len(params) == 0:
raise APIError(0, 'I need parameters!') raise APIError(0, 'I need parameters!')
msgid = self._decode(params[0], "hex") msgid = self._decode(params[0], "hex")
sqlExecute('''UPDATE sent SET folder='trash' WHERE msgid=?''', msgid) sqlExecute('''UPDATE sent SET folder='trash' WHERE msgid=?''', msgid)
return 'Trashed sent message (assuming message existed).' return 'Trashed sent message (assuming message existed).'
elif method == 'trashSentMessageByAckData':
# This API method should only be used when msgid is not available def HandleSendMessage(self, params):
if len(params) == 0:
raise APIError(0, 'I need parameters!')
ackdata = self._decode(params[0], "hex")
sqlExecute('''UPDATE sent SET folder='trash' WHERE ackdata=?''',
ackdata)
return 'Trashed sent message (assuming message existed).'
elif method == 'sendMessage':
if len(params) == 0: if len(params) == 0:
raise APIError(0, 'I need parameters!') raise APIError(0, 'I need parameters!')
elif len(params) == 4: elif len(params) == 4:
toAddress, fromAddress, subject, message = params toAddress, fromAddress, subject, message = params
encodingType = 2 encodingType = 2
TTL = 4*24*60*60
elif len(params) == 5: elif len(params) == 5:
toAddress, fromAddress, subject, message, encodingType = params toAddress, fromAddress, subject, message, encodingType = params
TTL = 4*24*60*60
elif len(params) == 6:
toAddress, fromAddress, subject, message, encodingType, TTL = params
if encodingType != 2: if encodingType != 2:
raise APIError(6, 'The encoding type must be 2 because that is the only one this program currently supports.') raise APIError(6, 'The encoding type must be 2 because that is the only one this program currently supports.')
subject = self._decode(subject, "base64") subject = self._decode(subject, "base64")
message = self._decode(message, "base64") message = self._decode(message, "base64")
if len(subject + message) > (2 ** 18 - 500): if len(subject + message) > (2 ** 18 - 500):
raise APIError(27, 'Message is too long.') raise APIError(27, 'Message is too long.')
if TTL < 60*60:
TTL = 60*60
if TTL > 28*24*60*60:
TTL = 28*24*60*60
toAddress = addBMIfNotPresent(toAddress) toAddress = addBMIfNotPresent(toAddress)
fromAddress = addBMIfNotPresent(fromAddress) fromAddress = addBMIfNotPresent(fromAddress)
status, addressVersionNumber, streamNumber, toRipe = self._verifyAddress(toAddress) status, addressVersionNumber, streamNumber, toRipe = self._verifyAddress(toAddress)
@ -645,21 +644,8 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
ackdata = OpenSSL.rand(32) ackdata = OpenSSL.rand(32)
t = ('', t = ('', toAddress, toRipe, fromAddress, subject, message, ackdata, int(
toAddress, time.time()), 'msgqueued', 1, 1, 'sent', 2)
toRipe,
fromAddress,
subject,
message,
ackdata,
int(time.time()), # sentTime (this won't change)
int(time.time()), # lastActionTime
0,
'msgqueued',
0,
'sent',
2,
TTL)
helper_sent.insert(t) helper_sent.insert(t)
toLabel = '' toLabel = ''
@ -675,28 +661,20 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
return ackdata.encode('hex') return ackdata.encode('hex')
elif method == 'sendBroadcast': def HandleSendBroadcast(self, params):
if len(params) == 0: if len(params) == 0:
raise APIError(0, 'I need parameters!') raise APIError(0, 'I need parameters!')
if len(params) == 3: if len(params) == 3:
fromAddress, subject, message = params fromAddress, subject, message = params
encodingType = 2 encodingType = 2
TTL = 4*24*60*60
elif len(params) == 4: elif len(params) == 4:
fromAddress, subject, message, encodingType = params fromAddress, subject, message, encodingType = params
TTL = 4*24*60*60
elif len(params) == 5:
fromAddress, subject, message, encodingType, TTL = params
if encodingType != 2: if encodingType != 2:
raise APIError(6, 'The encoding type must be 2 because that is the only one this program currently supports.') raise APIError(6, 'The encoding type must be 2 because that is the only one this program currently supports.')
subject = self._decode(subject, "base64") subject = self._decode(subject, "base64")
message = self._decode(message, "base64") message = self._decode(message, "base64")
if len(subject + message) > (2 ** 18 - 500): if len(subject + message) > (2 ** 18 - 500):
raise APIError(27, 'Message is too long.') raise APIError(27, 'Message is too long.')
if TTL < 60*60:
TTL = 60*60
if TTL > 28*24*60*60:
TTL = 28*24*60*60
fromAddress = addBMIfNotPresent(fromAddress) fromAddress = addBMIfNotPresent(fromAddress)
self._verifyAddress(fromAddress) self._verifyAddress(fromAddress)
try: try:
@ -708,21 +686,9 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
toAddress = '[Broadcast subscribers]' toAddress = '[Broadcast subscribers]'
ripe = '' ripe = ''
t = ('',
toAddress, t = ('', toAddress, ripe, fromAddress, subject, message, ackdata, int(
ripe, time.time()), 'broadcastqueued', 1, 1, 'sent', 2)
fromAddress,
subject,
message,
ackdata,
int(time.time()), # sentTime (this doesn't change)
int(time.time()), # lastActionTime
0,
'broadcastqueued',
0,
'sent',
2,
TTL)
helper_sent.insert(t) helper_sent.insert(t)
toLabel = '[Broadcast subscribers]' toLabel = '[Broadcast subscribers]'
@ -731,7 +697,8 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
shared.workerQueue.put(('sendbroadcast', '')) shared.workerQueue.put(('sendbroadcast', ''))
return ackdata.encode('hex') return ackdata.encode('hex')
elif method == 'getStatus':
def HandleGetStatus(self, params):
if len(params) != 1: if len(params) != 1:
raise APIError(0, 'I need one parameter!') raise APIError(0, 'I need one parameter!')
ackdata, = params ackdata, = params
@ -746,7 +713,8 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
for row in queryreturn: for row in queryreturn:
status, = row status, = row
return status return status
elif method == 'addSubscription':
def HandleAddSubscription(self, params):
if len(params) == 0: if len(params) == 0:
raise APIError(0, 'I need parameters!') raise APIError(0, 'I need parameters!')
if len(params) == 1: if len(params) == 1:
@ -774,62 +742,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
shared.UISignalQueue.put(('rerenderSubscriptions', '')) shared.UISignalQueue.put(('rerenderSubscriptions', ''))
return 'Added subscription.' return 'Added subscription.'
elif method == 'addAddressToBlackWhiteList': def HandleDeleteSubscription(self, params):
if len(params) == 0:
raise APIError(0, 'I need parameters!')
if len(params) == 1:
address, = params
label = ''
if len(params) == 2:
address, label = params
label = self._decode(label, "base64")
try:
unicode(label, 'utf-8')
except:
raise APIError(17, 'Label is not valid UTF-8 data.')
if len(params) > 2:
raise APIError(0, 'I need either 1 or 2 parameters!')
address = addBMIfNotPresent(address)
self._verifyAddress(address)
table = ''
if shared.config.get('bitmessagesettings', 'blackwhitelist') == 'black':
table = 'blacklist'
else:
table = 'whitelist'
# First we must check to see if the address is already in the
# black-/white-list.
queryreturn = sqlQuery('''select * from '''+table+''' where address=?''', address)
if queryreturn != []:
raise APIError(28, 'You have already black-/white-listed that address.')
sqlExecute('''INSERT INTO '''+table+''' VALUES (?,?,?)''',label, address, True)
shared.UISignalQueue.put(('rerenderBlackWhiteList', ''))
return 'Added black-/white-list entry.'
elif method == 'removeAddressFromBlackWhiteList':
if len(params) != 1:
raise APIError(0, 'I need 1 parameter!')
address, = params
address = addBMIfNotPresent(address)
table = ''
if shared.config.get('bitmessagesettings', 'blackwhitelist') == 'black':
table = 'blacklist'
else:
table = 'whitelist'
# First we must check to see if the address is already in the
# black-/white-list.
queryreturn = sqlQuery('''select * from '''+table+''' where address=?''', address)
if queryreturn == []:
raise APIError(29, 'That entry does not exist in the black-/white-list.')
sqlExecute('''DELETE FROM '''+table+''' WHERE address=?''', address)
shared.UISignalQueue.put(('rerenderBlackWhiteList', ''))
return 'Deleted black-/white-list entry if it existed.'
elif method == 'deleteSubscription':
if len(params) != 1: if len(params) != 1:
raise APIError(0, 'I need 1 parameter!') raise APIError(0, 'I need 1 parameter!')
address, = params address, = params
@ -839,7 +752,8 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
shared.UISignalQueue.put(('rerenderInboxFromLabels', '')) shared.UISignalQueue.put(('rerenderInboxFromLabels', ''))
shared.UISignalQueue.put(('rerenderSubscriptions', '')) shared.UISignalQueue.put(('rerenderSubscriptions', ''))
return 'Deleted subscription if it existed.' return 'Deleted subscription if it existed.'
elif method == 'listSubscriptions':
def ListSubscriptions(self, params):
queryreturn = sqlQuery('''SELECT label, address, enabled FROM subscriptions''') queryreturn = sqlQuery('''SELECT label, address, enabled FROM subscriptions''')
data = '{"subscriptions":[' data = '{"subscriptions":['
for row in queryreturn: for row in queryreturn:
@ -850,7 +764,8 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
data += json.dumps({'label':label.encode('base64'), 'address': address, 'enabled': enabled == 1}, indent=4, separators=(',',': ')) data += json.dumps({'label':label.encode('base64'), 'address': address, 'enabled': enabled == 1}, indent=4, separators=(',',': '))
data += ']}' data += ']}'
return data return data
elif method == 'disseminatePreEncryptedMsg':
def HandleDisseminatePreEncryptedMsg(self, params):
# The device issuing this command to PyBitmessage supplies a msg object that has # The device issuing this command to PyBitmessage supplies a msg object that has
# already been encrypted but which still needs the POW to be done. PyBitmessage # already been encrypted but which still needs the POW to be done. PyBitmessage
# accepts this msg object and sends it out to the rest of the Bitmessage network # accepts this msg object and sends it out to the rest of the Bitmessage network
@ -885,7 +800,16 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
print 'Broadcasting inv for msg(API disseminatePreEncryptedMsg command):', inventoryHash.encode('hex') print 'Broadcasting inv for msg(API disseminatePreEncryptedMsg command):', inventoryHash.encode('hex')
shared.broadcastToSendDataQueues(( shared.broadcastToSendDataQueues((
toStreamNumber, 'advertiseobject', inventoryHash)) toStreamNumber, 'advertiseobject', inventoryHash))
elif method == 'disseminatePubkey':
def HandleTrashSentMessageByAckDAta(self, params):
# This API method should only be used when msgid is not available
if len(params) == 0:
raise APIError(0, 'I need parameters!')
ackdata = self._decode(params[0], "hex")
sqlExecute('''UPDATE sent SET folder='trash' WHERE ackdata=?''', ackdata)
return 'Trashed sent message (assuming message existed).'
def HandleDissimatePubKey(self, params):
# The device issuing this command to PyBitmessage supplies a pubkey object to be # The device issuing this command to PyBitmessage supplies a pubkey object to be
# disseminated to the rest of the Bitmessage network. PyBitmessage accepts this # disseminated to the rest of the Bitmessage network. PyBitmessage accepts this
# pubkey object and sends it out to the rest of the Bitmessage network as if it # pubkey object and sends it out to the rest of the Bitmessage network as if it
@ -924,11 +848,11 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
print 'broadcasting inv within API command disseminatePubkey with hash:', inventoryHash.encode('hex') print 'broadcasting inv within API command disseminatePubkey with hash:', inventoryHash.encode('hex')
shared.broadcastToSendDataQueues(( shared.broadcastToSendDataQueues((
streamNumber, 'advertiseobject', inventoryHash)) streamNumber, 'advertiseobject', inventoryHash))
elif method == 'getMessageDataByDestinationHash' or method == 'getMessageDataByDestinationTag':
def HandleGetMessageDataByDestinationHash(self, params):
# Method will eventually be used by a particular Android app to # Method will eventually be used by a particular Android app to
# select relevant messages. Do not yet add this to the api # select relevant messages. Do not yet add this to the api
# doc. # doc.
if len(params) != 1: if len(params) != 1:
raise APIError(0, 'I need 1 parameter!') raise APIError(0, 'I need 1 parameter!')
requestedHash, = params requestedHash, = params
@ -959,7 +883,25 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
data += json.dumps({'data':payload.encode('hex')}, indent=4, separators=(',', ': ')) data += json.dumps({'data':payload.encode('hex')}, indent=4, separators=(',', ': '))
data += ']}' data += ']}'
return data return data
elif method == 'clientStatus':
def HandleGetPubKeyByHash(self, params):
# Method will eventually be used by a particular Android app to
# retrieve pubkeys. Please do not yet add this to the api docs.
if len(params) != 1:
raise APIError(0, 'I need 1 parameter!')
requestedHash, = params
if len(requestedHash) != 40:
raise APIError(19, 'The length of hash should be 20 bytes (encoded in hex thus 40 characters).')
requestedHash = self._decode(requestedHash, "hex")
queryreturn = sqlQuery('''SELECT transmitdata FROM pubkeys WHERE hash = ? ; ''', requestedHash)
data = '{"pubkey":['
for row in queryreturn:
transmitdata, = row
data += json.dumps({'data':transmitdata.encode('hex')}, indent=4, separators=(',', ': '))
data += ']}'
return data
def HandleClientStatus(self, params):
if len(shared.connectedHostsList) == 0: if len(shared.connectedHostsList) == 0:
networkStatus = 'notConnected' networkStatus = 'notConnected'
elif len(shared.connectedHostsList) > 0 and not shared.clientHasReceivedIncomingConnections: elif len(shared.connectedHostsList) > 0 and not shared.clientHasReceivedIncomingConnections:
@ -967,7 +909,8 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
else: else:
networkStatus = 'connectedAndReceivingIncomingConnections' networkStatus = 'connectedAndReceivingIncomingConnections'
return json.dumps({'networkConnections':len(shared.connectedHostsList),'numberOfMessagesProcessed':shared.numberOfMessagesProcessed, 'numberOfBroadcastsProcessed':shared.numberOfBroadcastsProcessed, 'numberOfPubkeysProcessed':shared.numberOfPubkeysProcessed, 'networkStatus':networkStatus, 'softwareName':'PyBitmessage','softwareVersion':shared.softwareVersion}, indent=4, separators=(',', ': ')) return json.dumps({'networkConnections':len(shared.connectedHostsList),'numberOfMessagesProcessed':shared.numberOfMessagesProcessed, 'numberOfBroadcastsProcessed':shared.numberOfBroadcastsProcessed, 'numberOfPubkeysProcessed':shared.numberOfPubkeysProcessed, 'networkStatus':networkStatus, 'softwareName':'PyBitmessage','softwareVersion':shared.softwareVersion}, indent=4, separators=(',', ': '))
elif method == 'decodeAddress':
def HandleDecodeAddress(self, params):
# Return a meaningful decoding of an address. # Return a meaningful decoding of an address.
if len(params) != 1: if len(params) != 1:
raise APIError(0, 'I need 1 parameter!') raise APIError(0, 'I need 1 parameter!')
@ -976,6 +919,74 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
return json.dumps({'status':status, 'addressVersion':addressVersion, return json.dumps({'status':status, 'addressVersion':addressVersion,
'streamNumber':streamNumber, 'ripe':ripe.encode('base64')}, indent=4, 'streamNumber':streamNumber, 'ripe':ripe.encode('base64')}, indent=4,
separators=(',', ': ')) separators=(',', ': '))
def HandleHelloWorld(self, params):
(a, b) = params
return a + '-' + b
def HandleAdd(self, params):
(a, b) = params
return a + b
def HandleStatusBar(self, params):
message, = params
shared.UISignalQueue.put(('updateStatusBar', message))
handlers = {}
handlers['helloWorld'] = HandleHelloWorld
handlers['add'] = HandleAdd
handlers['statusBar'] = HandleStatusBar
handlers['listAddresses'] = HandleListAddresses
handlers['listAddressBookEntries'] = HandleListAddressBookEntries;
handlers['listAddressbook'] = HandleListAddressBookEntries # the listAddressbook alias should be removed eventually.
handlers['addAddressBookEntry'] = HandleAddAddressBookEntry
handlers['addAddressbook'] = HandleAddAddressBookEntry # the addAddressbook alias should be deleted eventually.
handlers['deleteAddressBookEntry'] = HandleDeleteAddressBookEntry
handlers['deleteAddressbook'] = HandleDeleteAddressBookEntry # The deleteAddressbook alias should be deleted eventually.
handlers['createRandomAddress'] = HandleCreateRandomAddress
handlers['createDeterministicAddresses'] = HandleCreateDeterministicAddresses
handlers['getDeterministicAddress'] = HandleGetDeterministicAddress
handlers['createChan'] = HandleCreateChan
handlers['joinChan'] = HandleJoinChan
handlers['leaveChan'] = HandleLeaveChan
handlers['deleteAddress'] = HandleDeleteAddress
handlers['getAllInboxMessages'] = HandleGetAllInboxMessages
handlers['getAllInboxMessageIds'] = HandleGetAllInboxMessageIds
handlers['getAllInboxMessageIDs'] = HandleGetAllInboxMessageIds
handlers['getInboxMessageById'] = HandleGetInboxMessageById
handlers['getInboxMessageByID'] = HandleGetInboxMessageById
handlers['getAllSentMessages'] = HandleGetAllSentMessages
handlers['getAllSentMessageIds'] = HandleGetAllSentMessageIds
handlers['getAllSentMessageIDs'] = HandleGetAllSentMessageIds
handlers['getInboxMessagesByReceiver'] = HandleInboxMessagesByReceiver
handlers['getInboxMessagesByAddress'] = HandleInboxMessagesByReceiver #after some time getInboxMessagesByAddress should be removed
handlers['getSentMessageById'] = HandleGetSentMessageById
handlers['getSentMessageByID'] = HandleGetSentMessageById
handlers['getSentMessagesByAddress'] = HandleGetSentMessagesByAddress
handlers['getSentMessagesBySender'] = HandleGetSentMessagesByAddress
handlers['getSentMessageByAckData'] = HandleGetSentMessagesByAckData
handlers['trashMessage'] = HandleTrashMessage
handlers['trashInboxMessage'] = HandleTrashInboxMessage
handlers['trashSentMessage'] = HandleTrashSentMessage
handlers['trashSentMessageByAckData'] = HandleTrashSentMessageByAckDAta
handlers['sendMessage'] = HandleSendMessage
handlers['sendBroadcast'] = HandleSendBroadcast
handlers['getStatus'] = HandleGetStatus
handlers['addSubscription'] = HandleAddSubscription
handlers['deleteSubscription'] = HandleDeleteSubscription
handlers['listSubscriptions'] = ListSubscriptions
handlers['disseminatePreEncryptedMsg'] = HandleDisseminatePreEncryptedMsg
handlers['disseminatePubkey'] = HandleDissimatePubKey
handlers['getMessageDataByDestinationHash'] = HandleGetMessageDataByDestinationHash
handlers['getMessageDataByDestinationTag'] = HandleGetMessageDataByDestinationHash
handlers['getPubkeyByHash'] = HandleGetPubKeyByHash
handlers['clientStatus'] = HandleClientStatus
handlers['decodeAddress'] = HandleDecodeAddress
def _handle_request(self, method, params):
if (self.handlers.has_key(method)):
return self.handlers[method](self ,params)
else: else:
raise APIError(20, 'Invalid method: %s' % method) raise APIError(20, 'Invalid method: %s' % method)
@ -997,4 +1008,3 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
except Exception as e: except Exception as e:
logger.exception(e) logger.exception(e)
return "API Error 0021: Unexpected API Failure - %s" % str(e) return "API Error 0021: Unexpected API Failure - %s" % str(e)