Added some API commands for use with a mobile app #391
|
@ -747,6 +747,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
||||||
if len(params) != 1:
|
if len(params) != 1:
|
||||||
return 'API Error 0000: I need 1 parameter!'
|
return 'API Error 0000: I need 1 parameter!'
|
||||||
encryptedPayload, = params
|
encryptedPayload, = params
|
||||||
|
encryptedPayload = encryptedPayload.decode('hex')
|
||||||
inventoryHash = calculateInventoryHash(encryptedPayload)
|
inventoryHash = calculateInventoryHash(encryptedPayload)
|
||||||
objectType = 'msg'
|
objectType = 'msg'
|
||||||
shared.inventory[inventoryHash] = (
|
shared.inventory[inventoryHash] = (
|
||||||
|
@ -754,15 +755,16 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
||||||
with shared.printLock:
|
with shared.printLock:
|
||||||
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((
|
||||||
streamNumber, 'sendinv', inventoryHash))
|
toStreamNumber, 'sendinv', inventoryHash))
|
||||||
elif method == 'disseminatePubkey':
|
elif method == 'disseminatePubkey':
|
||||||
# The device issuing this command to PyBitmessage supplies a pubkey object that has
|
# The device issuing this command to PyBitmessage supplies a pubkey object that has
|
||||||
# already had the necessary proof of work done for it to be disseminated to the rest of the
|
# already had the necessary proof of work done for it to be disseminated to the rest of the
|
||||||
# Bitmessage network. PyBitmessage accepts this pubkey object and sends it out to the
|
# Bitmessage network. PyBitmessage accepts this pubkey object and sends it out to the
|
||||||
# rest of the Bitmessage network, as if it had generated the pubkey object itself.
|
# rest of the Bitmessage network as if it had generated the pubkey object itself.
|
||||||
if len(params) != 1:
|
if len(params) != 1:
|
||||||
return 'API Error 0000: I need 1 parameter!'
|
return 'API Error 0000: I need 1 parameter!'
|
||||||
payload, = params
|
payload, = params
|
||||||
|
payload = payload.decode('hex')
|
||||||
inventoryHash = calculateInventoryHash(payload)
|
inventoryHash = calculateInventoryHash(payload)
|
||||||
objectType = 'pubkey'
|
objectType = 'pubkey'
|
||||||
shared.inventory[inventoryHash] = (
|
shared.inventory[inventoryHash] = (
|
||||||
|
@ -772,30 +774,40 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
||||||
shared.broadcastToSendDataQueues((
|
shared.broadcastToSendDataQueues((
|
||||||
streamNumber, 'sendinv', inventoryHash))
|
streamNumber, 'sendinv', inventoryHash))
|
||||||
elif method == 'getMessageDataByDestinationRIPEHash':
|
elif method == 'getMessageDataByDestinationRIPEHash':
|
||||||
# Method will eventually be used by a particular Android app.
|
# Method will eventually be used by a particular Android app to
|
||||||
|
# select relevant messages.
|
||||||
|
|
||||||
if len(params) != 1:
|
if len(params) != 1:
|
||||||
return 'API Error 0000: I need 1 parameter!'
|
return 'API Error 0000: I need 1 parameter!'
|
||||||
hash, = params
|
requestedHash, = params
|
||||||
#if len(hash) != 40:
|
if len(requestedHash) != 40:
|
||||||
# return 'API Error 0019: The length of hash should be 20 bytes (encoded in hex thus 40 characters).'
|
return 'API Error 0019: The length of hash should be 20 bytes (encoded in hex thus 40 characters).'
|
||||||
print repr(hash)
|
requestedHash = requestedHash.decode('hex')
|
||||||
hash = hash.decode('hex')
|
|
||||||
print repr(hash)
|
|
||||||
with shared.sqlLock:
|
|
||||||
shared.sqlSubmitQueue.put('''PRAGMA case_sensitive_like = true''')
|
|
||||||
shared.sqlSubmitQueue.put('')
|
|
||||||
queryreturn = shared.sqlReturnQueue.get()
|
|
||||||
|
|
||||||
hash = string.replace(hash,'e','ee')
|
# This is not a particularly commonly used API function. Before we
|
||||||
hash = string.replace(hash,'%','e%')
|
# use it we'll need to fill out a field in our inventory database
|
||||||
hash = string.replace(hash,'_','e_')
|
# which is blank by default (first20bytesofencryptedmessage).
|
||||||
print 'searching for hash:', repr(hash)
|
parameters = ''
|
||||||
parameters = ('%'+ hash + '%',)
|
|
||||||
with shared.sqlLock:
|
with shared.sqlLock:
|
||||||
shared.sqlSubmitQueue.put('''SELECT payload FROM inventory WHERE hash LIKE ? ESCAPE'e'; ''')
|
shared.sqlSubmitQueue.put('''SELECT hash, payload FROM inventory WHERE first20bytesofencryptedmessage = '' and objecttype = 'msg' ; ''')
|
||||||
shared.sqlSubmitQueue.put(parameters)
|
shared.sqlSubmitQueue.put(parameters)
|
||||||
queryreturn = shared.sqlReturnQueue.get()
|
queryreturn = shared.sqlReturnQueue.get()
|
||||||
|
|
||||||
|
for row in queryreturn:
|
||||||
|
hash, payload = row
|
||||||
|
readPosition = 16 # Nonce length + time length
|
||||||
|
readPosition += decodeVarint(payload[readPosition:readPosition+10])[1] # Stream Number length
|
||||||
|
t = (payload[readPosition:readPosition+20],hash)
|
||||||
|
shared.sqlSubmitQueue.put('''UPDATE inventory SET first20bytesofencryptedmessage=? WHERE hash=?; ''')
|
||||||
|
shared.sqlSubmitQueue.put(t)
|
||||||
|
shared.sqlReturnQueue.get()
|
||||||
|
|
||||||
|
parameters = (requestedHash,)
|
||||||
|
with shared.sqlLock:
|
||||||
|
shared.sqlSubmitQueue.put('commit')
|
||||||
|
shared.sqlSubmitQueue.put('''SELECT payload FROM inventory WHERE first20bytesofencryptedmessage = ?''')
|
||||||
|
shared.sqlSubmitQueue.put(parameters)
|
||||||
|
queryreturn = shared.sqlReturnQueue.get()
|
||||||
data = '{"receivedMessageDatas":['
|
data = '{"receivedMessageDatas":['
|
||||||
for row in queryreturn:
|
for row in queryreturn:
|
||||||
payload, = row
|
payload, = row
|
||||||
|
@ -824,11 +836,8 @@ class singleAPI(threading.Thread):
|
||||||
se.register_introspection_functions()
|
se.register_introspection_functions()
|
||||||
se.serve_forever()
|
se.serve_forever()
|
||||||
|
|
||||||
selfInitiatedConnections = {}
|
|
||||||
# This is a list of current connections (the thread pointers at least)
|
# This is a list of current connections (the thread pointers at least)
|
||||||
|
selfInitiatedConnections = {}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if shared.useVeryEasyProofOfWorkForTesting:
|
if shared.useVeryEasyProofOfWorkForTesting:
|
||||||
|
|
|
@ -33,9 +33,9 @@ class singleCleaner(threading.Thread):
|
||||||
for hash, storedValue in shared.inventory.items():
|
for hash, storedValue in shared.inventory.items():
|
||||||
objectType, streamNumber, payload, receivedTime = storedValue
|
objectType, streamNumber, payload, receivedTime = storedValue
|
||||||
if int(time.time()) - 3600 > receivedTime:
|
if int(time.time()) - 3600 > receivedTime:
|
||||||
t = (hash, objectType, streamNumber, payload, receivedTime)
|
t = (hash, objectType, streamNumber, payload, receivedTime,'')
|
||||||
shared.sqlSubmitQueue.put(
|
shared.sqlSubmitQueue.put(
|
||||||
'''INSERT INTO inventory VALUES (?,?,?,?,?)''')
|
'''INSERT INTO inventory VALUES (?,?,?,?,?,?)''')
|
||||||
shared.sqlSubmitQueue.put(t)
|
shared.sqlSubmitQueue.put(t)
|
||||||
shared.sqlReturnQueue.get()
|
shared.sqlReturnQueue.get()
|
||||||
del shared.inventory[hash]
|
del shared.inventory[hash]
|
||||||
|
|
|
@ -46,7 +46,7 @@ class sqlThread(threading.Thread):
|
||||||
self.cur.execute(
|
self.cur.execute(
|
||||||
'''CREATE TABLE pubkeys (hash blob, transmitdata blob, time int, usedpersonally text, UNIQUE(hash) ON CONFLICT REPLACE)''' )
|
'''CREATE TABLE pubkeys (hash blob, transmitdata blob, time int, usedpersonally text, UNIQUE(hash) ON CONFLICT REPLACE)''' )
|
||||||
self.cur.execute(
|
self.cur.execute(
|
||||||
'''CREATE TABLE inventory (hash blob, objecttype text, streamnumber int, payload blob, receivedtime integer, UNIQUE(hash) ON CONFLICT REPLACE)''' )
|
'''CREATE TABLE inventory (hash blob, objecttype text, streamnumber int, payload blob, receivedtime integer, first20bytesofencryptedmessage blob, UNIQUE(hash) ON CONFLICT REPLACE)''' )
|
||||||
self.cur.execute(
|
self.cur.execute(
|
||||||
'''CREATE TABLE knownnodes (timelastseen int, stream int, services blob, host blob, port blob, UNIQUE(host, stream, port) ON CONFLICT REPLACE)''' )
|
'''CREATE TABLE knownnodes (timelastseen int, stream int, services blob, host blob, port blob, UNIQUE(host, stream, port) ON CONFLICT REPLACE)''' )
|
||||||
# This table isn't used in the program yet but I
|
# This table isn't used in the program yet but I
|
||||||
|
@ -55,7 +55,7 @@ class sqlThread(threading.Thread):
|
||||||
'''INSERT INTO subscriptions VALUES('Bitmessage new releases/announcements','BM-GtovgYdgs7qXPkoYaRgrLFuFKz1SFpsw',1)''')
|
'''INSERT INTO subscriptions VALUES('Bitmessage new releases/announcements','BM-GtovgYdgs7qXPkoYaRgrLFuFKz1SFpsw',1)''')
|
||||||
self.cur.execute(
|
self.cur.execute(
|
||||||
'''CREATE TABLE settings (key blob, value blob, UNIQUE(key) ON CONFLICT REPLACE)''' )
|
'''CREATE TABLE settings (key blob, value blob, UNIQUE(key) ON CONFLICT REPLACE)''' )
|
||||||
self.cur.execute( '''INSERT INTO settings VALUES('version','1')''')
|
self.cur.execute( '''INSERT INTO settings VALUES('version','2')''')
|
||||||
self.cur.execute( '''INSERT INTO settings VALUES('lastvacuumtime',?)''', (
|
self.cur.execute( '''INSERT INTO settings VALUES('lastvacuumtime',?)''', (
|
||||||
int(time.time()),))
|
int(time.time()),))
|
||||||
self.conn.commit()
|
self.conn.commit()
|
||||||
|
@ -190,13 +190,18 @@ class sqlThread(threading.Thread):
|
||||||
if not shared.config.has_option('bitmessagesettings', 'sockslisten'):
|
if not shared.config.has_option('bitmessagesettings', 'sockslisten'):
|
||||||
shared.config.set('bitmessagesettings', 'sockslisten', 'false')
|
shared.config.set('bitmessagesettings', 'sockslisten', 'false')
|
||||||
|
|
||||||
# Some prewritten code for future use whenever we need to modify the database
|
# Add a new column to the inventory table to store the first 20 bytes of encrypted messages to support Android app
|
||||||
"""item = '''SELECT value FROM settings WHERE key='version';'''
|
item = '''SELECT value FROM settings WHERE key='version';'''
|
||||||
parameters = ''
|
parameters = ''
|
||||||
self.cur.execute(item, parameters)
|
self.cur.execute(item, parameters)
|
||||||
if self.cur.fetchall()[0][0] == 1:
|
if int(self.cur.fetchall()[0][0]) == 1:
|
||||||
do something
|
print 'upgrading database'
|
||||||
increment the version to 2"""
|
item = '''ALTER TABLE inventory ADD first20bytesofencryptedmessage blob DEFAULT '' '''
|
||||||
|
parameters = ''
|
||||||
|
self.cur.execute(item, parameters)
|
||||||
|
item = '''update settings set value=? WHERE key='version';'''
|
||||||
|
parameters = (2,)
|
||||||
|
self.cur.execute(item, parameters)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
testpayload = '\x00\x00'
|
testpayload = '\x00\x00'
|
||||||
|
|
|
@ -54,13 +54,13 @@ def readPubkeys():
|
||||||
|
|
||||||
def readInventory():
|
def readInventory():
|
||||||
print 'Printing everything in inventory table:'
|
print 'Printing everything in inventory table:'
|
||||||
item = '''select hash, objecttype, streamnumber, payload, receivedtime from inventory'''
|
item = '''select hash, objecttype, streamnumber, payload, receivedtime, first20bytesofencryptedmessage from inventory where objecttype = 'msg' '''
|
||||||
parameters = ''
|
parameters = ''
|
||||||
cur.execute(item, parameters)
|
cur.execute(item, parameters)
|
||||||
output = cur.fetchall()
|
output = cur.fetchall()
|
||||||
for row in output:
|
for row in output[:50]:
|
||||||
hash, objecttype, streamnumber, payload, receivedtime = row
|
hash, objecttype, streamnumber, payload, receivedtime, first20bytesofencryptedmessage = row
|
||||||
print 'Hash:', hash.encode('hex'), objecttype, streamnumber, '\t', payload.encode('hex'), '\t', unicode(strftime('%a, %d %b %Y %I:%M %p',localtime(receivedtime)),'utf-8')
|
print 'Hash:', hash.encode('hex'), objecttype, streamnumber, '\t', 'first20bytesofencryptedmessage:', first20bytesofencryptedmessage.encode('hex'), '\t', payload.encode('hex'), '\t', unicode(strftime('%a, %d %b %Y %I:%M %p',localtime(receivedtime)),'utf-8')
|
||||||
|
|
||||||
def readInventory2():
|
def readInventory2():
|
||||||
searchValue = ' '
|
searchValue = ' '
|
||||||
|
@ -74,15 +74,17 @@ def readInventory2():
|
||||||
searchValue = string.replace(searchValue,'_','e_')
|
searchValue = string.replace(searchValue,'_','e_')
|
||||||
|
|
||||||
print 'Printing subset of inventory table:'
|
print 'Printing subset of inventory table:'
|
||||||
item = '''SELECT * FROM inventory WHERE hash LIKE ? ESCAPE'e'; '''
|
item = '''SELECT substr(payload,20) FROM inventory'''
|
||||||
parameters = ('%'+ searchValue + '%',)
|
#parameters = ('%'+ searchValue + '%',)
|
||||||
print repr(parameters), len(parameters[0])
|
#print repr(parameters), len(parameters[0])
|
||||||
|
parameters = ''
|
||||||
cur.execute(item, parameters)
|
cur.execute(item, parameters)
|
||||||
output = cur.fetchall()
|
output = cur.fetchall()
|
||||||
print 'Number of results:', len(output)
|
print 'Number of results:', len(output)
|
||||||
for row in output[:20]:
|
for row in output[:100]:
|
||||||
hash, objecttype, streamnumber, payload, receivedtime = row
|
print row
|
||||||
print 'Hash:', hash.encode('hex'), objecttype, streamnumber, '\t', payload.encode('hex'), '\t', unicode(strftime('%a, %d %b %Y %I:%M %p',localtime(receivedtime)),'utf-8')
|
#hash, objecttype, streamnumber, payload, receivedtime = row
|
||||||
|
#print 'Hash:', hash.encode('hex'), objecttype, streamnumber, '\t', payload.encode('hex'), '\t', unicode(strftime('%a, %d %b %Y %I:%M %p',localtime(receivedtime)),'utf-8')
|
||||||
print 'done'
|
print 'done'
|
||||||
|
|
||||||
|
|
||||||
|
@ -125,9 +127,9 @@ def vacuum():
|
||||||
#readSent()
|
#readSent()
|
||||||
#readPubkeys()
|
#readPubkeys()
|
||||||
#readSubscriptions()
|
#readSubscriptions()
|
||||||
#readInventory()
|
readInventory()
|
||||||
#vacuum() #will defragment and clean empty space from the messages.dat file.
|
#vacuum() #will defragment and clean empty space from the messages.dat file.
|
||||||
readInventory2()
|
#readInventory2()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -243,8 +243,7 @@ def reloadMyAddressHashes():
|
||||||
myAddressesByHash[hash] = addressInKeysFile
|
myAddressesByHash[hash] = addressInKeysFile
|
||||||
|
|
||||||
else:
|
else:
|
||||||
logger.error('Error in reloadMyAddressHashes: Can\'t handle address '
|
logger.error('Error in reloadMyAddressHashes: Can\'t handle address versions other than 2 or 3.\n')
|
||||||
'versions other than 2 or 3.\n')
|
|
||||||
|
|
||||||
if not keyfileSecure:
|
if not keyfileSecure:
|
||||||
fixSensitiveFilePermissions(appdata + 'keys.dat', hasEnabledKeys)
|
fixSensitiveFilePermissions(appdata + 'keys.dat', hasEnabledKeys)
|
||||||
|
@ -320,8 +319,8 @@ def flushInventory():
|
||||||
sqlLock.acquire()
|
sqlLock.acquire()
|
||||||
for hash, storedValue in inventory.items():
|
for hash, storedValue in inventory.items():
|
||||||
objectType, streamNumber, payload, receivedTime = storedValue
|
objectType, streamNumber, payload, receivedTime = storedValue
|
||||||
t = (hash,objectType,streamNumber,payload,receivedTime)
|
t = (hash,objectType,streamNumber,payload,receivedTime,'')
|
||||||
sqlSubmitQueue.put('''INSERT INTO inventory VALUES (?,?,?,?,?)''')
|
sqlSubmitQueue.put('''INSERT INTO inventory VALUES (?,?,?,?,?,?)''')
|
||||||
sqlSubmitQueue.put(t)
|
sqlSubmitQueue.put(t)
|
||||||
sqlReturnQueue.get()
|
sqlReturnQueue.get()
|
||||||
del inventory[hash]
|
del inventory[hash]
|
||||||
|
|
Reference in New Issue
Block a user