commit
825bfb0a3c
|
@ -2,7 +2,6 @@
|
||||||
Operations with addresses
|
Operations with addresses
|
||||||
"""
|
"""
|
||||||
# pylint: disable=redefined-outer-name,inconsistent-return-statements
|
# pylint: disable=redefined-outer-name,inconsistent-return-statements
|
||||||
|
|
||||||
import hashlib
|
import hashlib
|
||||||
from binascii import hexlify, unhexlify
|
from binascii import hexlify, unhexlify
|
||||||
from struct import pack, unpack
|
from struct import pack, unpack
|
||||||
|
@ -46,7 +45,8 @@ def decodeBase58(string, alphabet=ALPHABET):
|
||||||
for char in string:
|
for char in string:
|
||||||
num *= base
|
num *= base
|
||||||
num += alphabet.index(char)
|
num += alphabet.index(char)
|
||||||
except: # ValueError
|
# ValueError
|
||||||
|
except:
|
||||||
# character not found (like a space character or a 0)
|
# character not found (like a space character or a 0)
|
||||||
return 0
|
return 0
|
||||||
return num
|
return num
|
||||||
|
@ -85,13 +85,13 @@ def decodeVarint(data):
|
||||||
the minimum amount of data possible or else it is malformed.
|
the minimum amount of data possible or else it is malformed.
|
||||||
Returns a tuple: (theEncodedValue, theSizeOfTheVarintInBytes)
|
Returns a tuple: (theEncodedValue, theSizeOfTheVarintInBytes)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if not data:
|
if not data:
|
||||||
return (0, 0)
|
return (0, 0)
|
||||||
firstByte, = unpack('>B', data[0:1])
|
firstByte, = unpack('>B', data[0:1])
|
||||||
if firstByte < 253:
|
if firstByte < 253:
|
||||||
# encodes 0 to 252
|
# encodes 0 to 252
|
||||||
return (firstByte, 1) # the 1 is the length of the varint
|
# the 1 is the length of the varint
|
||||||
|
return (firstByte, 1)
|
||||||
if firstByte == 253:
|
if firstByte == 253:
|
||||||
# encodes 253 to 65535
|
# encodes 253 to 65535
|
||||||
if len(data) < 3:
|
if len(data) < 3:
|
||||||
|
@ -180,7 +180,8 @@ def decodeAddress(address):
|
||||||
returns (status, address version number, stream number,
|
returns (status, address version number, stream number,
|
||||||
data (almost certainly a ripe hash))
|
data (almost certainly a ripe hash))
|
||||||
"""
|
"""
|
||||||
# pylint: disable=too-many-return-statements,too-many-statements,too-many-return-statements,too-many-branches
|
# pylint: disable=too-many-return-statements,too-many-statements
|
||||||
|
# pylint: disable=too-many-branches
|
||||||
address = str(address).strip()
|
address = str(address).strip()
|
||||||
|
|
||||||
if address[:3] == 'BM-':
|
if address[:3] == 'BM-':
|
||||||
|
@ -237,7 +238,8 @@ def decodeAddress(address):
|
||||||
status = 'success'
|
status = 'success'
|
||||||
if addressVersionNumber == 1:
|
if addressVersionNumber == 1:
|
||||||
return status, addressVersionNumber, streamNumber, data[-24:-4]
|
return status, addressVersionNumber, streamNumber, data[-24:-4]
|
||||||
elif addressVersionNumber == 2 or addressVersionNumber == 3:
|
# elif addressVersionNumber == 2 or addressVersionNumber == 3:
|
||||||
|
elif addressVersionNumber in (2, 3):
|
||||||
embeddedRipeData = \
|
embeddedRipeData = \
|
||||||
data[bytesUsedByVersionNumber + bytesUsedByStreamNumber:-4]
|
data[bytesUsedByVersionNumber + bytesUsedByStreamNumber:-4]
|
||||||
if len(embeddedRipeData) == 19:
|
if len(embeddedRipeData) == 19:
|
||||||
|
|
65
src/api.py
65
src/api.py
|
@ -1,15 +1,12 @@
|
||||||
# pylint: disable=too-many-locals,too-many-lines,no-self-use,too-many-public-methods,too-many-branches
|
|
||||||
# pylint: disable=too-many-statements
|
|
||||||
|
|
||||||
# Copyright (c) 2012-2016 Jonathan Warren
|
|
||||||
# Copyright (c) 2012-2019 The Bitmessage developers
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
This is not what you run to run the Bitmessage API. Instead, enable the API
|
This is not what you run to run the Bitmessage API. Instead, enable the API
|
||||||
( https://bitmessage.org/wiki/API ) and optionally enable daemon mode
|
( https://bitmessage.org/wiki/API ) and optionally enable daemon mode
|
||||||
( https://bitmessage.org/wiki/Daemon ) then run bitmessagemain.py.
|
( https://bitmessage.org/wiki/Daemon ) then run bitmessagemain.py.
|
||||||
"""
|
"""
|
||||||
|
# pylint: disable=too-many-locals,too-many-lines,no-self-use,unused-argument
|
||||||
|
# pylint: disable=too-many-statements,too-many-public-methods,too-many-branches
|
||||||
|
# Copyright (c) 2012-2016 Jonathan Warren
|
||||||
|
# Copyright (c) 2012-2019 The Bitmessage developers
|
||||||
import base64
|
import base64
|
||||||
import errno
|
import errno
|
||||||
import hashlib
|
import hashlib
|
||||||
|
@ -58,6 +55,7 @@ class APIError(Exception):
|
||||||
|
|
||||||
class StoppableXMLRPCServer(SimpleXMLRPCServer):
|
class StoppableXMLRPCServer(SimpleXMLRPCServer):
|
||||||
"""A SimpleXMLRPCServer that honours state.shutdown"""
|
"""A SimpleXMLRPCServer that honours state.shutdown"""
|
||||||
|
# pylint:disable=too-few-public-methods
|
||||||
allow_reuse_address = True
|
allow_reuse_address = True
|
||||||
|
|
||||||
def serve_forever(self):
|
def serve_forever(self):
|
||||||
|
@ -150,7 +148,6 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
||||||
Note: this method is the same as in SimpleXMLRPCRequestHandler,
|
Note: this method is the same as in SimpleXMLRPCRequestHandler,
|
||||||
just hacked to handle cookies
|
just hacked to handle cookies
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Check that the path is legal
|
# Check that the path is legal
|
||||||
if not self.is_rpc_path_valid():
|
if not self.is_rpc_path_valid():
|
||||||
self.report_404()
|
self.report_404()
|
||||||
|
@ -175,10 +172,12 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
||||||
# SimpleXMLRPCDispatcher. To maintain backwards compatibility,
|
# SimpleXMLRPCDispatcher. To maintain backwards compatibility,
|
||||||
# check to see if a subclass implements _dispatch and dispatch
|
# check to see if a subclass implements _dispatch and dispatch
|
||||||
# using that method if present.
|
# using that method if present.
|
||||||
response = self.server._marshaled_dispatch( # pylint: disable=protected-access
|
# pylint: disable=protected-access
|
||||||
|
response = self.server._marshaled_dispatch(
|
||||||
data, getattr(self, '_dispatch', None)
|
data, getattr(self, '_dispatch', None)
|
||||||
)
|
)
|
||||||
except BaseException: # This should only happen if the module is buggy
|
# This should only happen if the module is buggy
|
||||||
|
except BaseException:
|
||||||
# internal error, report as HTTP server error
|
# internal error, report as HTTP server error
|
||||||
self.send_response(500)
|
self.send_response(500)
|
||||||
self.end_headers()
|
self.end_headers()
|
||||||
|
@ -251,7 +250,8 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
||||||
if status == 'invalidcharacters':
|
if status == 'invalidcharacters':
|
||||||
raise APIError(9, 'Invalid characters in address: ' + address)
|
raise APIError(9, 'Invalid characters in address: ' + address)
|
||||||
if status == 'versiontoohigh':
|
if status == 'versiontoohigh':
|
||||||
raise APIError(10, 'Address version number too high (or zero) in address: ' + address)
|
raise APIError(
|
||||||
|
10, 'Address version number too high (or zero) in address: ' + address)
|
||||||
if status == 'varintmalformed':
|
if status == 'varintmalformed':
|
||||||
raise APIError(26, 'Malformed varint in address: ' + address)
|
raise APIError(26, 'Malformed varint in address: ' + address)
|
||||||
raise APIError(7, 'Could not decode address: %s : %s' % (address, status))
|
raise APIError(7, 'Could not decode address: %s : %s' % (address, status))
|
||||||
|
@ -275,7 +275,8 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
||||||
|
|
||||||
data = '{"addresses":['
|
data = '{"addresses":['
|
||||||
for addressInKeysFile in BMConfigParser().addresses():
|
for addressInKeysFile in BMConfigParser().addresses():
|
||||||
status, addressVersionNumber, streamNumber, hash01 = decodeAddress( # pylint: disable=unused-variable
|
# pylint: disable=unused-variable
|
||||||
|
status, addressVersionNumber, streamNumber, hash01 = decodeAddress(
|
||||||
addressInKeysFile)
|
addressInKeysFile)
|
||||||
if len(data) > 20:
|
if len(data) > 20:
|
||||||
data += ','
|
data += ','
|
||||||
|
@ -485,7 +486,8 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
||||||
# 0 means "just use the proper addressVersionNumber"
|
# 0 means "just use the proper addressVersionNumber"
|
||||||
if addressVersionNumber == 0:
|
if addressVersionNumber == 0:
|
||||||
addressVersionNumber = 4
|
addressVersionNumber = 4
|
||||||
if addressVersionNumber != 3 and addressVersionNumber != 4:
|
# if addressVersionNumber != 3 and addressVersionNumber != 4:
|
||||||
|
if addressVersionNumber not in (3, 4):
|
||||||
raise APIError(
|
raise APIError(
|
||||||
2, 'The address version number currently must be 3, 4, or 0'
|
2, 'The address version number currently must be 3, 4, or 0'
|
||||||
' (which means auto-select). %i isn\'t supported.' %
|
' (which means auto-select). %i isn\'t supported.' %
|
||||||
|
@ -536,7 +538,8 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
||||||
if not passphrase:
|
if not passphrase:
|
||||||
raise APIError(1, 'The specified passphrase is blank.')
|
raise APIError(1, 'The specified passphrase is blank.')
|
||||||
passphrase = self._decode(passphrase, "base64")
|
passphrase = self._decode(passphrase, "base64")
|
||||||
if addressVersionNumber != 3 and addressVersionNumber != 4:
|
# if addressVersionNumber != 3 and addressVersionNumber != 4:
|
||||||
|
if addressVersionNumber not in (3, 4):
|
||||||
raise APIError(
|
raise APIError(
|
||||||
2, 'The address version number currently must be 3 or 4. %i'
|
2, 'The address version number currently must be 3 or 4. %i'
|
||||||
' isn\'t supported.' % addressVersionNumber)
|
' isn\'t supported.' % addressVersionNumber)
|
||||||
|
@ -606,8 +609,8 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
||||||
label = str_chan + ' ' + passphrase
|
label = str_chan + ' ' + passphrase
|
||||||
except BaseException:
|
except BaseException:
|
||||||
label = str_chan + ' ' + repr(passphrase)
|
label = str_chan + ' ' + repr(passphrase)
|
||||||
|
# pylint: disable=unused-variable
|
||||||
status, addressVersionNumber, streamNumber, toRipe = self._verifyAddress( # pylint: disable=unused-variable
|
status, addressVersionNumber, streamNumber, toRipe = self._verifyAddress(
|
||||||
suppliedAddress)
|
suppliedAddress)
|
||||||
suppliedAddress = addBMIfNotPresent(suppliedAddress)
|
suppliedAddress = addBMIfNotPresent(suppliedAddress)
|
||||||
queues.apiAddressGeneratorReturnQueue.queue.clear()
|
queues.apiAddressGeneratorReturnQueue.queue.clear()
|
||||||
|
@ -632,7 +635,8 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
||||||
elif len(params) == 1:
|
elif len(params) == 1:
|
||||||
address, = params
|
address, = params
|
||||||
# pylint: disable=unused-variable
|
# pylint: disable=unused-variable
|
||||||
status, addressVersionNumber, streamNumber, toRipe = self._verifyAddress(address)
|
status, addressVersionNumber, streamNumber, toRipe = \
|
||||||
|
self._verifyAddress(address)
|
||||||
address = addBMIfNotPresent(address)
|
address = addBMIfNotPresent(address)
|
||||||
if not BMConfigParser().has_section(address):
|
if not BMConfigParser().has_section(address):
|
||||||
raise APIError(
|
raise APIError(
|
||||||
|
@ -654,7 +658,8 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
||||||
elif len(params) == 1:
|
elif len(params) == 1:
|
||||||
address, = params
|
address, = params
|
||||||
# pylint: disable=unused-variable
|
# pylint: disable=unused-variable
|
||||||
status, addressVersionNumber, streamNumber, toRipe = self._verifyAddress(address)
|
status, addressVersionNumber, streamNumber, toRipe = \
|
||||||
|
self._verifyAddress(address)
|
||||||
address = addBMIfNotPresent(address)
|
address = addBMIfNotPresent(address)
|
||||||
if not BMConfigParser().has_section(address):
|
if not BMConfigParser().has_section(address):
|
||||||
raise APIError(
|
raise APIError(
|
||||||
|
@ -666,7 +671,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
||||||
shared.reloadMyAddressHashes()
|
shared.reloadMyAddressHashes()
|
||||||
return 'success'
|
return 'success'
|
||||||
|
|
||||||
def HandleGetAllInboxMessages(self, params): # pylint: disable=unused-argument
|
def HandleGetAllInboxMessages(self, params):
|
||||||
"""Handle a request to get all inbox messages"""
|
"""Handle a request to get all inbox messages"""
|
||||||
|
|
||||||
queryreturn = sqlQuery(
|
queryreturn = sqlQuery(
|
||||||
|
@ -694,7 +699,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
||||||
data += ']}'
|
data += ']}'
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def HandleGetAllInboxMessageIds(self, params): # pylint: disable=unused-argument
|
def HandleGetAllInboxMessageIds(self, params):
|
||||||
"""Handle a request to get all inbox message IDs"""
|
"""Handle a request to get all inbox message IDs"""
|
||||||
|
|
||||||
queryreturn = sqlQuery(
|
queryreturn = sqlQuery(
|
||||||
|
@ -753,7 +758,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
||||||
data += ']}'
|
data += ']}'
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def HandleGetAllSentMessages(self, params): # pylint: disable=unused-argument
|
def HandleGetAllSentMessages(self, params):
|
||||||
"""Handle a request to get all sent messages"""
|
"""Handle a request to get all sent messages"""
|
||||||
|
|
||||||
queryreturn = sqlQuery(
|
queryreturn = sqlQuery(
|
||||||
|
@ -782,7 +787,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
||||||
data += ']}'
|
data += ']}'
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def HandleGetAllSentMessageIds(self, params): # pylint: disable=unused-argument
|
def HandleGetAllSentMessageIds(self, params):
|
||||||
"""Handle a request to get all sent message IDs"""
|
"""Handle a request to get all sent message IDs"""
|
||||||
|
|
||||||
queryreturn = sqlQuery(
|
queryreturn = sqlQuery(
|
||||||
|
@ -1157,7 +1162,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
||||||
queues.UISignalQueue.put(('rerenderSubscriptions', ''))
|
queues.UISignalQueue.put(('rerenderSubscriptions', ''))
|
||||||
return 'Deleted subscription if it existed.'
|
return 'Deleted subscription if it existed.'
|
||||||
|
|
||||||
def ListSubscriptions(self, params): # pylint: disable=unused-argument
|
def ListSubscriptions(self, params):
|
||||||
"""Handle a request to list susbcriptions"""
|
"""Handle a request to list susbcriptions"""
|
||||||
|
|
||||||
# pylint: disable=unused-variable
|
# pylint: disable=unused-variable
|
||||||
|
@ -1206,7 +1211,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
||||||
initialHash = hashlib.sha512(encryptedPayload).digest()
|
initialHash = hashlib.sha512(encryptedPayload).digest()
|
||||||
trialValue, nonce = proofofwork.run(target, initialHash)
|
trialValue, nonce = proofofwork.run(target, initialHash)
|
||||||
with shared.printLock:
|
with shared.printLock:
|
||||||
print '(For msg message via API) Found proof of work', trialValue, 'Nonce:', nonce
|
print('(For msg message via API) Found proof of work', trialValue, 'Nonce:', nonce)
|
||||||
try:
|
try:
|
||||||
print(
|
print(
|
||||||
'POW took', int(time.time() - powStartTime), 'seconds.',
|
'POW took', int(time.time() - powStartTime), 'seconds.',
|
||||||
|
@ -1224,7 +1229,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
||||||
int(time.time()) + TTL, ''
|
int(time.time()) + TTL, ''
|
||||||
)
|
)
|
||||||
with shared.printLock:
|
with shared.printLock:
|
||||||
print 'Broadcasting inv for msg(API disseminatePreEncryptedMsg command):', hexlify(inventoryHash)
|
print('Broadcasting inv for msg(API disseminatePreEncryptedMsg command):', hexlify(inventoryHash))
|
||||||
queues.invQueue.put((toStreamNumber, inventoryHash))
|
queues.invQueue.put((toStreamNumber, inventoryHash))
|
||||||
|
|
||||||
def HandleTrashSentMessageByAckDAta(self, params):
|
def HandleTrashSentMessageByAckDAta(self, params):
|
||||||
|
@ -1237,7 +1242,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
||||||
sqlExecute("UPDATE sent SET folder='trash' WHERE ackdata=?", ackdata)
|
sqlExecute("UPDATE sent SET folder='trash' WHERE ackdata=?", ackdata)
|
||||||
return 'Trashed sent message (assuming message existed).'
|
return 'Trashed sent message (assuming message existed).'
|
||||||
|
|
||||||
def HandleDissimatePubKey(self, params): # pylint: disable=unused-argument
|
def HandleDissimatePubKey(self, params):
|
||||||
"""Handle a request to disseminate a public key"""
|
"""Handle a request to disseminate a public key"""
|
||||||
|
|
||||||
# The device issuing this command to PyBitmessage supplies a pubkey
|
# The device issuing this command to PyBitmessage supplies a pubkey
|
||||||
|
@ -1254,10 +1259,10 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
||||||
target = 2 ** 64 / ((
|
target = 2 ** 64 / ((
|
||||||
len(payload) + defaults.networkDefaultPayloadLengthExtraBytes + 8
|
len(payload) + defaults.networkDefaultPayloadLengthExtraBytes + 8
|
||||||
) * defaults.networkDefaultProofOfWorkNonceTrialsPerByte)
|
) * defaults.networkDefaultProofOfWorkNonceTrialsPerByte)
|
||||||
print '(For pubkey message via API) Doing proof of work...'
|
print('(For pubkey message via API) Doing proof of work...')
|
||||||
initialHash = hashlib.sha512(payload).digest()
|
initialHash = hashlib.sha512(payload).digest()
|
||||||
trialValue, nonce = proofofwork.run(target, initialHash)
|
trialValue, nonce = proofofwork.run(target, initialHash)
|
||||||
print '(For pubkey message via API) Found proof of work', trialValue, 'Nonce:', nonce
|
print('(For pubkey message via API) Found proof of work', trialValue, 'Nonce:', nonce)
|
||||||
payload = pack('>Q', nonce) + payload
|
payload = pack('>Q', nonce) + payload
|
||||||
|
|
||||||
pubkeyReadPosition = 8 # bypass the nonce
|
pubkeyReadPosition = 8 # bypass the nonce
|
||||||
|
@ -1279,7 +1284,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
||||||
objectType, pubkeyStreamNumber, payload, int(time.time()) + TTL, ''
|
objectType, pubkeyStreamNumber, payload, int(time.time()) + TTL, ''
|
||||||
)
|
)
|
||||||
with shared.printLock:
|
with shared.printLock:
|
||||||
print 'broadcasting inv within API command disseminatePubkey with hash:', hexlify(inventoryHash)
|
print('broadcasting inv within API command disseminatePubkey with hash:', hexlify(inventoryHash))
|
||||||
queues.invQueue.put((pubkeyStreamNumber, inventoryHash))
|
queues.invQueue.put((pubkeyStreamNumber, inventoryHash))
|
||||||
|
|
||||||
def HandleGetMessageDataByDestinationHash(self, params):
|
def HandleGetMessageDataByDestinationHash(self, params):
|
||||||
|
@ -1325,7 +1330,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
||||||
data += ']}'
|
data += ']}'
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def HandleClientStatus(self, params): # pylint: disable=unused-argument
|
def HandleClientStatus(self, params):
|
||||||
"""Handle a request to get the status of the client"""
|
"""Handle a request to get the status of the client"""
|
||||||
|
|
||||||
connections_num = len(network.stats.connectedHostsList())
|
connections_num = len(network.stats.connectedHostsList())
|
||||||
|
|
|
@ -1010,7 +1010,7 @@ def sendMessage(sender="", recv="", broadcast=None, subject="", body="", reply=F
|
||||||
def loadInbox():
|
def loadInbox():
|
||||||
"""Load the list of messages"""
|
"""Load the list of messages"""
|
||||||
sys.stdout = sys.__stdout__
|
sys.stdout = sys.__stdout__
|
||||||
print "Loading inbox messages..."
|
print("Loading inbox messages...")
|
||||||
sys.stdout = printlog
|
sys.stdout = printlog
|
||||||
|
|
||||||
where = "toaddress || fromaddress || subject || message"
|
where = "toaddress || fromaddress || subject || message"
|
||||||
|
@ -1062,7 +1062,7 @@ def loadInbox():
|
||||||
def loadSent():
|
def loadSent():
|
||||||
"""Load the messages that sent"""
|
"""Load the messages that sent"""
|
||||||
sys.stdout = sys.__stdout__
|
sys.stdout = sys.__stdout__
|
||||||
print "Loading sent messages..."
|
print("Loading sent messages...")
|
||||||
sys.stdout = printlog
|
sys.stdout = printlog
|
||||||
|
|
||||||
where = "toaddress || fromaddress || subject || message"
|
where = "toaddress || fromaddress || subject || message"
|
||||||
|
@ -1148,7 +1148,7 @@ def loadSent():
|
||||||
def loadAddrBook():
|
def loadAddrBook():
|
||||||
"""Load address book"""
|
"""Load address book"""
|
||||||
sys.stdout = sys.__stdout__
|
sys.stdout = sys.__stdout__
|
||||||
print "Loading address book..."
|
print("Loading address book...")
|
||||||
sys.stdout = printlog
|
sys.stdout = printlog
|
||||||
|
|
||||||
ret = sqlQuery("SELECT label, address FROM addressbook")
|
ret = sqlQuery("SELECT label, address FROM addressbook")
|
||||||
|
@ -1254,7 +1254,7 @@ def run(stdscr):
|
||||||
def doShutdown():
|
def doShutdown():
|
||||||
"""Shutting the app down"""
|
"""Shutting the app down"""
|
||||||
sys.stdout = sys.__stdout__
|
sys.stdout = sys.__stdout__
|
||||||
print "Shutting down..."
|
print("Shutting down...")
|
||||||
sys.stdout = printlog
|
sys.stdout = printlog
|
||||||
shutdown.doCleanShutdown()
|
shutdown.doCleanShutdown()
|
||||||
sys.stdout = sys.__stdout__
|
sys.stdout = sys.__stdout__
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
Core classes for loading images and converting them to a Texture.
|
Core classes for loading images and converting them to a Texture.
|
||||||
The raw image data can be keep in memory for further access
|
The raw image data can be keep in memory for further access
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import hashlib
|
import hashlib
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
|
||||||
|
@ -26,7 +25,6 @@ def generate(Generate_string=None):
|
||||||
image = Image.new(MODE, V_RESOLUTION, BACKGROUND_COLOR)
|
image = Image.new(MODE, V_RESOLUTION, BACKGROUND_COLOR)
|
||||||
image = generate_image(image, color, hash_string)
|
image = generate_image(image, color, hash_string)
|
||||||
image = image.resize(RESOLUTION, 0)
|
image = image.resize(RESOLUTION, 0)
|
||||||
|
|
||||||
data = BytesIO()
|
data = BytesIO()
|
||||||
image.save(data, format='png')
|
image.save(data, format='png')
|
||||||
data.seek(0)
|
data.seek(0)
|
||||||
|
@ -46,10 +44,8 @@ def generate_hash(string):
|
||||||
string = str.lower(string)
|
string = str.lower(string)
|
||||||
hash_object = hashlib.md5(str.encode(string))
|
hash_object = hashlib.md5(str.encode(string))
|
||||||
print(hash_object.hexdigest())
|
print(hash_object.hexdigest())
|
||||||
|
|
||||||
# returned object is a hex string
|
# returned object is a hex string
|
||||||
return hash_object.hexdigest()
|
return hash_object.hexdigest()
|
||||||
|
|
||||||
except IndexError:
|
except IndexError:
|
||||||
print("Error: Please enter a string as an argument.")
|
print("Error: Please enter a string as an argument.")
|
||||||
|
|
||||||
|
@ -59,29 +55,24 @@ def random_color(hash_string):
|
||||||
# remove first three digits from hex string
|
# remove first three digits from hex string
|
||||||
split = 6
|
split = 6
|
||||||
rgb = hash_string[:split]
|
rgb = hash_string[:split]
|
||||||
|
|
||||||
split = 2
|
split = 2
|
||||||
r = rgb[:split]
|
r = rgb[:split]
|
||||||
g = rgb[split:2 * split]
|
g = rgb[split:2 * split]
|
||||||
b = rgb[2 * split:3 * split]
|
b = rgb[2 * split:3 * split]
|
||||||
|
|
||||||
color = (int(r, 16), int(g, 16),
|
color = (int(r, 16), int(g, 16),
|
||||||
int(b, 16), 0xFF)
|
int(b, 16), 0xFF)
|
||||||
|
|
||||||
return color
|
return color
|
||||||
|
|
||||||
|
|
||||||
def generate_image(image, color, hash_string):
|
def generate_image(image, color, hash_string):
|
||||||
"""Generating images"""
|
"""Generating images"""
|
||||||
hash_string = hash_string[6:]
|
hash_string = hash_string[6:]
|
||||||
|
|
||||||
lower_x = 1
|
lower_x = 1
|
||||||
lower_y = 1
|
lower_y = 1
|
||||||
upper_x = int(V_RESOLUTION[0] / 2) + 1
|
upper_x = int(V_RESOLUTION[0] / 2) + 1
|
||||||
upper_y = V_RESOLUTION[1] - 1
|
upper_y = V_RESOLUTION[1] - 1
|
||||||
limit_x = V_RESOLUTION[0] - 1
|
limit_x = V_RESOLUTION[0] - 1
|
||||||
index = 0
|
index = 0
|
||||||
|
|
||||||
for x in range(lower_x, upper_x):
|
for x in range(lower_x, upper_x):
|
||||||
for y in range(lower_y, upper_y):
|
for y in range(lower_y, upper_y):
|
||||||
if int(hash_string[index], 16) % 2 == 0:
|
if int(hash_string[index], 16) % 2 == 0:
|
||||||
|
@ -89,5 +80,4 @@ def generate_image(image, color, hash_string):
|
||||||
image.putpixel((limit_x - x, y), color)
|
image.putpixel((limit_x - x, y), color)
|
||||||
|
|
||||||
index = index + 1
|
index = index + 1
|
||||||
|
|
||||||
return image
|
return image
|
||||||
|
|
|
@ -4,25 +4,25 @@ Sql queries for bitmessagekivy
|
||||||
from helper_sql import sqlQuery
|
from helper_sql import sqlQuery
|
||||||
|
|
||||||
|
|
||||||
def search_sql(xAddress="toaddress", account=None, folder="inbox", where=None, what=None, unreadOnly=False, start_indx=0, end_indx=20):
|
def search_sql(
|
||||||
|
xAddress="toaddress", account=None, folder="inbox", where=None,
|
||||||
|
what=None, unreadOnly=False, start_indx=0, end_indx=20):
|
||||||
"""Method helping for searching mails"""
|
"""Method helping for searching mails"""
|
||||||
# pylint: disable=too-many-arguments, too-many-branches
|
# pylint: disable=too-many-arguments, too-many-branches
|
||||||
if what is not None and what != "":
|
if what is not None and what != "":
|
||||||
what = "%" + what + "%"
|
what = "%" + what + "%"
|
||||||
else:
|
else:
|
||||||
what = None
|
what = None
|
||||||
|
|
||||||
if folder == "sent" or folder == "draft":
|
if folder == "sent" or folder == "draft":
|
||||||
sqlStatementBase = (
|
sqlStatementBase = (
|
||||||
'''SELECT toaddress, fromaddress, subject, message, status, ackdata,'''
|
'''SELECT toaddress, fromaddress, subject, message, status,'''
|
||||||
''' lastactiontime FROM sent ''')
|
''' ackdata, lastactiontime FROM sent ''')
|
||||||
elif folder == "addressbook":
|
elif folder == "addressbook":
|
||||||
sqlStatementBase = '''SELECT label, address From addressbook '''
|
sqlStatementBase = '''SELECT label, address From addressbook '''
|
||||||
else:
|
else:
|
||||||
sqlStatementBase = (
|
sqlStatementBase = (
|
||||||
'''SELECT folder, msgid, toaddress, message, fromaddress, subject,'''
|
'''SELECT folder, msgid, toaddress, message, fromaddress,'''
|
||||||
''' received, read FROM inbox ''')
|
''' subject, received, read FROM inbox ''')
|
||||||
|
|
||||||
sqlStatementParts = []
|
sqlStatementParts = []
|
||||||
sqlArguments = []
|
sqlArguments = []
|
||||||
if account is not None:
|
if account is not None:
|
||||||
|
@ -58,10 +58,15 @@ def search_sql(xAddress="toaddress", account=None, folder="inbox", where=None, w
|
||||||
sqlStatementParts.append("read = 0")
|
sqlStatementParts.append("read = 0")
|
||||||
if sqlStatementParts:
|
if sqlStatementParts:
|
||||||
sqlStatementBase += "WHERE " + " AND ".join(sqlStatementParts)
|
sqlStatementBase += "WHERE " + " AND ".join(sqlStatementParts)
|
||||||
|
# if folder in ("sent", "draft"):
|
||||||
if folder == "sent" or folder == "draft":
|
if folder == "sent" or folder == "draft":
|
||||||
sqlStatementBase += " ORDER BY lastactiontime DESC limit {0}, {1}".format(start_indx, end_indx)
|
sqlStatementBase += \
|
||||||
|
"ORDER BY lastactiontime DESC limit {0}, {1}".format(
|
||||||
|
start_indx, end_indx)
|
||||||
elif folder == "inbox":
|
elif folder == "inbox":
|
||||||
sqlStatementBase += " ORDER BY received DESC limit {0}, {1}".format(start_indx, end_indx)
|
sqlStatementBase += \
|
||||||
|
"ORDER BY received DESC limit {0}, {1}".format(
|
||||||
|
start_indx, end_indx)
|
||||||
# elif folder == "addressbook":
|
# elif folder == "addressbook":
|
||||||
# sqlStatementBase += " limit {0}, {1}".format(start_indx, end_indx)
|
# sqlStatementBase += " limit {0}, {1}".format(start_indx, end_indx)
|
||||||
return sqlQuery(sqlStatementBase, sqlArguments)
|
return sqlQuery(sqlStatementBase, sqlArguments)
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
"""
|
"""
|
||||||
Bitmessage android(mobile) interface
|
Bitmessage android(mobile) interface
|
||||||
"""
|
"""
|
||||||
# pylint: disable=relative-import, import-error, no-name-in-module
|
# pylint: disable=import-error, no-name-in-module, too-many-lines
|
||||||
# pylint: disable=too-few-public-methods, too-many-lines, unused-argument
|
# pylint: disable=too-few-public-methods, unused-argument, too-many-ancestors
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
from bmconfigparser import BMConfigParser
|
from bmconfigparser import BMConfigParser
|
||||||
|
@ -36,8 +36,6 @@ from kivy.uix.screenmanager import Screen
|
||||||
from kivy.uix.spinner import Spinner
|
from kivy.uix.spinner import Spinner
|
||||||
from kivy.uix.textinput import TextInput
|
from kivy.uix.textinput import TextInput
|
||||||
from kivy.utils import platform
|
from kivy.utils import platform
|
||||||
|
|
||||||
|
|
||||||
from bitmessagekivy import kivy_helper_search
|
from bitmessagekivy import kivy_helper_search
|
||||||
from kivymd.uix.button import MDIconButton
|
from kivymd.uix.button import MDIconButton
|
||||||
from kivymd.uix.dialog import MDDialog
|
from kivymd.uix.dialog import MDDialog
|
||||||
|
@ -48,7 +46,6 @@ from kivymd.uix.list import (
|
||||||
IRightBodyTouch,
|
IRightBodyTouch,
|
||||||
TwoLineAvatarIconListItem,
|
TwoLineAvatarIconListItem,
|
||||||
TwoLineListItem,
|
TwoLineListItem,
|
||||||
OneLineIconListItem
|
|
||||||
)
|
)
|
||||||
from kivymd.uix.navigationdrawer import (
|
from kivymd.uix.navigationdrawer import (
|
||||||
MDNavigationDrawer,
|
MDNavigationDrawer,
|
||||||
|
@ -525,7 +522,7 @@ class AddressBook(Screen):
|
||||||
class SelectableRecycleBoxLayout(
|
class SelectableRecycleBoxLayout(
|
||||||
FocusBehavior, LayoutSelectionBehavior, RecycleBoxLayout):
|
FocusBehavior, LayoutSelectionBehavior, RecycleBoxLayout):
|
||||||
"""Adds selection and focus behaviour to the view"""
|
"""Adds selection and focus behaviour to the view"""
|
||||||
# pylint: disable = too-many-ancestors, duplicate-bases
|
# pylint: disable = duplicate-bases
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@ -541,7 +538,6 @@ class SelectableLabel(RecycleDataViewBehavior, Label):
|
||||||
return super(SelectableLabel, self).refresh_view_attrs(
|
return super(SelectableLabel, self).refresh_view_attrs(
|
||||||
rv, index, data)
|
rv, index, data)
|
||||||
|
|
||||||
# pylint: disable=inconsistent-return-statements
|
|
||||||
def on_touch_down(self, touch):
|
def on_touch_down(self, touch):
|
||||||
"""Add selection on touch down"""
|
"""Add selection on touch down"""
|
||||||
if super(SelectableLabel, self).on_touch_down(touch):
|
if super(SelectableLabel, self).on_touch_down(touch):
|
||||||
|
@ -568,7 +564,6 @@ class RV(RecycleView):
|
||||||
class DropDownWidget(BoxLayout):
|
class DropDownWidget(BoxLayout):
|
||||||
"""Adding Dropdown Widget"""
|
"""Adding Dropdown Widget"""
|
||||||
# pylint: disable=too-many-statements, too-many-locals
|
# pylint: disable=too-many-statements, too-many-locals
|
||||||
# pylint: disable=inconsistent-return-statements
|
|
||||||
txt_input = ObjectProperty()
|
txt_input = ObjectProperty()
|
||||||
rv = ObjectProperty()
|
rv = ObjectProperty()
|
||||||
|
|
||||||
|
@ -606,8 +601,7 @@ class DropDownWidget(BoxLayout):
|
||||||
statusIconColor = 'red'
|
statusIconColor = 'red'
|
||||||
if (addressVersionNumber > 4) or (
|
if (addressVersionNumber > 4) or (
|
||||||
addressVersionNumber <= 1):
|
addressVersionNumber <= 1):
|
||||||
print ("addressVersionNumber > 4"\
|
print("addressVersionNumber > 4 or addressVersionNumber <= 1")
|
||||||
" or addressVersionNumber <= 1")
|
|
||||||
if streamNumber > 1 or streamNumber == 0:
|
if streamNumber > 1 or streamNumber == 0:
|
||||||
print("streamNumber > 1 or streamNumber == 0")
|
print("streamNumber > 1 or streamNumber == 0")
|
||||||
if statusIconColor == 'red':
|
if statusIconColor == 'red':
|
||||||
|
@ -802,6 +796,7 @@ class NetworkStat(Screen):
|
||||||
|
|
||||||
class ContentNavigationDrawer(Navigatorss):
|
class ContentNavigationDrawer(Navigatorss):
|
||||||
"""Navigate Content Drawer"""
|
"""Navigate Content Drawer"""
|
||||||
|
# pylint: disable=too-many-arguments
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@ -1283,8 +1278,6 @@ class NavigateApp(App): # pylint: disable=too-many-public-methods
|
||||||
|
|
||||||
def build(self):
|
def build(self):
|
||||||
"""Method builds the widget"""
|
"""Method builds the widget"""
|
||||||
print("SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSss")
|
|
||||||
print(os.path.join(os.path.dirname(__file__), 'main.kv'))
|
|
||||||
main_widget = Builder.load_file(
|
main_widget = Builder.load_file(
|
||||||
os.path.join(os.path.dirname(__file__), 'main.kv'))
|
os.path.join(os.path.dirname(__file__), 'main.kv'))
|
||||||
self.nav_drawer = Navigatorss()
|
self.nav_drawer = Navigatorss()
|
||||||
|
@ -1699,7 +1692,7 @@ class NavigateApp(App): # pylint: disable=too-many-public-methods
|
||||||
self.root.ids.scr_mngr.current = 'allmails'
|
self.root.ids.scr_mngr.current = 'allmails'
|
||||||
try:
|
try:
|
||||||
self.root.ids.sc17.children[1].active = True
|
self.root.ids.sc17.children[1].active = True
|
||||||
except Exception as e:
|
except Exception:
|
||||||
self.root.ids.sc17.children[0].children[1].active = True
|
self.root.ids.sc17.children[0].children[1].active = True
|
||||||
Clock.schedule_once(partial(self.load_screen_callback, instance), 1)
|
Clock.schedule_once(partial(self.load_screen_callback, instance), 1)
|
||||||
|
|
||||||
|
@ -1714,7 +1707,7 @@ class NavigateApp(App): # pylint: disable=too-many-public-methods
|
||||||
self.root.ids.sc17.add_widget(Allmails())
|
self.root.ids.sc17.add_widget(Allmails())
|
||||||
try:
|
try:
|
||||||
self.root.ids.sc17.children[1].active = False
|
self.root.ids.sc17.children[1].active = False
|
||||||
except Exception as e:
|
except Exception:
|
||||||
self.root.ids.sc17.children[0].children[1].active = False
|
self.root.ids.sc17.children[0].children[1].active = False
|
||||||
|
|
||||||
|
|
||||||
|
@ -2328,9 +2321,7 @@ class Draft(Screen):
|
||||||
0,
|
0,
|
||||||
'draft',
|
'draft',
|
||||||
encoding,
|
encoding,
|
||||||
int(BMConfigParser().safeGet(
|
int(BMConfigParser().safeGet('bitmessagesettings', 'ttl')))
|
||||||
'bitmessagesettings', 'ttl')))
|
|
||||||
|
|
||||||
state.msg_counter_objs = src_object.children[2].children[0].ids
|
state.msg_counter_objs = src_object.children[2].children[0].ids
|
||||||
state.draft_count = str(int(state.draft_count) + 1)
|
state.draft_count = str(int(state.draft_count) + 1)
|
||||||
src_object.ids.sc16.clear_widgets()
|
src_object.ids.sc16.clear_widgets()
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
|
"""
|
||||||
|
Ui Singnaler for kivy interface
|
||||||
|
"""
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
import state
|
|
||||||
import queues
|
import queues
|
||||||
|
import state
|
||||||
from semaphores import kivyuisignaler
|
from semaphores import kivyuisignaler
|
||||||
from helper_sql import SqlBulkExecute, sqlExecute, sqlQuery, sqlStoredProcedure
|
|
||||||
|
|
||||||
|
|
||||||
class UIkivySignaler(Thread):
|
class UIkivySignaler(Thread):
|
||||||
|
"""Kivy ui signaler"""
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
kivyuisignaler.acquire()
|
kivyuisignaler.acquire()
|
||||||
|
@ -14,13 +17,12 @@ class UIkivySignaler(Thread):
|
||||||
try:
|
try:
|
||||||
command, data = queues.UISignalQueue.get()
|
command, data = queues.UISignalQueue.get()
|
||||||
if command == 'writeNewAddressToTable':
|
if command == 'writeNewAddressToTable':
|
||||||
label, address, streamNumber = data
|
address = data[1]
|
||||||
state.kivyapp.variable_1.append(address)
|
state.kivyapp.variable_1.append(address)
|
||||||
# elif command == 'rerenderAddressBook':
|
# elif command == 'rerenderAddressBook':
|
||||||
# state.kivyapp.obj_1.refreshs()
|
# state.kivyapp.obj_1.refreshs()
|
||||||
# Need to discuss this
|
# Need to discuss this
|
||||||
elif command == 'updateSentItemStatusByAckdata':
|
elif command == 'updateSentItemStatusByAckdata':
|
||||||
state.kivyapp.status_dispatching(data)
|
state.kivyapp.status_dispatching(data)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e)
|
print(e)
|
||||||
|
|
|
@ -9,7 +9,6 @@ The PyBitmessage startup script
|
||||||
|
|
||||||
# Right now, PyBitmessage only support connecting to stream 1. It doesn't
|
# Right now, PyBitmessage only support connecting to stream 1. It doesn't
|
||||||
# yet contain logic to expand into further streams.
|
# yet contain logic to expand into further streams.
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import ctypes
|
import ctypes
|
||||||
|
@ -30,7 +29,8 @@ import state
|
||||||
import shutdown
|
import shutdown
|
||||||
|
|
||||||
from bmconfigparser import BMConfigParser
|
from bmconfigparser import BMConfigParser
|
||||||
from debug import logger # this should go before any threads
|
# this should go before any threads
|
||||||
|
from debug import logger
|
||||||
from helper_startup import (
|
from helper_startup import (
|
||||||
isOurOperatingSystemLimitedToHavingVeryFewHalfOpenConnections
|
isOurOperatingSystemLimitedToHavingVeryFewHalfOpenConnections
|
||||||
)
|
)
|
||||||
|
@ -189,8 +189,9 @@ class Main(object):
|
||||||
'Started proxy config plugin %s in %s sec',
|
'Started proxy config plugin %s in %s sec',
|
||||||
proxy_type, time.time() - proxyconfig_start)
|
proxy_type, time.time() - proxyconfig_start)
|
||||||
|
|
||||||
def start(self): # pylint: disable=too-many-statements, too-many-branches, too-many-locals
|
def start(self):
|
||||||
"""Start main application"""
|
"""Start main application"""
|
||||||
|
# pylint: disable=too-many-statements, too-many-branches, too-many-locals
|
||||||
_fixSocket()
|
_fixSocket()
|
||||||
|
|
||||||
config = BMConfigParser()
|
config = BMConfigParser()
|
||||||
|
@ -218,7 +219,8 @@ class Main(object):
|
||||||
if os.path.isfile(os.path.join(
|
if os.path.isfile(os.path.join(
|
||||||
state.appdata, 'unittest.lock')):
|
state.appdata, 'unittest.lock')):
|
||||||
daemon = True
|
daemon = True
|
||||||
state.enableGUI = False # run without a UI
|
# run without a UI
|
||||||
|
state.enableGUI = False
|
||||||
# Fallback: in case when no api command was issued
|
# Fallback: in case when no api command was issued
|
||||||
state.last_api_response = time.time()
|
state.last_api_response = time.time()
|
||||||
# Apply special settings
|
# Apply special settings
|
||||||
|
@ -234,7 +236,8 @@ class Main(object):
|
||||||
)
|
)
|
||||||
|
|
||||||
if daemon:
|
if daemon:
|
||||||
state.enableGUI = False # run without a UI
|
# run without a UI
|
||||||
|
state.enableGUI = False
|
||||||
|
|
||||||
# is the application already running? If yes then exit.
|
# is the application already running? If yes then exit.
|
||||||
if state.enableGUI and not state.curses and not state.kivy and not depends.check_pyqt():
|
if state.enableGUI and not state.curses and not state.kivy and not depends.check_pyqt():
|
||||||
|
@ -281,7 +284,6 @@ class Main(object):
|
||||||
|
|
||||||
readKnownNodes()
|
readKnownNodes()
|
||||||
|
|
||||||
|
|
||||||
# Not needed if objproc is disabled
|
# Not needed if objproc is disabled
|
||||||
if state.enableObjProc:
|
if state.enableObjProc:
|
||||||
|
|
||||||
|
@ -340,7 +342,8 @@ class Main(object):
|
||||||
shared.reloadBroadcastSendersForWhichImWatching()
|
shared.reloadBroadcastSendersForWhichImWatching()
|
||||||
# API is also objproc dependent
|
# API is also objproc dependent
|
||||||
if config.safeGetBoolean('bitmessagesettings', 'apienabled'):
|
if config.safeGetBoolean('bitmessagesettings', 'apienabled'):
|
||||||
import api # pylint: disable=relative-import
|
# pylint: disable=relative-import
|
||||||
|
import api
|
||||||
singleAPIThread = api.singleAPI()
|
singleAPIThread = api.singleAPI()
|
||||||
# close the main program even if there are threads left
|
# close the main program even if there are threads left
|
||||||
singleAPIThread.daemon = True
|
singleAPIThread.daemon = True
|
||||||
|
@ -405,7 +408,8 @@ class Main(object):
|
||||||
if (state.testmode and time.time() - state.last_api_response >= 30):
|
if (state.testmode and time.time() - state.last_api_response >= 30):
|
||||||
self.stop()
|
self.stop()
|
||||||
elif not state.enableGUI:
|
elif not state.enableGUI:
|
||||||
from tests import core as test_core # pylint: disable=relative-import
|
# pylint: disable=relative-import
|
||||||
|
from tests import core as test_core
|
||||||
test_core_result = test_core.run(self)
|
test_core_result = test_core.run(self)
|
||||||
state.enableGUI = True
|
state.enableGUI = True
|
||||||
self.stop()
|
self.stop()
|
||||||
|
@ -435,7 +439,8 @@ class Main(object):
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
parentPid = os.getpid()
|
parentPid = os.getpid()
|
||||||
shared.thisapp.lock() # relock
|
# relock
|
||||||
|
shared.thisapp.lock()
|
||||||
|
|
||||||
os.umask(0)
|
os.umask(0)
|
||||||
try:
|
try:
|
||||||
|
@ -450,14 +455,16 @@ class Main(object):
|
||||||
# wait until child ready
|
# wait until child ready
|
||||||
while True:
|
while True:
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
# pylint: disable=protected-access
|
||||||
os._exit(0) # pylint: disable=protected-access
|
os._exit(0)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
# fork not implemented
|
# fork not implemented
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
shared.thisapp.lock() # relock
|
# relock
|
||||||
shared.thisapp.lockPid = None # indicate we're the final child
|
shared.thisapp.lock()
|
||||||
|
# indicate we're the final child
|
||||||
|
shared.thisapp.lockPid = None
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
sys.stderr.flush()
|
sys.stderr.flush()
|
||||||
if not sys.platform.startswith('win'):
|
if not sys.platform.startswith('win'):
|
||||||
|
@ -480,7 +487,6 @@ class Main(object):
|
||||||
# signal.signal(signal.SIGINT, signal.SIG_DFL)
|
# signal.signal(signal.SIGINT, signal.SIG_DFL)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|
||||||
def usage():
|
def usage():
|
||||||
"""Displaying the usages"""
|
"""Displaying the usages"""
|
||||||
print('Usage: ' + sys.argv[0] + ' [OPTIONS]')
|
print('Usage: ' + sys.argv[0] + ' [OPTIONS]')
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
"""
|
"""
|
||||||
BMConfigParser class definition and default configuration settings
|
BMConfigParser class definition and default configuration settings
|
||||||
"""
|
"""
|
||||||
|
# pylint: disable=no-self-use, arguments-differ
|
||||||
import configparser
|
import configparser
|
||||||
import shutil
|
import shutil
|
||||||
import os
|
import os
|
||||||
|
@ -45,7 +45,7 @@ BMConfigDefaults = {
|
||||||
class BMConfigParser(configparser.ConfigParser):
|
class BMConfigParser(configparser.ConfigParser):
|
||||||
"""Singleton class inherited from ConfigParsedadfeConfigParser
|
"""Singleton class inherited from ConfigParsedadfeConfigParser
|
||||||
with additional methods specific to bitmessage config."""
|
with additional methods specific to bitmessage config."""
|
||||||
|
# pylint: disable=too-many-ancestors
|
||||||
_temp = {}
|
_temp = {}
|
||||||
|
|
||||||
def set(self, section, option, value=None):
|
def set(self, section, option, value=None):
|
||||||
|
@ -56,7 +56,8 @@ class BMConfigParser(configparser.ConfigParser):
|
||||||
raise ValueError("Invalid value %s" % value)
|
raise ValueError("Invalid value %s" % value)
|
||||||
return configparser.ConfigParser.set(self, section, option, value)
|
return configparser.ConfigParser.set(self, section, option, value)
|
||||||
|
|
||||||
def get(self, section, option, raw=False, variables=None): # pylint: disable=arguments-differ
|
def get(self, section, option, raw=False, variables=None):
|
||||||
|
# pylint: disable=unused-argument
|
||||||
try:
|
try:
|
||||||
if section == "bitmessagesettings" and option == "timeformat":
|
if section == "bitmessagesettings" and option == "timeformat":
|
||||||
return configparser.ConfigParser.get(
|
return configparser.ConfigParser.get(
|
||||||
|
@ -84,8 +85,8 @@ class BMConfigParser(configparser.ConfigParser):
|
||||||
self._temp[section] = {option: value}
|
self._temp[section] = {option: value}
|
||||||
|
|
||||||
def safeGetBoolean(self, section, field):
|
def safeGetBoolean(self, section, field):
|
||||||
|
"""Return value as boolean, False on exceptions"""
|
||||||
config = configparser.ConfigParser()
|
config = configparser.ConfigParser()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Used in the python2.7
|
# Used in the python2.7
|
||||||
# return self.getboolean(section, field)
|
# return self.getboolean(section, field)
|
||||||
|
@ -96,6 +97,8 @@ class BMConfigParser(configparser.ConfigParser):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def safeGetInt(self, section, field, default=0):
|
def safeGetInt(self, section, field, default=0):
|
||||||
|
"""Return value as integer, default on exceptions,
|
||||||
|
0 if default missing"""
|
||||||
config = configparser.ConfigParser()
|
config = configparser.ConfigParser()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -116,12 +119,14 @@ class BMConfigParser(configparser.ConfigParser):
|
||||||
return default
|
return default
|
||||||
|
|
||||||
def items(self, section, raw=False, variables=None):
|
def items(self, section, raw=False, variables=None):
|
||||||
|
"""Return section variables as parent,
|
||||||
|
but override the "raw" argument to always True"""
|
||||||
return configparser.ConfigParser.items(self, section, True, variables)
|
return configparser.ConfigParser.items(self, section, True, variables)
|
||||||
|
|
||||||
def addresses(self):
|
def addresses(self):
|
||||||
|
"""Return a list of local bitmessage addresses (from section labels)"""
|
||||||
return [x for x in BMConfigParser().sections() if x.startswith('BM-')]
|
return [x for x in BMConfigParser().sections() if x.startswith('BM-')]
|
||||||
|
|
||||||
|
|
||||||
def read(self, filenames):
|
def read(self, filenames):
|
||||||
configparser.ConfigParser.read(self, filenames)
|
configparser.ConfigParser.read(self, filenames)
|
||||||
for section in self.sections():
|
for section in self.sections():
|
||||||
|
@ -167,7 +172,8 @@ class BMConfigParser(configparser.ConfigParser):
|
||||||
def validate(self, section, option, value):
|
def validate(self, section, option, value):
|
||||||
"""Input validator interface (using factory pattern)"""
|
"""Input validator interface (using factory pattern)"""
|
||||||
try:
|
try:
|
||||||
return getattr(self, 'validate_{}_{}'.format(section, option))(value)
|
return getattr(self, 'validate_{}_{}'.format(
|
||||||
|
section, option))(value)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
|
@ -13,8 +13,14 @@ DATA_FILES = [
|
||||||
('bitmsghash', ['bitmsghash/bitmsghash.cl', 'bitmsghash/bitmsghash.so']),
|
('bitmsghash', ['bitmsghash/bitmsghash.cl', 'bitmsghash/bitmsghash.so']),
|
||||||
('translations', glob('translations/*.qm')),
|
('translations', glob('translations/*.qm')),
|
||||||
('ui', glob('bitmessageqt/*.ui')),
|
('ui', glob('bitmessageqt/*.ui')),
|
||||||
('translations', glob(str(QtCore.QLibraryInfo.location(QtCore.QLibraryInfo.TranslationsPath)) + '/qt_??.qm')),
|
('translations', glob(
|
||||||
('translations', glob(str(QtCore.QLibraryInfo.location(QtCore.QLibraryInfo.TranslationsPath)) + '/qt_??_??.qm')),
|
str(
|
||||||
|
QtCore.QLibraryInfo.location(
|
||||||
|
QtCore.QLibraryInfo.TranslationsPath)) + '/qt_??.qm')),
|
||||||
|
('translations', glob(
|
||||||
|
str(
|
||||||
|
QtCore.QLibraryInfo.location(
|
||||||
|
QtCore.QLibraryInfo.TranslationsPath)) + '/qt_??_??.qm')),
|
||||||
]
|
]
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
|
|
|
@ -20,7 +20,6 @@ from network.threads import StoppableThread
|
||||||
|
|
||||||
class addressGenerator(StoppableThread):
|
class addressGenerator(StoppableThread):
|
||||||
"""A thread for creating addresses"""
|
"""A thread for creating addresses"""
|
||||||
|
|
||||||
name = "addressGenerator"
|
name = "addressGenerator"
|
||||||
|
|
||||||
def stopThread(self):
|
def stopThread(self):
|
||||||
|
@ -35,7 +34,8 @@ class addressGenerator(StoppableThread):
|
||||||
Process the requests for addresses generation
|
Process the requests for addresses generation
|
||||||
from `.queues.addressGeneratorQueue`
|
from `.queues.addressGeneratorQueue`
|
||||||
"""
|
"""
|
||||||
# pylint: disable=too-many-locals, too-many-branches, protected-access, too-many-statements
|
# pylint: disable=too-many-locals, too-many-branches
|
||||||
|
# pylint: disable=protected-access, too-many-statements
|
||||||
while state.shutdown == 0:
|
while state.shutdown == 0:
|
||||||
queueValue = queues.addressGeneratorQueue.get()
|
queueValue = queues.addressGeneratorQueue.get()
|
||||||
nonceTrialsPerByte = 0
|
nonceTrialsPerByte = 0
|
||||||
|
@ -206,9 +206,14 @@ class addressGenerator(StoppableThread):
|
||||||
queues.workerQueue.put((
|
queues.workerQueue.put((
|
||||||
'sendOutOrStoreMyV4Pubkey', address))
|
'sendOutOrStoreMyV4Pubkey', address))
|
||||||
|
|
||||||
elif command == 'createDeterministicAddresses' \
|
# elif command == 'createDeterministicAddresses' \
|
||||||
or command == 'getDeterministicAddress' \
|
# or command == 'getDeterministicAddress' \
|
||||||
or command == 'createChan' or command == 'joinChan':
|
# or command == 'createChan' or command == 'joinChan':
|
||||||
|
elif command in (
|
||||||
|
'createDeterministicAddresses',
|
||||||
|
'getDeterministicAddress',
|
||||||
|
'createChan',
|
||||||
|
'joinChan'):
|
||||||
if not deterministicPassphrase:
|
if not deterministicPassphrase:
|
||||||
self.logger.warning(
|
self.logger.warning(
|
||||||
'You are creating deterministic'
|
'You are creating deterministic'
|
||||||
|
@ -333,8 +338,8 @@ class addressGenerator(StoppableThread):
|
||||||
BMConfigParser().set(address, 'label', label)
|
BMConfigParser().set(address, 'label', label)
|
||||||
BMConfigParser().set(address, 'enabled', 'true')
|
BMConfigParser().set(address, 'enabled', 'true')
|
||||||
BMConfigParser().set(address, 'decoy', 'false')
|
BMConfigParser().set(address, 'decoy', 'false')
|
||||||
if command == 'joinChan' \
|
# if command == 'joinChan' or command == 'createChan':
|
||||||
or command == 'createChan':
|
if command in ('joinChan', 'createChan'):
|
||||||
BMConfigParser().set(address, 'chan', 'true')
|
BMConfigParser().set(address, 'chan', 'true')
|
||||||
BMConfigParser().set(
|
BMConfigParser().set(
|
||||||
address, 'noncetrialsperbyte',
|
address, 'noncetrialsperbyte',
|
||||||
|
@ -385,8 +390,12 @@ class addressGenerator(StoppableThread):
|
||||||
address)
|
address)
|
||||||
|
|
||||||
# Done generating addresses.
|
# Done generating addresses.
|
||||||
if command == 'createDeterministicAddresses' \
|
# if command == 'createDeterministicAddresses' \
|
||||||
or command == 'joinChan' or command == 'createChan':
|
# or command == 'joinChan' or command == 'createChan':
|
||||||
|
if command in (
|
||||||
|
'createDeterministicAddresses',
|
||||||
|
'joinChan',
|
||||||
|
'createChan'):
|
||||||
queues.apiAddressGeneratorReturnQueue.put(
|
queues.apiAddressGeneratorReturnQueue.put(
|
||||||
listOfNewAddressesToSendOutThroughTheAPI)
|
listOfNewAddressesToSendOutThroughTheAPI)
|
||||||
elif command == 'getDeterministicAddress':
|
elif command == 'getDeterministicAddress':
|
||||||
|
|
|
@ -152,9 +152,8 @@ class objectProcessor(threading.Thread):
|
||||||
(data[readPosition:],
|
(data[readPosition:],
|
||||||
tr._translate(
|
tr._translate(
|
||||||
"MainWindow",
|
"MainWindow",
|
||||||
"Acknowledgement of the message received %1"
|
"Acknowledgement of the message received %1").arg(
|
||||||
).arg(l10n.formatTimestamp()))
|
l10n.formatTimestamp()))))
|
||||||
))
|
|
||||||
else:
|
else:
|
||||||
logger.debug('This object is not an acknowledgement bound for me.')
|
logger.debug('This object is not an acknowledgement bound for me.')
|
||||||
|
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
import queue as Queue
|
|
||||||
import threading
|
|
||||||
import time
|
|
||||||
|
|
||||||
class ObjectProcessorQueue(Queue.Queue):
|
|
||||||
maxSize = 32000000
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
Queue.Queue.__init__(self)
|
|
||||||
self.sizeLock = threading.Lock()
|
|
||||||
self.curSize = 0 # in Bytes. We maintain this to prevent nodes from flooing us with objects which take up too much memory. If this gets too big we'll sleep before asking for further objects.
|
|
||||||
|
|
||||||
def put(self, item, block = True, timeout = None):
|
|
||||||
while self.curSize >= self.maxSize:
|
|
||||||
time.sleep(1)
|
|
||||||
with self.sizeLock:
|
|
||||||
self.curSize += len(item[1])
|
|
||||||
Queue.Queue.put(self, item, block, timeout)
|
|
||||||
|
|
||||||
def get(self, block = True, timeout = None):
|
|
||||||
item = Queue.Queue.get(self, block, timeout)
|
|
||||||
with self.sizeLock:
|
|
||||||
self.curSize -= len(item[1])
|
|
||||||
return item
|
|
|
@ -35,6 +35,7 @@ from inventory import Inventory
|
||||||
from network.connectionpool import BMConnectionPool
|
from network.connectionpool import BMConnectionPool
|
||||||
from network.threads import StoppableThread
|
from network.threads import StoppableThread
|
||||||
|
|
||||||
|
|
||||||
class singleCleaner(StoppableThread):
|
class singleCleaner(StoppableThread):
|
||||||
"""The singleCleaner thread class"""
|
"""The singleCleaner thread class"""
|
||||||
name = "singleCleaner"
|
name = "singleCleaner"
|
||||||
|
@ -200,6 +201,10 @@ def deleteTrashMsgPermonantly():
|
||||||
"""This method is used to delete old messages"""
|
"""This method is used to delete old messages"""
|
||||||
ndays_before_time = datetime.now() - timedelta(days=30)
|
ndays_before_time = datetime.now() - timedelta(days=30)
|
||||||
old_messages = time.mktime(ndays_before_time.timetuple())
|
old_messages = time.mktime(ndays_before_time.timetuple())
|
||||||
sqlExecute("delete from sent where folder = 'trash' and lastactiontime <= ?;", int(old_messages))
|
sqlExecute(
|
||||||
sqlExecute("delete from inbox where folder = 'trash' and received <= ?;", int(old_messages))
|
"delete from sent where folder = 'trash' and lastactiontime <= ?;",
|
||||||
|
int(old_messages))
|
||||||
|
sqlExecute(
|
||||||
|
"delete from inbox where folder = 'trash' and received <= ?;",
|
||||||
|
int(old_messages))
|
||||||
return
|
return
|
||||||
|
|
|
@ -23,7 +23,8 @@ import queues
|
||||||
import shared
|
import shared
|
||||||
import state
|
import state
|
||||||
import tr
|
import tr
|
||||||
from addresses import calculateInventoryHash, decodeAddress, decodeVarint, encodeVarint
|
from addresses import (
|
||||||
|
calculateInventoryHash, decodeAddress, decodeVarint, encodeVarint)
|
||||||
from bmconfigparser import BMConfigParser
|
from bmconfigparser import BMConfigParser
|
||||||
from helper_sql import sqlExecute, sqlQuery
|
from helper_sql import sqlExecute, sqlQuery
|
||||||
from inventory import Inventory
|
from inventory import Inventory
|
||||||
|
|
|
@ -3,7 +3,6 @@ src/class_smtpDeliver.py
|
||||||
========================
|
========================
|
||||||
"""
|
"""
|
||||||
# pylint: disable=unused-variable
|
# pylint: disable=unused-variable
|
||||||
|
|
||||||
import smtplib
|
import smtplib
|
||||||
import urlparse
|
import urlparse
|
||||||
from email.header import Header
|
from email.header import Header
|
||||||
|
@ -24,7 +23,8 @@ class smtpDeliver(StoppableThread):
|
||||||
|
|
||||||
def stopThread(self):
|
def stopThread(self):
|
||||||
try:
|
try:
|
||||||
queues.UISignallerQueue.put(("stopThread", "data")) # pylint: disable=no-member
|
# pylint: disable=no-member
|
||||||
|
queues.UISignallerQueue.put(("stopThread", "data"))
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
super(smtpDeliver, self).stopThread()
|
super(smtpDeliver, self).stopThread()
|
||||||
|
@ -50,23 +50,27 @@ class smtpDeliver(StoppableThread):
|
||||||
ackData, message = data
|
ackData, message = data
|
||||||
elif command == 'displayNewInboxMessage':
|
elif command == 'displayNewInboxMessage':
|
||||||
inventoryHash, toAddress, fromAddress, subject, body = data
|
inventoryHash, toAddress, fromAddress, subject, body = data
|
||||||
dest = BMConfigParser().safeGet("bitmessagesettings", "smtpdeliver", '')
|
dest = BMConfigParser().safeGet(
|
||||||
|
"bitmessagesettings", "smtpdeliver", '')
|
||||||
if dest == '':
|
if dest == '':
|
||||||
continue
|
continue
|
||||||
try:
|
try:
|
||||||
|
# pylint: disable=deprecated-lambda
|
||||||
u = urlparse.urlparse(dest)
|
u = urlparse.urlparse(dest)
|
||||||
to = urlparse.parse_qs(u.query)['to']
|
to = urlparse.parse_qs(u.query)['to']
|
||||||
client = smtplib.SMTP(u.hostname, u.port)
|
client = smtplib.SMTP(u.hostname, u.port)
|
||||||
msg = MIMEText(body, 'plain', 'utf-8')
|
msg = MIMEText(body, 'plain', 'utf-8')
|
||||||
msg['Subject'] = Header(subject, 'utf-8')
|
msg['Subject'] = Header(subject, 'utf-8')
|
||||||
msg['From'] = fromAddress + '@' + SMTPDOMAIN
|
msg['From'] = fromAddress + '@' + SMTPDOMAIN
|
||||||
toLabel = map( # pylint: disable=deprecated-lambda
|
toLabel = map(
|
||||||
lambda y: BMConfigParser().safeGet(y, "label"),
|
lambda y: BMConfigParser().safeGet(y, "label"),
|
||||||
filter( # pylint: disable=deprecated-lambda
|
filter(
|
||||||
lambda x: x == toAddress, BMConfigParser().addresses())
|
lambda x: x == toAddress, BMConfigParser().addresses())
|
||||||
)
|
)
|
||||||
if toLabel:
|
if toLabel:
|
||||||
msg['To'] = "\"%s\" <%s>" % (Header(toLabel[0], 'utf-8'), toAddress + '@' + SMTPDOMAIN)
|
msg['To'] = "\"%s\" <%s>" % (
|
||||||
|
Header(toLabel[0], 'utf-8'),
|
||||||
|
toAddress + '@' + SMTPDOMAIN)
|
||||||
else:
|
else:
|
||||||
msg['To'] = toAddress + '@' + SMTPDOMAIN
|
msg['To'] = toAddress + '@' + SMTPDOMAIN
|
||||||
client.ehlo()
|
client.ehlo()
|
||||||
|
@ -80,7 +84,8 @@ class smtpDeliver(StoppableThread):
|
||||||
except:
|
except:
|
||||||
self.logger.error('smtp delivery error', exc_info=True)
|
self.logger.error('smtp delivery error', exc_info=True)
|
||||||
elif command == 'displayNewSentMessage':
|
elif command == 'displayNewSentMessage':
|
||||||
toAddress, fromLabel, fromAddress, subject, message, ackdata = data
|
toAddress, fromLabel, fromAddress, subject, message, ackdata = \
|
||||||
|
data
|
||||||
elif command == 'updateNetworkStatusTab':
|
elif command == 'updateNetworkStatusTab':
|
||||||
pass
|
pass
|
||||||
elif command == 'updateNumberOfMessagesProcessed':
|
elif command == 'updateNumberOfMessagesProcessed':
|
||||||
|
|
|
@ -214,7 +214,8 @@ class sqlThread(threading.Thread):
|
||||||
parameters = ''
|
parameters = ''
|
||||||
self.cur.execute(item, parameters)
|
self.cur.execute(item, parameters)
|
||||||
currentVersion = int(self.cur.fetchall()[0][0])
|
currentVersion = int(self.cur.fetchall()[0][0])
|
||||||
if currentVersion == 1 or currentVersion == 3:
|
# if currentVersion == 1 or currentVersion == 3:
|
||||||
|
if currentVersion in (1, 3):
|
||||||
logger.debug(
|
logger.debug(
|
||||||
'In messages.dat database, adding tag field to'
|
'In messages.dat database, adding tag field to'
|
||||||
' the inventory table.')
|
' the inventory table.')
|
||||||
|
@ -578,9 +579,13 @@ class sqlThread(threading.Thread):
|
||||||
# print ('+++++++++++++++++++++++++++++')
|
# print ('+++++++++++++++++++++++++++++')
|
||||||
try:
|
try:
|
||||||
if 'sent' == parameters[1] and 'B' in parameters[0]:
|
if 'sent' == parameters[1] and 'B' in parameters[0]:
|
||||||
item = '''SELECT toaddress, fromaddress, subject, message, status, ackdata, lastactiontime FROM sent WHERE fromaddress = ? ORDER BY lastactiontime DESC '''
|
item = (
|
||||||
|
'''SELECT toaddress, fromaddress, subject,'''
|
||||||
|
''' message, status, ackdata, lastactiontime'''
|
||||||
|
''' FROM sent WHERE fromaddress = ?'''
|
||||||
|
''' ORDER BY lastactiontime DESC''')
|
||||||
parameters = (parameters[0],)
|
parameters = (parameters[0],)
|
||||||
except (IndexError,TypeError) as e:
|
except(IndexError, TypeError):
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
self.cur.execute(item, parameters)
|
self.cur.execute(item, parameters)
|
||||||
|
|
Reference in New Issue
Block a user