diff --git a/pybitmessage b/pybitmessage
deleted file mode 120000
index e8310385..00000000
--- a/pybitmessage
+++ /dev/null
@@ -1 +0,0 @@
-src
\ No newline at end of file
diff --git a/python3_requirements.txt b/python3_requirements.txt
new file mode 100644
index 00000000..1115fe09
--- /dev/null
+++ b/python3_requirements.txt
@@ -0,0 +1,21 @@
+astroid==2.3.3
+certifi==2019.9.11
+chardet==3.0.4
+docutils==0.15.2
+idna==2.8
+isort==4.3.21
+Kivy==1.11.1
+Kivy-Garden==0.1.4
+git+https://github.com/HeaTTheatR/KivyMD.git
+lazy-object-proxy==1.4.3
+mccabe==0.6.1
+Pillow==6.1.0
+pkg-resources==0.0.0
+pydenticon==0.3.1
+Pygments==2.4.2
+pylint==2.4.4
+qrcode==6.1
+requests==2.22.0
+six==1.12.0
+typed-ast==1.4.0
+urllib3==1.25.6
diff --git a/src/addresses.py b/src/addresses.py
index 0d3d4400..0072a2f1 100644
--- a/src/addresses.py
+++ b/src/addresses.py
@@ -44,7 +44,8 @@ def decodeBase58(string, alphabet=ALPHABET):
for char in string:
num *= base
num += alphabet.index(char)
- except: # ValueError
+ # ValueError
+ except:
# character not found (like a space character or a 0)
return 0
return num
@@ -83,13 +84,13 @@ def decodeVarint(data):
the minimum amount of data possible or else it is malformed.
Returns a tuple: (theEncodedValue, theSizeOfTheVarintInBytes)
"""
-
if not data:
return (0, 0)
firstByte, = unpack('>B', data[0:1])
if firstByte < 253:
# 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:
# encodes 253 to 65535
if len(data) < 3:
@@ -157,7 +158,7 @@ def encodeAddress(version, stream, ripe):
raise Exception(
'Programming error in encodeAddress: The length of'
' a given ripe hash was not 20.')
- ripe = ripe.lstrip('\x00')
+ ripe = ripe.lstrip('\x00'.encode('utf-8'))
storedBinaryData = encodeVarint(version) + encodeVarint(stream) + ripe
@@ -180,7 +181,6 @@ def decodeAddress(address):
"""
# pylint: disable=too-many-return-statements,too-many-statements
# pylint: disable=too-many-branches
-
address = str(address).strip()
if address[:3] == 'BM-':
@@ -192,7 +192,7 @@ def decodeAddress(address):
return status, 0, 0, ''
# after converting to hex, the string will be prepended
# with a 0x and appended with a L
- hexdata = hex(integer)[2:-1]
+ hexdata = hex(integer)[2:]
if len(hexdata) % 2 != 0:
hexdata = '0' + hexdata
@@ -237,7 +237,8 @@ def decodeAddress(address):
status = 'success'
if addressVersionNumber == 1:
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 = \
data[bytesUsedByVersionNumber + bytesUsedByStreamNumber:-4]
if len(embeddedRipeData) == 19:
@@ -248,7 +249,7 @@ def decodeAddress(address):
embeddedRipeData
elif len(embeddedRipeData) == 18:
return status, addressVersionNumber, streamNumber, \
- '\x00\x00' + embeddedRipeData
+ '\x00\x00'.encode('utf-8') + embeddedRipeData
elif len(embeddedRipeData) < 18:
return 'ripetooshort', 0, 0, ''
elif len(embeddedRipeData) > 20:
@@ -265,7 +266,8 @@ def decodeAddress(address):
return 'ripetoolong', 0, 0, ''
elif len(embeddedRipeData) < 4:
return 'ripetooshort', 0, 0, ''
- x00string = '\x00' * (20 - len(embeddedRipeData))
+ x00string = '\x00'.encode('utf-8') * (20 - len(embeddedRipeData))
+
return status, addressVersionNumber, streamNumber, \
x00string + embeddedRipeData
diff --git a/src/api.py b/src/api.py
index 70da0cda..e6771f4b 100644
--- a/src/api.py
+++ b/src/api.py
@@ -3,9 +3,16 @@ 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/Daemon ) then run bitmessagemain.py.
"""
+<<<<<<< HEAD
# Copyright (c) 2012-2016 Jonathan Warren
# Copyright (c) 2012-2020 The Bitmessage developers
# pylint: disable=too-many-lines,no-self-use,unused-variable,unused-argument
+=======
+# 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
+>>>>>>> 86df28c260eb1dd4acae506c1366f3cf136c5840
import base64
import errno
import hashlib
@@ -27,6 +34,7 @@ import queues
import shared
import shutdown
import state
+<<<<<<< HEAD
from addresses import (
addBMIfNotPresent,
calculateInventoryHash,
@@ -34,13 +42,21 @@ from addresses import (
decodeVarint,
varintDecodeError
)
+=======
+
+from addresses import addBMIfNotPresent, calculateInventoryHash, decodeAddress, decodeVarint, varintDecodeError
+>>>>>>> 86df28c260eb1dd4acae506c1366f3cf136c5840
from bmconfigparser import BMConfigParser
from debug import logger
from helper_ackPayload import genAckPayload
from helper_sql import SqlBulkExecute, sqlExecute, sqlQuery, sqlStoredProcedure
from inventory import Inventory
from network.threads import StoppableThread
+<<<<<<< HEAD
from version import softwareVersion
+=======
+# pylint: disable=unused-variable
+>>>>>>> 86df28c260eb1dd4acae506c1366f3cf136c5840
str_chan = '[chan]'
@@ -59,6 +75,7 @@ class APIError(Exception):
class StoppableXMLRPCServer(SimpleXMLRPCServer):
"""A SimpleXMLRPCServer that honours state.shutdown"""
+ # pylint:disable=too-few-public-methods
allow_reuse_address = True
def serve_forever(self):
@@ -153,7 +170,6 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
Note: this method is the same as in SimpleXMLRPCRequestHandler,
just hacked to handle cookies
"""
-
# Check that the path is legal
if not self.is_rpc_path_valid():
self.report_404()
@@ -182,7 +198,8 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
response = self.server._marshaled_dispatch(
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
self.send_response(500)
self.end_headers()
@@ -258,9 +275,13 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
raise APIError(9, 'Invalid characters in address: ' + address)
if status == 'versiontoohigh':
raise APIError(
+<<<<<<< HEAD
10,
'Address version number too high (or zero) in address: ' +
address)
+=======
+ 10, 'Address version number too high (or zero) in address: ' + address)
+>>>>>>> 86df28c260eb1dd4acae506c1366f3cf136c5840
if status == 'varintmalformed':
raise APIError(26, 'Malformed varint in address: ' + address)
raise APIError(
@@ -501,7 +522,8 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
# 0 means "just use the proper addressVersionNumber"
if addressVersionNumber == 0:
addressVersionNumber = 4
- if addressVersionNumber != 3 and addressVersionNumber != 4:
+ # if addressVersionNumber != 3 and addressVersionNumber != 4:
+ if addressVersionNumber not in (3, 4):
raise APIError(
2, 'The address version number currently must be 3, 4, or 0'
' (which means auto-select). %i isn\'t supported.' %
@@ -552,7 +574,8 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
if not passphrase:
raise APIError(1, 'The specified passphrase is blank.')
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(
2, 'The address version number currently must be 3 or 4. %i'
' isn\'t supported.' % addressVersionNumber)
@@ -622,8 +645,13 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
label = str_chan + ' ' + passphrase
except BaseException:
label = str_chan + ' ' + repr(passphrase)
+<<<<<<< HEAD
status, addressVersionNumber, streamNumber, toRipe = (
self._verifyAddress(suppliedAddress))
+=======
+ status, addressVersionNumber, streamNumber, toRipe = self._verifyAddress(
+ suppliedAddress)
+>>>>>>> 86df28c260eb1dd4acae506c1366f3cf136c5840
suppliedAddress = addBMIfNotPresent(suppliedAddress)
queues.apiAddressGeneratorReturnQueue.queue.clear()
queues.addressGeneratorQueue.put((
@@ -646,8 +674,13 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
raise APIError(0, 'I need parameters.')
elif len(params) == 1:
address, = params
+<<<<<<< HEAD
status, addressVersionNumber, streamNumber, toRipe = (
self._verifyAddress(address))
+=======
+ status, addressVersionNumber, streamNumber, toRipe = \
+ self._verifyAddress(address)
+>>>>>>> 86df28c260eb1dd4acae506c1366f3cf136c5840
address = addBMIfNotPresent(address)
if not BMConfigParser().has_section(address):
raise APIError(
@@ -668,8 +701,13 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
raise APIError(0, 'I need parameters.')
elif len(params) == 1:
address, = params
+<<<<<<< HEAD
status, addressVersionNumber, streamNumber, toRipe = (
self._verifyAddress(address))
+=======
+ status, addressVersionNumber, streamNumber, toRipe = \
+ self._verifyAddress(address)
+>>>>>>> 86df28c260eb1dd4acae506c1366f3cf136c5840
address = addBMIfNotPresent(address)
if not BMConfigParser().has_section(address):
raise APIError(
@@ -1222,7 +1260,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
initialHash = hashlib.sha512(encryptedPayload).digest()
trialValue, nonce = proofofwork.run(target, initialHash)
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:
print(
'POW took', int(time.time() - powStartTime),
@@ -1241,7 +1279,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
int(time.time()) + TTL, ''
)
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))
def HandleTrashSentMessageByAckDAta(self, params):
@@ -1271,10 +1309,10 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
target = 2 ** 64 / ((
len(payload) + defaults.networkDefaultPayloadLengthExtraBytes + 8
) * 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()
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
pubkeyReadPosition = 8 # bypass the nonce
@@ -1295,7 +1333,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
objectType, pubkeyStreamNumber, payload, int(time.time()) + TTL, ''
)
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))
def HandleGetMessageDataByDestinationHash(self, params):
diff --git a/src/bitmessagecli.py b/src/bitmessagecli.py
index 01dbc9bb..fb825b0e 100644
--- a/src/bitmessagecli.py
+++ b/src/bitmessagecli.py
@@ -29,7 +29,8 @@ from bmconfigparser import BMConfigParser
api = ''
keysName = 'keys.dat'
keysPath = 'keys.dat'
-usrPrompt = 0 # 0 = First Start, 1 = prompt, 2 = no prompt if the program is starting up
+# 0 = First Start, 1 = prompt, 2 = no prompt if the program is starting up
+usrPrompt = 0
knownAddresses = dict()
@@ -38,7 +39,7 @@ def userInput(message):
global usrPrompt
- print '\n' + message
+ print('\n' + message)
uInput = raw_input('> ')
if uInput.lower() == 'exit': # Returns the user to the main menu
@@ -46,7 +47,7 @@ def userInput(message):
main()
elif uInput.lower() == 'quit': # Quits the program
- print '\n Bye\n'
+ print('\n Bye\n')
sys.exit(0)
else:
@@ -55,9 +56,9 @@ def userInput(message):
def restartBmNotify():
"""Prompt the user to restart Bitmessage"""
- print '\n *******************************************************************'
- print ' WARNING: If Bitmessage is running locally, you must restart it now.'
- print ' *******************************************************************\n'
+ print('\n *******************************************************************')
+ print(' WARNING: If Bitmessage is running locally, you must restart it now.')
+ print(' *******************************************************************\n')
# Begin keys.dat interactions
@@ -96,8 +97,8 @@ def configInit():
with open(keysName, 'wb') as configfile:
BMConfigParser().write(configfile)
- print '\n ' + str(keysName) + ' Initalized in the same directory as daemon.py'
- print ' You will now need to configure the ' + str(keysName) + ' file.\n'
+ print('\n ' + str(keysName) + ' Initalized in the same directory as daemon.py')
+ print(' You will now need to configure the ' + str(keysName) + ' file.\n')
def apiInit(apiEnabled):
@@ -114,20 +115,20 @@ def apiInit(apiEnabled):
with open(keysPath, 'wb') as configfile:
BMConfigParser().write(configfile)
- print 'Done'
+ print('Done')
restartBmNotify()
return True
elif uInput == "n":
- print ' \n************************************************************'
- print ' Daemon will not work when the API is disabled. '
- print ' Please refer to the Bitmessage Wiki on how to setup the API.'
- print ' ************************************************************\n'
+ print(' \n************************************************************')
+ print(' Daemon will not work when the API is disabled. ')
+ print(' Please refer to the Bitmessage Wiki on how to setup the API.')
+ print(' ************************************************************\n')
usrPrompt = 1
main()
else:
- print '\n Invalid Entry\n'
+ print('\n Invalid Entry\n')
usrPrompt = 1
main()
@@ -136,11 +137,11 @@ def apiInit(apiEnabled):
return True
else: # API information was not present.
- print '\n ' + str(keysPath) + ' not properly configured!\n'
+ print('\n ' + str(keysPath) + ' not properly configured!\n')
uInput = userInput("Would you like to do this now, (Y)es or (N)o?").lower()
if uInput == "y": # User said yes, initalize the api by writing these values to the keys.dat file
- print ' '
+ print(' ')
apiUsr = userInput("API Username")
apiPwd = userInput("API Password")
@@ -149,11 +150,11 @@ def apiInit(apiEnabled):
daemon = userInput("Daemon mode Enabled? (True) or (False)").lower()
if (daemon != 'true' and daemon != 'false'):
- print '\n Invalid Entry for Daemon.\n'
+ print('\n Invalid Entry for Daemon.\n')
uInput = 1
main()
- print ' -----------------------------------\n'
+ print(' -----------------------------------\n')
# sets the bitmessage port to stop the warning about the api not properly
# being setup. This is in the event that the keys.dat is in a different
@@ -168,18 +169,18 @@ def apiInit(apiEnabled):
with open(keysPath, 'wb') as configfile:
BMConfigParser().write(configfile)
- print '\n Finished configuring the keys.dat file with API information.\n'
+ print('\n Finished configuring the keys.dat file with API information.\n')
restartBmNotify()
return True
elif uInput == "n":
- print '\n ***********************************************************'
- print ' Please refer to the Bitmessage Wiki on how to setup the API.'
- print ' ***********************************************************\n'
+ print('\n ***********************************************************')
+ print(' Please refer to the Bitmessage Wiki on how to setup the API.')
+ print(' ***********************************************************\n')
usrPrompt = 1
main()
else:
- print ' \nInvalid entry\n'
+ print(' \nInvalid entry\n')
usrPrompt = 1
main()
@@ -206,11 +207,11 @@ def apiData():
BMConfigParser().get('bitmessagesettings', 'port')
except:
# keys.dat was not there either, something is wrong.
- print '\n ******************************************************************'
- print ' There was a problem trying to access the Bitmessage keys.dat file'
- print ' or keys.dat is not set up correctly'
- print ' Make sure that daemon is in the same directory as Bitmessage. '
- print ' ******************************************************************\n'
+ print('\n ******************************************************************')
+ print(' There was a problem trying to access the Bitmessage keys.dat file')
+ print(' or keys.dat is not set up correctly')
+ print(' Make sure that daemon is in the same directory as Bitmessage. ')
+ print(' ******************************************************************\n')
uInput = userInput("Would you like to create a keys.dat in the local directory, (Y)es or (N)o?").lower()
@@ -220,11 +221,11 @@ def apiData():
usrPrompt = 0
main()
elif (uInput == "n" or uInput == "no"):
- print '\n Trying Again.\n'
+ print('\n Trying Again.\n')
usrPrompt = 0
main()
else:
- print '\n Invalid Input.\n'
+ print('\n Invalid Input.\n')
usrPrompt = 1
main()
@@ -249,7 +250,7 @@ def apiData():
apiUsername = BMConfigParser().get('bitmessagesettings', 'apiusername')
apiPassword = BMConfigParser().get('bitmessagesettings', 'apipassword')
- print '\n API data successfully imported.\n'
+ print('\n API data successfully imported.\n')
# Build the api credentials
return "http://" + apiUsername + ":" + apiPassword + "@" + apiInterface + ":" + str(apiPort) + "/"
@@ -281,7 +282,7 @@ def bmSettings():
try:
port = BMConfigParser().get('bitmessagesettings', 'port')
except:
- print '\n File not found.\n'
+ print('\n File not found.\n')
usrPrompt = 0
main()
@@ -300,27 +301,27 @@ def bmSettings():
socksusername = BMConfigParser().get('bitmessagesettings', 'socksusername')
sockspassword = BMConfigParser().get('bitmessagesettings', 'sockspassword')
- print '\n -----------------------------------'
- print ' | Current Bitmessage Settings |'
- print ' -----------------------------------'
- print ' port = ' + port
- print ' startonlogon = ' + str(startonlogon)
- print ' minimizetotray = ' + str(minimizetotray)
- print ' showtraynotifications = ' + str(showtraynotifications)
- print ' startintray = ' + str(startintray)
- print ' defaultnoncetrialsperbyte = ' + defaultnoncetrialsperbyte
- print ' defaultpayloadlengthextrabytes = ' + defaultpayloadlengthextrabytes
- print ' daemon = ' + str(daemon)
- print '\n ------------------------------------'
- print ' | Current Connection Settings |'
- print ' -----------------------------------'
- print ' socksproxytype = ' + socksproxytype
- print ' sockshostname = ' + sockshostname
- print ' socksport = ' + socksport
- print ' socksauthentication = ' + str(socksauthentication)
- print ' socksusername = ' + socksusername
- print ' sockspassword = ' + sockspassword
- print ' '
+ print('\n -----------------------------------')
+ print(' | Current Bitmessage Settings |')
+ print(' -----------------------------------')
+ print(' port = ' + port)
+ print(' startonlogon = ' + str(startonlogon))
+ print(' minimizetotray = ' + str(minimizetotray))
+ print(' showtraynotifications = ' + str(showtraynotifications))
+ print(' startintray = ' + str(startintray))
+ print(' defaultnoncetrialsperbyte = ' + defaultnoncetrialsperbyte)
+ print(' defaultpayloadlengthextrabytes = ' + defaultpayloadlengthextrabytes)
+ print(' daemon = ' + str(daemon))
+ print('\n ------------------------------------')
+ print(' | Current Connection Settings |')
+ print(' -----------------------------------')
+ print(' socksproxytype = ' + socksproxytype)
+ print(' sockshostname = ' + sockshostname)
+ print(' socksport = ' + socksport)
+ print(' socksauthentication = ' + str(socksauthentication))
+ print(' socksusername = ' + socksusername)
+ print(' sockspassword = ' + sockspassword)
+ print(' ')
uInput = userInput("Would you like to modify any of these settings, (Y)es or (N)o?").lower()
@@ -328,74 +329,74 @@ def bmSettings():
while True: # loops if they mistype the setting name, they can exit the loop with 'exit'
invalidInput = False
uInput = userInput("What setting would you like to modify?").lower()
- print ' '
+ print(' ')
if uInput == "port":
- print ' Current port number: ' + port
+ print(' Current port number: ' + port)
uInput = userInput("Enter the new port number.")
BMConfigParser().set('bitmessagesettings', 'port', str(uInput))
elif uInput == "startonlogon":
- print ' Current status: ' + str(startonlogon)
+ print(' Current status: ' + str(startonlogon))
uInput = userInput("Enter the new status.")
BMConfigParser().set('bitmessagesettings', 'startonlogon', str(uInput))
elif uInput == "minimizetotray":
- print ' Current status: ' + str(minimizetotray)
+ print(' Current status: ' + str(minimizetotray))
uInput = userInput("Enter the new status.")
BMConfigParser().set('bitmessagesettings', 'minimizetotray', str(uInput))
elif uInput == "showtraynotifications":
- print ' Current status: ' + str(showtraynotifications)
+ print(' Current status: ' + str(showtraynotifications))
uInput = userInput("Enter the new status.")
BMConfigParser().set('bitmessagesettings', 'showtraynotifications', str(uInput))
elif uInput == "startintray":
- print ' Current status: ' + str(startintray)
+ print(' Current status: ' + str(startintray))
uInput = userInput("Enter the new status.")
BMConfigParser().set('bitmessagesettings', 'startintray', str(uInput))
elif uInput == "defaultnoncetrialsperbyte":
- print ' Current default nonce trials per byte: ' + defaultnoncetrialsperbyte
+ print(' Current default nonce trials per byte: ' + defaultnoncetrialsperbyte)
uInput = userInput("Enter the new defaultnoncetrialsperbyte.")
BMConfigParser().set('bitmessagesettings', 'defaultnoncetrialsperbyte', str(uInput))
elif uInput == "defaultpayloadlengthextrabytes":
- print ' Current default payload length extra bytes: ' + defaultpayloadlengthextrabytes
+ print(' Current default payload length extra bytes: ' + defaultpayloadlengthextrabytes)
uInput = userInput("Enter the new defaultpayloadlengthextrabytes.")
BMConfigParser().set('bitmessagesettings', 'defaultpayloadlengthextrabytes', str(uInput))
elif uInput == "daemon":
- print ' Current status: ' + str(daemon)
+ print(' Current status: ' + str(daemon))
uInput = userInput("Enter the new status.").lower()
BMConfigParser().set('bitmessagesettings', 'daemon', str(uInput))
elif uInput == "socksproxytype":
- print ' Current socks proxy type: ' + socksproxytype
- print "Possibilities: 'none', 'SOCKS4a', 'SOCKS5'."
+ print(' Current socks proxy type: ' + socksproxytype)
+ print("Possibilities: 'none', 'SOCKS4a', 'SOCKS5'.")
uInput = userInput("Enter the new socksproxytype.")
BMConfigParser().set('bitmessagesettings', 'socksproxytype', str(uInput))
elif uInput == "sockshostname":
- print ' Current socks host name: ' + sockshostname
+ print(' Current socks host name: ' + sockshostname)
uInput = userInput("Enter the new sockshostname.")
BMConfigParser().set('bitmessagesettings', 'sockshostname', str(uInput))
elif uInput == "socksport":
- print ' Current socks port number: ' + socksport
+ print(' Current socks port number: ' + socksport)
uInput = userInput("Enter the new socksport.")
BMConfigParser().set('bitmessagesettings', 'socksport', str(uInput))
elif uInput == "socksauthentication":
- print ' Current status: ' + str(socksauthentication)
+ print(' Current status: ' + str(socksauthentication))
uInput = userInput("Enter the new status.")
BMConfigParser().set('bitmessagesettings', 'socksauthentication', str(uInput))
elif uInput == "socksusername":
- print ' Current socks username: ' + socksusername
+ print(' Current socks username: ' + socksusername)
uInput = userInput("Enter the new socksusername.")
BMConfigParser().set('bitmessagesettings', 'socksusername', str(uInput))
elif uInput == "sockspassword":
- print ' Current socks password: ' + sockspassword
+ print(' Current socks password: ' + sockspassword)
uInput = userInput("Enter the new password.")
BMConfigParser().set('bitmessagesettings', 'sockspassword', str(uInput))
else:
- print "\n Invalid input. Please try again.\n"
+ print("\n Invalid input. Please try again.\n")
invalidInput = True
if invalidInput is not True: # don't prompt if they made a mistake.
uInput = userInput("Would you like to change another setting, (Y)es or (N)o?").lower()
if uInput != "y":
- print '\n Changes Made.\n'
+ print('\n Changes Made.\n')
with open(keysPath, 'wb') as configfile:
BMConfigParser().write(configfile)
restartBmNotify()
@@ -405,7 +406,7 @@ def bmSettings():
usrPrompt = 1
main()
else:
- print "Invalid input."
+ print("Invalid input.")
usrPrompt = 1
main()
@@ -433,10 +434,10 @@ def subscribe():
if address == "c":
usrPrompt = 1
- print ' '
+ print(' ')
main()
elif validAddress(address) is False:
- print '\n Invalid. "c" to cancel. Please try again.\n'
+ print('\n Invalid. "c" to cancel. Please try again.\n')
else:
break
@@ -444,7 +445,7 @@ def subscribe():
label = label.encode('base64')
api.addSubscription(address, label)
- print '\n You are now subscribed to: ' + address + '\n'
+ print('\n You are now subscribed to: ' + address + '\n')
def unsubscribe():
@@ -456,31 +457,31 @@ def unsubscribe():
if address == "c":
usrPrompt = 1
- print ' '
+ print(' ')
main()
elif validAddress(address) is False:
- print '\n Invalid. "c" to cancel. Please try again.\n'
+ print('\n Invalid. "c" to cancel. Please try again.\n')
else:
break
userInput("Are you sure, (Y)es or (N)o?").lower() # uInput =
api.deleteSubscription(address)
- print '\n You are now unsubscribed from: ' + address + '\n'
+ print('\n You are now unsubscribed from: ' + address + '\n')
def listSubscriptions():
"""List subscriptions"""
global usrPrompt
- print '\nLabel, Address, Enabled\n'
+ print('\nLabel, Address, Enabled\n')
try:
- print api.listSubscriptions()
+ print(api.listSubscriptions())
except:
- print '\n Connection Error\n'
+ print('\n Connection Error\n')
usrPrompt = 0
main()
- print ' '
+ print(' ')
def createChan():
@@ -490,9 +491,9 @@ def createChan():
password = userInput("Enter channel name")
password = password.encode('base64')
try:
- print api.createChan(password)
+ print(api.createChan(password))
except:
- print '\n Connection Error\n'
+ print('\n Connection Error\n')
usrPrompt = 0
main()
@@ -506,19 +507,19 @@ def joinChan():
if address == "c":
usrPrompt = 1
- print ' '
+ print(' ')
main()
elif validAddress(address) is False:
- print '\n Invalid. "c" to cancel. Please try again.\n'
+ print('\n Invalid. "c" to cancel. Please try again.\n')
else:
break
password = userInput("Enter channel name")
password = password.encode('base64')
try:
- print api.joinChan(password, address)
+ print(api.joinChan(password, address))
except:
- print '\n Connection Error\n'
+ print('\n Connection Error\n')
usrPrompt = 0
main()
@@ -532,17 +533,17 @@ def leaveChan():
if address == "c":
usrPrompt = 1
- print ' '
+ print(' ')
main()
elif validAddress(address) is False:
- print '\n Invalid. "c" to cancel. Please try again.\n'
+ print('\n Invalid. "c" to cancel. Please try again.\n')
else:
break
try:
- print api.leaveChan(address)
+ print(api.leaveChan(address))
except:
- print '\n Connection Error\n'
+ print('\n Connection Error\n')
usrPrompt = 0
main()
@@ -554,14 +555,14 @@ def listAdd():
jsonAddresses = json.loads(api.listAddresses())
numAddresses = len(jsonAddresses['addresses']) # Number of addresses
except:
- print '\n Connection Error\n'
+ print('\n Connection Error\n')
usrPrompt = 0
main()
- # print '\nAddress Number,Label,Address,Stream,Enabled\n'
- print '\n --------------------------------------------------------------------------'
- print ' | # | Label | Address |S#|Enabled|'
- print ' |---|-------------------|-------------------------------------|--|-------|'
+ # print('\nAddress Number,Label,Address,Stream,Enabled\n')
+ print('\n --------------------------------------------------------------------------')
+ print(' | # | Label | Address |S#|Enabled|')
+ print(' |---|-------------------|-------------------------------------|--|-------|')
for addNum in range(0, numAddresses): # processes all of the addresses and lists them out
label = (jsonAddresses['addresses'][addNum]['label']).encode(
'utf') # may still misdiplay in some consoles
@@ -572,7 +573,7 @@ def listAdd():
if len(label) > 19:
label = label[:16] + '...'
- print ''.join([
+ print(''.join([
' |',
str(addNum).ljust(3),
'|',
@@ -584,13 +585,13 @@ def listAdd():
'|',
enabled.ljust(7),
'|',
- ])
+ ]))
- print ''.join([
+ print(''.join([
' ',
74 * '-',
'\n',
- ])
+ ]))
def genAdd(lbl, deterministic, passphrase, numOfAdd, addVNum, streamNum, ripe):
@@ -603,7 +604,7 @@ def genAdd(lbl, deterministic, passphrase, numOfAdd, addVNum, streamNum, ripe):
try:
generatedAddress = api.createRandomAddress(addressLabel)
except:
- print '\n Connection Error\n'
+ print('\n Connection Error\n')
usrPrompt = 0
main()
@@ -614,7 +615,7 @@ def genAdd(lbl, deterministic, passphrase, numOfAdd, addVNum, streamNum, ripe):
try:
generatedAddress = api.createDeterministicAddresses(passphrase, numOfAdd, addVNum, streamNum, ripe)
except:
- print '\n Connection Error\n'
+ print('\n Connection Error\n')
usrPrompt = 0
main()
return generatedAddress
@@ -646,7 +647,7 @@ def saveFile(fileName, fileData):
with open(filePath, 'wb+') as path_to_file:
path_to_file.write(fileData.decode("base64"))
- print '\n Successfully saved ' + filePath + '\n'
+ print('\n Successfully saved ' + filePath + '\n')
def attachment():
@@ -667,26 +668,26 @@ def attachment():
with open(filePath):
break
except IOError:
- print '\n %s was not found on your filesystem or can not be opened.\n' % filePath
+ print('\n %s was not found on your filesystem or can not be opened.\n' % filePath)
- # print filesize, and encoding estimate with confirmation if file is over X size (1mb?)
+ # print(filesize, and encoding estimate with confirmation if file is over X size (1mb?))
invSize = os.path.getsize(filePath)
invSize = (invSize / 1024) # Converts to kilobytes
round(invSize, 2) # Rounds to two decimal places
if invSize > 500.0: # If over 500KB
- print ''.join([
+ print(''.join([
'\n WARNING:The file that you are trying to attach is ',
invSize,
'KB and will take considerable time to send.\n'
- ])
+ ]))
uInput = userInput('Are you sure you still want to attach it, (Y)es or (N)o?').lower()
if uInput != "y":
- print '\n Attachment discarded.\n'
+ print('\n Attachment discarded.\n')
return ''
elif invSize > 184320.0: # If larger than 180MB, discard.
- print '\n Attachment too big, maximum allowed size:180MB\n'
+ print('\n Attachment too big, maximum allowed size:180MB\n')
main()
pathLen = len(str(ntpath.basename(filePath))) # Gets the length of the filepath excluding the filename
@@ -694,17 +695,17 @@ def attachment():
filetype = imghdr.what(filePath) # Tests if it is an image file
if filetype is not None:
- print '\n ---------------------------------------------------'
- print ' Attachment detected as an Image.'
- print ' tags will automatically be included,'
- print ' allowing the recipient to view the image'
- print ' using the "View HTML code..." option in Bitmessage.'
- print ' ---------------------------------------------------\n'
+ print('\n ---------------------------------------------------')
+ print(' Attachment detected as an Image.')
+ print(' tags will automatically be included,')
+ print(' allowing the recipient to view the image')
+ print(' using the "View HTML code..." option in Bitmessage.')
+ print(' ---------------------------------------------------\n')
isImage = True
time.sleep(2)
# Alert the user that the encoding process may take some time.
- print '\n Encoding Attachment, Please Wait ...\n'
+ print('\n Encoding Attachment, Please Wait ...\n')
with open(filePath, 'rb') as f: # Begin the actual encoding
data = f.read(188743680) # Reads files up to 180MB, the maximum size for Bitmessage.
@@ -759,10 +760,10 @@ def sendMsg(toAddress, fromAddress, subject, message):
if toAddress == "c":
usrPrompt = 1
- print ' '
+ print(' ')
main()
elif validAddress(toAddress) is False:
- print '\n Invalid Address. "c" to cancel. Please try again.\n'
+ print('\n Invalid Address. "c" to cancel. Please try again.\n')
else:
break
@@ -771,14 +772,14 @@ def sendMsg(toAddress, fromAddress, subject, message):
jsonAddresses = json.loads(api.listAddresses())
numAddresses = len(jsonAddresses['addresses']) # Number of addresses
except:
- print '\n Connection Error\n'
+ print('\n Connection Error\n')
usrPrompt = 0
main()
if numAddresses > 1: # Ask what address to send from if multiple addresses
found = False
while True:
- print ' '
+ print(' ')
fromAddress = userInput("Enter an Address or Address Label to send from.")
if fromAddress == "exit":
@@ -795,7 +796,7 @@ def sendMsg(toAddress, fromAddress, subject, message):
if found is False:
if validAddress(fromAddress) is False:
- print '\n Invalid Address. Please try again.\n'
+ print('\n Invalid Address. Please try again.\n')
else:
for addNum in range(0, numAddresses): # processes all of the addresses
@@ -805,13 +806,13 @@ def sendMsg(toAddress, fromAddress, subject, message):
break
if found is False:
- print '\n The address entered is not one of yours. Please try again.\n'
+ print('\n The address entered is not one of yours. Please try again.\n')
if found:
break # Address was found
else: # Only one address in address book
- print '\n Using the only address in the addressbook to send from.\n'
+ print('\n Using the only address in the addressbook to send from.\n')
fromAddress = jsonAddresses['addresses'][0]['address']
if subject == '':
@@ -828,9 +829,9 @@ def sendMsg(toAddress, fromAddress, subject, message):
try:
ackData = api.sendMessage(toAddress, fromAddress, subject, message)
- print '\n Message Status:', api.getStatus(ackData), '\n'
+ print('\n Message Status:', api.getStatus(ackData), '\n')
except:
- print '\n Connection Error\n'
+ print('\n Connection Error\n')
usrPrompt = 0
main()
@@ -845,7 +846,7 @@ def sendBrd(fromAddress, subject, message):
jsonAddresses = json.loads(api.listAddresses())
numAddresses = len(jsonAddresses['addresses']) # Number of addresses
except:
- print '\n Connection Error\n'
+ print('\n Connection Error\n')
usrPrompt = 0
main()
@@ -868,7 +869,7 @@ def sendBrd(fromAddress, subject, message):
if found is False:
if validAddress(fromAddress) is False:
- print '\n Invalid Address. Please try again.\n'
+ print('\n Invalid Address. Please try again.\n')
else:
for addNum in range(0, numAddresses): # processes all of the addresses
@@ -878,13 +879,13 @@ def sendBrd(fromAddress, subject, message):
break
if found is False:
- print '\n The address entered is not one of yours. Please try again.\n'
+ print('\n The address entered is not one of yours. Please try again.\n')
if found:
break # Address was found
else: # Only one address in address book
- print '\n Using the only address in the addressbook to send from.\n'
+ print('\n Using the only address in the addressbook to send from.\n')
fromAddress = jsonAddresses['addresses'][0]['address']
if subject == '':
@@ -901,9 +902,9 @@ def sendBrd(fromAddress, subject, message):
try:
ackData = api.sendBroadcast(fromAddress, subject, message)
- print '\n Message Status:', api.getStatus(ackData), '\n'
+ print('\n Message Status:', api.getStatus(ackData), '\n')
except:
- print '\n Connection Error\n'
+ print('\n Connection Error\n')
usrPrompt = 0
main()
@@ -916,7 +917,7 @@ def inbox(unreadOnly=False):
inboxMessages = json.loads(api.getAllInboxMessages())
numMessages = len(inboxMessages['inboxMessages'])
except:
- print '\n Connection Error\n'
+ print('\n Connection Error\n')
usrPrompt = 0
main()
@@ -926,16 +927,16 @@ def inbox(unreadOnly=False):
message = inboxMessages['inboxMessages'][msgNum]
# if we are displaying all messages or if this message is unread then display it
if not unreadOnly or not message['read']:
- print ' -----------------------------------\n'
- print ' Message Number:', msgNum # Message Number
- print ' To:', getLabelForAddress(message['toAddress']) # Get the to address
- print ' From:', getLabelForAddress(message['fromAddress']) # Get the from address
- print ' Subject:', message['subject'].decode('base64') # Get the subject
- print ''.join([
+ print(' -----------------------------------\n')
+ print(' Message Number:', msgNum) # Message Number
+ print(' To:', getLabelForAddress(message['toAddress'])) # Get the to address
+ print(' From:', getLabelForAddress(message['fromAddress'])) # Get the from address
+ print(' Subject:', message['subject'].decode('base64')) # Get the subject
+ print(''.join([
' Received:',
datetime.datetime.fromtimestamp(
float(message['receivedTime'])).strftime('%Y-%m-%d %H:%M:%S'),
- ])
+ ]))
messagesPrinted += 1
if not message['read']:
messagesUnread += 1
@@ -943,9 +944,9 @@ def inbox(unreadOnly=False):
if messagesPrinted % 20 == 0 and messagesPrinted != 0:
userInput('(Press Enter to continue or type (Exit) to return to the main menu.)').lower() # uInput =
- print '\n -----------------------------------'
- print ' There are %d unread messages of %d messages in the inbox.' % (messagesUnread, numMessages)
- print ' -----------------------------------\n'
+ print('\n -----------------------------------')
+ print(' There are %d unread messages of %d messages in the inbox.' % (messagesUnread, numMessages))
+ print(' -----------------------------------\n')
def outbox():
@@ -956,32 +957,32 @@ def outbox():
outboxMessages = json.loads(api.getAllSentMessages())
numMessages = len(outboxMessages['sentMessages'])
except:
- print '\n Connection Error\n'
+ print('\n Connection Error\n')
usrPrompt = 0
main()
for msgNum in range(0, numMessages): # processes all of the messages in the outbox
- print '\n -----------------------------------\n'
- print ' Message Number:', msgNum # Message Number
- # print ' Message ID:', outboxMessages['sentMessages'][msgNum]['msgid']
- print ' To:', getLabelForAddress(outboxMessages['sentMessages'][msgNum]['toAddress']) # Get the to address
+ print('\n -----------------------------------\n')
+ print(' Message Number:', msgNum) # Message Number
+ # print(' Message ID:', outboxMessages['sentMessages'][msgNum]['msgid'])
+ # Get the to address
+ print(' To:', getLabelForAddress(outboxMessages['sentMessages'][msgNum]['toAddress']))
# Get the from address
- print ' From:', getLabelForAddress(outboxMessages['sentMessages'][msgNum]['fromAddress'])
- print ' Subject:', outboxMessages['sentMessages'][msgNum]['subject'].decode('base64') # Get the subject
- print ' Status:', outboxMessages['sentMessages'][msgNum]['status'] # Get the subject
-
- print ''.join([
+ print(' From:', getLabelForAddress(outboxMessages['sentMessages'][msgNum]['fromAddress']))
+ print(' Subject:', outboxMessages['sentMessages'][msgNum]['subject'].decode('base64')) # Get the subject
+ print(' Status:', outboxMessages['sentMessages'][msgNum]['status']) # Get the subject
+ print(''.join([
' Last Action Time:',
datetime.datetime.fromtimestamp(
float(outboxMessages['sentMessages'][msgNum]['lastActionTime'])).strftime('%Y-%m-%d %H:%M:%S'),
- ])
+ ]))
if msgNum % 20 == 0 and msgNum != 0:
userInput('(Press Enter to continue or type (Exit) to return to the main menu.)').lower() # uInput =
- print '\n -----------------------------------'
- print ' There are ', numMessages, ' messages in the outbox.'
- print ' -----------------------------------\n'
+ print('\n -----------------------------------')
+ print(' There are ', numMessages, ' messages in the outbox.')
+ print(' -----------------------------------\n')
def readSentMsg(msgNum):
@@ -992,14 +993,14 @@ def readSentMsg(msgNum):
outboxMessages = json.loads(api.getAllSentMessages())
numMessages = len(outboxMessages['sentMessages'])
except:
- print '\n Connection Error\n'
+ print('\n Connection Error\n')
usrPrompt = 0
main()
- print ' '
+ print(' ')
if msgNum >= numMessages:
- print '\n Invalid Message Number.\n'
+ print('\n Invalid Message Number.\n')
main()
# Begin attachment detection
@@ -1035,19 +1036,19 @@ def readSentMsg(msgNum):
# End attachment Detection
- print '\n To:', getLabelForAddress(outboxMessages['sentMessages'][msgNum]['toAddress']) # Get the to address
+ print('\n To:', getLabelForAddress(outboxMessages['sentMessages'][msgNum]['toAddress'])) # Get the to address
# Get the from address
- print ' From:', getLabelForAddress(outboxMessages['sentMessages'][msgNum]['fromAddress'])
- print ' Subject:', outboxMessages['sentMessages'][msgNum]['subject'].decode('base64') # Get the subject
- print ' Status:', outboxMessages['sentMessages'][msgNum]['status'] # Get the subject
- print ''.join([
+ print(' From:', getLabelForAddress(outboxMessages['sentMessages'][msgNum]['fromAddress']))
+ print(' Subject:', outboxMessages['sentMessages'][msgNum]['subject'].decode('base64')) # Get the subject
+ print(' Status:', outboxMessages['sentMessages'][msgNum]['status']) # Get the subject
+ print(''.join([
' Last Action Time:',
datetime.datetime.fromtimestamp(
float(outboxMessages['sentMessages'][msgNum]['lastActionTime'])).strftime('%Y-%m-%d %H:%M:%S'),
- ])
- print ' Message:\n'
- print message # inboxMessages['inboxMessages'][msgNum]['message'].decode('base64')
- print ' '
+ ]))
+ print(' Message:\n')
+ print(message) # inboxMessages['inboxMessages'][msgNum]['message'].decode('base64')
+ print(' ')
def readMsg(msgNum):
@@ -1057,12 +1058,12 @@ def readMsg(msgNum):
inboxMessages = json.loads(api.getAllInboxMessages())
numMessages = len(inboxMessages['inboxMessages'])
except:
- print '\n Connection Error\n'
+ print('\n Connection Error\n')
usrPrompt = 0
main()
if msgNum >= numMessages:
- print '\n Invalid Message Number.\n'
+ print('\n Invalid Message Number.\n')
main()
# Begin attachment detection
@@ -1097,17 +1098,17 @@ def readMsg(msgNum):
break
# End attachment Detection
- print '\n To:', getLabelForAddress(inboxMessages['inboxMessages'][msgNum]['toAddress']) # Get the to address
+ print('\n To:', getLabelForAddress(inboxMessages['inboxMessages'][msgNum]['toAddress'])) # Get the to address
# Get the from address
- print ' From:', getLabelForAddress(inboxMessages['inboxMessages'][msgNum]['fromAddress'])
- print ' Subject:', inboxMessages['inboxMessages'][msgNum]['subject'].decode('base64') # Get the subject
- print ''.join([
+ print(' From:', getLabelForAddress(inboxMessages['inboxMessages'][msgNum]['fromAddress']))
+ print(' Subject:', inboxMessages['inboxMessages'][msgNum]['subject'].decode('base64')) # Get the subject
+ print(''.join([
' Received:', datetime.datetime.fromtimestamp(
float(inboxMessages['inboxMessages'][msgNum]['receivedTime'])).strftime('%Y-%m-%d %H:%M:%S'),
- ])
- print ' Message:\n'
- print message # inboxMessages['inboxMessages'][msgNum]['message'].decode('base64')
- print ' '
+ ]))
+ print(' Message:\n')
+ print(message) # inboxMessages['inboxMessages'][msgNum]['message'].decode('base64')
+ print(' ')
return inboxMessages['inboxMessages'][msgNum]['msgid']
@@ -1119,7 +1120,7 @@ def replyMsg(msgNum, forwardORreply):
try:
inboxMessages = json.loads(api.getAllInboxMessages())
except:
- print '\n Connection Error\n'
+ print('\n Connection Error\n')
usrPrompt = 0
main()
@@ -1141,14 +1142,14 @@ def replyMsg(msgNum, forwardORreply):
if toAdd == "c":
usrPrompt = 1
- print ' '
+ print(' ')
main()
elif validAddress(toAdd) is False:
- print '\n Invalid Address. "c" to cancel. Please try again.\n'
+ print('\n Invalid Address. "c" to cancel. Please try again.\n')
else:
break
else:
- print '\n Invalid Selection. Reply or Forward only'
+ print('\n Invalid Selection. Reply or Forward only')
usrPrompt = 0
main()
@@ -1180,7 +1181,7 @@ def delMsg(msgNum):
msgAck = api.trashMessage(msgId)
except:
- print '\n Connection Error\n'
+ print('\n Connection Error\n')
usrPrompt = 0
main()
@@ -1197,7 +1198,7 @@ def delSentMsg(msgNum):
msgId = outboxMessages['sentMessages'][int(msgNum)]['msgid']
msgAck = api.trashSentMessage(msgId)
except:
- print '\n Connection Error\n'
+ print('\n Connection Error\n')
usrPrompt = 0
main()
@@ -1233,7 +1234,7 @@ def buildKnownAddresses():
if entry['address'] not in knownAddresses:
knownAddresses[entry['address']] = "%s (%s)" % (entry['label'].decode('base64'), entry['address'])
except:
- print '\n Connection Error\n'
+ print('\n Connection Error\n')
usrPrompt = 0
main()
@@ -1248,7 +1249,7 @@ def buildKnownAddresses():
if entry['address'] not in knownAddresses:
knownAddresses[entry['address']] = "%s (%s)" % (entry['label'].decode('base64'), entry['address'])
except:
- print '\n Connection Error\n'
+ print('\n Connection Error\n')
usrPrompt = 0
main()
@@ -1263,21 +1264,20 @@ def listAddressBookEntries():
if "API Error" in response:
return getAPIErrorCode(response)
addressBook = json.loads(response)
- print
- print ' --------------------------------------------------------------'
- print ' | Label | Address |'
- print ' |--------------------|---------------------------------------|'
+ print()
+ print(' --------------------------------------------------------------')
+ print(' | Label | Address |')
+ print(' |--------------------|---------------------------------------|')
for entry in addressBook['addresses']:
label = entry['label'].decode('base64')
address = entry['address']
if len(label) > 19:
label = label[:16] + '...'
- print ' | ' + label.ljust(19) + '| ' + address.ljust(37) + ' |'
- print ' --------------------------------------------------------------'
- print
-
+ print(' | ' + label.ljust(19) + '| ' + address.ljust(37) + ' |')
+ print(' --------------------------------------------------------------')
+ print()
except:
- print '\n Connection Error\n'
+ print('\n Connection Error\n')
usrPrompt = 0
main()
@@ -1292,7 +1292,7 @@ def addAddressToAddressBook(address, label):
if "API Error" in response:
return getAPIErrorCode(response)
except:
- print '\n Connection Error\n'
+ print('\n Connection Error\n')
usrPrompt = 0
main()
@@ -1307,7 +1307,7 @@ def deleteAddressFromAddressBook(address):
if "API Error" in response:
return getAPIErrorCode(response)
except:
- print '\n Connection Error\n'
+ print('\n Connection Error\n')
usrPrompt = 0
main()
@@ -1331,7 +1331,7 @@ def markMessageRead(messageID):
if "API Error" in response:
return getAPIErrorCode(response)
except:
- print '\n Connection Error\n'
+ print('\n Connection Error\n')
usrPrompt = 0
main()
@@ -1346,7 +1346,7 @@ def markMessageUnread(messageID):
if "API Error" in response:
return getAPIErrorCode(response)
except:
- print '\n Connection Error\n'
+ print('\n Connection Error\n')
usrPrompt = 0
main()
@@ -1359,7 +1359,7 @@ def markAllMessagesRead():
try:
inboxMessages = json.loads(api.getAllInboxMessages())['inboxMessages']
except:
- print '\n Connection Error\n'
+ print('\n Connection Error\n')
usrPrompt = 0
main()
for message in inboxMessages:
@@ -1375,7 +1375,7 @@ def markAllMessagesUnread():
try:
inboxMessages = json.loads(api.getAllInboxMessages())['inboxMessages']
except:
- print '\n Connection Error\n'
+ print('\n Connection Error\n')
usrPrompt = 0
main()
for message in inboxMessages:
@@ -1391,15 +1391,15 @@ def clientStatus():
try:
client_status = json.loads(api.clientStatus())
except:
- print '\n Connection Error\n'
+ print('\n Connection Error\n')
usrPrompt = 0
main()
- print "\nnetworkStatus: " + client_status['networkStatus'] + "\n"
- print "\nnetworkConnections: " + str(client_status['networkConnections']) + "\n"
- print "\nnumberOfPubkeysProcessed: " + str(client_status['numberOfPubkeysProcessed']) + "\n"
- print "\nnumberOfMessagesProcessed: " + str(client_status['numberOfMessagesProcessed']) + "\n"
- print "\nnumberOfBroadcastsProcessed: " + str(client_status['numberOfBroadcastsProcessed']) + "\n"
+ print("\nnetworkStatus: " + client_status['networkStatus'] + "\n")
+ print("\nnetworkConnections: " + str(client_status['networkConnections']) + "\n")
+ print("\nnumberOfPubkeysProcessed: " + str(client_status['numberOfPubkeysProcessed']) + "\n")
+ print("\nnumberOfMessagesProcessed: " + str(client_status['numberOfMessagesProcessed']) + "\n")
+ print("\nnumberOfBroadcastsProcessed: " + str(client_status['numberOfBroadcastsProcessed']) + "\n")
def shutdown():
@@ -1409,7 +1409,7 @@ def shutdown():
api.shutdown()
except socket.error:
pass
- print "\nShutdown command relayed\n"
+ print("\nShutdown command relayed\n")
def UI(usrInput):
@@ -1418,75 +1418,75 @@ def UI(usrInput):
global usrPrompt
if usrInput == "help" or usrInput == "h" or usrInput == "?":
- print ' '
- print ' -------------------------------------------------------------------------'
- print ' | https://github.com/Dokument/PyBitmessage-Daemon |'
- print ' |-----------------------------------------------------------------------|'
- print ' | Command | Description |'
- print ' |------------------------|----------------------------------------------|'
- print ' | help | This help file. |'
- print ' | apiTest | Tests the API |'
- print ' | addInfo | Returns address information (If valid) |'
- print ' | bmSettings | BitMessage settings |'
- print ' | exit | Use anytime to return to main menu |'
- print ' | quit | Quits the program |'
- print ' |------------------------|----------------------------------------------|'
- print ' | listAddresses | Lists all of the users addresses |'
- print ' | generateAddress | Generates a new address |'
- print ' | getAddress | Get determinist address from passphrase |'
- print ' |------------------------|----------------------------------------------|'
- print ' | listAddressBookEntries | Lists entries from the Address Book |'
- print ' | addAddressBookEntry | Add address to the Address Book |'
- print ' | deleteAddressBookEntry | Deletes address from the Address Book |'
- print ' |------------------------|----------------------------------------------|'
- print ' | subscribe | Subscribes to an address |'
- print ' | unsubscribe | Unsubscribes from an address |'
- print ' |------------------------|----------------------------------------------|'
- print ' | create | Creates a channel |'
- print ' | join | Joins a channel |'
- print ' | leave | Leaves a channel |'
- print ' |------------------------|----------------------------------------------|'
- print ' | inbox | Lists the message information for the inbox |'
- print ' | outbox | Lists the message information for the outbox |'
- print ' | send | Send a new message or broadcast |'
- print ' | unread | Lists all unread inbox messages |'
- print ' | read | Reads a message from the inbox or outbox |'
- print ' | save | Saves message to text file |'
- print ' | delete | Deletes a message or all messages |'
- print ' -------------------------------------------------------------------------'
- print ' '
+ print(' ')
+ print(' -------------------------------------------------------------------------')
+ print(' | https://github.com/Dokument/PyBitmessage-Daemon |')
+ print(' |-----------------------------------------------------------------------|')
+ print(' | Command | Description |')
+ print(' |------------------------|----------------------------------------------|')
+ print(' | help | This help file. |')
+ print(' | apiTest | Tests the API |')
+ print(' | addInfo | Returns address information (If valid) |')
+ print(' | bmSettings | BitMessage settings |')
+ print(' | exit | Use anytime to return to main menu |')
+ print(' | quit | Quits the program |')
+ print(' |------------------------|----------------------------------------------|')
+ print(' | listAddresses | Lists all of the users addresses |')
+ print(' | generateAddress | Generates a new address |')
+ print(' | getAddress | Get determinist address from passphrase |')
+ print(' |------------------------|----------------------------------------------|')
+ print(' | listAddressBookEntries | Lists entries from the Address Book |')
+ print(' | addAddressBookEntry | Add address to the Address Book |')
+ print(' | deleteAddressBookEntry | Deletes address from the Address Book |')
+ print(' |------------------------|----------------------------------------------|')
+ print(' | subscribe | Subscribes to an address |')
+ print(' | unsubscribe | Unsubscribes from an address |')
+ print(' |------------------------|----------------------------------------------|')
+ print(' | create | Creates a channel |')
+ print(' | join | Joins a channel |')
+ print(' | leave | Leaves a channel |')
+ print(' |------------------------|----------------------------------------------|')
+ print(' | inbox | Lists the message information for the inbox |')
+ print(' | outbox | Lists the message information for the outbox |')
+ print(' | send | Send a new message or broadcast |')
+ print(' | unread | Lists all unread inbox messages |')
+ print(' | read | Reads a message from the inbox or outbox |')
+ print(' | save | Saves message to text file |')
+ print(' | delete | Deletes a message or all messages |')
+ print(' -------------------------------------------------------------------------')
+ print(' ')
main()
elif usrInput == "apitest": # tests the API Connection.
if apiTest():
- print '\n API connection test has: PASSED\n'
+ print('\n API connection test has: PASSED\n')
else:
- print '\n API connection test has: FAILED\n'
+ print('\n API connection test has: FAILED\n')
main()
elif usrInput == "addinfo":
tmp_address = userInput('\nEnter the Bitmessage Address.')
address_information = json.loads(api.decodeAddress(tmp_address))
- print '\n------------------------------'
+ print('\n------------------------------')
if 'success' in str(address_information['status']).lower():
- print ' Valid Address'
- print ' Address Version: %s' % str(address_information['addressVersion'])
- print ' Stream Number: %s' % str(address_information['streamNumber'])
+ print(' Valid Address')
+ print(' Address Version: %s' % str(address_information['addressVersion']))
+ print(' Stream Number: %s' % str(address_information['streamNumber']))
else:
- print ' Invalid Address !'
+ print(' Invalid Address !')
- print '------------------------------\n'
+ print('------------------------------\n')
main()
elif usrInput == "bmsettings": # tests the API Connection.
bmSettings()
- print ' '
+ print(' ')
main()
elif usrInput == "quit": # Quits the application
- print '\n Bye\n'
+ print('\n Bye\n')
sys.exit(0)
elif usrInput == "listaddresses": # Lists all of the identities in the addressbook
@@ -1508,17 +1508,17 @@ def UI(usrInput):
if isRipe == "y":
ripe = True
- print genAdd(lbl, deterministic, passphrase, numOfAdd, addVNum, streamNum, ripe)
+ print(genAdd(lbl, deterministic, passphrase, numOfAdd, addVNum, streamNum, ripe))
main()
elif isRipe == "n":
ripe = False
- print genAdd(lbl, deterministic, passphrase, numOfAdd, addVNum, streamNum, ripe)
+ print(genAdd(lbl, deterministic, passphrase, numOfAdd, addVNum, streamNum, ripe))
main()
elif isRipe == "exit":
usrPrompt = 1
main()
else:
- print '\n Invalid input\n'
+ print('\n Invalid input\n')
main()
elif uInput == "r" or uInput == "random": # Creates a random address with user-defined label
@@ -1526,18 +1526,18 @@ def UI(usrInput):
null = ''
lbl = userInput('Enter the label for the new address.')
- print genAdd(lbl, deterministic, null, null, null, null, null)
+ print(genAdd(lbl, deterministic, null, null, null, null, null))
main()
else:
- print '\n Invalid input\n'
+ print('\n Invalid input\n')
main()
elif usrInput == "getaddress": # Gets the address for/from a passphrase
phrase = userInput("Enter the address passphrase.")
- print '\n Working...\n'
+ print('\n Working...\n')
address = getAddress(phrase, 4, 1) # ,vNumber,sNumber)
- print '\n Address: ' + address + '\n'
+ print('\n Address: ' + address + '\n')
usrPrompt = 1
main()
@@ -1572,17 +1572,17 @@ def UI(usrInput):
main()
elif usrInput == "inbox":
- print '\n Loading...\n'
+ print('\n Loading...\n')
inbox()
main()
elif usrInput == "unread":
- print '\n Loading...\n'
+ print('\n Loading...\n')
inbox(True)
main()
elif usrInput == "outbox":
- print '\n Loading...\n'
+ print('\n Loading...\n')
outbox()
main()
@@ -1603,14 +1603,14 @@ def UI(usrInput):
uInput = userInput("Would you like to read a message from the (I)nbox or (O)utbox?").lower()
if (uInput != 'i' and uInput != 'inbox' and uInput != 'o' and uInput != 'outbox'):
- print '\n Invalid Input.\n'
+ print('\n Invalid Input.\n')
usrPrompt = 1
main()
msgNum = int(userInput("What is the number of the message you wish to open?"))
if (uInput == 'i' or uInput == 'inbox'):
- print '\n Loading...\n'
+ print('\n Loading...\n')
messageID = readMsg(msgNum)
uInput = userInput("\nWould you like to keep this message unread, (Y)es or (N)o?").lower()
@@ -1622,14 +1622,14 @@ def UI(usrInput):
uInput = userInput("\nWould you like to (D)elete, (F)orward, (R)eply to, or (Exit) this message?").lower()
if uInput in ['r', 'reply']:
- print '\n Loading...\n'
- print ' '
+ print('\n Loading...\n')
+ print(' ')
replyMsg(msgNum, 'reply')
usrPrompt = 1
elif uInput == 'f' or uInput == 'forward':
- print '\n Loading...\n'
- print ' '
+ print('\n Loading...\n')
+ print(' ')
replyMsg(msgNum, 'forward')
usrPrompt = 1
@@ -1638,12 +1638,12 @@ def UI(usrInput):
if uInput == "y":
delMsg(msgNum)
- print '\n Message Deleted.\n'
+ print('\n Message Deleted.\n')
usrPrompt = 1
else:
usrPrompt = 1
else:
- print '\n Invalid entry\n'
+ print('\n Invalid entry\n')
usrPrompt = 1
elif (uInput == 'o' or uInput == 'outbox'):
@@ -1657,12 +1657,12 @@ def UI(usrInput):
if uInput == "y":
delSentMsg(msgNum)
- print '\n Message Deleted.\n'
+ print('\n Message Deleted.\n')
usrPrompt = 1
else:
usrPrompt = 1
else:
- print '\n Invalid Entry\n'
+ print('\n Invalid Entry\n')
usrPrompt = 1
main()
@@ -1672,7 +1672,7 @@ def UI(usrInput):
uInput = userInput("Would you like to save a message from the (I)nbox or (O)utbox?").lower()
if uInput not in ['i', 'inbox', 'o', 'outbox']:
- print '\n Invalid Input.\n'
+ print('\n Invalid Input.\n')
usrPrompt = 1
main()
@@ -1684,7 +1684,7 @@ def UI(usrInput):
msgNum = int(userInput("What is the number of the message you wish to save?"))
if msgNum >= numMessages:
- print '\n Invalid Message Number.\n'
+ print('\n Invalid Message Number.\n')
else:
break
@@ -1700,7 +1700,7 @@ def UI(usrInput):
msgNum = int(userInput("What is the number of the message you wish to save?"))
if msgNum >= numMessages:
- print '\n Invalid Message Number.\n'
+ print('\n Invalid Message Number.\n')
else:
break
@@ -1729,7 +1729,7 @@ def UI(usrInput):
if msgNum == 'a' or msgNum == 'all':
break
elif int(msgNum) >= numMessages:
- print '\n Invalid Message Number.\n'
+ print('\n Invalid Message Number.\n')
else:
break
@@ -1737,17 +1737,17 @@ def UI(usrInput):
if uInput == "y":
if msgNum in ['a', 'all']:
- print ' '
+ print(' ')
for msgNum in range(0, numMessages): # processes all of the messages in the inbox
- print ' Deleting message ', msgNum + 1, ' of ', numMessages
+ print(' Deleting message ', msgNum + 1, ' of ', numMessages)
delMsg(0)
- print '\n Inbox is empty.'
+ print('\n Inbox is empty.')
usrPrompt = 1
else:
delMsg(int(msgNum))
- print '\n Notice: Message numbers may have changed.\n'
+ print('\n Notice: Message numbers may have changed.\n')
main()
else:
usrPrompt = 1
@@ -1763,7 +1763,7 @@ def UI(usrInput):
if msgNum in ['a', 'all']:
break
elif int(msgNum) >= numMessages:
- print '\n Invalid Message Number.\n'
+ print('\n Invalid Message Number.\n')
else:
break
@@ -1771,33 +1771,33 @@ def UI(usrInput):
if uInput == "y":
if msgNum in ['a', 'all']:
- print ' '
+ print(' ')
for msgNum in range(0, numMessages): # processes all of the messages in the outbox
- print ' Deleting message ', msgNum + 1, ' of ', numMessages
+ print(' Deleting message ', msgNum + 1, ' of ', numMessages)
delSentMsg(0)
- print '\n Outbox is empty.'
+ print('\n Outbox is empty.')
usrPrompt = 1
else:
delSentMsg(int(msgNum))
- print '\n Notice: Message numbers may have changed.\n'
+ print('\n Notice: Message numbers may have changed.\n')
main()
else:
usrPrompt = 1
else:
- print '\n Invalid Entry.\n'
+ print('\n Invalid Entry.\n')
usrPrompt = 1
main()
elif usrInput == "exit":
- print '\n You are already at the main menu. Use "quit" to quit.\n'
+ print('\n You are already at the main menu. Use "quit" to quit.\n')
usrPrompt = 1
main()
elif usrInput == "listaddressbookentries":
res = listAddressBookEntries()
if res == 20:
- print '\n Error: API function not supported.\n'
+ print('\n Error: API function not supported.\n')
usrPrompt = 1
main()
@@ -1806,9 +1806,9 @@ def UI(usrInput):
label = userInput('Enter label')
res = addAddressToAddressBook(address, label)
if res == 16:
- print '\n Error: Address already exists in Address Book.\n'
+ print('\n Error: Address already exists in Address Book.\n')
if res == 20:
- print '\n Error: API function not supported.\n'
+ print('\n Error: API function not supported.\n')
usrPrompt = 1
main()
@@ -1816,7 +1816,7 @@ def UI(usrInput):
address = userInput('Enter address')
res = deleteAddressFromAddressBook(address)
if res == 20:
- print '\n Error: API function not supported.\n'
+ print('\n Error: API function not supported.\n')
usrPrompt = 1
main()
@@ -1841,7 +1841,7 @@ def UI(usrInput):
main()
else:
- print '\n "', usrInput, '" is not a command.\n'
+ print('\n "', usrInput, '" is not a command.\n')
usrPrompt = 1
main()
@@ -1853,24 +1853,24 @@ def main():
global usrPrompt
if usrPrompt == 0:
- print '\n ------------------------------'
- print ' | Bitmessage Daemon by .dok |'
- print ' | Version 0.3.1 for BM 0.6.2 |'
- print ' ------------------------------'
+ print('\n ------------------------------')
+ print(' | Bitmessage Daemon by .dok |')
+ print(' | Version 0.3.1 for BM 0.6.2 |')
+ print(' ------------------------------')
api = xmlrpclib.ServerProxy(apiData()) # Connect to BitMessage using these api credentials
if apiTest() is False:
- print '\n ****************************************************************'
- print ' WARNING: You are not connected to the Bitmessage client.'
- print ' Either Bitmessage is not running or your settings are incorrect.'
- print ' Use the command "apiTest" or "bmSettings" to resolve this issue.'
- print ' ****************************************************************\n'
+ print('\n ****************************************************************')
+ print(' WARNING: You are not connected to the Bitmessage client.')
+ print(' Either Bitmessage is not running or your settings are incorrect.')
+ print(' Use the command "apiTest" or "bmSettings" to resolve this issue.')
+ print(' ****************************************************************\n')
- print 'Type (H)elp for a list of commands.' # Startup message
+ print('Type (H)elp for a list of commands.') # Startup message
usrPrompt = 2
elif usrPrompt == 1:
- print '\nType (H)elp for a list of commands.' # Startup message
+ print('\nType (H)elp for a list of commands.') # Startup message
usrPrompt = 2
try:
diff --git a/src/bitmessagecurses/__init__.py b/src/bitmessagecurses/__init__.py
index d8daeef7..d4b72f8c 100644
--- a/src/bitmessagecurses/__init__.py
+++ b/src/bitmessagecurses/__init__.py
@@ -258,7 +258,7 @@ def drawtab(stdscr):
stdscr.addstr(6, 18, "Connections", curses.A_BOLD)
stdscr.hline(7, 6, '-', 23)
streamcount = []
- for host, stream in connected_hosts:
+ for _, stream in connected_hosts:
if stream >= len(streamcount):
streamcount.append(1)
else:
@@ -1016,7 +1016,7 @@ def sendMessage(sender="", recv="", broadcast=None, subject="", body="", reply=F
def loadInbox():
"""Load the list of messages"""
sys.stdout = sys.__stdout__
- print "Loading inbox messages..."
+ print("Loading inbox messages...")
sys.stdout = printlog
where = "toaddress || fromaddress || subject || message"
@@ -1068,7 +1068,7 @@ def loadInbox():
def loadSent():
"""Load the messages that sent"""
sys.stdout = sys.__stdout__
- print "Loading sent messages..."
+ print("Loading sent messages...")
sys.stdout = printlog
where = "toaddress || fromaddress || subject || message"
@@ -1154,7 +1154,7 @@ def loadSent():
def loadAddrBook():
"""Load address book"""
sys.stdout = sys.__stdout__
- print "Loading address book..."
+ print("Loading address book...")
sys.stdout = printlog
ret = sqlQuery("SELECT label, address FROM addressbook")
@@ -1261,7 +1261,7 @@ def run(stdscr):
def doShutdown():
"""Shutting the app down"""
sys.stdout = sys.__stdout__
- print "Shutting down..."
+ print("Shutting down...")
sys.stdout = printlog
shutdown.doCleanShutdown()
sys.stdout = sys.__stdout__
diff --git a/src/bitmessagekivy/identiconGeneration.py b/src/bitmessagekivy/identiconGeneration.py
index ca8bd3bd..0f8c4203 100644
--- a/src/bitmessagekivy/identiconGeneration.py
+++ b/src/bitmessagekivy/identiconGeneration.py
@@ -2,7 +2,6 @@
Core classes for loading images and converting them to a Texture.
The raw image data can be keep in memory for further access
"""
-
import hashlib
from io import BytesIO
@@ -13,7 +12,7 @@ from kivy.uix.image import Image as kiImage
# constants
-RESOLUTION = 128, 128
+RESOLUTION = 300, 300
V_RESOLUTION = 7, 7
BACKGROUND_COLOR = 255, 255, 255, 255
MODE = "RGB"
@@ -26,7 +25,6 @@ def generate(Generate_string=None):
image = Image.new(MODE, V_RESOLUTION, BACKGROUND_COLOR)
image = generate_image(image, color, hash_string)
image = image.resize(RESOLUTION, 0)
-
data = BytesIO()
image.save(data, format='png')
data.seek(0)
@@ -45,13 +43,11 @@ def generate_hash(string):
# make input case insensitive
string = str.lower(string)
hash_object = hashlib.md5(str.encode(string))
- print hash_object.hexdigest()
-
+ print(hash_object.hexdigest())
# returned object is a hex string
return hash_object.hexdigest()
-
except IndexError:
- print "Error: Please enter a string as an argument."
+ print("Error: Please enter a string as an argument.")
def random_color(hash_string):
@@ -59,35 +55,27 @@ def random_color(hash_string):
# remove first three digits from hex string
split = 6
rgb = hash_string[:split]
-
split = 2
r = rgb[:split]
g = rgb[split:2 * split]
b = rgb[2 * split:3 * split]
-
- color = (int(r, 16), int(g, 16),
- int(b, 16), 0xFF)
-
+ color = (int(r, 16), int(g, 16), int(b, 16), 0xFF)
return color
def generate_image(image, color, hash_string):
"""Generating images"""
hash_string = hash_string[6:]
-
lower_x = 1
lower_y = 1
upper_x = int(V_RESOLUTION[0] / 2) + 1
upper_y = V_RESOLUTION[1] - 1
limit_x = V_RESOLUTION[0] - 1
index = 0
-
for x in range(lower_x, upper_x):
for y in range(lower_y, upper_y):
if int(hash_string[index], 16) % 2 == 0:
image.putpixel((x, y), color)
image.putpixel((limit_x - x, y), color)
-
index = index + 1
-
return image
diff --git a/src/bitmessagekivy/kivy_helper_search.py b/src/bitmessagekivy/kivy_helper_search.py
index 085e2aa2..5842d116 100644
--- a/src/bitmessagekivy/kivy_helper_search.py
+++ b/src/bitmessagekivy/kivy_helper_search.py
@@ -7,24 +7,24 @@ 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):
- """Method helping for searching mails"""
# pylint: disable=too-many-arguments, too-many-branches
+ """Method helping for searching mails"""
if what is not None and what != "":
what = "%" + what + "%"
else:
what = None
-
- if folder == "sent" or folder == "draft":
+ if folder in ("sent", "draft"):
sqlStatementBase = (
'''SELECT toaddress, fromaddress, subject, message, status,'''
- ''' ackdata, lastactiontime FROM sent ''')
+ ''' ackdata, senttime FROM sent '''
+ )
elif folder == "addressbook":
sqlStatementBase = '''SELECT label, address From addressbook '''
else:
sqlStatementBase = (
'''SELECT folder, msgid, toaddress, message, fromaddress,'''
- ''' subject, received, read FROM inbox ''')
-
+ ''' subject, received, read FROM inbox '''
+ )
sqlStatementParts = []
sqlArguments = []
if account is not None:
@@ -60,13 +60,14 @@ def search_sql(
sqlStatementParts.append("read = 0")
if sqlStatementParts:
sqlStatementBase += "WHERE " + " AND ".join(sqlStatementParts)
- if folder == "sent" or folder == "draft":
+ # if folder in ("sent", "draft"):
+ if folder in ("sent", "draft"):
sqlStatementBase += \
- " ORDER BY lastactiontime DESC limit {0}, {1}".format(
+ "ORDER BY senttime DESC limit {0}, {1}".format(
start_indx, end_indx)
elif folder == "inbox":
sqlStatementBase += \
- " ORDER BY received DESC limit {0}, {1}".format(
+ "ORDER BY received DESC limit {0}, {1}".format(
start_indx, end_indx)
# elif folder == "addressbook":
# sqlStatementBase += " limit {0}, {1}".format(start_indx, end_indx)
diff --git a/src/bitmessagekivy/kv/addressbook.kv b/src/bitmessagekivy/kv/addressbook.kv
new file mode 100644
index 00000000..e789afa0
--- /dev/null
+++ b/src/bitmessagekivy/kv/addressbook.kv
@@ -0,0 +1,24 @@
+:
+ name: 'addressbook'
+ BoxLayout:
+ orientation: 'vertical'
+ spacing: dp(5)
+ SearchBar:
+ GridLayout:
+ id: identi_tag
+ padding: [20, 0, 0, 5]
+ cols: 1
+ size_hint_y: None
+ height: self.minimum_height
+ MDLabel:
+ text: ''
+ font_style: 'Subtitle2'
+ BoxLayout:
+ orientation:'vertical'
+ ScrollView:
+ id: scroll_y
+ do_scroll_x: False
+ MDList:
+ id: ml
+ Loader:
+ ComposerButton:
\ No newline at end of file
diff --git a/src/bitmessagekivy/kv/allmails.kv b/src/bitmessagekivy/kv/allmails.kv
new file mode 100644
index 00000000..a0514a48
--- /dev/null
+++ b/src/bitmessagekivy/kv/allmails.kv
@@ -0,0 +1,24 @@
+:
+ name: 'allmails'
+ BoxLayout:
+ orientation: 'vertical'
+ spacing: dp(5)
+ GridLayout:
+ id: identi_tag
+ padding: [20, 20, 0, 5]
+ spacing: dp(5)
+ cols: 1
+ size_hint_y: None
+ height: self.minimum_height
+ MDLabel:
+ text: ''
+ font_style: 'Subtitle2'
+ BoxLayout:
+ orientation:'vertical'
+ ScrollView:
+ id: scroll_y
+ do_scroll_x: False
+ MDList:
+ id: ml
+ Loader:
+ ComposerButton:
\ No newline at end of file
diff --git a/src/bitmessagekivy/kv/common_widgets.kv b/src/bitmessagekivy/kv/common_widgets.kv
new file mode 100644
index 00000000..dfcde98e
--- /dev/null
+++ b/src/bitmessagekivy/kv/common_widgets.kv
@@ -0,0 +1,65 @@
+:
+ source: './images/down-arrow.png' if self.parent.is_open == True else './images/right-arrow.png'
+ size: 15, 15
+ x: self.parent.x + self.parent.width - self.width - 5
+ y: self.parent.y + self.parent.height/2 - self.height + 5
+
+:
+ id: search_bar
+ size_hint_y: None
+ height: self.minimum_height
+
+ MDIconButton:
+ icon: 'magnify'
+
+ MDTextField:
+ id: search_field
+ hint_text: 'Search'
+ on_text: app.searchQuery(self)
+ canvas.before:
+ Color:
+ rgba: (0,0,0,1)
+
+:
+ id: spinner
+ size_hint: None, None
+ size: dp(46), dp(46)
+ pos_hint: {'center_x': 0.5, 'center_y': 0.5}
+ active: False
+
+:
+ size_hint_y: None
+ height: dp(56)
+ spacing: '10dp'
+ pos_hint: {'center_x':0.45, 'center_y': .1}
+
+ Widget:
+
+ MDFloatingActionButton:
+ icon: 'plus'
+ opposite_colors: True
+ elevation_normal: 8
+ md_bg_color: [0.941, 0, 0,1]
+ on_press: app.root.ids.scr_mngr.current = 'create'
+ on_press: app.clear_composer()
+
+
+:
+ id: cpyButton
+ color: 0,0,0,1
+ background_color: (0,0,0,0)
+ center_x: self.parent.center_x * 2 - self.parent.parent.padding[0]/2
+ center_y: self.parent.center_y
+ on_press:app.root.ids.sc14.copy_composer_text(self)
+ Image:
+ source: './images/copy_text.png'
+ center_x: self.parent.center_x
+ center_y: self.parent.center_y
+ size: 20, 20
+
+
+:
+ #size_hint: None, None
+ size: dp(36), dp(48)
+ pos_hint: {'center_x': .95, 'center_y': .4}
+ on_press: app.root.ids.sc10.toggleAction(self)
diff --git a/src/bitmessagekivy/kv/composer.kv b/src/bitmessagekivy/kv/composer.kv
new file mode 100644
index 00000000..25a47e3d
--- /dev/null
+++ b/src/bitmessagekivy/kv/composer.kv
@@ -0,0 +1,109 @@
+:
+ ScrollView:
+ BoxLayout:
+ orientation: 'vertical'
+ size_hint_y: None
+ height: self.minimum_height + 2 * self.parent.height/4
+ padding: dp(32)
+ spacing: 15
+ BoxLayout:
+ orientation: 'vertical'
+ MyMDTextField:
+ id: ti
+ hint_text: 'type or select sender address'
+ size_hint_y: None
+ height: 100
+ font_size: '13sp'
+ multiline: False
+ required: True
+ helper_text_mode: "on_error"
+
+ BoxLayout:
+ size_hint_y: None
+ height: dp(40)
+ CustomSpinner:
+ id: btn
+ background_color: app.theme_cls.primary_dark
+ values: app.variable_1
+ on_text: root.auto_fill_fromaddr() if self.text != 'Select' else ''
+ option_cls: Factory.get("MySpinnerOption")
+ #background_color: color_button if self.state == 'normal' else color_button_pressed
+ #background_down: 'atlas://data/images/defaulttheme/spinner'
+ background_normal: ''
+ background_color: app.theme_cls.primary_color
+ color: color_font
+ font_size: '12.5sp'
+ ArrowImg:
+
+ BoxLayout:
+ orientation: 'vertical'
+ txt_input: txt_input
+ rv: rv
+ size : (890, 60)
+ MyTextInput:
+ id: txt_input
+ size_hint_y: None
+ font_size: '13sp'
+ height: self.parent.height/2
+ hint_text: 'type, select or scan QR code for recipients address'
+ RV:
+ id: rv
+ MyMDTextField:
+ id: subject
+ hint_text: 'subject'
+ required: True
+ height: 100
+ font_size: '13sp'
+ size_hint_y: None
+ multiline: False
+ helper_text_mode: "on_error"
+
+ MyMDTextField:
+ id: body
+ multiline: True
+ hint_text: 'body'
+ size_hint_y: None
+ font_size: '13sp'
+ required: True
+ helper_text_mode: "on_error"
+ BoxLayout:
+ spacing:50
+
+:
+ readonly: False
+ multiline: False
+
+
+:
+ # Draw a background to indicate selection
+ color: 0,0,0,1
+ canvas.before:
+ Color:
+ rgba: app.theme_cls.primary_dark if self.selected else (1, 1, 1, 0)
+ Rectangle:
+ pos: self.pos
+ size: self.size
+
+:
+ canvas:
+ Color:
+ rgba: 0,0,0,.2
+
+ Line:
+ rectangle: self.x +1 , self.y, self.width - 2, self.height -2
+ bar_width: 10
+ scroll_type:['bars']
+ viewclass: 'SelectableLabel'
+ SelectableRecycleBoxLayout:
+ default_size: None, dp(20)
+ default_size_hint: 1, None
+ size_hint_y: None
+ height: self.minimum_height
+ orientation: 'vertical'
+ multiselect: False
+
+
+:
+ canvas.before:
+ Color:
+ rgba: (0,0,0,1)
\ No newline at end of file
diff --git a/src/bitmessagekivy/kv/credits.kv b/src/bitmessagekivy/kv/credits.kv
new file mode 100644
index 00000000..9371311f
--- /dev/null
+++ b/src/bitmessagekivy/kv/credits.kv
@@ -0,0 +1,20 @@
+:
+ name: 'credits'
+ ScrollView:
+ do_scroll_x: False
+ MDList:
+ id: ml
+ size_hint_y: None
+ height: dp(200)
+ OneLineListItem:
+ text: "Available Credits"
+ BoxLayout:
+ AnchorLayout:
+ MDRaisedButton:
+ height: dp(40)
+ MDLabel:
+ font_style: 'H4'
+ text: root.available_credits
+ font_size: '13sp'
+ color: (1,1,1,1)
+ halign: 'center'
\ No newline at end of file
diff --git a/src/bitmessagekivy/kv/draft.kv b/src/bitmessagekivy/kv/draft.kv
new file mode 100644
index 00000000..8182d91e
--- /dev/null
+++ b/src/bitmessagekivy/kv/draft.kv
@@ -0,0 +1,22 @@
+:
+ name: 'draft'
+ BoxLayout:
+ orientation: 'vertical'
+ spacing: dp(5)
+ GridLayout:
+ id: identi_tag
+ padding: [20, 20, 0, 5]
+ cols: 1
+ size_hint_y: None
+ height: self.minimum_height
+ MDLabel:
+ text: ''
+ font_style: 'Subtitle2'
+ BoxLayout:
+ orientation:'vertical'
+ ScrollView:
+ id: scroll_y
+ do_scroll_x: False
+ MDList:
+ id: ml
+ ComposerButton:
\ No newline at end of file
diff --git a/src/bitmessagekivy/kv/inbox.kv b/src/bitmessagekivy/kv/inbox.kv
new file mode 100644
index 00000000..106d2d47
--- /dev/null
+++ b/src/bitmessagekivy/kv/inbox.kv
@@ -0,0 +1,32 @@
+:
+ name: 'inbox'
+ #transition: NoTransition()
+ BoxLayout:
+ orientation: 'vertical'
+ spacing: dp(5)
+ SearchBar:
+ GridLayout:
+ id: identi_tag
+ padding: [20, 0, 0, 5]
+ cols: 1
+ size_hint_y: None
+ height: self.minimum_height
+ MDLabel:
+ text: ''
+ font_style: 'Subtitle2'
+ #FloatLayout:
+ # MDScrollViewRefreshLayout:
+ # id: refresh_layout
+ # refresh_callback: root.refresh_callback
+ # root_layout: root.set_root_layout()
+ # MDList:
+ # id: ml
+ BoxLayout:
+ orientation:'vertical'
+ ScrollView:
+ id: scroll_y
+ do_scroll_x: False
+ MDList:
+ id: ml
+ Loader:
+ ComposerButton:
\ No newline at end of file
diff --git a/src/bitmessagekivy/kv/login.kv b/src/bitmessagekivy/kv/login.kv
new file mode 100644
index 00000000..c668ebd1
--- /dev/null
+++ b/src/bitmessagekivy/kv/login.kv
@@ -0,0 +1,106 @@
+:
+ name: 'login'
+ ScrollView:
+ do_scroll_x: False
+ BoxLayout:
+ orientation: 'vertical'
+ size_hint_y: None
+ height: dp(750)
+ padding: dp(10)
+ BoxLayout:
+ MDLabel:
+ font_style: 'Subtitle2'
+ theme_text_color: 'Primary'
+ text: "You may generate addresses by using either random numbers or by using a passphrase If you use a passphrase, the address is called a deterministic; address The Random Number option is selected by default but deterministic addresses have several \n pros and cons:\n"
+ halign: 'center'
+ color:app.theme_cls.primary_dark
+ BoxLayout:
+ MDLabel:
+ font_style: 'Subtitle2'
+ theme_text_color: 'Primary'
+ text: "If talk about pros You can recreate your addresses on any computer from memory, You need-not worry about backing up your keys.dat file as long as you can remember your passphrase and aside talk about cons You must remember (or write down) your You must remember the address version number and the stream number along with your passphrase If you choose a weak passphrase and someone on the Internet can brute-force it, they can read your messages and send messages as you"
+ halign: 'center'
+ color:app.theme_cls.primary_dark
+ MDCheckbox:
+ id: grp_chkbox_1
+ group: 'test'
+ active: True
+ allow_no_selection: False
+ MDLabel:
+ font_style: 'Body2'
+ theme_text_color: 'Primary'
+ text: "use a random number generator to make an address"
+ halign: 'center'
+ size_hint_y: None
+ height: self.texture_size[1] + dp(4)
+ color: [0.941, 0, 0,1]
+ MDCheckbox:
+ id: grp_chkbox_1
+ group: 'test'
+ allow_no_selection: False
+ MDLabel:
+ font_style: 'Body2'
+ theme_text_color: 'Primary'
+ text: "use a pseudo number generator to make an address"
+ halign: 'center'
+ size_hint_y: None
+ color: [0.941, 0, 0,1]
+ height: self.texture_size[1] + dp(4)
+ BoxLayout:
+ AnchorLayout:
+ MDRaisedButton:
+ height: dp(40)
+ on_press: app.root.ids.scr_mngr.current = 'random'
+ on_press: app.root.ids.sc7.reset_address_label()
+ MDLabel:
+ font_style: 'H6'
+ text: 'proceed'
+ font_size: '13sp'
+ color: (1,1,1,1)
+ halign: 'center'
+
+:
+ name: 'random'
+ ScrollView:
+ BoxLayout:
+ orientation: 'vertical'
+ size_hint_y: None
+ height: self.minimum_height
+ padding: dp(20)
+ spacing: 100
+ MDLabel:
+ font_style: 'Subtitle2'
+ theme_text_color: 'Primary'
+ text: "Random Addresses"
+ halign: 'center'
+ color:app.theme_cls.primary_dark
+
+ MDLabel:
+ font_style: 'Subtitle2'
+ theme_text_color: 'Primary'
+ text: "Here you may generate as many addresses as you like, Indeed creating and abandoning addresses is encouraged"
+ halign: 'center'
+ color:app.theme_cls.primary_dark
+
+ MDTextField:
+ id: label
+ multiline: True
+ hint_text: "Label"
+ required: True
+ helper_text_mode: "on_error"
+ on_text: root.add_validation(self)
+ canvas.before:
+ Color:
+ rgba: (0,0,0,1)
+ BoxLayout:
+ AnchorLayout:
+ MDRaisedButton:
+ height: dp(40)
+ on_release: root.generateaddress(app)
+ opposite_colors: True
+ MDLabel:
+ font_style: 'H6'
+ text: 'next'
+ font_size: '13sp'
+ color: (1,1,1,1)
+ halign: 'center'
diff --git a/src/bitmessagekivy/kv/maildetail.kv b/src/bitmessagekivy/kv/maildetail.kv
new file mode 100644
index 00000000..710a49c7
--- /dev/null
+++ b/src/bitmessagekivy/kv/maildetail.kv
@@ -0,0 +1,84 @@
+:
+ name: 'mailDetail'
+ # ScrollView:
+ # do_scroll_x: False
+ # BoxLayout:
+ # orientation: 'vertical'
+ # size_hint_y: None
+ # height: dp(500) + self.minimum_height
+ # padding: dp(32)
+ # MDLabel:
+ # font_style: 'Subtitle1'
+ # theme_text_color: 'Primary'
+ # text: root.subject
+ # halign: 'left'
+ # font_size: '20sp'
+ # CopyTextBtn:
+ # MDLabel:
+ # font_style: 'Body1'
+ # theme_text_color: 'Primary'
+ # text: "From: " + root.from_addr
+ # halign: 'left'
+ # CopyTextBtn:
+ # MDLabel:
+ # font_style: 'Body1'
+ # theme_text_color: 'Primary'
+ # text: "To: " + root.to_addr
+ # halign: 'left'
+ # CopyTextBtn:
+ # MDLabel:
+ # font_style: 'Body1'
+ # theme_text_color: 'Primary'
+ # text: root.status
+ # halign: 'left'
+ # MDLabel:
+ # font_style: 'Subtitle2'
+ # theme_text_color: 'Primary'
+ # text: root.message
+ # halign: 'left'
+ # bold: True
+ # CopyTextBtn:
+ # BoxLayout:
+ # orientation: 'vertical'
+ # size_hint_y: None
+ # height: dp(100) + self.minimum_height
+ ScrollView:
+ do_scroll_x: False
+ BoxLayout:
+ size_hint_y: None
+ orientation: 'vertical'
+ height: dp(bod.height) + self.minimum_height
+ padding: dp(20)
+ OneLineListItem:
+ id: subj
+ text: root.subject
+ divider: None
+ disabled: True
+ font_style: 'H5'
+ theme_text_color: 'Primary'
+ TwoLineAvatarIconListItem:
+ id: subaft
+ text: root.from_addr
+ secondary_text: 'to ' + root.to_addr
+ divider: None
+ BadgeText:
+ text: root.time_tag
+ halign:'right'
+ font_style:'Caption'
+ AvatarSampleWidget:
+ source: root.avatarImg
+ OneLineListItem:
+ text: root.status
+ divider: None
+ disabled: True
+ font_style: 'Body2'
+ theme_text_color: 'Primary'
+ halign:'left'
+ MDLabel:
+ id: bod
+ font_style: 'Subtitle2'
+ theme_text_color: 'Primary'
+ text: root.message
+ halign: 'left'
+ height: self.texture_size[1]
+ Loader:
\ No newline at end of file
diff --git a/src/bitmessagekivy/kv/myaddress.kv b/src/bitmessagekivy/kv/myaddress.kv
new file mode 100644
index 00000000..a150d59f
--- /dev/null
+++ b/src/bitmessagekivy/kv/myaddress.kv
@@ -0,0 +1,23 @@
+:
+ name: 'myaddress'
+ BoxLayout:
+ orientation: 'vertical'
+ spacing: dp(5)
+ SearchBar:
+ GridLayout:
+ id: identi_tag
+ padding: [20, 0, 0, 5]
+ cols: 1
+ size_hint_y: None
+ height: self.minimum_height
+ MDLabel:
+ text: 'My Addresses'
+ font_style: 'Subtitle2'
+ FloatLayout:
+ MDScrollViewRefreshLayout:
+ id: refresh_layout
+ refresh_callback: root.refresh_callback
+ root_layout: root
+ MDList:
+ id: ml
+ Loader:
diff --git a/src/bitmessagekivy/kv/network.kv b/src/bitmessagekivy/kv/network.kv
new file mode 100644
index 00000000..80d1bba1
--- /dev/null
+++ b/src/bitmessagekivy/kv/network.kv
@@ -0,0 +1,87 @@
+:
+ name: 'networkstat'
+ MDTabs:
+ id: tab_panel
+ tab_display_mode:'text'
+
+ Tab:
+ text: "Total connections"
+ ScrollView:
+ do_scroll_x: False
+ MDList:
+ id: ml
+ size_hint_y: None
+ height: dp(200)
+ OneLineListItem:
+ text: "Total Connections"
+ BoxLayout:
+ AnchorLayout:
+ MDRaisedButton:
+ size_hint: .6, .3
+ height: dp(40)
+ MDLabel:
+ font_style: 'H6'
+ text: root.text_variable_1
+ font_size: '13sp'
+ color: (1,1,1,1)
+ halign: 'center'
+ Tab:
+ text: 'Processes'
+ ScrollView:
+ do_scroll_x: False
+ MDList:
+ id: ml
+ size_hint_y: None
+ height: dp(500)
+ OneLineListItem:
+ text: "person-to-person"
+ BoxLayout:
+ AnchorLayout:
+ MDRaisedButton:
+ size_hint: .7, .55
+ height: dp(40)
+ MDLabel:
+ font_style: 'H6'
+ text: root.text_variable_2
+ font_size: '13sp'
+ color: (1,1,1,1)
+ halign: 'center'
+ OneLineListItem:
+ text: "Brodcast"
+ BoxLayout:
+ AnchorLayout:
+ MDRaisedButton:
+ size_hint: .7, .55
+ height: dp(40)
+ MDLabel:
+ font_style: 'H6'
+ text: root.text_variable_3
+ font_size: '13sp'
+ color: (1,1,1,1)
+ halign: 'center'
+ OneLineListItem:
+ text: "publickeys"
+ BoxLayout:
+ AnchorLayout:
+ MDRaisedButton:
+ size_hint: .7, .55
+ height: dp(40)
+ MDLabel:
+ font_style: 'H6'
+ text: root.text_variable_4
+ font_size: '13sp'
+ color: (1,1,1,1)
+ halign: 'center'
+ OneLineListItem:
+ text: "objects"
+ BoxLayout:
+ AnchorLayout:
+ MDRaisedButton:
+ size_hint: .7, .55
+ height: dp(40)
+ MDLabel:
+ font_style: 'H6'
+ text: root.text_variable_5
+ font_size: '13sp'
+ color: (1,1,1,1)
+ halign: 'center'
\ No newline at end of file
diff --git a/src/bitmessagekivy/kv/payment.kv b/src/bitmessagekivy/kv/payment.kv
new file mode 100644
index 00000000..2398817f
--- /dev/null
+++ b/src/bitmessagekivy/kv/payment.kv
@@ -0,0 +1,144 @@
+:
+ name: 'payment'
+ ScrollView:
+ do_scroll_x: False
+ BoxLayout:
+ orientation: 'vertical'
+ padding: [dp(app.window_size[0]/16 if app.window_size[0] <= 720 else app.window_size[0]/6 if app.window_size[0] <= 800 else app.window_size[0]/18), dp(10)]
+ spacing: 12
+ size_hint_y: None
+ height: self.minimum_height + dp(app.window_size[1]) if app.window_size[1] > app.window_size[0] else dp(app.window_size[0])
+ BoxLayout:
+ orientation: 'vertical'
+ padding: dp(5)
+ canvas.before:
+ Color:
+ rgba: app.theme_cls.primary_dark
+ Rectangle:
+ # self here refers to the widget i.e FloatLayout
+ pos: self.pos
+ size: self.size
+ MDLabel:
+ size_hint_y: None
+ font_style: 'H5'
+ theme_text_color: 'Primary'
+ text: 'Platinum'
+ halign: 'center'
+ color: 1,1,1,1
+ MDLabel:
+ font_style: 'Subtitle1'
+ theme_text_color: 'Primary'
+ text: 'We provide subscriptions for proof of work calculation for first month. '
+ halign: 'center'
+ color: 1,1,1,1
+ MDLabel:
+ id: free_pak
+ font_style: 'H5'
+ theme_text_color: 'Primary'
+ text: '€ 50.0'
+ halign: 'center'
+ color: 1,1,1,1
+ MDRaisedButton:
+ canvas:
+ Color:
+ rgb: (0.93, 0.93, 0.93)
+ Rectangle:
+ pos: self.pos
+ size: self.size
+ size: dp(app.window_size[0] - 2*self.parent.parent.padding[0]) - 10 , 1
+ height: dp(40)
+ on_press: root.get_available_credits(self)
+ MDLabel:
+ font_style: 'H6'
+ text: 'Get Free Credits'
+ font_size: '13sp'
+ color: (0,0,0,1)
+ halign: 'center'
+ BoxLayout:
+ orientation: 'vertical'
+ padding: dp(5)
+ canvas.before:
+ Color:
+ rgba: app.theme_cls.primary_dark
+ Rectangle:
+ # self here refers to the widget i.e FloatLayout
+ pos: self.pos
+ size: self.size
+ MDLabel:
+ size_hint_y: None
+ font_style: 'H5'
+ theme_text_color: 'Primary'
+ text: 'Silver'
+ halign: 'center'
+ color: 1,1,1,1
+ MDLabel:
+ font_style: 'Subtitle1'
+ theme_text_color: 'Primary'
+ text: 'We provide for proof of work calculation for six month. '
+ halign: 'center'
+ color: 1,1,1,1
+ MDLabel:
+ font_style: 'H5'
+ theme_text_color: 'Primary'
+ text: '€ 100.0'
+ halign: 'center'
+ color: 1,1,1,1
+ MDRaisedButton:
+ canvas:
+ Color:
+ rgb: (0.93, 0.93, 0.93)
+ Rectangle:
+ pos: self.pos
+ size: self.size
+ size: dp(app.window_size[0] - 2*self.parent.parent.padding[0]) - 10 , 1
+ height: dp(40)
+ MDLabel:
+ font_style: 'H6'
+ text: 'Get Monthly Credits'
+ font_size: '13sp'
+ color: (0,0,0,1)
+ halign: 'center'
+ BoxLayout:
+ orientation: 'vertical'
+ padding: dp(5)
+ canvas.before:
+ Color:
+ rgba: app.theme_cls.primary_dark
+ Rectangle:
+ # self here refers to the widget i.e FloatLayout
+ pos: self.pos
+ size: self.size
+ MDLabel:
+ size_hint_y: None
+ font_style: 'H5'
+ theme_text_color: 'Primary'
+ text: 'Gold'
+ halign: 'center'
+ color: 1,1,1,1
+ MDLabel:
+ font_style: 'Subtitle1'
+ theme_text_color: 'Primary'
+ text: 'We provide for proof of work calculation for 1years. '
+ halign: 'center'
+ color: 1,1,1,1
+ MDLabel:
+ font_style: 'H5'
+ theme_text_color: 'Primary'
+ text: '€ 500.0'
+ halign: 'center'
+ color: 1,1,1,1
+ MDRaisedButton:
+ canvas:
+ Color:
+ rgb: (0.93, 0.93, 0.93)
+ Rectangle:
+ pos: self.pos
+ size: self.size
+ size: dp(app.window_size[0] - 2*self.parent.parent.padding[0]) - 10 , 1
+ height: dp(40)
+ MDLabel:
+ font_style: 'H6'
+ text: 'Get Yearly Credits'
+ font_size: '13sp'
+ color: (0,0,0,1)
+ halign: 'center'
\ No newline at end of file
diff --git a/src/bitmessagekivy/kv/popup.kv b/src/bitmessagekivy/kv/popup.kv
new file mode 100644
index 00000000..b83ef5d7
--- /dev/null
+++ b/src/bitmessagekivy/kv/popup.kv
@@ -0,0 +1,314 @@
+:
+ separator_color: 1, 1, 1, 1
+ background: "White.png"
+ Button:
+ id: btn
+ disabled: True
+ background_disabled_normal: "White.png"
+ Image:
+ source: './images/loader.zip'
+ anim_delay: 0
+ #mipmap: True
+ size: root.size
+
+
+:
+ id: popup
+ size_hint : (None,None)
+ height: 2*(label.height + address.height) + 10
+ width :app.window_size[0] - (app.window_size[0]/10 if app.app_platform == 'android' else app.window_size[0]/4)
+ title: 'add contact\'s'
+ background: './images/popup.jpeg'
+ title_size: sp(20)
+ title_color: 0.4, 0.3765, 0.3451, 1
+ auto_dismiss: False
+ separator_color: 0.3529, 0.3922, 0.102, 0.7
+ BoxLayout:
+ size_hint_y: 0.5
+ orientation: 'vertical'
+ spacing:dp(20)
+ id: popup_box
+ BoxLayout:
+ orientation: 'vertical'
+ MDTextField:
+ id: label
+ multiline: False
+ hint_text: "Label"
+ required: True
+ helper_text_mode: "on_error"
+ on_text: root.checkLabel_valid(self)
+ canvas.before:
+ Color:
+ rgba: (0,0,0,1)
+ MDTextField:
+ id: address
+ hint_text: "Address"
+ required: True
+ helper_text_mode: "on_error"
+ on_text: root.checkAddress_valid(self)
+ canvas.before:
+ Color:
+ rgba: (0,0,0,1)
+ BoxLayout:
+ spacing:5
+ orientation: 'horizontal'
+ MDRaisedButton:
+ id: save_addr
+ size_hint: 1.5, None
+ height: dp(40)
+ on_release:
+ root.savecontact()
+ MDLabel:
+ font_style: 'H6'
+ text: 'Save'
+ font_size: '13sp'
+ color: (1,1,1,1)
+ halign: 'center'
+ MDRaisedButton:
+ size_hint: 1.5, None
+ height: dp(40)
+ on_press: root.dismiss()
+ on_press: root.close_pop()
+ MDLabel:
+ font_style: 'H6'
+ text: 'Cancel'
+ font_size: '13sp'
+ color: (1,1,1,1)
+ halign: 'center'
+ MDRaisedButton:
+ size_hint: 2, None
+ height: dp(40)
+ MDLabel:
+ font_style: 'H6'
+ text: 'Scan QR code'
+ font_size: '13sp'
+ color: (1,1,1,1)
+ halign: 'center'
+
+:
+ id: addbook_popup
+ size_hint : (None,None)
+ height: 4*(add_label.height)
+ width :app.window_size[0] - (app.window_size[0]/10 if app.app_platform == 'android' else app.window_size[0]/4)
+ background: './images/popup.jpeg'
+ separator_height: 0
+ auto_dismiss: False
+ BoxLayout:
+ size_hint_y: None
+ spacing:dp(70)
+ id: addbook_popup_box
+ orientation: 'vertical'
+ BoxLayout:
+ size_hint_y: None
+ orientation: 'vertical'
+ spacing:dp(20)
+ MDLabel:
+ font_style: 'Subtitle2'
+ theme_text_color: 'Primary'
+ text: "Label"
+ font_size: '17sp'
+ halign: 'left'
+ MDTextField:
+ id: add_label
+ font_style: 'Body1'
+ font_size: '15sp'
+ halign: 'left'
+ text: root.address_label
+ theme_text_color: 'Primary'
+ required: True
+ helper_text_mode: "on_error"
+ on_text: root.checkLabel_valid(self)
+ canvas.before:
+ Color:
+ rgba: (0,0,0,1)
+ MDLabel:
+ font_style: 'Subtitle2'
+ theme_text_color: 'Primary'
+ text: "Address"
+ font_size: '17sp'
+ halign: 'left'
+ MDLabel:
+ id: address
+ font_style: 'Body1'
+ theme_text_color: 'Primary'
+ text: root.address
+ font_size: '15sp'
+ halign: 'left'
+ BoxLayout:
+ id: addbook_btn
+ spacing:5
+ orientation: 'horizontal'
+ MDRaisedButton:
+ size_hint: 2, None
+ height: dp(40)
+ on_press: root.send_message_to()
+ MDLabel:
+ font_style: 'H6'
+ text: 'Send message to'
+ font_size: '13sp'
+ color: (1,1,1,1)
+ halign: 'center'
+ MDRaisedButton:
+ size_hint: 1.5, None
+ height: dp(40)
+ font_size: '10sp'
+ on_press: root.update_addbook_label(root.address)
+ MDLabel:
+ font_style: 'H6'
+ text: 'Save'
+ font_size: '13sp'
+ color: (1,1,1,1)
+ halign: 'center'
+ MDRaisedButton:
+ size_hint: 1.5, None
+ height: dp(40)
+ on_press: root.dismiss()
+ on_press: root.close_pop()
+ MDLabel:
+ font_style: 'H6'
+ text: 'Cancel'
+ font_size: '13sp'
+ color: (1,1,1,1)
+ halign: 'center'
+
+
+:
+ id: myadd_popup
+ size_hint : (None,None)
+ height: 4.5*(myaddr_label.height+ my_add_btn.children[0].height)
+ width :app.window_size[0] - (app.window_size[0]/10 if app.app_platform == 'android' else app.window_size[0]/4)
+ background: './images/popup.jpeg'
+ auto_dismiss: False
+ separator_height: 0
+ BoxLayout:
+ id: myadd_popup_box
+ size_hint_y: None
+ spacing:dp(70)
+ orientation: 'vertical'
+ BoxLayout:
+ size_hint_y: None
+ orientation: 'vertical'
+ spacing:dp(25)
+ MDLabel:
+ id: myaddr_label
+ font_style: 'Subtitle2'
+ theme_text_color: 'Primary'
+ text: "Label"
+ font_size: '17sp'
+ halign: 'left'
+ MDLabel:
+ font_style: 'Body1'
+ theme_text_color: 'Primary'
+ text: root.address_label
+ font_size: '15sp'
+ halign: 'left'
+ MDLabel:
+ font_style: 'Subtitle2'
+ theme_text_color: 'Primary'
+ text: "Address"
+ font_size: '17sp'
+ halign: 'left'
+ MDLabel:
+ font_style: 'Body1'
+ theme_text_color: 'Primary'
+ text: root.address
+ font_size: '15sp'
+ halign: 'left'
+ BoxLayout:
+ id: my_add_btn
+ spacing:5
+ orientation: 'horizontal'
+ MDRaisedButton:
+ size_hint: 2, None
+ height: dp(40)
+ on_press: root.send_message_from()
+ MDLabel:
+ font_style: 'H6'
+ text: 'Send message from'
+ font_size: '13sp'
+ color: (1,1,1,1)
+ halign: 'center'
+ MDRaisedButton:
+ size_hint: 1.5, None
+ height: dp(40)
+ on_press: root.dismiss()
+ on_press: app.root.ids.scr_mngr.current = 'showqrcode'
+ on_press: app.root.ids.sc15.qrdisplay()
+ MDLabel:
+ font_style: 'H6'
+ text: 'Show QR code'
+ font_size: '13sp'
+ color: (1,1,1,1)
+ halign: 'center'
+ MDRaisedButton:
+ size_hint: 1.5, None
+ height: dp(40)
+ on_press: root.dismiss()
+ on_press: root.close_pop()
+ MDLabel:
+ font_style: 'H6'
+ text: 'Cancel'
+ font_size: '13sp'
+ color: (1,1,1,1)
+ halign: 'center'
+
+:
+ id: closing_popup
+ size_hint : (None,None)
+ height: 1.3*(popup_label.height+ my_add_btn.children[0].height)
+ width :app.window_size[0] - (app.window_size[0]/10 if app.app_platform == 'android' else app.window_size[0]/4)
+ background: './images/popup.jpeg'
+ auto_dismiss: False
+ separator_height: 0
+ BoxLayout:
+ id: myadd_popup_box
+ size_hint_y: None
+ spacing:dp(70)
+ orientation: 'vertical'
+ BoxLayout:
+ size_hint_y: None
+ orientation: 'vertical'
+ spacing:dp(25)
+ MDLabel:
+ id: popup_label
+ font_style: 'Subtitle2'
+ theme_text_color: 'Primary'
+ text: "Bitmessage isn't connected to the network.\n If you quit now, it may cause delivery delays.\n Wait until connected and the synchronisation finishes?"
+ font_size: '17sp'
+ halign: 'center'
+ BoxLayout:
+ id: my_add_btn
+ spacing:5
+ orientation: 'horizontal'
+ MDRaisedButton:
+ size_hint: 1.5, None
+ height: dp(40)
+ on_press: root.closingAction(self.children[0].text)
+ on_press: app.stop()
+ MDLabel:
+ font_style: 'H6'
+ text: 'Yes'
+ font_size: '13sp'
+ color: (1,1,1,1)
+ halign: 'center'
+ MDRaisedButton:
+ size_hint: 1.5, None
+ height: dp(40)
+ on_press: root.closingAction(self.children[0].text)
+ MDLabel:
+ font_style: 'H6'
+ text: 'No'
+ font_size: '13sp'
+ color: (1,1,1,1)
+ halign: 'center'
+ MDRaisedButton:
+ size_hint: 1.5, None
+ height: dp(40)
+ #on_press: root.dismiss()
+ on_press: root.closingAction(self.children[0].text)
+ MDLabel:
+ font_style: 'H6'
+ text: 'Cancel'
+ font_size: '13sp'
+ color: (1,1,1,1)
+ halign: 'center'
\ No newline at end of file
diff --git a/src/bitmessagekivy/kv/sent.kv b/src/bitmessagekivy/kv/sent.kv
new file mode 100644
index 00000000..17fa0e2f
--- /dev/null
+++ b/src/bitmessagekivy/kv/sent.kv
@@ -0,0 +1,24 @@
+:
+ name: 'sent'
+ BoxLayout:
+ orientation: 'vertical'
+ spacing: dp(5)
+ SearchBar:
+ GridLayout:
+ id: identi_tag
+ padding: [20, 0, 0, 5]
+ cols: 1
+ size_hint_y: None
+ height: self.minimum_height
+ MDLabel:
+ text: ''
+ font_style: 'Subtitle2'
+ BoxLayout:
+ orientation:'vertical'
+ ScrollView:
+ id: scroll_y
+ do_scroll_x: False
+ MDList:
+ id: ml
+ Loader:
+ ComposerButton:
\ No newline at end of file
diff --git a/src/bitmessagekivy/kv/settings.kv b/src/bitmessagekivy/kv/settings.kv
new file mode 100644
index 00000000..efa3640b
--- /dev/null
+++ b/src/bitmessagekivy/kv/settings.kv
@@ -0,0 +1,68 @@
+:
+ name: 'set'
+ ScrollView:
+ do_scroll_x: False
+ MDList:
+ id: ml
+ size_hint_y: None
+ height: dp(500)
+ OneLineListItem:
+ text: "SERVER SETTINGS"
+ BoxLayout:
+ AnchorLayout:
+ MDRaisedButton:
+ size_hint: .6, .55
+ height: dp(40)
+ MDLabel:
+ font_style: 'H6'
+ text: 'Server'
+ font_size: '13sp'
+ color: (1,1,1,1)
+ halign: 'center'
+ OneLineListItem:
+ text: "DATA SETTINGS"
+ BoxLayout:
+ AnchorLayout:
+ MDRaisedButton:
+ size_hint: .6, .55
+ height: dp(40)
+ MDLabel:
+ font_style: 'H6'
+ text: 'Import or export data'
+ font_size: '13sp'
+ color: (1,1,1,1)
+ halign: 'center'
+ OneLineListItem:
+ text: "OTHER SETTINGS"
+ BoxLayout:
+ AnchorLayout:
+ MDRaisedButton:
+ size_hint: .6, .55
+ height: dp(40)
+ MDLabel:
+ font_style: 'H6'
+ text: 'Restart background service'
+ font_size: '13sp'
+ color: (1,1,1,1)
+ halign: 'center'
+ BoxLayout:
+ AnchorLayout:
+ MDLabel:
+ font_style: 'Body1'
+ theme_text_color: 'Primary'
+ text: "bitmessage is 11 seconds behind the network"
+ halign: 'center'
+ color: [0.941, 0, 0,1]
+
+ BoxLayout:
+ MDCheckbox:
+ id: chkbox
+ size_hint: None, None
+ size: dp(48), dp(64)
+ active: True
+ MDLabel:
+ font_style: 'Body1'
+ theme_text_color: 'Primary'
+ text: "show settings (for advanced users only)"
+ halign: 'left'
+ color: app.theme_cls.primary_dark
\ No newline at end of file
diff --git a/src/bitmessagekivy/kv/trash.kv b/src/bitmessagekivy/kv/trash.kv
new file mode 100644
index 00000000..7475c334
--- /dev/null
+++ b/src/bitmessagekivy/kv/trash.kv
@@ -0,0 +1,24 @@
+:
+ name: 'trash'
+ BoxLayout:
+ orientation: 'vertical'
+ spacing: dp(5)
+ GridLayout:
+ id: identi_tag
+ padding: [20, 20, 0, 5]
+ spacing: dp(5)
+ cols: 1
+ size_hint_y: None
+ height: self.minimum_height
+ MDLabel:
+ text: ''
+ font_style: 'Subtitle2'
+ BoxLayout:
+ orientation:'vertical'
+ ScrollView:
+ id: scroll_y
+ do_scroll_x: False
+ MDList:
+ id: ml
+ Loader:
+ ComposerButton:
\ No newline at end of file
diff --git a/src/bitmessagekivy/main.kv b/src/bitmessagekivy/main.kv
index 85ba2979..42a924a8 100644
--- a/src/bitmessagekivy/main.kv
+++ b/src/bitmessagekivy/main.kv
@@ -1,1286 +1,275 @@
-
-#:import Toolbar kivymd.toolbar.Toolbar
-#:import NavigationLayout kivymd.navigationdrawer.NavigationLayout
-#:import NavigationDrawerDivider kivymd.navigationdrawer.NavigationDrawerDivider
-#:import NavigationDrawerSubheader kivymd.navigationdrawer.NavigationDrawerSubheader
-#:import MDCheckbox kivymd.selectioncontrols.MDCheckbox
-#:import MDList kivymd.list.MDList
-#:import OneLineListItem kivymd.list.OneLineListItem
-#:import MDTextField kivymd.textfields.MDTextField
-#:import get_color_from_hex kivy.utils.get_color_from_hex
-#:import colors kivymd.color_definitions.colors
-#:import MDTabbedPanel kivymd.tabs.MDTabbedPanel
-#:import MDTab kivymd.tabs.MDTab
-#:import MDFloatingActionButton kivymd.button.MDFloatingActionButton
+#:import IconLeftWidget kivymd.uix.list.IconLeftWidget
+#:import images_path kivymd.images_path
+#:import Spinner kivy.uix.spinner.Spinner
#:import Factory kivy.factory.Factory
-#:import MDScrollViewRefreshLayout kivymd.refreshlayout.MDScrollViewRefreshLayout
-#:import MDSpinner kivymd.spinner.MDSpinner
-#:import NoTransition kivy.uix.screenmanager.NoTransition
-#:import MDSeparator kivymd.card.MDSeparator
+
+#:import MDCheckbox kivymd.uix.selectioncontrol.MDCheckbox
+#:import MDList kivymd.uix.list.MDList
+#:import OneLineListItem kivymd.uix.list.OneLineListItem
+#:import MDTextField kivymd.uix.textfield.MDTextField
+#:import get_color_from_hex kivy.utils.get_color_from_hex
+#:import MDCard kivymd.uix.card.MDCard
+#:import colors kivymd.color_definitions.colors
+#:import MDTabs kivymd.uix.tab.MDTabs
+#:import MDFloatingActionButton kivymd.uix.button.MDFloatingActionButton
+#:import Factory kivy.factory.Factory
+#:import MDScrollViewRefreshLayout kivymd.uix.refreshlayout.MDScrollViewRefreshLayout
+#:import MDSpinner kivymd.uix.spinner.MDSpinner
+#:import MDTabsBase kivymd.uix.tab.MDTabsBase
+
#:set color_button (0.784, 0.443, 0.216, 1) # brown
#:set color_button_pressed (0.659, 0.522, 0.431, 1) # darker brown
#:set color_font (0.957, 0.890, 0.843, 1) # off white
-:
- icon: 'checkbox-blank-circle'
-
:
font_size: '12.5sp'
- background_color: color_button if self.state == 'down' else color_button_pressed
- background_down: 'atlas://data/images/defaulttheme/button'
+ #background_color: color_button if self.state == 'down' else color_button_pressed
+ #background_down: 'atlas://data/images/defaulttheme/button'
+ background_normal: ''
+ background_color: app.theme_cls.primary_color
color: color_font
-:
- drawer_logo: './images/drawer_logo1.png'
- NavigationDrawerDivider:
- NavigationDrawerSubheader:
- text: "Accounts"
- NavigationDrawerIconButton:
- CustomSpinner:
- id: btn
- pos_hint:{"x":0,"y":.25}
- option_cls: Factory.get("MySpinnerOption")
- font_size: '11.9sp'
- text: app.getDefaultAccData()
- background_color: color_button if self.state == 'normal' else color_button_pressed
- background_down: 'atlas://data/images/defaulttheme/spinner'
- color: color_font
- values: app.variable_1
- on_text:app.getCurrentAccountData(self.text)
- Image:
- source: app.get_default_image()
- x: self.width/6
- y: self.parent.y + self.parent.height/4
- size: self.parent.height/2, self.parent.height/2
- ArrowImg:
- NavigationDrawerIconButton:
- id: inbox_cnt
- icon: 'email-open'
- text: "Inbox"
- on_release: app.root.ids.scr_mngr.current = 'inbox'
- badge_text: "0"
- on_press: app.load_screen(self)
- NavigationDrawerIconButton:
- id: send_cnt
- icon: 'send'
- text: "Sent"
- on_release: app.root.ids.scr_mngr.current = 'sent'
- badge_text: "0"
- NavigationDrawerIconButton:
- id: draft_cnt
- icon: 'message-draw'
- text: "Draft"
- on_release: app.root.ids.scr_mngr.current = 'draft'
- badge_text: "0"
- #NavigationDrawerIconButton:
- #text: "Starred"
- #icon:'star'
- #on_release: app.root.ids.scr_mngr.current = 'starred'
- #badge_text: "0"
- #NavigationDrawerIconButton:
- #icon: 'archive'
- #text: "Archieve"
- #on_release: app.root.ids.scr_mngr.current = 'archieve'
- #badge_text: "0"
- #NavigationDrawerIconButton:
- #icon: 'email-open-outline'
- #text: "Spam"
- #on_release: app.root.ids.scr_mngr.current = 'spam'
- #badge_text: "0"
- NavigationDrawerIconButton:
- id: trash_cnt
- icon: 'delete'
- text: "Trash"
- on_release: app.root.ids.scr_mngr.current = 'trash'
- badge_text: "0"
- NavigationDrawerIconButton:
- id: allmail_cnt
- text: "All Mails"
- icon:'contact-mail'
- on_release: app.root.ids.scr_mngr.current = 'allmails'
- badge_text: "0"
- on_press: app.load_screen(self)
- NavigationDrawerDivider:
- NavigationDrawerSubheader:
- text: "All labels"
- NavigationDrawerIconButton:
- text: "Address Book"
- icon:'book-multiple'
- on_release: app.root.ids.scr_mngr.current = 'addressbook'
- NavigationDrawerIconButton:
- text: "Settings"
- icon:'settings'
- on_release: app.root.ids.scr_mngr.current = 'set'
- NavigationDrawerIconButton:
- text: "Subscriptions/Payment"
- icon:'bell'
- on_release: app.root.ids.scr_mngr.current = 'payment'
- NavigationDrawerIconButton:
- text: "Credits"
- icon:'wallet'
- on_release: app.root.ids.scr_mngr.current = 'credits'
- NavigationDrawerIconButton:
- text: "new address"
- icon:'account-plus'
- on_release: app.root.ids.scr_mngr.current = 'login'
- NavigationDrawerIconButton:
- text: "Network Status"
- icon:'server-network'
- on_release: app.root.ids.scr_mngr.current = 'networkstat'
- NavigationDrawerIconButton:
- text: "My Addresses"
- icon:'account-multiple'
- on_release: app.root.ids.scr_mngr.current = 'myaddress'
+
+ #on_press: root.active = not root.active
+ on_press: root.currentlyActive()
+ active_color: root.theme_cls.primary_color if root.active else root.theme_cls.text_color
+
+ IconLeftWidget:
+ icon: root.icon
+ theme_text_color: "Custom"
+ text_color: root.active_color
+
+ BadgeText:
+ text: f"{root.badge_text}"
+ theme_text_color: "Custom"
+ #text_color: root.active_color
+ halign: 'right'
+
+:
+ canvas:
+ Color:
+ rgba: self.theme_cls.divider_color
+ Line:
+ points: root.x, root.y + dp(8), root.x + self.width, root.y + dp(8)
+
+
+
+ BoxLayout:
+ orientation: 'vertical'
+
+ FloatLayout:
+ size_hint_y: None
+ height: "200dp"
+
+ BoxLayout:
+ id: top_box
+ size_hint_y: None
+ height: "200dp"
+ #padding: "10dp"
+ x: root.parent.x
+ pos_hint: {"top": 1}
+ Image:
+ #source: './images/drawer_logo1.png'
+ source: app.get_default_logo()
+
+ ScrollView:
+ pos_hint: {"top": 1}
+
+ GridLayout:
+ id: box_item
+ cols: 1
+ size_hint_y: None
+ height: self.minimum_height
+ NavigationDrawerDivider:
+ NavigationDrawerSubheader:
+ text: "Accounts"
+ height:"35dp"
+ NavigationItem:
+ size: 50,50
+ CustomSpinner:
+ id: btn
+ pos_hint:{"x":0,"y":0}
+ option_cls: Factory.get("MySpinnerOption")
+ font_size: '10.9sp'
+ text: app.getDefaultAccData()
+ #background_color: color_button if self.state == 'normal' else color_button_pressed
+ #background_down: 'atlas://data/images/defaulttheme/spinner'
+ color: color_font
+ background_normal: ''
+ background_color: app.theme_cls.primary_color
+ #background_color: (0.62,0.67,0.72,1)
+ values: app.variable_1
+ on_text:app.getCurrentAccountData(self.text)
+ Image:
+ source: app.get_default_image()
+ x: self.width/6
+ y: self.parent.y + self.parent.height/4
+ size: self.parent.height/2, self.parent.height/2
+ ArrowImg:
+ NavigationItem:
+ id: inbox_cnt
+ text: 'Inbox'
+ icon: 'email-open'
+ divider: None
+ on_release: app.root.ids.scr_mngr.current = 'inbox'
+ on_release: root.parent.set_state()
+ on_press: app.load_screen(self)
+ NavigationItem:
+ id: send_cnt
+ text: 'Sent'
+ icon: 'send'
+ divider: None
+ on_release: app.root.ids.scr_mngr.current = 'sent'
+ on_release: root.parent.set_state()
+ NavigationItem:
+ id: draft_cnt
+ text: 'Draft'
+ icon: 'message-draw'
+ divider: None
+ on_release: app.root.ids.scr_mngr.current = 'draft'
+ on_release: root.parent.set_state()
+ NavigationItem:
+ id: trash_cnt
+ text: 'Trash'
+ icon: 'delete'
+ divider: None
+ on_release: app.root.ids.scr_mngr.current = 'trash'
+ on_release: root.parent.set_state()
+ NavigationItem:
+ id: allmail_cnt
+ text: 'All Mails'
+ icon: 'contact-mail'
+ divider: None
+ on_release: app.root.ids.scr_mngr.current = 'allmails'
+ on_release: root.parent.set_state()
+ on_press: app.load_screen(self)
+ NavigationDrawerDivider:
+ NavigationDrawerSubheader:
+ text: "All labels"
+ NavigationItem:
+ text: 'Address Book'
+ icon: 'book-multiple'
+ divider: None
+ on_release: app.root.ids.scr_mngr.current = 'addressbook'
+ on_release: root.parent.set_state()
+ NavigationItem:
+ text: 'Settings'
+ icon: 'settings'
+ divider: None
+ on_release: app.root.ids.scr_mngr.current = 'set'
+ on_release: root.parent.set_state()
+ NavigationItem:
+ text: 'Payment'
+ icon: 'bell'
+ divider: None
+ on_release: app.root.ids.scr_mngr.current = 'payment'
+ on_release: root.parent.set_state()
+ NavigationItem:
+ text: 'Credits'
+ icon: 'wallet'
+ divider: None
+ on_release: app.root.ids.scr_mngr.current = 'credits'
+ on_release: root.parent.set_state()
+ NavigationItem:
+ text: 'New address'
+ icon: 'account-plus'
+ divider: None
+ on_release: app.root.ids.scr_mngr.current = 'login'
+ on_release: root.parent.set_state()
+ NavigationItem:
+ text: 'Network status'
+ icon: 'server-network'
+ divider: None
+ on_release: app.root.ids.scr_mngr.current = 'networkstat'
+ on_release: root.parent.set_state()
+ NavigationItem:
+ text: 'My addresses'
+ icon: 'account-multiple'
+ divider: None
+ on_release: app.root.ids.scr_mngr.current = 'myaddress'
+ on_release: root.parent.set_state()
NavigationLayout:
id: nav_layout
- ContentNavigationDrawer:
+ MDToolbar:
+ id: toolbar
+ title: app.current_address_label()
+ opacity: 1 if app.addressexist() else 0
+ disabled: False if app.addressexist() else True
+ pos_hint: {"top": 1}
+ md_bg_color: app.theme_cls.primary_color
+ elevation: 10
+ left_action_items: [['menu', lambda x: nav_drawer.set_state("toggle")]]
+ right_action_items: [['account-plus', lambda x: app.addingtoaddressbook()]]
+
+ ScreenManager:
+ id: scr_mngr
+ size_hint_y: None
+ height: root.height - toolbar.height
+ Inbox:
+ id:sc1
+ Page:
+ id:sc2
+ Create:
+ id:sc3
+ Sent:
+ id:sc4
+ Trash:
+ id:sc5
+ Login:
+ id:sc6
+ Random:
+ id:sc7
+ Spam:
+ id:sc8
+ Setting:
+ id:sc9
+ MyAddress:
+ id:sc10
+ AddressBook:
+ id:sc11
+ Payment:
+ id:sc12
+ NetworkStat:
+ id:sc13
+ MailDetail:
+ id:sc14
+ ShowQRCode:
+ id:sc15
+ Draft:
+ id:sc16
+ Allmails:
+ id:sc17
+ Credits:
+ id:sc18
+ Starred:
+ id:sc19
+ Archieve:
+ id:sc20
+
+ MDNavigationDrawer:
id: nav_drawer
- FloatLayout:
- id: float_box
- BoxLayout:
- id: box_layout
- orientation: 'vertical'
- Toolbar:
- id: toolbar
- title: app.current_address_label()
- opacity: 1 if app.addressexist() else 0
- disabled: False if app.addressexist() else True
- md_bg_color: app.theme_cls.primary_color
- background_palette: 'Primary'
- background_hue: '500'
- left_action_items: [['menu', lambda x: app.root.toggle_nav_drawer()]]
- right_action_items: [['account-plus', lambda x: app.addingtoaddressbook()]]
-
- ScreenManager:
- id: scr_mngr
- Inbox:
- id:sc1
- Page:
- id:sc2
- Create:
- id:sc3
- Sent:
- id:sc4
- Trash:
- id:sc5
- Login:
- id:sc6
- Random:
- id:sc7
- Spam:
- id:sc8
- Setting:
- id:sc9
- MyAddress:
- id:sc10
- AddressBook:
- id:sc11
- Payment:
- id:sc12
- NetworkStat:
- id:sc13
- MailDetail:
- id:sc14
- ShowQRCode:
- id:sc15
- Draft:
- id:sc16
- Allmails:
- id:sc17
- Credits:
- id:sc18
- Starred:
- id:sc19
- Archieve:
- id:sc20
-
-:
- name: 'inbox'
- transition: NoTransition()
- BoxLayout:
- orientation: 'vertical'
- spacing: dp(5)
- SearchBar:
- GridLayout:
- id: identi_tag
- padding: [20, 0, 0, 5]
- cols: 1
- size_hint_y: None
- height: self.minimum_height
- MDLabel:
- text: ''
- font_style: 'Body1'
- bold: True
- #FloatLayout:
- # MDScrollViewRefreshLayout:
- # id: refresh_layout
- # refresh_callback: root.refresh_callback
- # root_layout: root.set_root_layout()
- # MDList:
- # id: ml
- BoxLayout:
- orientation:'vertical'
- ScrollView:
- id: scroll_y
- do_scroll_x: False
- MDList:
- id: ml
- Loader:
- ComposerButton:
-
-:
- name: 'sent'
- BoxLayout:
- orientation: 'vertical'
- spacing: dp(5)
- SearchBar:
- GridLayout:
- id: identi_tag
- padding: [20, 0, 0, 5]
- cols: 1
- size_hint_y: None
- height: self.minimum_height
- MDLabel:
- text: ''
- font_style: 'Body1'
- bold: True
- BoxLayout:
- orientation:'vertical'
- ScrollView:
- id: scroll_y
- do_scroll_x: False
- MDList:
- id: ml
- Loader:
- ComposerButton:
-
-:
- name: 'trash'
- BoxLayout:
- orientation: 'vertical'
- spacing: dp(5)
- GridLayout:
- id: identi_tag
- padding: [20, 20, 0, 5]
- spacing: dp(5)
- cols: 1
- size_hint_y: None
- height: self.minimum_height
- MDLabel:
- text: ''
- font_style: 'Body1'
- bold: True
- BoxLayout:
- orientation:'vertical'
- ScrollView:
- id: scroll_y
- do_scroll_x: False
- MDList:
- id: ml
- Loader:
- ComposerButton:
-
-:
- name: 'draft'
- BoxLayout:
- orientation: 'vertical'
- spacing: dp(5)
- GridLayout:
- id: identi_tag
- padding: [20, 20, 0, 5]
- cols: 1
- size_hint_y: None
- height: self.minimum_height
- MDLabel:
- text: ''
- font_style: 'Body1'
- bold: True
- BoxLayout:
- orientation:'vertical'
- ScrollView:
- id: scroll_y
- do_scroll_x: False
- MDList:
- id: ml
- ComposerButton:
-
-:
- name: 'starred'
- ScrollView:
- do_scroll_x: False
- MDList:
- id: ml
- ComposerButton:
-
-:
- name: 'archieve'
- ScrollView:
- do_scroll_x: False
- MDList:
- id: ml
- ComposerButton:
-
-:
- name: 'spam'
- ScrollView:
- do_scroll_x: False
- MDList:
- id: ml
- ComposerButton:
-
-:
- name: 'allmails'
- #FloatLayout:
- # MDScrollViewRefreshLayout:
- # id: refresh_layout
- # refresh_callback: root.refresh_callback
- # root_layout: root.set_root_layout()
- # MDList:
- # id: ml
- BoxLayout:
- orientation: 'vertical'
- spacing: dp(5)
- GridLayout:
- id: identi_tag
- padding: [20, 20, 0, 5]
- spacing: dp(5)
- cols: 1
- size_hint_y: None
- height: self.minimum_height
- MDLabel:
- text: ''
- font_style: 'Body1'
- bold: True
- BoxLayout:
- orientation:'vertical'
- ScrollView:
- id: scroll_y
- do_scroll_x: False
- MDList:
- id: ml
- Loader:
- ComposerButton:
-
-:
- name: 'test'
- Label:
- text:"I am in test"
- color: 0,0,0,1
+ ContentNavigationDrawer:
+ id: content_drawer
:
name: 'page'
Label:
- text:"I am on page"
+ text:"I am in Page"
color: 0,0,0,1
:
name: 'create'
Loader:
-:
- name: 'credits'
- ScrollView:
- do_scroll_x: False
- MDList:
- id: ml
- size_hint_y: None
- height: dp(200)
- OneLineListItem:
- text: "Available Credits"
- BoxLayout:
- AnchorLayout:
- MDRaisedButton:
- size_hint: .6, .35
- height: dp(40)
- MDLabel:
- font_style: 'Title'
- text: root.available_credits
- font_size: '13sp'
- color: (1,1,1,1)
- halign: 'center'
-
-:
- ScrollView:
- BoxLayout:
- orientation: 'vertical'
- size_hint_y: None
- height: self.minimum_height + 2 * self.parent.height/4
- padding: dp(32)
- spacing: 15
- BoxLayout:
- orientation: 'vertical'
- MDTextField:
- id: ti
- hint_text: 'type or select sender address'
- size_hint_y: None
- height: 100
- font_size: '13sp'
- multiline: False
- required: True
- helper_text_mode: "on_error"
-
- BoxLayout:
- size_hint_y: None
- height: dp(40)
- CustomSpinner:
- background_color: app.theme_cls.primary_dark
- id: btn
- values: app.variable_1
- on_text: root.auto_fill_fromaddr() if self.text != 'Select' else ''
- option_cls: Factory.get("MySpinnerOption")
- background_color: color_button if self.state == 'normal' else color_button_pressed
- background_down: 'atlas://data/images/defaulttheme/spinner'
- color: color_font
- font_size: '12.5sp'
- ArrowImg:
-
- BoxLayout:
- orientation: 'vertical'
- txt_input: txt_input
- rv: rv
- size : (890, 60)
- size_hint: 1,1
- MyTextInput:
- id: txt_input
- size_hint_y: None
- font_size: '13sp'
- height: self.parent.height/2
- #hint_text: 'type or search recipients address starting with BM-'
- hint_text: 'type, select or scan QR code for recipients address'
- RV:
- id: rv
- MDTextField:
- id: subject
- hint_text: 'subject'
- required: True
- height: 100
- font_size: '13sp'
- size_hint_y: None
- multiline: False
- helper_text_mode: "on_error"
-
- MDTextField:
- id: body
- multiline: True
- hint_text: 'body'
- size_hint_y: None
- font_size: '13sp'
- required: True
- helper_text_mode: "on_error"
- BoxLayout:
- spacing:50
-
-:
- readonly: False
- multiline: False
-
-:
- # Draw a background to indicate selection
- color: 0,0,0,1
- canvas.before:
- Color:
- rgba: app.theme_cls.primary_dark if self.selected else (1, 1, 1, 0)
- Rectangle:
- pos: self.pos
- size: self.size
-
-:
- canvas:
- Color:
- rgba: 0,0,0,.2
-
- Line:
- rectangle: self.x +1 , self.y, self.width - 2, self.height -2
- bar_width: 10
- scroll_type:['bars']
- viewclass: 'SelectableLabel'
- SelectableRecycleBoxLayout:
- default_size: None, dp(20)
- default_size_hint: 1, None
- size_hint_y: None
- height: self.minimum_height
- orientation: 'vertical'
- multiselect: False
-
-
-:
- name: 'login'
- ScrollView:
- do_scroll_x: False
- BoxLayout:
- orientation: 'vertical'
- size_hint_y: None
- height: dp(750)
- padding: dp(10)
- BoxLayout:
- MDLabel:
- font_style: 'Body1'
- theme_text_color: 'Primary'
- text: "You may generate addresses by using either random numbers or by using a passphrase If you use a passphrase, the address is called a deterministic; address The Random Number option is selected by default but deterministic addresses have several \n pros and cons:\n"
- halign: 'center'
- bold: True
- color:app.theme_cls.primary_dark
- BoxLayout:
- MDLabel:
- font_style: 'Caption'
- theme_text_color: 'Primary'
- text: "If talk about pros You can recreate your addresses on any computer from memory, You need-not worry about backing up your keys.dat file as long as you can remember your passphrase and aside talk about cons You must remember (or write down) your You must remember the address version number and the stream number along with your passphrase If you choose a weak passphrase and someone on the Internet can brute-force it, they can read your messages and send messages as you"
- halign: 'center'
- bold: True
- color:app.theme_cls.primary_dark
- MDCheckbox:
- id: grp_chkbox_1
- group: 'test'
- active: True
- allow_no_selection: False
- MDLabel:
- font_style: 'Caption'
- theme_text_color: 'Primary'
- text: "use a random number generator to make an address"
- halign: 'center'
- size_hint_y: None
- bold: True
- height: self.texture_size[1] + dp(4)
- color: [0.941, 0, 0,1]
- MDCheckbox:
- id: grp_chkbox_1
- group: 'test'
- allow_no_selection: False
- MDLabel:
- font_style: 'Caption'
- theme_text_color: 'Primary'
- text: "use a pseudo number generator to make an address"
- halign: 'center'
- size_hint_y: None
- bold: True
- color: [0.941, 0, 0,1]
- height: self.texture_size[1] + dp(4)
- BoxLayout:
- AnchorLayout:
- MDRaisedButton:
- height: dp(40)
- on_press: app.root.ids.scr_mngr.current = 'random'
- on_press: app.root.ids.sc7.reset_address_label()
- MDLabel:
- font_style: 'Title'
- text: 'proceed'
- font_size: '13sp'
- color: (1,1,1,1)
- halign: 'center'
-
-:
- name: 'random'
- ScrollView:
- BoxLayout:
- orientation: 'vertical'
- size_hint_y: None
- height: self.minimum_height
- padding: dp(20)
- spacing: 100
- MDLabel:
- font_style: 'Body1'
- theme_text_color: 'Primary'
- text: "Random Addresses"
- halign: 'center'
- bold: True
- color:app.theme_cls.primary_dark
-
- MDLabel:
- font_style: 'Body1'
- theme_text_color: 'Primary'
- text: "Here you may generate as many addresses as you like, Indeed creating and abandoning addresses is encouraged"
- halign: 'center'
- bold: True
- color:app.theme_cls.primary_dark
-
- MDTextField:
- id: label
- multiline: True
- hint_text: "Label"
- required: True
- helper_text_mode: "on_error"
- on_text: root.add_validation(self)
- BoxLayout:
- AnchorLayout:
- MDRaisedButton:
- height: dp(40)
- on_release: root.generateaddress(app)
- opposite_colors: True
- MDLabel:
- font_style: 'Title'
- text: 'next'
- font_size: '13sp'
- color: (1,1,1,1)
- halign: 'center'
-
-:
- name: 'set'
- ScrollView:
- do_scroll_x: False
- MDList:
- id: ml
- size_hint_y: None
- height: dp(500)
- OneLineListItem:
- text: "SERVER SETTINGS"
- BoxLayout:
- AnchorLayout:
- MDRaisedButton:
- size_hint: .6, .55
- height: dp(40)
- MDLabel:
- font_style: 'Title'
- text: 'Server'
- font_size: '13sp'
- color: (1,1,1,1)
- halign: 'center'
- OneLineListItem:
- text: "DATA SETTINGS"
- BoxLayout:
- AnchorLayout:
- MDRaisedButton:
- size_hint: .6, .55
- height: dp(40)
- MDLabel:
- font_style: 'Title'
- text: 'Import or export data'
- font_size: '13sp'
- color: (1,1,1,1)
- halign: 'center'
- OneLineListItem:
- text: "OTHER SETTINGS"
- BoxLayout:
- AnchorLayout:
- MDRaisedButton:
- size_hint: .6, .55
- height: dp(40)
- MDLabel:
- font_style: 'Title'
- text: 'Restart background service'
- font_size: '13sp'
- color: (1,1,1,1)
- halign: 'center'
- BoxLayout:
- AnchorLayout:
- MDLabel:
- font_style: 'Body1'
- theme_text_color: 'Primary'
- text: "bitmessage is 11 seconds behind the network"
- halign: 'center'
- bold: True
- color: [0.941, 0, 0,1]
-
- BoxLayout:
- MDCheckbox:
- id: chkbox
- size_hint: None, None
- size: dp(48), dp(64)
- active: True
- MDLabel:
- font_style: 'Body1'
- theme_text_color: 'Primary'
- text: "show settings (for advanced users only)"
- halign: 'left'
- bold: True
- color: app.theme_cls.primary_dark
-
-:
- name: 'myaddress'
- BoxLayout:
- orientation: 'vertical'
- spacing: dp(5)
- SearchBar:
- GridLayout:
- id: identi_tag
- padding: [20, 0, 0, 5]
- cols: 1
- size_hint_y: None
- height: self.minimum_height
- MDLabel:
- text: 'My Addresses'
- font_style: 'Body1'
- bold: True
- FloatLayout:
- MDScrollViewRefreshLayout:
- id: refresh_layout
- refresh_callback: root.refresh_callback
- root_layout: root.set_root_layout()
- MDList:
- id: ml
- Loader:
- ComposerButton:
-
-:
- name: 'addressbook'
- BoxLayout:
- orientation: 'vertical'
- spacing: dp(5)
- SearchBar:
- GridLayout:
- id: identi_tag
- padding: [20, 0, 0, 5]
- cols: 1
- size_hint_y: None
- height: self.minimum_height
- MDLabel:
- text: ''
- font_style: 'Body1'
- bold: True
- BoxLayout:
- orientation:'vertical'
- ScrollView:
- id: scroll_y
- do_scroll_x: False
- MDList:
- id: ml
- Loader:
- ComposerButton:
-
-:
- name: 'payment'
- ScrollView:
- do_scroll_x: False
- BoxLayout:
- orientation: 'vertical'
- padding: [dp(app.window_size[0]/16 if app.window_size[0] <= 720 else app.window_size[0]/6 if app.window_size[0] <= 800 else app.window_size[0]/18), dp(10)]
- spacing: 12
- size_hint_y: None
- height: self.minimum_height + dp(app.window_size[1]) if app.window_size[1] > app.window_size[0] else dp(app.window_size[0])
- BoxLayout:
- orientation: 'vertical'
- padding: dp(5)
- canvas.before:
- Color:
- rgba: app.theme_cls.primary_dark
- Rectangle:
- # self here refers to the widget i.e FloatLayout
- pos: self.pos
- size: self.size
- MDLabel:
- size_hint_y: None
- font_style: 'Headline'
- theme_text_color: 'Primary'
- text: 'Platinum'
- halign: 'center'
- color: 1,1,1,1
- MDLabel:
- font_style: 'Subhead'
- theme_text_color: 'Primary'
- text: 'We provide subscriptions for proof of work calculation for first month. '
- halign: 'center'
- color: 1,1,1,1
- MDLabel:
- id: free_pak
- font_style: 'Headline'
- theme_text_color: 'Primary'
- text: '€ 50.0'
- halign: 'center'
- color: 1,1,1,1
- MDRaisedButton:
- canvas:
- Color:
- rgb: (0.93, 0.93, 0.93)
- Rectangle:
- pos: self.pos
- size: self.size
- size_hint: 1, None
- height: dp(40)
- on_press: root.get_available_credits(self)
- MDLabel:
- font_style: 'Title'
- text: 'Get Free Credits'
- font_size: '13sp'
- color: (0,0,0,1)
- halign: 'center'
- BoxLayout:
- orientation: 'vertical'
- padding: dp(5)
- canvas.before:
- Color:
- rgba: app.theme_cls.primary_dark
- Rectangle:
- # self here refers to the widget i.e FloatLayout
- pos: self.pos
- size: self.size
- MDLabel:
- size_hint_y: None
- font_style: 'Headline'
- theme_text_color: 'Primary'
- text: 'Silver'
- halign: 'center'
- color: 1,1,1,1
- MDLabel:
- font_style: 'Subhead'
- theme_text_color: 'Primary'
- text: 'We provide for proof of work calculation for six month. '
- halign: 'center'
- color: 1,1,1,1
- MDLabel:
- font_style: 'Headline'
- theme_text_color: 'Primary'
- text: '€ 100.0'
- halign: 'center'
- color: 1,1,1,1
- MDRaisedButton:
- canvas:
- Color:
- rgb: (0.93, 0.93, 0.93)
- Rectangle:
- pos: self.pos
- size: self.size
- size_hint: 1, None
- height: dp(40)
- MDLabel:
- font_style: 'Title'
- text: 'Get Monthly Credits'
- font_size: '13sp'
- color: (0,0,0,1)
- halign: 'center'
- BoxLayout:
- orientation: 'vertical'
- padding: dp(5)
- canvas.before:
- Color:
- rgba: app.theme_cls.primary_dark
- Rectangle:
- # self here refers to the widget i.e FloatLayout
- pos: self.pos
- size: self.size
- MDLabel:
- size_hint_y: None
- font_style: 'Headline'
- theme_text_color: 'Primary'
- text: 'Gold'
- halign: 'center'
- color: 1,1,1,1
- MDLabel:
- font_style: 'Subhead'
- theme_text_color: 'Primary'
- text: 'We provide for proof of work calculation for 1years. '
- halign: 'center'
- color: 1,1,1,1
- MDLabel:
- font_style: 'Headline'
- theme_text_color: 'Primary'
- text: '€ 500.0'
- halign: 'center'
- color: 1,1,1,1
- MDRaisedButton:
- canvas:
- Color:
- rgb: (0.93, 0.93, 0.93)
- Rectangle:
- pos: self.pos
- size: self.size
- size_hint: 1, None
- height: dp(40)
- MDLabel:
- font_style: 'Title'
- text: 'Get Yearly Credits'
- font_size: '13sp'
- color: (0,0,0,1)
- halign: 'center'
-
-
-:
- id: popup
- size_hint : (None,None)
- height: 2*(label.height + address.height) + 10
- width :app.window_size[0] - (app.window_size[0]/10 if app.app_platform == 'android' else app.window_size[0]/4)
- title: 'add contact\'s'
- background: './images/popup.jpeg'
- title_size: sp(20)
- title_color: 0.4, 0.3765, 0.3451, 1
- auto_dismiss: False
- separator_color: 0.3529, 0.3922, 0.102, 0.7
- BoxLayout:
- size_hint_y: 0.5
- orientation: 'vertical'
- spacing:dp(20)
- id: popup_box
- BoxLayout:
- orientation: 'vertical'
- MDTextField:
- id: label
- multiline: False
- hint_text: "Label"
- required: True
- helper_text_mode: "on_error"
- on_text: root.checkLabel_valid(self)
- MDTextField:
- id: address
- hint_text: "Address"
- required: True
- helper_text_mode: "on_error"
- on_text: root.checkAddress_valid(self)
- BoxLayout:
- spacing:5
- orientation: 'horizontal'
- MDRaisedButton:
- id: save_addr
- size_hint: 1.5, None
- height: dp(40)
- on_release:
- root.savecontact()
- MDLabel:
- font_style: 'Title'
- text: 'Save'
- font_size: '13sp'
- color: (1,1,1,1)
- halign: 'center'
- MDRaisedButton:
- size_hint: 1.5, None
- height: dp(40)
- on_press: root.dismiss()
- on_press: root.close_pop()
- MDLabel:
- font_style: 'Title'
- text: 'Cancel'
- font_size: '13sp'
- color: (1,1,1,1)
- halign: 'center'
- MDRaisedButton:
- size_hint: 2, None
- height: dp(40)
- MDLabel:
- font_style: 'Title'
- text: 'Scan QR code'
- font_size: '13sp'
- color: (1,1,1,1)
- halign: 'center'
-
-
-:
- name: 'networkstat'
- MDTabbedPanel:
- id: tab_panel
- tab_display_mode:'text'
-
- MDTab:
- name: 'connections'
- text: "Total connections"
- ScrollView:
- do_scroll_x: False
- MDList:
- id: ml
- size_hint_y: None
- height: dp(200)
- OneLineListItem:
- text: "Total Connections"
- BoxLayout:
- AnchorLayout:
- MDRaisedButton:
- size_hint: .6, .35
- height: dp(40)
- MDLabel:
- font_style: 'Title'
- text: root.text_variable_1
- font_size: '13sp'
- color: (1,1,1,1)
- halign: 'center'
- MDTab:
- name: 'processes'
- text: 'Processes'
- ScrollView:
- do_scroll_x: False
- MDList:
- id: ml
- size_hint_y: None
- height: dp(500)
- OneLineListItem:
- text: "person-to-person"
- BoxLayout:
- AnchorLayout:
- MDRaisedButton:
- size_hint: .7, .6
- height: dp(40)
- MDLabel:
- font_style: 'Title'
- text: root.text_variable_2
- font_size: '13sp'
- color: (1,1,1,1)
- halign: 'center'
- OneLineListItem:
- text: "Brodcast"
- BoxLayout:
- AnchorLayout:
- MDRaisedButton:
- size_hint: .7, .6
- height: dp(40)
- MDLabel:
- font_style: 'Title'
- text: root.text_variable_3
- font_size: '13sp'
- color: (1,1,1,1)
- halign: 'center'
- OneLineListItem:
- text: "publickeys"
- BoxLayout:
- AnchorLayout:
- MDRaisedButton:
- size_hint: .7, .6
- height: dp(40)
- MDLabel:
- font_style: 'Title'
- text: root.text_variable_4
- font_size: '13sp'
- color: (1,1,1,1)
- halign: 'center'
- OneLineListItem:
- text: "objects"
- BoxLayout:
- AnchorLayout:
- MDRaisedButton:
- size_hint: .7, .6
- height: dp(40)
- MDLabel:
- font_style: 'Title'
- text: root.text_variable_5
- font_size: '13sp'
- color: (1,1,1,1)
- halign: 'center'
-
-:
- name: 'mailDetail'
- ScrollView:
- do_scroll_x: False
- BoxLayout:
- orientation: 'vertical'
- size_hint_y: None
- height: dp(500) + self.minimum_height
- padding: dp(32)
- MDLabel:
- font_style: 'Headline'
- theme_text_color: 'Primary'
- text: root.subject
- halign: 'left'
- font_size: '20sp'
- CopyTextBtn:
- MDLabel:
- font_style: 'Subhead'
- theme_text_color: 'Primary'
- text: "From: " + root.from_addr
- halign: 'left'
- CopyTextBtn:
- MDLabel:
- font_style: 'Subhead'
- theme_text_color: 'Primary'
- text: "To: " + root.to_addr
- halign: 'left'
- CopyTextBtn:
- MDLabel:
- font_style: 'Subhead'
- theme_text_color: 'Primary'
- text: root.status
- halign: 'left'
- MDLabel:
- font_style: 'Subhead'
- theme_text_color: 'Primary'
- text: root.message
- halign: 'left'
- bold: True
- CopyTextBtn:
- BoxLayout:
- orientation: 'vertical'
- size_hint_y: None
- height: dp(100) + self.minimum_height
- Loader:
-
-:
- id: cpyButton
- color: 0,0,0,1
- background_color: (0,0,0,0)
- center_x: self.parent.center_x * 2 - self.parent.parent.padding[0]/2
- center_y: self.parent.center_y
- on_press:app.root.ids.sc14.copy_composer_text(self)
- Image:
- source: './images/copy_text.png'
- center_x: self.parent.center_x
- center_y: self.parent.center_y
- size: 20, 20
-
-:
- size_hint_y: None
- height: dp(56)
- spacing: '10dp'
- pos_hint: {'center_x':0.45, 'center_y': .1}
-
- Widget:
-
- MDFloatingActionButton:
- icon: 'plus'
- opposite_colors: True
- elevation_normal: 8
- md_bg_color: [0.941, 0, 0,1]
- on_press: app.root.ids.scr_mngr.current = 'create'
- on_press: app.clear_composer()
-
-:
- id: myadd_popup
- size_hint : (None,None)
- height: 4.5*(myaddr_label.height+ my_add_btn.children[0].height)
- width :app.window_size[0] - (app.window_size[0]/10 if app.app_platform == 'android' else app.window_size[0]/4)
- background: './images/popup.jpeg'
- auto_dismiss: False
- separator_height: 0
- BoxLayout:
- id: myadd_popup_box
- size_hint_y: None
- spacing:dp(70)
- orientation: 'vertical'
- BoxLayout:
- size_hint_y: None
- orientation: 'vertical'
- spacing:dp(25)
- MDLabel:
- id: myaddr_label
- font_style: 'Title'
- theme_text_color: 'Primary'
- text: "Label"
- font_size: '17sp'
- halign: 'left'
- MDLabel:
- font_style: 'Subhead'
- theme_text_color: 'Primary'
- text: root.address_label
- font_size: '15sp'
- halign: 'left'
- MDLabel:
- font_style: 'Title'
- theme_text_color: 'Primary'
- text: "Address"
- font_size: '17sp'
- halign: 'left'
- MDLabel:
- font_style: 'Subhead'
- theme_text_color: 'Primary'
- text: root.address
- font_size: '15sp'
- halign: 'left'
- BoxLayout:
- id: my_add_btn
- spacing:5
- orientation: 'horizontal'
- MDRaisedButton:
- size_hint: 2, None
- height: dp(40)
- on_press: root.send_message_from()
- MDLabel:
- font_style: 'Title'
- text: 'Send message from'
- font_size: '13sp'
- color: (1,1,1,1)
- halign: 'center'
- MDRaisedButton:
- size_hint: 1.5, None
- height: dp(40)
- on_press: root.dismiss()
- on_press: app.root.ids.scr_mngr.current = 'showqrcode'
- on_press: app.root.ids.sc15.qrdisplay()
- MDLabel:
- font_style: 'Title'
- text: 'Show QR code'
- font_size: '13sp'
- color: (1,1,1,1)
- halign: 'center'
- MDRaisedButton:
- size_hint: 1.5, None
- height: dp(40)
- on_press: root.dismiss()
- on_press: root.close_pop()
- MDLabel:
- font_style: 'Title'
- text: 'Cancel'
- font_size: '13sp'
- color: (1,1,1,1)
- halign: 'center'
-
-:
- id: addbook_popup
- size_hint : (None,None)
- height: 4*(add_label.height)
- width :app.window_size[0] - (app.window_size[0]/10 if app.app_platform == 'android' else app.window_size[0]/4)
- background: './images/popup.jpeg'
- separator_height: 0
- auto_dismiss: False
- BoxLayout:
- size_hint_y: None
- spacing:dp(70)
- id: addbook_popup_box
- orientation: 'vertical'
- BoxLayout:
- size_hint_y: None
- orientation: 'vertical'
- spacing:dp(20)
- MDLabel:
- font_style: 'Title'
- theme_text_color: 'Primary'
- text: "Label"
- font_size: '17sp'
- halign: 'left'
- MDTextField:
- id: add_label
- font_style: 'Subhead'
- font_size: '15sp'
- halign: 'left'
- text: root.address_label
- theme_text_color: 'Primary'
- required: True
- helper_text_mode: "on_error"
- on_text: root.checkLabel_valid(self)
- MDLabel:
- font_style: 'Title'
- theme_text_color: 'Primary'
- text: "Address"
- font_size: '17sp'
- halign: 'left'
- MDLabel:
- id: address
- font_style: 'Subhead'
- theme_text_color: 'Primary'
- text: root.address
- font_size: '15sp'
- halign: 'left'
- BoxLayout:
- id: addbook_btn
- spacing:5
- orientation: 'horizontal'
- MDRaisedButton:
- size_hint: 2, None
- height: dp(40)
- on_press: root.send_message_to()
- MDLabel:
- font_style: 'Title'
- text: 'Send message to'
- font_size: '13sp'
- color: (1,1,1,1)
- halign: 'center'
- MDRaisedButton:
- size_hint: 1.5, None
- height: dp(40)
- font_size: '10sp'
- on_press: root.update_addbook_label(root.address)
- MDLabel:
- font_style: 'Title'
- text: 'Save'
- font_size: '13sp'
- color: (1,1,1,1)
- halign: 'center'
- MDRaisedButton:
- size_hint: 1.5, None
- height: dp(40)
- on_press: root.dismiss()
- on_press: root.close_pop()
- MDLabel:
- font_style: 'Title'
- text: 'Cancel'
- font_size: '13sp'
- color: (1,1,1,1)
- halign: 'center'
+:
+ name: 'spam'
+ Label:
+ text:"I am in Spam"
+ color: 0,0,0,1
:
name: 'showqrcode'
@@ -1288,45 +277,18 @@ NavigationLayout:
orientation: 'vertical'
id: qr
+:
+ name: 'starred'
+ Label:
+ text:"I am in Starred"
+ color: 0,0,0,1
-:
- source: './images/down-arrow.png' if self.parent.is_open == True else './images/right-arrow.png'
- size: 15, 15
- x: self.parent.x + self.parent.width - self.width - 5
- y: self.parent.y + self.parent.height/2 - self.height + 5
+ color: 0,0,0,1
+:
+ name: 'archieve'
+ Label:
+ text:"I am in Archieve"
+ color: 0,0,0,1
-:
- id: search_bar
- size_hint_y: None
- height: self.minimum_height
-
- MDIconButton:
- icon: 'magnify'
-
- MDTextField:
- id: search_field
- hint_text: 'Search'
- on_text: app.searchQuery(self)
-
-
-:
- separator_color: 1, 1, 1, 1
- background: "White.png"
- Button:
- id: btn
- disabled: True
- background_disabled_normal: "White.png"
- Image:
- source: './images/loader.zip'
- anim_delay: 0
- #mipmap: True
- size: root.size
-
-
-:
- id: spinner
- size_hint: None, None
- size: dp(46), dp(46)
- pos_hint: {'center_x': 0.5, 'center_y': 0.5}
- active: False
\ No newline at end of file
+ color: 0,0,0,1
diff --git a/src/bitmessagekivy/mpybit.py b/src/bitmessagekivy/mpybit.py
index 2b2f9d56..c0e90757 100644
--- a/src/bitmessagekivy/mpybit.py
+++ b/src/bitmessagekivy/mpybit.py
@@ -1,18 +1,22 @@
"""
Bitmessage android(mobile) interface
"""
-# pylint: disable=relative-import, import-error, no-name-in-module
-# pylint: disable=too-few-public-methods, too-many-lines, unused-argument
+# pylint: disable=too-many-lines,import-error,no-name-in-module,unused-argument
+# pylint: disable=too-many-ancestors,too-many-locals,useless-super-delegation
import os
import time
+from bitmessagekivy import identiconGeneration
+from bitmessagekivy import kivy_helper_search
+from bitmessagekivy.uikivysignaler import UIkivySignaler
from bmconfigparser import BMConfigParser
from functools import partial
from helper_sql import sqlExecute, sqlQuery
-from kivy.app import App
+from kivymd.app import MDApp
from kivy.clock import Clock
from kivy.core.clipboard import Clipboard
from kivy.core.window import Window
from kivy.lang import Builder
+from kivy.metrics import dp
from kivy.properties import (
BooleanProperty,
ListProperty,
@@ -35,58 +39,87 @@ from kivy.uix.screenmanager import Screen
from kivy.uix.spinner import Spinner
from kivy.uix.textinput import TextInput
from kivy.utils import platform
-
-import kivy_helper_search
-from kivymd.button import MDIconButton
-from kivymd.dialog import MDDialog
-from kivymd.label import MDLabel
-from kivymd.list import (
+from kivymd.uix.button import MDIconButton
+from kivymd.uix.dialog import MDDialog
+from kivymd.uix.label import MDLabel
+from kivymd.uix.list import (
ILeftBody,
ILeftBodyTouch,
IRightBodyTouch,
TwoLineAvatarIconListItem,
- TwoLineListItem
+ OneLineIconListItem,
+ OneLineAvatarIconListItem,
+ OneLineListItem
)
-from kivymd.navigationdrawer import (
- MDNavigationDrawer,
- NavigationDrawerHeaderBase
-)
-from kivymd.selectioncontrols import MDCheckbox
-from kivymd.theming import ThemeManager
+# from kivymd.uix.navigationdrawer import (
+# MDNavigationDrawer,
+# NavigationDrawerHeaderBase
+# )
+from kivymd.uix.selectioncontrol import MDCheckbox, MDSwitch
import queues
from semaphores import kivyuisignaler
import state
-from uikivysignaler import UIkivySignaler
+from addresses import decodeAddress
+from kivy.config import Config
+Config.set('input', 'mouse', 'mouse,multitouch_on_demand')
+# pylint: disable=too-few-public-methods,too-many-arguments,attribute-defined-outside-init
-import identiconGeneration
-from addresses import addBMIfNotPresent, decodeAddress
+KVFILES = [
+ 'settings', 'popup', 'allmails', 'draft',
+ 'maildetail', 'common_widgets', 'addressbook',
+ 'myaddress', 'composer', 'payment', 'sent',
+ 'network', 'login', 'credits', 'trash', 'inbox'
+]
def toast(text):
- """Function displays toast message"""
+ """Method will display the toast message"""
# pylint: disable=redefined-outer-name
from kivymd.toast.kivytoast import toast
toast(text)
return
-class Navigatorss(MDNavigationDrawer):
- """Navigator class (image, title and logo)"""
- image_source = StringProperty('images/qidenticon_two.png')
- title = StringProperty('Navigation')
- drawer_logo = StringProperty()
+def showLimitedCnt(total_msg):
+ """This method set the total count limit in badge_text"""
+ return "99+" if total_msg > 99 else str(total_msg)
+
+
+def ShowTimeHistoy(act_time):
+ """This method is used to return the message sent or receive time"""
+ from datetime import datetime
+ action_time = datetime.fromtimestamp(int(act_time))
+ crnt_date = datetime.now()
+ duration = crnt_date - action_time
+ display_data = (action_time.strftime('%d/%m/%Y')
+ if duration.days >= 365 else action_time.strftime('%I:%M %p').lstrip('0')
+ if duration.days == 0 and crnt_date.strftime('%d/%m/%Y') == action_time.strftime('%d/%m/%Y')
+ else action_time.strftime("%d %b"))
+ return display_data
+
+
+def AddTimeWidget(time):
+ """This method is used to create TimeWidget"""
+ action_time = BadgeText(
+ size_hint= (None, None),
+ text= f"{ShowTimeHistoy(time)}",
+ halign='right',
+ font_style='Caption',
+ size= [65,70])
+ return action_time
class Inbox(Screen):
- """Inbox Screen uses screen to show widgets of screens."""
+ """Inbox Screen uses screen to show widgets of screens"""
+
queryreturn = ListProperty()
has_refreshed = True
account = StringProperty()
def __init__(self, *args, **kwargs):
- """Method Parsing the address."""
+ """Method Parsing the address"""
super(Inbox, self).__init__(*args, **kwargs)
Clock.schedule_once(self.init_ui, 0)
@@ -98,12 +131,11 @@ class Inbox(Screen):
state.association = BMConfigParser().addresses()[0]
def init_ui(self, dt=0):
- """Clock schdule for method inbox accounts."""
+ """Clock schdule for method inbox accounts"""
self.loadMessagelist()
def loadMessagelist(self, where="", what=""):
- """Load Inbox list for Inbox messages."""
- # pylint: disable=too-many-locals
+ """Load Inbox list for Inbox messages"""
self.set_defaultAddress()
self.account = state.association
if state.searcing_text:
@@ -112,36 +144,46 @@ class Inbox(Screen):
what = state.searcing_text
xAddress = 'toaddress'
data = []
+ self.ids.identi_tag.children[0].text = ''
self.inboxDataQuery(xAddress, where, what)
self.ids.identi_tag.children[0].text = ''
if self.queryreturn:
self.ids.identi_tag.children[0].text = 'Inbox'
state.kivyapp.get_inbox_count()
- src_mng_obj = state.kivyapp.root.children[2].children[0].ids
- src_mng_obj.inbox_cnt.badge_text = state.inbox_count
+ self.set_inboxCount(state.inbox_count)
for mail in self.queryreturn:
# third_text = mail[3].replace('\n', ' ')
+ subject = mail[3].decode() if isinstance(mail[3],bytes) else mail[3]
+ body = mail[5].decode() if isinstance(mail[5],bytes) else mail[5]
data.append({
'text': mail[4].strip(),
- 'secondary_text': mail[5][:50] + '........' if len(
- mail[5]) >= 50 else (mail[5] + ',' + mail[3].replace(
+ 'secondary_text': body[:50] + '........' if len(
+ body) >= 50 else (body + ',' + subject.replace(
'\n', ''))[0:50] + '........',
- 'msgid': mail[1]})
+ 'msgid': mail[1], 'received': mail[6]})
self.has_refreshed = True
self.set_mdList(data)
self.children[2].children[0].children[0].bind(
scroll_y=self.check_scroll_y)
else:
+ self.set_inboxCount('0')
content = MDLabel(
- font_style='Body1', theme_text_color='Primary',
+ font_style='Caption',
+ theme_text_color='Primary',
text="No message found!" if state.searcing_text
else "yet no message for this account!!!!!!!!!!!!!",
- halign='center', bold=True, size_hint_y=None, valign='top')
+ halign='center',
+ size_hint_y=None,
+ valign='top')
self.ids.ml.add_widget(content)
- # pylint: disable=too-many-arguments
+ def set_inboxCount(self, msgCnt): # pylint: disable=no-self-use
+ """This method is used to sent inbox message count"""
+ src_mng_obj = state.kivyapp.root.ids.content_drawer.ids.inbox_cnt
+ src_mng_obj.children[0].children[0].text = showLimitedCnt(int(msgCnt))
+
def inboxDataQuery(self, xAddress, where, what, start_indx=0, end_indx=20):
- """This method used for retrieving inbox data"""
+ """This method is used for retrieving inbox data"""
self.queryreturn = kivy_helper_search.search_sql(
xAddress, self.account, "inbox", where, what,
False, start_indx, end_indx)
@@ -158,6 +200,7 @@ class Inbox(Screen):
source='./images/text_images/{}.png'.format(
avatarImageFirstLetter(item['secondary_text'].strip()))))
meny.bind(on_press=partial(self.inbox_detail, item['msgid']))
+ meny.add_widget(AddTimeWidget(item['received']))
carousel = Carousel(direction='right')
carousel.height = meny.height
carousel.size_hint_y = None
@@ -170,10 +213,10 @@ class Inbox(Screen):
del_btn.bind(on_press=partial(self.delete, item['msgid']))
carousel.add_widget(del_btn)
carousel.add_widget(meny)
- ach_btn = Button(text='Achieve')
- ach_btn.background_color = (0, 1, 0, 1)
- ach_btn.bind(on_press=partial(self.archive, item['msgid']))
- carousel.add_widget(ach_btn)
+ # ach_btn = Button(text='Achieve')
+ # ach_btn.background_color = (0, 1, 0, 1)
+ # ach_btn.bind(on_press=partial(self.archive, item['msgid']))
+ # carousel.add_widget(ach_btn)
carousel.index = 1
self.ids.ml.add_widget(carousel)
update_message = len(self.ids.ml.children)
@@ -198,10 +241,12 @@ class Inbox(Screen):
self.inboxDataQuery('toaddress', where, what, total_message, 5)
for mail in self.queryreturn:
# third_text = mail[3].replace('\n', ' ')
+ subject = mail[3].decode() if isinstance(mail[3],bytes) else mail[3]
+ body = mail[5].decode() if isinstance(mail[5],bytes) else mail[5]
data.append({
'text': mail[4].strip(),
- 'secondary_text': mail[5][:50] + '........' if len(
- mail[5]) >= 50 else (mail[5] + ',' + mail[3].replace(
+ 'secondary_text': body[:50] + '........' if len(
+ body) >= 50 else (body + ',' +subject.replace(
'\n', ''))[0:50] + '........',
'msgid': mail[1]})
self.set_mdList(data)
@@ -221,22 +266,12 @@ class Inbox(Screen):
def delete(self, data_index, instance, *args):
"""Delete inbox mail from inbox listing"""
sqlExecute(
- "UPDATE inbox SET folder = 'trash' WHERE msgid = ?;", str(
- data_index))
- try:
- msg_count_objs = (
- self.parent.parent.parent.parent.children[2].children[0].ids)
- except Exception:
- msg_count_objs = (
- self.parent.parent.parent.parent.parent.children[
- 2].children[0].ids)
+ "UPDATE inbox SET folder = 'trash' WHERE msgid = ?;", data_index)
+ msg_count_objs = self.parent.parent.ids.content_drawer.ids
if int(state.inbox_count) > 0:
- msg_count_objs.inbox_cnt.badge_text = str(
- int(state.inbox_count) - 1)
- msg_count_objs.trash_cnt.badge_text = str(
- int(state.trash_count) + 1)
- msg_count_objs.allmail_cnt.badge_text = str(
- int(state.all_count) - 1)
+ msg_count_objs.inbox_cnt.children[0].children[0].text = showLimitedCnt(int(state.inbox_count) - 1)
+ msg_count_objs.trash_cnt.children[0].children[0].text = showLimitedCnt(int(state.trash_count) + 1)
+ msg_count_objs.allmail_cnt.children[0].children[0].text = showLimitedCnt(int(state.all_count) - 1)
state.inbox_count = str(
int(state.inbox_count) - 1)
state.trash_count = str(
@@ -253,8 +288,7 @@ class Inbox(Screen):
def archive(self, data_index, instance, *args):
"""Archive inbox mail from inbox listing"""
sqlExecute(
- "UPDATE inbox SET folder = 'trash' WHERE msgid = ?;",
- str(data_index))
+ "UPDATE inbox SET folder = 'trash' WHERE msgid = ?;", data_index)
self.ids.ml.remove_widget(instance.parent.parent)
self.update_trash()
@@ -267,7 +301,6 @@ class Inbox(Screen):
self.parent.parent.screens[4].clear_widgets()
self.parent.parent.screens[4].add_widget(Trash())
- # pylint: disable=attribute-defined-outside-init
def refresh_callback(self, *args):
"""Method updates the state of application,
While the spinner remains on the screen"""
@@ -282,34 +315,30 @@ class Inbox(Screen):
self.tick = 0
Clock.schedule_once(refresh_callback, 1)
- # def set_root_layout(self):
- # """Setting root layout"""
- # return self.parent.parent.parent
-
class MyAddress(Screen):
- """MyAddress screen uses screen to show widgets of screens."""
+ """MyAddress screen uses screen to show widgets of screens"""
+
addresses_list = ListProperty()
has_refreshed = True
is_add_created = False
def __init__(self, *args, **kwargs):
- """Clock schdule for method Myaddress accounts."""
+ """Clock schdule for method Myaddress accounts"""
super(MyAddress, self).__init__(*args, **kwargs)
Clock.schedule_once(self.init_ui, 0)
def init_ui(self, dt=0):
"""Clock schdule for method Myaddress accounts"""
- self.addresses_list = state.kivyapp.variable_1
+ # pylint: disable=unnecessary-lambda, deprecated-lambda
+ # self.addresses_list = state.kivyapp.variable_1
+ self.addresses_list = BMConfigParser().addresses()
if state.searcing_text:
self.ids.refresh_layout.scroll_y = 1.0
- # filtered_list = filter(
- # lambda addr: self.filter_address(
- # addr), BMConfigParser().addresses())
filtered_list = [
- x
- for x in BMConfigParser().addresses()
- if self.filter_address(x)]
+ x for x in BMConfigParser().addresses()
+ if self.filter_address(x)
+ ]
self.addresses_list = filtered_list
self.addresses_list = [obj for obj in reversed(self.addresses_list)]
self.ids.identi_tag.children[0].text = ''
@@ -320,10 +349,13 @@ class MyAddress(Screen):
self.ids.refresh_layout.bind(scroll_y=self.check_scroll_y)
else:
content = MDLabel(
- font_style='Body1', theme_text_color='Primary',
+ font_style='Caption',
+ theme_text_color='Primary',
text="No address found!" if state.searcing_text
else "yet no address is created by user!!!!!!!!!!!!!",
- halign='center', bold=True, size_hint_y=None, valign='top')
+ halign='center',
+ size_hint_y=None,
+ valign='top')
self.ids.ml.add_widget(content)
if not state.searcing_text and not self.is_add_created:
try:
@@ -339,15 +371,41 @@ class MyAddress(Screen):
'text': BMConfigParser().get(address, 'label'),
'secondary_text': address})
for item in data:
+ is_enable = BMConfigParser().get(item['secondary_text'], 'enabled')
meny = TwoLineAvatarIconListItem(
text=item['text'], secondary_text=item['secondary_text'],
- theme_text_color='Custom',
- text_color=NavigateApp().theme_cls.primary_color)
+ theme_text_color='Custom' if is_enable == 'true' else 'Primary',
+ text_color=NavigateApp().theme_cls.primary_color,
+ )
meny.add_widget(AvatarSampleWidget(
source='./images/text_images/{}.png'.format(
avatarImageFirstLetter(item['text'].strip()))))
meny.bind(on_press=partial(
self.myadd_detail, item['secondary_text'], item['text']))
+ if state.association == item['secondary_text']:
+ meny.add_widget(BadgeText(size_hint= (None, None),
+ text='Active', halign='right',
+ font_style='Body1', size= [50,60],
+ theme_text_color='Custom',
+ text_color=NavigateApp().theme_cls.primary_color))
+ else:
+ meny.add_widget(ToggleBtn(active = True if is_enable == 'true' else False))
+ # carousel = Carousel(direction='right')
+ # carousel.height = meny.height
+ # carousel.size_hint_y = None
+ # carousel.ignore_perpendicular_swipes = True
+ # carousel.data_index = 0
+ # carousel.min_move = 0.2
+ # del_btn = Button(text='Disable' if is_enable == 'true' else 'Enable')
+ # if is_enable == 'true':
+ # del_btn.background_normal = ''
+ # del_btn.background_color = (1, 0, 0, 1) if is_enable == 'true' else (0, 1, 0, 1)
+ # del_btn.bind(
+ # on_press=partial(
+ # self.disableAddress if is_enable == 'true' else self.enableAddress , item['secondary_text']))
+ # carousel.add_widget(del_btn)
+ # carousel.add_widget(meny)
+ # carousel.index = 1
self.ids.ml.add_widget(meny)
def check_scroll_y(self, instance, somethingelse):
@@ -369,18 +427,18 @@ class MyAddress(Screen):
@staticmethod
def myadd_detail(fromaddress, label, *args):
"""Load myaddresses details"""
- p = MyaddDetailPopup()
- p.open()
- p.set_address(fromaddress, label)
+ if BMConfigParser().get(fromaddress, 'enabled') == 'true':
+ p = MyaddDetailPopup()
+ p.open()
+ p.set_address(fromaddress, label)
- # pylint: disable=attribute-defined-outside-init
def refresh_callback(self, *args):
"""Method updates the state of application,
While the spinner remains on the screen"""
def refresh_callback(interval):
"""Method used for loading the myaddress screen data"""
state.searcing_text = ''
- state.kivyapp.root.ids.sc10.children[2].active = False
+ # state.kivyapp.root.ids.sc10.children[2].active = False
self.children[2].children[2].ids.search_field.text = ''
self.has_refreshed = True
self.ids.ml.clear_widgets()
@@ -392,22 +450,52 @@ class MyAddress(Screen):
@staticmethod
def filter_address(address):
"""Method will filter the my address list data"""
- # if filter(lambda x: (state.searcing_text).lower() in x, [
- # BMConfigParser().get(
- # address, 'label').lower(), address.lower()]):
- if [x for x in [BMConfigParser().get(
- address, 'label').lower(), address.lower()] if (
- state.searcing_text).lower() in x]:
+ if [
+ x for x in [
+ BMConfigParser().get(address, 'label').lower(),
+ address.lower()
+ ]
+ if (state.searcing_text).lower() in x
+ ]:
return True
return False
- def set_root_layout(self):
- """Setting root layout"""
- return self.manager.parent.parent
+
+ def disableAddress(self, address, instance):
+ """This method is use for disabling address"""
+ BMConfigParser().set(str(address), 'enabled', 'false')
+ BMConfigParser().save()
+ instance.parent.parent.theme_text_color = 'Primary'
+ toast('Address disabled')
+ Clock.schedule_once(self.address_permision_callback, 0)
+
+ def enableAddress(self, address, instance):
+ """This method is use for enabling address"""
+ BMConfigParser().set(address, 'enabled', 'true')
+ BMConfigParser().save()
+ instance.parent.parent.theme_text_color = 'Custom'
+ toast('Address Enabled')
+ Clock.schedule_once(self.address_permision_callback, 0)
+
+ def address_permision_callback(self, dt=0):
+ """callback for enable or disable addresses"""
+ addresses = [addr for addr in BMConfigParser().addresses()
+ if BMConfigParser().get(str(addr), 'enabled') == 'true']
+ self.parent.parent.ids.content_drawer.ids.btn.values = addresses
+ self.parent.parent.ids.sc3.children[1].ids.btn.values = addresses
+
+ def toggleAction(self, instance):
+ """This method is used for enable or disable address"""
+ addr = instance.parent.parent.secondary_text
+ if instance.active:
+ self.disableAddress(addr, instance)
+ else:
+ self.enableAddress(addr, instance)
class AddressBook(Screen):
"""AddressBook Screen uses screen to show widgets of screens"""
+
queryreturn = ListProperty()
has_refreshed = True
@@ -419,7 +507,7 @@ class AddressBook(Screen):
def init_ui(self, dt=0):
"""Clock Schdule for method AddressBook"""
self.loadAddresslist(None, 'All', '')
- print dt
+ print(dt)
def loadAddresslist(self, account, where="", what=""):
"""Clock Schdule for method AddressBook"""
@@ -439,10 +527,13 @@ class AddressBook(Screen):
self.ids.scroll_y.bind(scroll_y=self.check_scroll_y)
else:
content = MDLabel(
- font_style='Body1', theme_text_color='Primary',
+ font_style='Caption',
+ theme_text_color='Primary',
text="No contact found!" if state.searcing_text
else "No contact found yet...... ",
- halign='center', bold=True, size_hint_y=None, valign='top')
+ halign='center',
+ size_hint_y=None,
+ valign='top')
self.ids.ml.add_widget(content)
def set_mdList(self, start_index, end_index):
@@ -504,7 +595,8 @@ class AddressBook(Screen):
def delete_address(self, address, instance, *args):
"""Delete inbox mail from inbox listing"""
self.ids.ml.remove_widget(instance.parent.parent)
- if len(self.ids.ml.children) == 0:
+ # if len(self.ids.ml.children) == 0:
+ if self.ids.ml.children is not None:
self.ids.identi_tag.children[0].text = ''
sqlExecute(
"DELETE FROM addressbook WHERE address = '{}';".format(address))
@@ -513,12 +605,14 @@ class AddressBook(Screen):
class SelectableRecycleBoxLayout(
FocusBehavior, LayoutSelectionBehavior, RecycleBoxLayout):
"""Adds selection and focus behaviour to the view"""
- # pylint: disable = too-many-ancestors, duplicate-bases
+ # pylint: disable = duplicate-bases
+
pass
class SelectableLabel(RecycleDataViewBehavior, Label):
"""Add selection support to the Label"""
+
index = None
selected = BooleanProperty(False)
selectable = BooleanProperty(True)
@@ -529,8 +623,7 @@ class SelectableLabel(RecycleDataViewBehavior, Label):
return super(SelectableLabel, self).refresh_view_attrs(
rv, index, data)
- # pylint: disable=inconsistent-return-statements
- def on_touch_down(self, touch):
+ def on_touch_down(self, touch): # pylint: disable=inconsistent-return-statements
"""Add selection on touch down"""
if super(SelectableLabel, self).on_touch_down(touch):
return True
@@ -541,7 +634,7 @@ class SelectableLabel(RecycleDataViewBehavior, Label):
"""Respond to the selection of items in the view"""
self.selected = is_selected
if is_selected:
- print "selection changed to {0}".format(rv.data[index])
+ print("selection changed to {0}".format(rv.data[index]))
rv.parent.txt_input.text = rv.parent.txt_input.text.replace(
rv.parent.txt_input.text, rv.data[index]['text'])
@@ -549,26 +642,26 @@ class SelectableLabel(RecycleDataViewBehavior, Label):
class RV(RecycleView):
"""Recycling View"""
- def __init__(self, **kwargs): # pylint: disable=useless-super-delegation
+ def __init__(self, **kwargs):
"""Recycling Method"""
super(RV, self).__init__(**kwargs)
class DropDownWidget(BoxLayout):
"""Adding Dropdown Widget"""
- # pylint: disable=too-many-statements, too-many-locals
- # pylint: disable=inconsistent-return-statements
+ # pylint: disable=too-many-statements
+
txt_input = ObjectProperty()
rv = ObjectProperty()
def send(self, navApp):
"""Send message from one address to another"""
- fromAddress = str(self.ids.ti.text)
- toAddress = str(self.ids.txt_input.text)
- subject = self.ids.subject.text.encode('utf-8').strip()
- message = self.ids.body.text.encode('utf-8').strip()
+ fromAddress = self.ids.ti.text.strip()
+ toAddress = self.ids.txt_input.text.strip()
+ subject = self.ids.subject.text.strip()
+ message = self.ids.body.text.strip()
encoding = 3
- print "message: ", self.ids.body.text
+ print("message: ", self.ids.body.text)
sendMessageToPeople = True
if sendMessageToPeople:
if toAddress != '' and subject and message:
@@ -579,23 +672,35 @@ class DropDownWidget(BoxLayout):
if state.detailPageType == 'draft' \
and state.send_draft_mail:
sqlExecute(
- "UPDATE sent SET toaddress = ?, fromaddress = ? ,"
- " subject = ?, message = ?, folder = 'sent' WHERE"
- " ackdata = ?;", toAddress, fromAddress, subject,
- message, str(state.send_draft_mail))
+ "UPDATE sent SET toaddress = ?"
+ ", fromaddress = ? , subject = ?"
+ ", message = ?, folder = 'sent'"
+ ", senttime = ?, lastactiontime = ?"
+ " WHERE ackdata = ?;",
+ toAddress,
+ fromAddress,
+ subject,
+ message,
+ int(time.time()),
+ int(time.time()),
+ state.send_draft_mail)
self.parent.parent.screens[15].clear_widgets()
self.parent.parent.screens[15].add_widget(Draft())
+ # state.detailPageType = ''
+ # state.send_draft_mail = None
else:
+ from addresses import addBMIfNotPresent
toAddress = addBMIfNotPresent(toAddress)
statusIconColor = 'red'
if (addressVersionNumber > 4) or (
addressVersionNumber <= 1):
- print "addressVersionNumber > 4"\
- " or addressVersionNumber <= 1"
+ print(
+ "addressVersionNumber > 4"
+ " or addressVersionNumber <= 1")
if streamNumber > 1 or streamNumber == 0:
- print "streamNumber > 1 or streamNumber == 0"
+ print("streamNumber > 1 or streamNumber == 0")
if statusIconColor == 'red':
- print "shared.statusIconColor == 'red'"
+ print("shared.statusIconColor == 'red'")
stealthLevel = BMConfigParser().safeGetInt(
'bitmessagesettings', 'ackstealthlevel')
from helper_ackPayload import genAckPayload
@@ -604,27 +709,36 @@ class DropDownWidget(BoxLayout):
sqlExecute(
'''INSERT INTO sent VALUES
(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)''',
- '', toAddress, ripe, fromAddress, subject, message,
- ackdata, int(time.time()), int(time.time()), 0,
- 'msgqueued', 0, 'sent', encoding,
- BMConfigParser().getint(
+ '',
+ toAddress,
+ ripe,
+ fromAddress,
+ subject,
+ message,
+ ackdata,
+ int(time.time()),
+ int(time.time()),
+ 0,
+ 'msgqueued',
+ 0,
+ 'sent',
+ encoding,
+ BMConfigParser().safeGetInt(
'bitmessagesettings', 'ttl'))
state.check_sent_acc = fromAddress
- state.msg_counter_objs = self.parent.parent.parent.parent\
- .parent.parent.children[2].children[0].ids
- if state.detailPageType == 'draft' and state.send_draft_mail:
+ # state.msg_counter_objs = self.parent.parent.parent.parent\
+ # .parent.parent.children[2].children[0].ids
+ if state.detailPageType == 'draft' \
+ and state.send_draft_mail:
state.draft_count = str(int(state.draft_count) - 1)
- state.msg_counter_objs.draft_cnt.badge_text = state.draft_count
+ # state.msg_counter_objs.draft_cnt.badge_text = (
+ # state.draft_count)
state.detailPageType = ''
state.send_draft_mail = None
- # self.parent.parent.screens[0].ids.ml.clear_widgets()
- # self.parent.parent.screens[0].loadMessagelist(state.association)
self.parent.parent.screens[3].update_sent_messagelist()
- # self.parent.parent.screens[16].clear_widgets()
- # self.parent.parent.screens[16].add_widget(Allmails())
Clock.schedule_once(self.callback_for_msgsend, 3)
queues.workerQueue.put(('sendmessage', toAddress))
- print "sqlExecute successfully #######################"
+ print("sqlExecute successfully #######################")
state.in_composer = True
return
else:
@@ -643,7 +757,6 @@ class DropDownWidget(BoxLayout):
state.kivyapp.back_press()
toast('sent')
- # pylint: disable=attribute-defined-outside-init
def address_error_message(self, msg):
"""Generates error message"""
width = .8 if platform == 'android' else .55
@@ -654,7 +767,7 @@ class DropDownWidget(BoxLayout):
msg_dialog.open()
@staticmethod
- def callback_for_menu_items(text_item):
+ def callback_for_menu_items(text_item, *arg):
"""Callback of alert box"""
toast(text_item)
@@ -675,14 +788,15 @@ class DropDownWidget(BoxLayout):
class MyTextInput(TextInput):
"""Takes the text input in the field"""
+
txt_input = ObjectProperty()
flt_list = ObjectProperty()
word_list = ListProperty()
starting_no = NumericProperty(3)
suggestion_text = ''
- def __init__(self, **kwargs): # pylint: disable=useless-super-delegation
- """Getting Text Input"""
+ def __init__(self, **kwargs):
+ """Getting Text Input."""
super(MyTextInput, self).__init__(**kwargs)
def on_text(self, instance, value):
@@ -712,8 +826,9 @@ class MyTextInput(TextInput):
class Payment(Screen):
"""Payment module"""
- def get_available_credits(self, instance): # pylint: disable=no-self-use
+ def get_available_credits(self, instance):
"""Get the available credits"""
+ # pylint: disable=no-self-use
state.availabe_credit = instance.parent.children[1].text
existing_credits = (
state.kivyapp.root.ids.sc18.ids.ml.children[0].children[
@@ -730,17 +845,21 @@ class Payment(Screen):
class Credits(Screen):
- """Module for screen screen"""
- available_credits = StringProperty('{0}'.format('0'))
+ """Credits Method"""
+
+ available_credits = StringProperty(
+ '{0}'.format('0'))
class Login(Screen):
"""Login Screeen"""
+
pass
class NetworkStat(Screen):
"""Method used to show network stat"""
+
text_variable_1 = StringProperty(
'{0}::{1}'.format('Total Connections', '0'))
text_variable_2 = StringProperty(
@@ -774,13 +893,15 @@ class NetworkStat(Screen):
len(objectracker.missingObjects))
-class ContentNavigationDrawer(Navigatorss):
+class ContentNavigationDrawer(BoxLayout):
"""Navigate Content Drawer"""
+
pass
class Random(Screen):
"""Generates Random Address"""
+
is_active = BooleanProperty(False)
checked = StringProperty("")
@@ -801,16 +922,16 @@ class Random(Screen):
"", eighteenByteRipe, nonceTrialsPerByte,
payloadLengthExtraBytes))
self.ids.label.text = ''
- self.parent.parent.children[1].opacity = 1
- self.parent.parent.children[1].disabled = False
- state.kivyapp.root.ids.sc10.children[1].active = True
+ self.parent.parent.ids.toolbar.opacity = 1
+ self.parent.parent.ids.toolbar.disabled = False
+ state.kivyapp.loadMyAddressScreen(True)
self.manager.current = 'myaddress'
Clock.schedule_once(self.address_created_callback, 6)
@staticmethod
def address_created_callback(dt=0):
"""New address created"""
- state.kivyapp.root.ids.sc10.children[1].active = False
+ state.kivyapp.loadMyAddressScreen(False)
state.kivyapp.root.ids.sc10.ids.ml.clear_widgets()
state.kivyapp.root.ids.sc10.is_add_created = True
state.kivyapp.root.ids.sc10.init_ui()
@@ -839,12 +960,13 @@ class Random(Screen):
class Sent(Screen):
"""Sent Screen uses screen to show widgets of screens"""
+
queryreturn = ListProperty()
has_refreshed = True
account = StringProperty()
def __init__(self, *args, **kwargs):
- """Association with the screen."""
+ """Association with the screen"""
super(Sent, self).__init__(*args, **kwargs)
if state.association == '':
if BMConfigParser().addresses():
@@ -854,10 +976,10 @@ class Sent(Screen):
def init_ui(self, dt=0):
"""Clock Schdule for method sent accounts"""
self.loadSent()
- print dt
+ print(dt)
def loadSent(self, where="", what=""):
- """Load Sent list for Sent messages."""
+ """Load Sent list for Sent messages"""
self.account = state.association
if state.searcing_text:
self.ids.scroll_y.scroll_y = 1.0
@@ -876,24 +998,33 @@ class Sent(Screen):
'secondary_text': mail[2][:50] + '........' if len(
mail[2]) >= 50 else (mail[2] + ',' + mail[3].replace(
'\n', ''))[0:50] + '........',
- 'ackdata': mail[5]})
+ 'ackdata': mail[5], 'senttime': mail[6]},)
self.set_mdlist(data, 0)
self.has_refreshed = True
self.ids.scroll_y.bind(scroll_y=self.check_scroll_y)
else:
+ self.set_sentCount('0')
content = MDLabel(
- font_style='Body1', theme_text_color='Primary',
+ font_style='Caption',
+ theme_text_color='Primary',
text="No message found!" if state.searcing_text
else "yet no message for this account!!!!!!!!!!!!!",
- halign='center', bold=True, size_hint_y=None, valign='top')
+ halign='center',
+ size_hint_y=None,
+ valign='top')
self.ids.ml.add_widget(content)
- # pylint: disable=too-many-arguments
def sentDataQuery(self, xAddress, where, what, start_indx=0, end_indx=20):
"""This method is used to retrieving data from sent table"""
self.queryreturn = kivy_helper_search.search_sql(
- xAddress, self.account, "sent", where, what,
- False, start_indx, end_indx)
+ xAddress,
+ self.account,
+ 'sent',
+ where,
+ what,
+ False,
+ start_indx,
+ end_indx)
def set_mdlist(self, data, set_index=0):
"""This method is used to create the mdList"""
@@ -902,11 +1033,13 @@ class Sent(Screen):
meny = TwoLineAvatarIconListItem(
text=item['text'], secondary_text=item['secondary_text'],
theme_text_color='Custom',
- text_color=NavigateApp().theme_cls.primary_color)
+ text_color=NavigateApp().theme_cls.primary_color
+ )
meny.add_widget(AvatarSampleWidget(
source='./images/text_images/{}.png'.format(
avatarImageFirstLetter(item['secondary_text'].strip()))))
meny.bind(on_press=partial(self.sent_detail, item['ackdata']))
+ meny.add_widget(AddTimeWidget(item['senttime']))
carousel = Carousel(direction='right')
carousel.height = meny.height
carousel.size_hint_y = None
@@ -919,10 +1052,10 @@ class Sent(Screen):
del_btn.bind(on_press=partial(self.delete, item['ackdata']))
carousel.add_widget(del_btn)
carousel.add_widget(meny)
- ach_btn = Button(text='Achieve')
- ach_btn.background_color = (0, 1, 0, 1)
- ach_btn.bind(on_press=partial(self.archive, item['ackdata']))
- carousel.add_widget(ach_btn)
+ # ach_btn = Button(text='Achieve')
+ # ach_btn.background_color = (0, 1, 0, 1)
+ # ach_btn.bind(on_press=partial(self.archive, item['ackdata']))
+ # carousel.add_widget(ach_btn)
carousel.index = 1
self.ids.ml.add_widget(carousel, index=set_index)
updated_msgs = len(self.ids.ml.children)
@@ -947,7 +1080,7 @@ class Sent(Screen):
'secondary_text': mail[2][:50] + '........' if len(
mail[2]) >= 50 else (mail[2] + ',' + mail[3].replace(
'\n', ''))[0:50] + '........',
- 'ackdata': mail[5]})
+ 'ackdata': mail[5], 'senttime': mail[6]})
self.set_mdlist(data, total_sent - 1)
if state.msg_counter_objs and state.association == (
state.check_sent_acc):
@@ -983,9 +1116,12 @@ class Sent(Screen):
@staticmethod
def set_sentCount(total_sent):
"""Set the total no. of sent message count"""
- src_mng_obj = state.kivyapp.root.children[2].children[0].ids
- src_mng_obj.send_cnt.badge_text = str(total_sent)
- state.sent_count = str(total_sent)
+ src_mng_obj = state.kivyapp.root.ids.content_drawer.ids.send_cnt
+ if state.association:
+ src_mng_obj.children[0].children[0].text = showLimitedCnt(int(total_sent))
+ state.kivyapp.get_sent_count()
+ else:
+ src_mng_obj.children[0].children[0].text = '0'
def sent_detail(self, ackdata, *args):
"""Load sent mail details"""
@@ -1001,19 +1137,11 @@ class Sent(Screen):
def delete(self, data_index, instance, *args):
"""Delete sent mail from sent mail listing"""
- try:
- msg_count_objs = self.parent.parent.parent.parent.children[
- 2].children[0].ids
- except Exception:
- msg_count_objs = self.parent.parent.parent.parent.parent.children[
- 2].children[0].ids
+ msg_count_objs = self.parent.parent.ids.content_drawer.ids
if int(state.sent_count) > 0:
- msg_count_objs.send_cnt.badge_text = str(
- int(state.sent_count) - 1)
- msg_count_objs.trash_cnt.badge_text = str(
- int(state.trash_count) + 1)
- msg_count_objs.allmail_cnt.badge_text = str(
- int(state.all_count) - 1)
+ msg_count_objs.send_cnt.children[0].children[0].text = showLimitedCnt(int(state.sent_count) - 1)
+ msg_count_objs.trash_cnt.children[0].children[0].text = showLimitedCnt(int(state.trash_count) + 1)
+ msg_count_objs.allmail_cnt.children[0].children[0].text = showLimitedCnt(int(state.all_count) - 1)
state.sent_count = str(int(state.sent_count) - 1)
state.trash_count = str(int(state.trash_count) + 1)
state.all_count = str(int(state.all_count) - 1)
@@ -1021,7 +1149,7 @@ class Sent(Screen):
self.ids.identi_tag.children[0].text = ''
sqlExecute(
"UPDATE sent SET folder = 'trash'"
- " WHERE ackdata = ?;", str(data_index))
+ " WHERE ackdata = ?;", data_index)
self.ids.ml.remove_widget(instance.parent.parent)
toast('Deleted')
self.update_trash()
@@ -1029,8 +1157,8 @@ class Sent(Screen):
def archive(self, data_index, instance, *args):
"""Archive sent mail from sent mail listing"""
sqlExecute(
- "UPDATE sent SET folder = 'trash' WHERE ackdata = ?;",
- str(data_index))
+ "UPDATE sent SET folder = 'trash'"
+ " WHERE ackdata = ?;", data_index)
self.ids.ml.remove_widget(instance.parent.parent)
self.update_trash()
@@ -1050,9 +1178,10 @@ class Sent(Screen):
class Trash(Screen):
"""Trash Screen uses screen to show widgets of screens"""
+
trash_messages = ListProperty()
has_refreshed = True
- delete_index = StringProperty()
+ # delete_index = StringProperty()
table_name = StringProperty()
def __init__(self, *args, **kwargs):
@@ -1061,7 +1190,7 @@ class Trash(Screen):
Clock.schedule_once(self.init_ui, 0)
def init_ui(self, dt=0):
- """Clock Schdule for method trash screen."""
+ """Clock Schdule for method trash screen"""
if state.association == '':
if BMConfigParser().addresses():
state.association = BMConfigParser().addresses()[0]
@@ -1069,15 +1198,20 @@ class Trash(Screen):
self.trashDataQuery(0, 20)
if self.trash_messages:
self.ids.identi_tag.children[0].text = 'Trash'
- src_mng_obj = state.kivyapp.root.children[2].children[0].ids
- src_mng_obj.trash_cnt.badge_text = state.trash_count
+ # src_mng_obj = state.kivyapp.root.children[2].children[0].ids
+ # src_mng_obj.trash_cnt.badge_text = state.trash_count
+ self.set_TrashCnt(state.trash_count)
self.set_mdList()
self.ids.scroll_y.bind(scroll_y=self.check_scroll_y)
else:
+ self.set_TrashCnt('0')
content = MDLabel(
- font_style='Body1', theme_text_color='Primary',
+ font_style='Caption',
+ theme_text_color='Primary',
text="yet no trashed message for this account!!!!!!!!!!!!!",
- halign='center', bold=True, size_hint_y=None, valign='top')
+ halign='center',
+ size_hint_y=None,
+ valign='top')
self.ids.ml.add_widget(content)
def trashDataQuery(self, start_indx, end_indx):
@@ -1085,30 +1219,37 @@ class Trash(Screen):
self.trash_messages = sqlQuery(
"SELECT toaddress, fromaddress, subject, message,"
" folder ||',' || 'sent' as folder, ackdata As"
- " id, DATE(lastactiontime) As actionTime FROM sent"
+ " id, DATE(senttime) As actionTime, senttime as msgtime FROM sent"
" WHERE folder = 'trash' and fromaddress = '{0}' UNION"
" SELECT toaddress, fromaddress, subject, message,"
" folder ||',' || 'inbox' as folder, msgid As id,"
- " DATE(received) As actionTime FROM inbox"
+ " DATE(received) As actionTime, received as msgtime FROM inbox"
" WHERE folder = 'trash' and toaddress = '{0}'"
" ORDER BY actionTime DESC limit {1}, {2}".format(
state.association, start_indx, end_indx))
+ def set_TrashCnt(self, Count): # pylint: disable=no-self-use
+ """This method is used to set trash message count"""
+ trashCnt_obj = state.kivyapp.root.ids.content_drawer.ids.trash_cnt
+ trashCnt_obj.children[0].children[0].text = showLimitedCnt(int(Count))
+
def set_mdList(self):
"""This method is used to create the mdlist"""
total_trash_msg = len(self.ids.ml.children)
for item in self.trash_messages:
+ subject = item[2].decode() if isinstance(item[2],bytes) else item[2]
+ body = item[3].decode() if isinstance(item[3],bytes) else item[3]
meny = TwoLineAvatarIconListItem(
text=item[1],
secondary_text=item[2][:50] + '........' if len(
- item[2]) >= 50 else (item[2] + ',' + item[3].replace(
+ subject) >= 50 else (subject + ',' + body.replace(
'\n', ''))[0:50] + '........',
theme_text_color='Custom',
text_color=NavigateApp().theme_cls.primary_color)
img_latter = './images/text_images/{}.png'.format(
- item[2][0].upper() if (item[2][0].upper() >= 'A' and item[
- 2][0].upper() <= 'Z') else '!')
+ subject[0].upper() if (subject[0].upper() >= 'A' and subject[0].upper() <= 'Z') else '!')
meny.add_widget(AvatarSampleWidget(source=img_latter))
+ meny.add_widget(AddTimeWidget(item[7]))
carousel = Carousel(direction='right')
carousel.height = meny.height
carousel.size_hint_y = None
@@ -1159,13 +1300,15 @@ class Trash(Screen):
width = .8 if platform == 'android' else .55
delete_msg_dialog = MDDialog(
text='Are you sure you want to delete this'
- ' message permanently from trash?', title='',
- size_hint=(width, .25), text_button_ok='Yes',
+ ' message permanently from trash?',
+ title='',
+ size_hint=(width, .25),
+ text_button_ok='Yes',
text_button_cancel='No',
events_callback=self.callback_for_delete_msg)
delete_msg_dialog.open()
- def callback_for_delete_msg(self, text_item):
+ def callback_for_delete_msg(self, text_item, *arg):
"""Getting the callback of alert box"""
if text_item == 'Yes':
self.delete_message_from_trash()
@@ -1177,22 +1320,21 @@ class Trash(Screen):
self.children[1].active = True
if self.table_name == 'inbox':
sqlExecute(
- "DELETE FROM inbox WHERE msgid = ?;",
- str(self.delete_index))
+ "DELETE FROM inbox WHERE msgid = ?;", self.delete_index)
elif self.table_name == 'sent':
sqlExecute(
- "DELETE FROM sent WHERE ackdata = ?;",
- str(self.delete_index))
- msg_count_objs = state.kivyapp.root.children[2].children[0].ids
+ "DELETE FROM sent WHERE ackdata = ?;", self.delete_index)
if int(state.trash_count) > 0:
- msg_count_objs.trash_cnt.badge_text = str(
- int(state.trash_count) - 1)
+ # msg_count_objs.trash_cnt.badge_text = str(
+ # int(state.trash_count) - 1)
+ self.set_TrashCnt(int(state.trash_count) - 1)
state.trash_count = str(int(state.trash_count) - 1)
Clock.schedule_once(self.callback_for_screen_load, 1)
class Page(Screen):
"""Page Screen show widgets of page"""
+
pass
@@ -1212,15 +1354,19 @@ class Create(Screen):
class Setting(Screen):
"""Setting the Screen components"""
+
pass
-class NavigateApp(App): # pylint: disable=too-many-public-methods
+class NavigateApp(MDApp):
"""Navigation Layout of class"""
- theme_cls = ThemeManager()
+ # pylint: disable=too-many-public-methods,inconsistent-return-statements
+
+ # theme_cls = ThemeManager()
previous_date = ObjectProperty()
obj_1 = ObjectProperty()
- variable_1 = ListProperty(BMConfigParser().addresses())
+ variable_1 = ListProperty(addr for addr in BMConfigParser().addresses()
+ if BMConfigParser().get(str(addr), 'enabled') == 'true')
nav_drawer = ObjectProperty()
state.screen_density = Window.size
window_size = state.screen_density
@@ -1228,34 +1374,24 @@ class NavigateApp(App): # pylint: disable=too-many-public-methods
title = "PyBitmessage"
imgstatus = False
count = 0
- menu_items = [
- {'viewclass': 'MDMenuItem', 'text': 'Example item'},
- {'viewclass': 'MDMenuItem', 'text': 'Example item'},
- {'viewclass': 'MDMenuItem', 'text': 'Example item'},
- {'viewclass': 'MDMenuItem', 'text': 'Example item'},
- {'viewclass': 'MDMenuItem', 'text': 'Example item'},
- {'viewclass': 'MDMenuItem', 'text': 'Example item'},
- {'viewclass': 'MDMenuItem', 'text': 'Example item'},
- ]
def build(self):
"""Method builds the widget"""
- main_widget = Builder.load_file(
- os.path.join(os.path.dirname(__file__), 'main.kv'))
- self.nav_drawer = Navigatorss()
+ for kv_file in KVFILES:
+ Builder.load_file(os.path.join(os.path.dirname(__file__), "kv/{}.kv").format(kv_file))
self.obj_1 = AddressBook()
kivysignalthread = UIkivySignaler()
kivysignalthread.daemon = True
kivysignalthread.start()
- Window.bind(on_keyboard=self.on_key)
- return main_widget
+ Window.bind(on_keyboard=self.on_key, on_request_close=self.on_request_close)
+ return Builder.load_file(
+ os.path.join(os.path.dirname(__file__), 'main.kv'))
def run(self):
"""Running the widgets"""
kivyuisignaler.release()
super(NavigateApp, self).run()
- # pylint: disable=inconsistent-return-statements
@staticmethod
def showmeaddresses(name="text"):
"""Show the addresses in spinner to make as dropdown"""
@@ -1279,10 +1415,13 @@ class NavigateApp(App): # pylint: disable=too-many-public-methods
state.searcing_text = ''
LoadingPopup().open()
self.set_message_count()
+ for nav_obj in self.root.ids.content_drawer.children[
+ 0].children[0].children[0].children:
+ nav_obj.active = True if nav_obj.text == 'Inbox' else False
Clock.schedule_once(self.setCurrentAccountData, 0.5)
def setCurrentAccountData(self, dt=0):
- """This method set the current accout data on all the screens."""
+ """This method set the current accout data on all the screens"""
self.root.ids.sc1.ids.ml.clear_widgets()
self.root.ids.sc1.loadMessagelist(state.association)
@@ -1299,6 +1438,9 @@ class NavigateApp(App): # pylint: disable=too-many-public-methods
self.root.ids.sc17.clear_widgets()
self.root.ids.sc17.add_widget(Allmails())
+ self.root.ids.sc10.ids.ml.clear_widgets()
+ self.root.ids.sc10.init_ui()
+
self.root.ids.scr_mngr.current = 'inbox'
@staticmethod
@@ -1339,7 +1481,7 @@ class NavigateApp(App): # pylint: disable=too-many-public-methods
if not os.path.exists(directory):
os.makedirs(directory)
except OSError:
- print 'Error: Creating directory. ' + directory
+ print('Error: Creating directory. ' + directory)
@staticmethod
def get_default_image():
@@ -1349,6 +1491,14 @@ class NavigateApp(App): # pylint: disable=too-many-public-methods
BMConfigParser().addresses()[0])
return './images/no_identicons.png'
+ @staticmethod
+ def get_default_logo():
+ """Getting default logo image"""
+ if BMConfigParser().addresses():
+ return './images/default_identicon/{}.png'.format(
+ BMConfigParser().addresses()[0])
+ return './images/drawer_logo1.png'
+
@staticmethod
def addressexist():
"""Checking address existence"""
@@ -1357,6 +1507,7 @@ class NavigateApp(App): # pylint: disable=too-many-public-methods
return False
def on_key(self, window, key, *args):
+ # pylint: disable=inconsistent-return-statements
"""Method is used for going on previous screen"""
if key == 27:
if state.in_search_mode and self.root.ids.scr_mngr.current != (
@@ -1390,7 +1541,7 @@ class NavigateApp(App): # pylint: disable=too-many-public-methods
self.root.ids.sc11.children[1].active = True
Clock.schedule_once(self.search_callback, 0.5)
elif state.search_screen == 'myaddress':
- self.root.ids.sc10.children[1].active = True
+ self.loadMyAddressScreen(True)
Clock.schedule_once(self.search_callback, 0.5)
elif state.search_screen == 'sent':
self.root.ids.sc4.children[1].active = True
@@ -1409,13 +1560,20 @@ class NavigateApp(App): # pylint: disable=too-many-public-methods
elif state.search_screen == 'myaddress':
self.root.ids.sc10.ids.ml.clear_widgets()
self.root.ids.sc10.init_ui()
- self.root.ids.sc10.children[1].active = False
+ self.loadMyAddressScreen(False)
else:
self.root.ids.sc4.ids.ml.clear_widgets()
self.root.ids.sc4.loadSent(state.association)
self.root.ids.sc4.children[1].active = False
self.root.ids.scr_mngr.current = state.search_screen
+ def loadMyAddressScreen(self, action):
+ """loadMyAddressScreen method spin the loader"""
+ if len(self.root.ids.sc10.children) <= 2:
+ self.root.ids.sc10.children[0].active = action
+ else:
+ self.root.ids.sc10.children[1].active = action
+
def save_draft(self):
"""Saving drafts messages"""
composer_objs = self.root
@@ -1460,12 +1618,20 @@ class NavigateApp(App): # pylint: disable=too-many-public-methods
['send',
lambda x: self.root.ids.sc3.children[1].send(self)]]
+ def set_toolbar_for_QrCode(self):
+ """This method is use for setting Qr code toolbar."""
+ self.root.ids.toolbar.left_action_items = [
+ ['arrow-left', lambda x: self.back_press()]]
+ self.root.ids.toolbar.right_action_items = []
+
def set_common_header(self):
"""Common header for all window"""
self.root.ids.toolbar.right_action_items = [
['account-plus', lambda x: self.addingtoaddressbook()]]
+ # self.root.ids.toolbar.left_action_items = [
+ # ['menu', lambda x: self.root.toggle_nav_drawer()]]
self.root.ids.toolbar.left_action_items = [
- ['menu', lambda x: self.root.toggle_nav_drawer()]]
+ ['menu', lambda x: self.root.ids.nav_drawer.set_state("toggle")]]
return
def back_press(self):
@@ -1483,7 +1649,8 @@ class NavigateApp(App): # pylint: disable=too-many-public-methods
self.root.ids.scr_mngr.current = 'inbox' \
if state.in_composer else 'allmails'\
if state.is_allmail else state.detailPageType\
- if state.detailPageType else 'inbox'
+ if state.detailPageType else 'myaddress'\
+ if self.root.ids.scr_mngr.current == 'showqrcode' else 'inbox'
self.root.ids.scr_mngr.transition.direction = 'right'
self.root.ids.scr_mngr.transition.bind(on_complete=self.reset)
if state.is_allmail or state.detailPageType == 'draft':
@@ -1532,15 +1699,15 @@ class NavigateApp(App): # pylint: disable=too-many-public-methods
msg_counter_objs.allmail_cnt.badge_text = state.all_count
def on_start(self):
- """Method activates on start"""
+ """Setting message count"""
self.set_message_count()
- @staticmethod
- def on_stop():
- """On stop methos is used for stoping the runing script"""
- print "*******************EXITING FROM APPLICATION*******************"
- import shutdown
- shutdown.doCleanShutdown()
+ # @staticmethod
+ # def on_stop():
+ # """On stop methos is used for stoping the runing script"""
+ # print("*******************EXITING FROM APPLICATION*******************")
+ # import shutdown
+ # shutdown.doCleanShutdown()
@staticmethod
def current_address_label(current_add_label=None, current_addr=None):
@@ -1555,7 +1722,7 @@ class NavigateApp(App): # pylint: disable=too-many-public-methods
f_name = first_name.split()
label = f_name[0][:14].capitalize() + '...' if len(
f_name[0]) > 15 else f_name[0].capitalize()
- address = ' (' + addr + '...)'
+ address = ' (' + addr + ')'
return label + address
return ''
@@ -1583,8 +1750,9 @@ class NavigateApp(App): # pylint: disable=too-many-public-methods
self.refreshScreen()
state.in_search_mode = False
- def refreshScreen(self): # pylint: disable=unused-variable
+ def refreshScreen(self):
"""Method show search button only on inbox or sent screen"""
+ # pylint: disable=unused-variable
state.searcing_text = ''
if state.search_screen == 'inbox':
try:
@@ -1604,11 +1772,11 @@ class NavigateApp(App): # pylint: disable=too-many-public-methods
elif state.search_screen == 'myaddress':
try:
self.root.ids.sc10.children[
- 3].children[2].ids.search_field.text = ''
+ 1].children[2].ids.search_field.text = ''
except Exception:
self.root.ids.sc10.children[
2].children[2].ids.search_field.text = ''
- self.root.ids.sc10.children[1].active = True
+ self.loadMyAddressScreen(True)
Clock.schedule_once(self.search_callback, 0.5)
else:
self.root.ids.sc4.children[
@@ -1620,8 +1788,9 @@ class NavigateApp(App): # pylint: disable=too-many-public-methods
def set_identicon(self, text):
"""Show identicon in address spinner"""
img = identiconGeneration.generate(text)
- self.root.children[2].children[0].ids.btn.children[1].texture = (
- img.texture)
+ self.root.children[0].children[0].ids.btn.children[1].texture = (img.texture)
+ # below line is for displaing logo
+ self.root.ids.content_drawer.ids.top_box.children[0].texture = (img.texture)
def set_mail_detail_header(self):
"""Setting the details of the page"""
@@ -1663,23 +1832,31 @@ class NavigateApp(App): # pylint: disable=too-many-public-methods
self.root.ids.sc1.loadMessagelist(state.association)
self.root.ids.sc1.children[1].active = False
elif instance.text == 'All Mails':
- if len(self.root.ids.sc17.ids.ml.children) <= 2:
- self.root.ids.sc17.clear_widgets()
- self.root.ids.sc17.add_widget(Allmails())
- else:
- self.root.ids.sc17.ids.ml.clear_widgets()
- self.root.ids.sc17.loadMessagelist()
+ # if len(self.root.ids.sc17.ids.ml.children) <= 2:
+ # self.root.ids.sc17.clear_widgets()
+ # self.root.ids.sc17.add_widget(Allmails())
+ # else:
+ # self.root.ids.sc17.ids.ml.clear_widgets()
+ # self.root.ids.sc17.loadMessagelist()
+ self.root.ids.sc17.clear_widgets()
+ self.root.ids.sc17.add_widget(Allmails())
try:
self.root.ids.sc17.children[1].active = False
except Exception:
self.root.ids.sc17.children[0].children[1].active = False
+ def on_request_close(self, *args): # pylint: disable=no-self-use
+ """This method is for app closing request"""
+ AppClosingPopup().open()
+ return True
+
class GrashofPopup(Popup):
"""Moule for save contacts and error messages"""
+
valid = False
- def __init__(self, **kwargs): # pylint: disable=useless-super-delegation
+ def __init__(self, **kwargs):
"""Grash of pop screen settings"""
super(GrashofPopup, self).__init__(**kwargs)
@@ -1717,8 +1894,10 @@ class GrashofPopup(Popup):
def checkAddress_valid(self, instance):
"""Checking address is valid or not"""
+ # my_addresses = (
+ # self.parent.children[1].children[2].children[0].ids.btn.values)
my_addresses = (
- self.parent.children[1].children[2].children[0].ids.btn.values)
+ self.parent.children[1].children[0].children[0].ids.btn.values)
add_book = [addr[1] for addr in kivy_helper_search.search_sql(
folder="addressbook")]
entered_text = str(instance.text).strip()
@@ -1769,10 +1948,13 @@ class GrashofPopup(Popup):
elif status == 'missingbm':
text = "The address should start with ''BM-''"
elif status == 'checksumfailed':
- text = "The address is not typed or copied correctly(the checksum failed)."
+ text = (
+ "The address is not typed or copied correctly"
+ " (the checksum failed).")
elif status == 'versiontoohigh':
- text = "The version number of this address is higher"\
- " than this software can support. Please upgrade Bitmessage."
+ text = (
+ "The version number of this address is higher than this"
+ " software can support. Please upgrade Bitmessage.")
elif status == 'invalidcharacters':
text = "The address contains invalid characters."
elif status == 'ripetooshort':
@@ -1786,52 +1968,38 @@ class GrashofPopup(Popup):
class AvatarSampleWidget(ILeftBody, Image):
"""Avatar Sample Widget"""
+
pass
class IconLeftSampleWidget(ILeftBodyTouch, MDIconButton):
"""Left icon sample widget"""
+
pass
class IconRightSampleWidget(IRightBodyTouch, MDCheckbox):
"""Right icon sample widget"""
+
pass
-class NavigationDrawerTwoLineListItem(
- TwoLineListItem, NavigationDrawerHeaderBase):
- """Navigation Drawer in Listitems"""
- address_property = StringProperty()
-
- def __init__(self, **kwargs):
- """Method for Navigation Drawer"""
- super(NavigationDrawerTwoLineListItem, self).__init__(**kwargs)
- Clock.schedule_once(lambda dt: self.setup())
-
- def setup(self):
- """Bind Controller.current_account property"""
- pass
-
- def on_current_account(self, account):
- """Account detail"""
- pass
-
- def _update_specific_text_color(self, instance, value):
- pass
-
- def _set_active(self, active, list_):
- pass
+class ToggleBtn(IRightBodyTouch, MDSwitch):
+ """Right toggle button widget"""
+ pass
class MailDetail(Screen):
"""MailDetail Screen uses to show the detail of mails"""
+
to_addr = StringProperty()
from_addr = StringProperty()
subject = StringProperty()
message = StringProperty()
status = StringProperty()
page_type = StringProperty()
+ time_tag = StringProperty()
+ avatarImg = StringProperty()
def __init__(self, *args, **kwargs):
"""Mail Details method"""
@@ -1844,31 +2012,37 @@ class MailDetail(Screen):
if state.detailPageType == 'sent' or state.detailPageType == 'draft':
data = sqlQuery(
"select toaddress, fromaddress, subject, message, status,"
- " ackdata from sent where ackdata = ?;", state.mail_id)
+ " ackdata, senttime from sent where ackdata = ?;", state.mail_id)
state.status = self
state.ackdata = data[0][5]
self.assign_mail_details(data)
state.kivyapp.set_mail_detail_header()
elif state.detailPageType == 'inbox':
data = sqlQuery(
- "select toaddress, fromaddress, subject, message from inbox"
- " where msgid = ?;", str(state.mail_id))
+ "select toaddress, fromaddress, subject, message, received from inbox"
+ " where msgid = ?;", state.mail_id)
self.assign_mail_details(data)
state.kivyapp.set_mail_detail_header()
def assign_mail_details(self, data):
"""Assigning mail details"""
+ subject = data[0][2].decode() if isinstance(data[0][2],bytes) else data[0][2]
+ body = data[0][3].decode() if isinstance(data[0][2],bytes) else data[0][3]
self.to_addr = data[0][0]
self.from_addr = data[0][1]
- self.subject = data[0][2].upper(
- ) if data[0][2].upper() else '(no subject)'
- self.message = data[0][3]
- if len(data[0]) == 6:
+
+ self.subject = subject.upper(
+ ) if subject.upper() else '(no subject)'
+ self.message = body
+ if len(data[0]) == 7:
self.status = data[0][4]
+ self.time_tag = ShowTimeHistoy(data[0][4]) if state.detailPageType == 'inbox' else ShowTimeHistoy(data[0][6])
+ self.avatarImg = './images/text_images/{0}.png'.format(
+ 'avatar.png' if state.detailPageType == 'draft' else avatarImageFirstLetter(self.subject.strip()))
def delete_mail(self):
"""Method for mail delete"""
- msg_count_objs = state.kivyapp.root.children[2].children[0].ids
+ msg_count_objs = state.kivyapp.root.ids.content_drawer.ids
state.searcing_text = ''
self.children[0].children[0].active = True
if state.detailPageType == 'sent':
@@ -1876,9 +2050,9 @@ class MailDetail(Screen):
2].children[2].ids.search_field.text = ''
sqlExecute(
"UPDATE sent SET folder = 'trash' WHERE"
- " ackdata = ?;", str(state.mail_id))
- msg_count_objs.send_cnt.badge_text = str(int(state.sent_count) - 1) if int(state.sent_count) else '0'
- state.sent_count = str(int(state.sent_count) - 1) if int(state.sent_count) else '0'
+ " ackdata = ?;", state.mail_id)
+ msg_count_objs.send_cnt.children[0].children[0].text = str(int(state.sent_count) - 1)
+ state.sent_count = str(int(state.sent_count) - 1)
self.parent.screens[3].ids.ml.clear_widgets()
self.parent.screens[3].loadSent(state.association)
elif state.detailPageType == 'inbox':
@@ -1888,29 +2062,26 @@ class MailDetail(Screen):
2].ids.search_field.text = ''
sqlExecute(
"UPDATE inbox SET folder = 'trash' WHERE"
- " msgid = ?;", str(state.mail_id))
- msg_count_objs.inbox_cnt.badge_text = str(
- int(state.inbox_count) - 1) if int(state.inbox_count) else '0'
- state.inbox_count = str(int(state.inbox_count) - 1) if int(state.inbox_count) else '0'
+ " msgid = ?;", state.mail_id)
+ msg_count_objs.inbox_cnt.children[0].children[0].text = str(
+ int(state.inbox_count) - 1)
+ state.inbox_count = str(int(state.inbox_count) - 1)
self.parent.screens[0].ids.ml.clear_widgets()
self.parent.screens[0].loadMessagelist(state.association)
elif state.detailPageType == 'draft':
- sqlExecute(
- "DELETE FROM sent WHERE ackdata = ?;", str(state.mail_id))
- msg_count_objs.draft_cnt.badge_text = str(
+ sqlExecute("DELETE FROM sent WHERE ackdata = ?;", state.mail_id)
+ msg_count_objs.draft_cnt.children[0].children[0].text = str(
int(state.draft_count) - 1)
state.draft_count = str(int(state.draft_count) - 1)
self.parent.screens[15].clear_widgets()
self.parent.screens[15].add_widget(Draft())
- # self.parent.current = 'allmails' \
- # if state.is_allmail else state.detailPageType
if state.detailPageType != 'draft':
- msg_count_objs.trash_cnt.badge_text = str(
+ msg_count_objs.trash_cnt.children[0].children[0].text = str(
int(state.trash_count) + 1)
- msg_count_objs.allmail_cnt.badge_text = str(
- int(state.all_count) - 1) if int(state.all_count) else '0'
+ msg_count_objs.allmail_cnt.children[0].children[0].text = str(
+ int(state.all_count) - 1)
state.trash_count = str(int(state.trash_count) + 1)
state.all_count = str(int(state.all_count) - 1) if int(state.all_count) else '0'
self.parent.screens[4].clear_widgets()
@@ -1932,7 +2103,7 @@ class MailDetail(Screen):
"""Reply inbox messages"""
data = sqlQuery(
"select toaddress, fromaddress, subject, message from inbox where"
- " msgid = ?;", str(state.mail_id))
+ " msgid = ?;", state.mail_id)
composer_obj = self.parent.screens[2].children[1].ids
composer_obj.ti.text = data[0][0]
composer_obj.btn.text = data[0][0]
@@ -1948,9 +2119,9 @@ class MailDetail(Screen):
state.send_draft_mail = state.mail_id
data = sqlQuery(
"select toaddress, fromaddress, subject, message from sent where"
- " ackdata = ?;", str(state.mail_id))
+ " ackdata = ?;", state.mail_id)
composer_ids = (
- self.parent.parent.parent.parent.parent.ids.sc3.children[1].ids)
+ self.parent.parent.ids.sc3.children[1].ids)
composer_ids.ti.text = data[0][1]
composer_ids.btn.text = data[0][1]
composer_ids.txt_input.text = data[0][0]
@@ -1972,10 +2143,11 @@ class MailDetail(Screen):
class MyaddDetailPopup(Popup):
"""MyaddDetailPopup pop is used for showing my address detail"""
+
address_label = StringProperty()
address = StringProperty()
- def __init__(self, **kwargs): # pylint: disable=useless-super-delegation
+ def __init__(self, **kwargs):
"""My Address Details screen setting"""
super(MyaddDetailPopup, self).__init__(**kwargs)
@@ -2004,12 +2176,12 @@ class MyaddDetailPopup(Popup):
class AddbookDetailPopup(Popup):
"""AddbookDetailPopup pop is used for showing my address detail"""
+
address_label = StringProperty()
address = StringProperty()
def __init__(self, **kwargs):
"""Set screen of address detail page"""
- # pylint: disable=useless-super-delegation
super(AddbookDetailPopup, self).__init__(**kwargs)
def set_addbook_data(self, address, label):
@@ -2073,17 +2245,21 @@ class ShowQRCode(Screen):
"""ShowQRCode Screen uses to show the detail of mails"""
def qrdisplay(self):
- """Showing QR Code"""
- # self.manager.parent.parent.parent.ids.search_bar.clear_widgets()
+ """Method used for showing QR Code"""
self.ids.qr.clear_widgets()
+ state.kivyapp.set_toolbar_for_QrCode()
from kivy.garden.qrcode import QRCodeWidget
- self.ids.qr.add_widget(QRCodeWidget(
- data=self.manager.get_parent_window().children[0].address))
+ try:
+ address = self.manager.get_parent_window().children[0].address
+ except Exception:
+ address = self.manager.get_parent_window().children[1].address
+ self.ids.qr.add_widget(QRCodeWidget(data=address))
toast('Show QR code')
class Draft(Screen):
"""Draft screen is used to show the list of draft messages"""
+
data = ListProperty()
account = StringProperty()
queryreturn = ListProperty()
@@ -2100,41 +2276,47 @@ class Draft(Screen):
def init_ui(self, dt=0):
"""Clock Schdule for method draft accounts"""
self.sentaccounts()
- print dt
+ print(dt)
def sentaccounts(self):
- """Load draft accounts."""
+ """Load draft accounts"""
self.account = state.association
self.loadDraft()
def loadDraft(self, where="", what=""):
- """Load draft list for Draft messages."""
+ """Load draft list for Draft messages"""
xAddress = 'fromaddress'
self.ids.identi_tag.children[0].text = ''
self.draftDataQuery(xAddress, where, what)
- if state.msg_counter_objs:
- state.msg_counter_objs.draft_cnt.badge_text = str(
- len(self.queryreturn))
+ # if state.msg_counter_objs:
+ # state.msg_counter_objs.draft_cnt.children[0].children[0].text = showLimitedCnt(len(self.queryreturn))
if self.queryreturn:
self.ids.identi_tag.children[0].text = 'Draft'
- src_mng_obj = state.kivyapp.root.children[2].children[0].ids
- src_mng_obj.draft_cnt.badge_text = state.draft_count
+ self.set_draftCnt(state.draft_count)
self.set_mdList()
self.ids.scroll_y.bind(scroll_y=self.check_scroll_y)
else:
+ self.set_draftCnt('0')
content = MDLabel(
- font_style='Body1', theme_text_color='Primary',
+ font_style='Caption',
+ theme_text_color='Primary',
text="yet no message for this account!!!!!!!!!!!!!",
- halign='center', bold=True, size_hint_y=None, valign='top')
+ halign='center',
+ size_hint_y=None,
+ valign='top')
self.ids.ml.add_widget(content)
- # pylint: disable=too-many-arguments
def draftDataQuery(self, xAddress, where, what, start_indx=0, end_indx=20):
"""This methosd is for retrieving draft messages"""
self.queryreturn = kivy_helper_search.search_sql(
xAddress, self.account, "draft", where, what,
False, start_indx, end_indx)
+ def set_draftCnt(self, Count): # pylint: disable=no-self-use
+ """This method set the count of draft mails"""
+ draftCnt_obj = state.kivyapp.root.ids.content_drawer.ids.draft_cnt
+ draftCnt_obj.children[0].children[0].text = showLimitedCnt(int(Count))
+
def set_mdList(self):
"""This method is used to create mdlist"""
data = []
@@ -2147,7 +2329,7 @@ class Draft(Screen):
mail[2]) > 10 else mail[2] + '\n' + " " + (
third_text[:25] + '...!') if len(
third_text) > 25 else third_text,
- 'ackdata': mail[5]})
+ 'ackdata': mail[5], 'senttime': mail[6]})
for item in data:
meny = TwoLineAvatarIconListItem(
text='Draft', secondary_text=item['text'],
@@ -2157,6 +2339,7 @@ class Draft(Screen):
source='./images/avatar.png'))
meny.bind(on_press=partial(
self.draft_detail, item['ackdata']))
+ meny.add_widget(AddTimeWidget(item['senttime']))
carousel = Carousel(direction='right')
carousel.height = meny.height
carousel.size_hint_y = None
@@ -2202,26 +2385,29 @@ class Draft(Screen):
def delete_draft(self, data_index, instance, *args):
"""Delete draft message permanently"""
- sqlExecute("DELETE FROM sent WHERE ackdata = ?;", str(
- data_index))
- try:
- msg_count_objs = (
- self.parent.parent.parent.parent.parent.parent.children[
- 2].children[0].ids)
- except Exception:
- msg_count_objs = self.parent.parent.parent.parent.parent.children[
- 2].children[0].ids
+ sqlExecute("DELETE FROM sent WHERE ackdata = ?;", data_index)
+ # try:
+ # msg_count_objs = (
+ # self.parent.parent.parent.parent.parent.children[
+ # 2].children[0].ids)
+ # except Exception:
+ # msg_count_objs = (
+ # self.parent.parent.parent.parent.parent.parent.children[
+ # 2].children[0].ids)
+ # msg_count_objs = self.parent.parent.parent.parent.parent.children[
+ # 2].children[0].ids
if int(state.draft_count) > 0:
- msg_count_objs.draft_cnt.badge_text = str(
- int(state.draft_count) - 1)
+ # msg_count_objs.draft_cnt.badge_text = str(
+ # int(state.draft_count) - 1)
state.draft_count = str(int(state.draft_count) - 1)
+ self.set_draftCnt(state.draft_count)
if int(state.draft_count) <= 0:
self.ids.identi_tag.children[0].text = ''
self.ids.ml.remove_widget(instance.parent.parent)
toast('Deleted')
@staticmethod
- def draft_msg(src_object): # pylint: disable=too-many-locals
+ def draft_msg(src_object):
"""Save draft mails"""
composer_object = state.kivyapp.root.ids.sc3.children[1].ids
fromAddress = str(composer_object.ti.text)
@@ -2232,6 +2418,7 @@ class Draft(Screen):
sendMessageToPeople = True
if sendMessageToPeople:
streamNumber, ripe = decodeAddress(toAddress)[2:]
+ from addresses import addBMIfNotPresent
toAddress = addBMIfNotPresent(toAddress)
stealthLevel = BMConfigParser().safeGetInt(
'bitmessagesettings', 'ackstealthlevel')
@@ -2239,12 +2426,24 @@ class Draft(Screen):
ackdata = genAckPayload(streamNumber, stealthLevel)
sqlExecute(
'''INSERT INTO sent VALUES
- (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)''', '', toAddress, ripe,
- fromAddress, subject, message, ackdata, int(time.time()),
- int(time.time()), 0, 'msgqueued', 0, 'draft', encoding,
- BMConfigParser().getint('bitmessagesettings', 'ttl'))
+ (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)''',
+ '',
+ toAddress,
+ ripe,
+ fromAddress,
+ subject,
+ message,
+ ackdata,
+ int(time.time()),
+ int(time.time()),
+ 0,
+ 'msgqueued',
+ 0,
+ 'draft',
+ encoding,
+ BMConfigParser().safeGetInt('bitmessagesettings', 'ttl'))
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) if state.association == fromAddress else state.draft_count
src_object.ids.sc16.clear_widgets()
src_object.ids.sc16.add_widget(Draft())
toast('Save draft')
@@ -2255,20 +2454,21 @@ class CustomSpinner(Spinner):
"""This class is used for setting spinner size"""
def __init__(self, *args, **kwargs):
- """Setting size of spinner"""
+ """Method used for setting size of spinner"""
super(CustomSpinner, self).__init__(*args, **kwargs)
self.dropdown_cls.max_height = Window.size[1] / 3
class Allmails(Screen):
"""All mails Screen uses screen to show widgets of screens"""
+
data = ListProperty()
has_refreshed = True
all_mails = ListProperty()
account = StringProperty()
def __init__(self, *args, **kwargs):
- """Method Parsing the address."""
+ """Method Parsing the address"""
super(Allmails, self).__init__(*args, **kwargs)
if state.association == '':
if BMConfigParser().addresses():
@@ -2278,10 +2478,10 @@ class Allmails(Screen):
def init_ui(self, dt=0):
"""Clock Schdule for method all mails"""
self.loadMessagelist()
- print dt
+ print(dt)
def loadMessagelist(self):
- """Load Inbox, Sent anf Draft list of messages."""
+ """Load Inbox, Sent anf Draft list of messages"""
self.account = state.association
self.ids.identi_tag.children[0].text = ''
self.allMessageQuery(0, 20)
@@ -2291,47 +2491,58 @@ class Allmails(Screen):
state.kivyapp.get_sent_count()
state.all_count = str(
int(state.sent_count) + int(state.inbox_count))
- state.kivyapp.root.children[2].children[
- 0].ids.allmail_cnt.badge_text = state.all_count
+ self.set_AllmailCnt(state.all_count)
self.set_mdlist()
# self.ids.refresh_layout.bind(scroll_y=self.check_scroll_y)
self.ids.scroll_y.bind(scroll_y=self.check_scroll_y)
else:
+ self.set_AllmailCnt('0')
content = MDLabel(
- font_style='Body1', theme_text_color='Primary',
+ font_style='Caption',
+ theme_text_color='Primary',
text="yet no message for this account!!!!!!!!!!!!!",
- halign='center', bold=True, size_hint_y=None, valign='top')
+ halign='center',
+ size_hint_y=None,
+ valign='top')
self.ids.ml.add_widget(content)
def allMessageQuery(self, start_indx, end_indx):
"""Retrieving data from inbox or sent both tables"""
self.all_mails = sqlQuery(
"SELECT toaddress, fromaddress, subject, message, folder, ackdata"
- " As id, DATE(lastactiontime) As actionTime FROM sent WHERE"
+ " As id, DATE(senttime) As actionTime, senttime as msgtime FROM sent WHERE"
" folder = 'sent' and fromaddress = '{0}'"
" UNION SELECT toaddress, fromaddress, subject, message, folder,"
- " msgid As id, DATE(received) As actionTime FROM inbox"
+ " msgid As id, DATE(received) As actionTime, received as msgtime FROM inbox"
" WHERE folder = 'inbox' and toaddress = '{0}'"
" ORDER BY actionTime DESC limit {1}, {2}".format(
self.account, start_indx, end_indx))
+ def set_AllmailCnt(self, Count): # pylint: disable=no-self-use
+ """This method is used to set allmails message count"""
+ allmailCnt_obj = state.kivyapp.root.ids.content_drawer.ids.allmail_cnt
+ allmailCnt_obj.children[0].children[0].text = showLimitedCnt(int(Count))
+
def set_mdlist(self):
"""This method is used to create mdList for allmaills"""
data_exist = len(self.ids.ml.children)
for item in self.all_mails:
+ body = item[3].decode() if isinstance(item[3],bytes) else item[3]
+ subject = item[2].decode() if isinstance(item[2],bytes) else item[2]
meny = TwoLineAvatarIconListItem(
text=item[1],
- secondary_text=item[2][:50] + '........' if len(
- item[2]) >= 50 else (
- item[2] + ',' + item[3].replace(
+ secondary_text=body[:50] + '........' if len(
+ body) >= 50 else (
+ body + ',' + subject.replace(
'\n', ''))[0:50] + '........',
theme_text_color='Custom',
text_color=NavigateApp().theme_cls.primary_color)
meny.add_widget(AvatarSampleWidget(
source='./images/text_images/{}.png'.format(
- avatarImageFirstLetter(item[2].strip()))))
+ avatarImageFirstLetter(body.strip()))))
meny.bind(on_press=partial(
self.mail_detail, item[5], item[4]))
+ meny.add_widget(AddTimeWidget(item[7]))
carousel = Carousel(direction='right')
carousel.height = meny.height
carousel.size_hint_y = None
@@ -2383,33 +2594,30 @@ class Allmails(Screen):
if folder == 'inbox':
sqlExecute(
"UPDATE inbox SET folder = 'trash' WHERE msgid = ?;",
- str(unique_id))
+ unique_id)
else:
sqlExecute(
"UPDATE sent SET folder = 'trash' WHERE ackdata = ?;",
- str(unique_id))
+ unique_id)
self.ids.ml.remove_widget(instance.parent.parent)
try:
- msg_count_objs = self.parent.parent.parent.parent.parent.children[
- 2].children[0].ids
- nav_lay_obj = self.parent.parent.parent.parent.parent.ids
+ msg_count_objs = self.parent.parent.ids.content_drawer.ids
+ nav_lay_obj = self.parent.parent.ids
except Exception:
- msg_count_objs = self.parent.parent.parent.parent.parent.parent.children[
- 2].children[0].ids
- nav_lay_obj = self.parent.parent.parent.parent.parent.parent.ids
+ msg_count_objs = self.parent.parent.parent.ids.content_drawer.ids
+ nav_lay_obj = self.parent.parent.parent.ids
if folder == 'inbox':
- msg_count_objs.inbox_cnt.badge_text = str(
- int(state.inbox_count) - 1)
+ msg_count_objs.inbox_cnt.children[0].children[0].text = showLimitedCnt(int(state.inbox_count) - 1)
state.inbox_count = str(int(state.inbox_count) - 1)
nav_lay_obj.sc1.ids.ml.clear_widgets()
nav_lay_obj.sc1.loadMessagelist(state.association)
else:
- msg_count_objs.send_cnt.badge_text = str(int(state.sent_count) - 1)
+ msg_count_objs.send_cnt.children[0].children[0].text = showLimitedCnt(int(state.sent_count) - 1)
state.sent_count = str(int(state.sent_count) - 1)
nav_lay_obj.sc4.ids.ml.clear_widgets()
nav_lay_obj.sc4.loadSent(state.association)
- msg_count_objs.trash_cnt.badge_text = str(int(state.trash_count) + 1)
- msg_count_objs.allmail_cnt.badge_text = str(int(state.all_count) - 1)
+ msg_count_objs.trash_cnt.children[0].children[0].text = showLimitedCnt(int(state.trash_count) + 1)
+ msg_count_objs.allmail_cnt.children[0].children[0].text = showLimitedCnt(int(state.all_count) - 1)
state.trash_count = str(int(state.trash_count) + 1)
state.all_count = str(int(state.all_count) - 1)
if int(state.all_count) <= 0:
@@ -2418,7 +2626,6 @@ class Allmails(Screen):
nav_lay_obj.sc5.add_widget(Trash())
nav_lay_obj.sc17.remove_widget(instance.parent.parent)
- # pylint: disable=attribute-defined-outside-init
def refresh_callback(self, *args):
"""Method updates the state of application,
While the spinner remains on the screen"""
@@ -2435,13 +2642,6 @@ class Allmails(Screen):
self.tick = 0
Clock.schedule_once(refresh_callback, 1)
- def set_root_layout(self):
- """Setting root layout"""
- try:
- return self.manager.parent.parent
- except Exception:
- return state.kivyapp.root.ids.float_box
-
def avatarImageFirstLetter(letter_string):
"""This function is used to the first letter for the avatar image"""
@@ -2483,3 +2683,72 @@ class LoadingPopup(Popup):
def dismiss_popup(self, dt):
"""Dismiss popups"""
self.dismiss()
+
+
+class AddressDropdown(OneLineIconListItem):
+ """AddressDropdown showns all the addresses"""
+
+ pass
+
+
+class BadgeText(IRightBodyTouch, MDLabel):
+ """Class for badgetext"""
+ pass
+
+
+class NavigationItem(OneLineAvatarIconListItem):
+ """NavigationItem class is for button behaviour"""
+ badge_text = StringProperty()
+ icon = StringProperty()
+ active = BooleanProperty(False)
+
+ def currentlyActive(self):
+ for nav_obj in self.parent.children:
+ nav_obj.active = False
+ self.active = True
+
+
+class NavigationDrawerDivider(OneLineListItem):
+ """
+ A small full-width divider that can be placed
+ in the :class:`MDNavigationDrawer`
+ """
+
+ disabled = True
+ divider = None
+ _txt_top_pad = NumericProperty(dp(8))
+ _txt_bot_pad = NumericProperty(dp(8))
+
+ def __init__(self, **kwargs):
+ # pylint: disable=bad-super-call
+ super(OneLineListItem, self).__init__(**kwargs)
+ self.height = dp(16)
+
+
+class NavigationDrawerSubheader(OneLineListItem):
+ """
+ A subheader for separating content in :class:`MDNavigationDrawer`
+
+ Works well alongside :class:`NavigationDrawerDivider`
+ """
+
+ disabled = True
+ divider = None
+ theme_text_color = 'Secondary'
+
+
+class AppClosingPopup(Popup):
+ """Class for app closing popup"""
+
+ def __init__(self, **kwargs):
+ super(AppClosingPopup, self).__init__(**kwargs)
+
+ def closingAction(self, text):
+ """Action on closing window"""
+ if text == 'Yes':
+ print("*******************EXITING FROM APPLICATION*******************")
+ import shutdown
+ shutdown.doCleanShutdown()
+ else:
+ self.dismiss()
+ toast(text)
diff --git a/src/bitmessagekivy/uikivysignaler.py b/src/bitmessagekivy/uikivysignaler.py
index fe9c9884..aac45fd5 100644
--- a/src/bitmessagekivy/uikivysignaler.py
+++ b/src/bitmessagekivy/uikivysignaler.py
@@ -25,4 +25,4 @@ class UIkivySignaler(Thread):
elif command == 'updateSentItemStatusByAckdata':
state.kivyapp.status_dispatching(data)
except Exception as e:
- print e
+ print(e)
diff --git a/src/bitmessagemain.py b/src/bitmessagemain.py
index d1e023c6..1809ffd8 100755
--- a/src/bitmessagemain.py
+++ b/src/bitmessagemain.py
@@ -27,8 +27,10 @@ import depends
import shared
import shutdown
import state
+
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 (
isOurOperatingSystemLimitedToHavingVeryFewHalfOpenConnections,
start_proxyconfig
@@ -158,13 +160,13 @@ def signal_handler(signum, frame):
if shared.thisapp.daemon or not state.enableGUI:
shutdown.doCleanShutdown()
else:
- print '# Thread: %s(%d)' % (thread.name, thread.ident)
+ print('# Thread: {}({})'.format(thread.name, thread.ident))
for filename, lineno, name, line in traceback.extract_stack(frame):
- print 'File: "%s", line %d, in %s' % (filename, lineno, name)
+ print("File: '{}', line {}, in {}" .format(filename, lineno, name))
if line:
- print ' %s' % line.strip()
- print 'Unfortunately you cannot use Ctrl+C when running the UI \
- because the UI captures the signal.'
+ print(' {}'.format(line.strip()))
+ print('Unfortunately you cannot use Ctrl+C when running the UI \
+ because the UI captures the signal.')
class Main(object):
@@ -199,7 +201,8 @@ class Main(object):
if os.path.isfile(os.path.join(
state.appdata, 'unittest.lock')):
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
state.last_api_response = time.time()
# Apply special settings
@@ -215,7 +218,8 @@ class Main(object):
)
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.
if state.enableGUI and not state.curses and not state.kivy and not depends.check_pyqt():
@@ -239,18 +243,17 @@ class Main(object):
if daemon:
with shared.printLock:
- print 'Running as a daemon. Send TERM signal to end.'
+ print('Running as a daemon. Send TERM signal to end.')
self.daemonize()
self.setSignalHandler()
set_thread_name("PyBitmessage")
- state.dandelion = config.safeGetInt('network', 'dandelion')
+ state.dandelion = config.safeGet('network', 'dandelion')
# dandelion requires outbound connections, without them,
# stem objects will get stuck forever
- if state.dandelion and not config.safeGetBoolean(
- 'bitmessagesettings', 'sendoutgoingconnections'):
+ if state.dandelion and not (config.safeGet('bitmessagesettings', 'sendoutgoingconnections') == 'True'):
state.dandelion = 0
if state.testmode or config.safeGetBoolean(
@@ -262,7 +265,6 @@ class Main(object):
readKnownNodes()
-
# Not needed if objproc is disabled
if state.enableObjProc:
@@ -321,7 +323,8 @@ class Main(object):
shared.reloadBroadcastSendersForWhichImWatching()
# API is also objproc dependent
if config.safeGetBoolean('bitmessagesettings', 'apienabled'):
- import api # pylint: disable=relative-import
+ # pylint: disable=relative-import
+ import api
singleAPIThread = api.singleAPI()
# close the main program even if there are threads left
singleAPIThread.daemon = True
@@ -333,7 +336,7 @@ class Main(object):
asyncoreThread = BMNetworkThread()
asyncoreThread.daemon = True
asyncoreThread.start()
- for i in range(config.getint('threads', 'receive')):
+ for i in range(config.safeGet('threads', 'receive')):
receiveQueueThread = ReceiveQueueThread(i)
receiveQueueThread.daemon = True
receiveQueueThread.start()
@@ -365,12 +368,13 @@ class Main(object):
if state.curses:
if not depends.check_curses():
sys.exit()
- print 'Running with curses'
+ print('Running with curses')
import bitmessagecurses
bitmessagecurses.runwrapper()
elif state.kivy:
config.remove_option('bitmessagesettings', 'dontconnect')
+ # pylint: disable=no-member,import-error,no-name-in-module,relative-import
from bitmessagekivy.mpybit import NavigateApp
state.kivyapp = NavigateApp()
state.kivyapp.run()
@@ -420,7 +424,8 @@ class Main(object):
pass
else:
parentPid = os.getpid()
- shared.thisapp.lock() # relock
+ # relock
+ shared.thisapp.lock()
os.umask(0)
try:
@@ -435,13 +440,16 @@ class Main(object):
# wait until child ready
while True:
time.sleep(1)
- os._exit(0) # pylint: disable=protected-access
+ # pylint: disable=protected-access
+ os._exit(0)
except AttributeError:
# fork not implemented
pass
else:
- shared.thisapp.lock() # relock
- shared.thisapp.lockPid = None # indicate we're the final child
+ # relock
+ shared.thisapp.lock()
+ # indicate we're the final child
+ shared.thisapp.lockPid = None
sys.stdout.flush()
sys.stderr.flush()
if not sys.platform.startswith('win'):
@@ -481,7 +489,7 @@ All parameters are optional.
def stop():
"""Stop main application"""
with shared.printLock:
- print 'Stopping Bitmessage Deamon.'
+ print('Stopping Bitmessage Deamon.')
shutdown.doCleanShutdown()
# .. todo:: nice function but no one is using this
diff --git a/src/bitmessageqt/networkstatus.py b/src/bitmessageqt/networkstatus.py
index 6fbf5df6..5f014563 100644
--- a/src/bitmessageqt/networkstatus.py
+++ b/src/bitmessageqt/networkstatus.py
@@ -14,7 +14,7 @@ import network.stats
import shared
import widgets
from inventory import Inventory
-from network import BMConnectionPool
+from network.connectionpool import BMConnectionPool
from retranslateui import RetranslateMixin
from tr import _translate
from uisignaler import UISignaler
diff --git a/src/bitmessageqt/statusbar.py b/src/bitmessageqt/statusbar.py
index 65a5acfb..68ddba3f 100644
--- a/src/bitmessageqt/statusbar.py
+++ b/src/bitmessageqt/statusbar.py
@@ -1,5 +1,4 @@
from PyQt4 import QtCore, QtGui
-from Queue import Queue
from time import time
class BMStatusBar(QtGui.QStatusBar):
diff --git a/src/bmconfigparser.py b/src/bmconfigparser.py
index 328cf0c7..d2d9010d 100644
--- a/src/bmconfigparser.py
+++ b/src/bmconfigparser.py
@@ -1,8 +1,9 @@
"""
BMConfigParser class definition and default configuration settings
"""
-
-import ConfigParser
+# pylint: disable=no-self-use, arguments-differ
+import configparser
+import shutil
import os
import shutil
from datetime import datetime
@@ -42,39 +43,36 @@ BMConfigDefaults = {
@Singleton
-class BMConfigParser(ConfigParser.SafeConfigParser):
- """
- Singleton class inherited from :class:`ConfigParser.SafeConfigParser`
- with additional methods specific to bitmessage config.
- """
+class BMConfigParser(configparser.ConfigParser):
+ """Singleton class inherited from ConfigParsedadfeConfigParser
+ with additional methods specific to bitmessage config."""
# pylint: disable=too-many-ancestors
-
_temp = {}
def set(self, section, option, value=None):
if self._optcre is self.OPTCRE or value:
- if not isinstance(value, basestring):
+ if not isinstance(value, str):
raise TypeError("option values must be strings")
if not self.validate(section, option, 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
+ # pylint: disable=unused-argument
try:
if section == "bitmessagesettings" and option == "timeformat":
- return ConfigParser.ConfigParser.get(
- self, section, option, raw, variables)
+ return configparser.ConfigParser.get(
+ self, section, option, raw=True, vars=variables)
try:
return self._temp[section][option]
except KeyError:
pass
- return ConfigParser.ConfigParser.get(
- self, section, option, True, variables)
- except ConfigParser.InterpolationError:
- return ConfigParser.ConfigParser.get(
- self, section, option, True, variables)
- except (ConfigParser.NoSectionError, ConfigParser.NoOptionError) as e:
+ return configparser.ConfigParser.get(
+ self, section, option, raw=True, vars=variables)
+ except configparser.InterpolationError:
+ return configparser.ConfigParser.get(
+ self, section, option, raw=True, vars=variables)
+ except (configparser.NoSectionError, configparser.NoOptionError) as e:
try:
return BMConfigDefaults[section][option]
except (KeyError, ValueError, AttributeError):
@@ -89,9 +87,13 @@ class BMConfigParser(ConfigParser.SafeConfigParser):
def safeGetBoolean(self, section, field):
"""Return value as boolean, False on exceptions"""
+ config = configparser.ConfigParser()
try:
- return self.getboolean(section, field)
- except (ConfigParser.NoSectionError, ConfigParser.NoOptionError,
+ # Used in the python2.7
+ # return self.getboolean(section, field)
+ # Used in the python3.5.2
+ return config.getboolean(section, field)
+ except (configparser.NoSectionError, configparser.NoOptionError,
ValueError, AttributeError):
return False
@@ -99,8 +101,11 @@ class BMConfigParser(ConfigParser.SafeConfigParser):
"""Return value as integer, default on exceptions,
0 if default missing"""
try:
- return self.getint(section, field)
- except (ConfigParser.NoSectionError, ConfigParser.NoOptionError,
+ # Used in the python2.7
+ # return self.getint(section, field)
+ # Used in the python3.7.0
+ return int(self.get(section, field))
+ except (configparser.NoSectionError, configparser.NoOptionError,
ValueError, AttributeError):
return default
@@ -108,38 +113,38 @@ class BMConfigParser(ConfigParser.SafeConfigParser):
"""Return value as is, default on exceptions, None if default missing"""
try:
return self.get(section, option)
- except (ConfigParser.NoSectionError, ConfigParser.NoOptionError,
+ except (configparser.NoSectionError, configparser.NoOptionError,
ValueError, AttributeError):
return default
def items(self, section, raw=False, variables=None):
+ # pylint: disable=signature-differs
"""Return section variables as parent,
but override the "raw" argument to always True"""
- # pylint: disable=arguments-differ
- return ConfigParser.ConfigParser.items(self, section, True, variables)
+ return configparser.ConfigParser.items(self, section, True, variables)
- @staticmethod
- def addresses():
+ 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):
- ConfigParser.ConfigParser.read(self, filenames)
+ configparser.ConfigParser.read(self, filenames)
for section in self.sections():
for option in self.options(section):
try:
if not self.validate(
section, option,
- ConfigParser.ConfigParser.get(self, section, option)
+ self[section][option]
):
try:
newVal = BMConfigDefaults[section][option]
+ except configparser.NoSectionError:
+ continue
except KeyError:
continue
- ConfigParser.ConfigParser.set(
+ configparser.ConfigParser.set(
self, section, option, newVal)
- except ConfigParser.InterpolationError:
+ except configparser.InterpolationError:
continue
def save(self):
@@ -158,7 +163,7 @@ class BMConfigParser(ConfigParser.SafeConfigParser):
# didn't exist before.
fileNameExisted = False
# write the file
- with open(fileName, 'wb') as configfile:
+ with open(fileName, 'w') as configfile:
self.write(configfile)
# delete the backup
if fileNameExisted:
@@ -167,7 +172,8 @@ class BMConfigParser(ConfigParser.SafeConfigParser):
def validate(self, section, option, value):
"""Input validator interface (using factory pattern)"""
try:
- return getattr(self, 'validate_%s_%s' % (section, option))(value)
+ return getattr(self, 'validate_{}_{}'.format(
+ section, option))(value)
except AttributeError:
return True
diff --git a/src/class_addressGenerator.py b/src/class_addressGenerator.py
index 520733fb..5a1c0ac4 100644
--- a/src/class_addressGenerator.py
+++ b/src/class_addressGenerator.py
@@ -14,14 +14,13 @@ import tr
from addresses import decodeAddress, encodeAddress, encodeVarint
from bmconfigparser import BMConfigParser
from fallback import RIPEMD160Hash
-from network import StoppableThread
from pyelliptic import arithmetic
from pyelliptic.openssl import OpenSSL
+from network.threads import StoppableThread
class addressGenerator(StoppableThread):
"""A thread for creating addresses"""
-
name = "addressGenerator"
def stopThread(self):
@@ -142,7 +141,7 @@ class addressGenerator(StoppableThread):
ripe = RIPEMD160Hash(sha.digest()).digest()
if (
ripe[:numberOfNullBytesDemandedOnFrontOfRipeHash] ==
- '\x00' * numberOfNullBytesDemandedOnFrontOfRipeHash
+ '\x00'.encode('utf-8') * numberOfNullBytesDemandedOnFrontOfRipeHash
):
break
self.logger.info(
@@ -159,19 +158,20 @@ class addressGenerator(StoppableThread):
# The user must have a pretty fast computer.
# time.time() - startTime equaled zero.
pass
+
address = encodeAddress(
addressVersionNumber, streamNumber, ripe)
# An excellent way for us to store our keys
# is in Wallet Import Format. Let us convert now.
# https://en.bitcoin.it/wiki/Wallet_import_format
- privSigningKey = '\x80' + potentialPrivSigningKey
+ privSigningKey = '\x80'.encode('utf-8')[1:] + potentialPrivSigningKey
checksum = hashlib.sha256(hashlib.sha256(
privSigningKey).digest()).digest()[0:4]
privSigningKeyWIF = arithmetic.changebase(
privSigningKey + checksum, 256, 58)
- privEncryptionKey = '\x80' + potentialPrivEncryptionKey
+ privEncryptionKey = '\x80'.encode('utf-8')[1:] + potentialPrivEncryptionKey
checksum = hashlib.sha256(hashlib.sha256(
privEncryptionKey).digest()).digest()[0:4]
privEncryptionKeyWIF = arithmetic.changebase(
@@ -193,7 +193,6 @@ class addressGenerator(StoppableThread):
# The API and the join and create Chan functionality
# both need information back from the address generator.
queues.apiAddressGeneratorReturnQueue.put(address)
-
queues.UISignalQueue.put((
'updateStatusBar', ""
))
@@ -207,9 +206,14 @@ class addressGenerator(StoppableThread):
queues.workerQueue.put((
'sendOutOrStoreMyV4Pubkey', address))
- elif command == 'createDeterministicAddresses' \
- or command == 'getDeterministicAddress' \
- or command == 'createChan' or command == 'joinChan':
+ # elif command == 'createDeterministicAddresses' \
+ # or command == 'getDeterministicAddress' \
+ # or command == 'createChan' or command == 'joinChan':
+ elif command in (
+ 'createDeterministicAddresses',
+ 'getDeterministicAddress',
+ 'createChan',
+ 'joinChan'):
if not deterministicPassphrase:
self.logger.warning(
'You are creating deterministic'
@@ -334,8 +338,8 @@ class addressGenerator(StoppableThread):
BMConfigParser().set(address, 'label', label)
BMConfigParser().set(address, 'enabled', 'true')
BMConfigParser().set(address, 'decoy', 'false')
- if command == 'joinChan' \
- or command == 'createChan':
+ # if command == 'joinChan' or command == 'createChan':
+ if command in ('joinChan', 'createChan'):
BMConfigParser().set(address, 'chan', 'true')
BMConfigParser().set(
address, 'noncetrialsperbyte',
@@ -386,8 +390,12 @@ class addressGenerator(StoppableThread):
address)
# Done generating addresses.
- if command == 'createDeterministicAddresses' \
- or command == 'joinChan' or command == 'createChan':
+ # if command == 'createDeterministicAddresses' \
+ # or command == 'joinChan' or command == 'createChan':
+ if command in (
+ 'createDeterministicAddresses',
+ 'joinChan',
+ 'createChan'):
queues.apiAddressGeneratorReturnQueue.put(
listOfNewAddressesToSendOutThroughTheAPI)
elif command == 'getDeterministicAddress':
diff --git a/src/class_objectProcessor.py b/src/class_objectProcessor.py
index 824580c2..adb506d3 100644
--- a/src/class_objectProcessor.py
+++ b/src/class_objectProcessor.py
@@ -47,7 +47,7 @@ class objectProcessor(threading.Thread):
def __init__(self):
threading.Thread.__init__(self, name="objectProcessor")
random.seed()
- # It may be the case that the last time Bitmessage was running,
+ # It may be the case that the last time Bitmes0sage was running,
# the user closed it before it finished processing everything in the
# objectProcessorQueue. Assuming that Bitmessage wasn't closed
# forcefully, it should have saved the data in the queue into the
@@ -68,9 +68,7 @@ class objectProcessor(threading.Thread):
"""Process the objects from `.queues.objectProcessorQueue`"""
while True:
objectType, data = queues.objectProcessorQueue.get()
-
self.checkackdata(data)
-
try:
if objectType == protocol.OBJECT_GETPUBKEY:
self.processgetpubkey(data)
@@ -140,9 +138,9 @@ class objectProcessor(threading.Thread):
# bypass nonce and time, retain object type/version/stream + body
readPosition = 16
- if data[readPosition:] in shared.ackdataForWhichImWatching:
+ if bytes(data[readPosition:]) in shared.ackdataForWhichImWatching:
logger.info('This object is an acknowledgement bound for me.')
- del shared.ackdataForWhichImWatching[data[readPosition:]]
+ del shared.ackdataForWhichImWatching[bytes(data[readPosition:])]
sqlExecute(
'UPDATE sent SET status=?, lastactiontime=?'
' WHERE ackdata=?',
@@ -223,7 +221,7 @@ class objectProcessor(threading.Thread):
'the hash requested in this getpubkey request is: %s',
hexlify(requestedHash))
# if this address hash is one of mine
- if requestedHash in shared.myAddressesByHash:
+ if bytes(requestedHash) in shared.myAddressesByHash:
myAddress = shared.myAddressesByHash[requestedHash]
elif requestedAddressVersionNumber >= 4:
requestedTag = data[readPosition:readPosition + 32]
@@ -235,8 +233,8 @@ class objectProcessor(threading.Thread):
logger.debug(
'the tag requested in this getpubkey request is: %s',
hexlify(requestedTag))
- if requestedTag in shared.myAddressesByTag:
- myAddress = shared.myAddressesByTag[requestedTag]
+ if bytes(requestedTag) in shared.myAddressesByTag:
+ myAddress = shared.myAddressesByTag[bytes(requestedTag)]
if myAddress == '':
logger.info('This getpubkey request is not for any of my keys.')
@@ -330,7 +328,7 @@ class objectProcessor(threading.Thread):
dataToStore = data[20:readPosition]
sha = hashlib.new('sha512')
sha.update(
- '\x04' + publicSigningKey + '\x04' + publicEncryptionKey)
+ '\x04'.encode() + publicSigningKey + '\x04'.encode() + publicEncryptionKey)
ripe = RIPEMD160Hash(sha.digest()).digest()
if logger.isEnabledFor(logging.DEBUG):
@@ -369,9 +367,9 @@ class objectProcessor(threading.Thread):
' Sanity check failed.')
return
readPosition += 4
- publicSigningKey = '\x04' + data[readPosition:readPosition + 64]
+ publicSigningKey = ('\x04').encode() + data[readPosition:readPosition + 64]
readPosition += 64
- publicEncryptionKey = '\x04' + data[readPosition:readPosition + 64]
+ publicEncryptionKey = ('\x04').encode() + data[readPosition:readPosition + 64]
readPosition += 64
_, specifiedNonceTrialsPerByteLength = decodeVarint(
data[readPosition:readPosition + 10])
@@ -385,9 +383,9 @@ class objectProcessor(threading.Thread):
signatureLength, signatureLengthLength = decodeVarint(
data[readPosition:readPosition + 10])
readPosition += signatureLengthLength
- signature = data[readPosition:readPosition + signatureLength]
+ signature = bytes(data[readPosition:readPosition + signatureLength])
if highlevelcrypto.verify(
- data[8:endOfSignedDataPosition],
+ bytes(data[8:endOfSignedDataPosition]),
signature, hexlify(publicSigningKey)):
logger.debug('ECDSA verify passed (within processpubkey)')
else:
@@ -435,14 +433,14 @@ class objectProcessor(threading.Thread):
return
tag = data[readPosition:readPosition + 32]
- if tag not in state.neededPubkeys:
+ if bytes(tag) not in state.neededPubkeys:
logger.info(
'We don\'t need this v4 pubkey. We didn\'t ask for it.')
return
# Let us try to decrypt the pubkey
- toAddress, _ = state.neededPubkeys[tag]
- if protocol.decryptAndCheckPubkeyPayload(data, toAddress) == \
+ toAddress, _ = state.neededPubkeys[bytes(tag)] #check with py2
+ if protocol.decryptAndCheckPubkeyPayload(bytes(data), toAddress) == \
'successful':
# At this point we know that we have been waiting on this
# pubkey. This function will command the workerThread
@@ -480,16 +478,15 @@ class objectProcessor(threading.Thread):
# This is not an acknowledgement bound for me. See if it is a message
# bound for me by trying to decrypt it with my private keys.
-
for key, cryptorObject in sorted(
shared.myECCryptorObjects.items(),
key=lambda x: random.random()):
try:
# continue decryption attempts to avoid timing attacks
if initialDecryptionSuccessful:
- cryptorObject.decrypt(data[readPosition:])
+ cryptorObject.decrypt(bytes(data[readPosition:]))
else:
- decryptedData = cryptorObject.decrypt(data[readPosition:])
+ decryptedData = cryptorObject.decrypt(bytes(data[readPosition:]))
# This is the RIPE hash of my pubkeys. We need this
# below to compare to the destination_ripe included
# in the encrypted data.
@@ -537,9 +534,9 @@ class objectProcessor(threading.Thread):
return
readPosition += sendersStreamNumberLength
readPosition += 4
- pubSigningKey = '\x04' + decryptedData[readPosition:readPosition + 64]
+ pubSigningKey = '\x04'.encode() + decryptedData[readPosition:readPosition + 64]
readPosition += 64
- pubEncryptionKey = '\x04' + decryptedData[readPosition:readPosition + 64]
+ pubEncryptionKey = '\x04'.encode() + decryptedData[readPosition:readPosition + 64]
readPosition += 64
if sendersAddressVersionNumber >= 3:
requiredAverageProofOfWorkNonceTrialsPerByte, varintLength = \
@@ -590,7 +587,7 @@ class objectProcessor(threading.Thread):
readPosition += signatureLengthLength
signature = decryptedData[
readPosition:readPosition + signatureLength]
- signedData = data[8:20] + encodeVarint(1) + encodeVarint(
+ signedData = bytes(data[8:20]) + encodeVarint(1) + encodeVarint(
streamNumberAsClaimedByMsg
) + decryptedData[:positionOfBottomOfAckData]
@@ -636,7 +633,6 @@ class objectProcessor(threading.Thread):
# pubkey in order to send a message. If we are, it will do the POW
# and send it.
self.possibleNewPubkey(fromAddress)
-
# If this message is bound for one of my version 3 addresses (or
# higher), then we must check to make sure it meets our demanded
# proof of work requirement. If this is bound for one of my chan
@@ -649,10 +645,10 @@ class objectProcessor(threading.Thread):
# If I'm not friendly with this person:
if not shared.isAddressInMyAddressBookSubscriptionsListOrWhitelist(
fromAddress):
- requiredNonceTrialsPerByte = BMConfigParser().getint(
- toAddress, 'noncetrialsperbyte')
- requiredPayloadLengthExtraBytes = BMConfigParser().getint(
- toAddress, 'payloadlengthextrabytes')
+ requiredNonceTrialsPerByte = int(BMConfigParser().get(
+ toAddress, 'noncetrialsperbyte'))
+ requiredPayloadLengthExtraBytes = int(BMConfigParser().get(
+ toAddress, 'payloadlengthextrabytes'))
if not protocol.isProofOfWorkSufficient(
data, requiredNonceTrialsPerByte,
requiredPayloadLengthExtraBytes):
@@ -685,7 +681,6 @@ class objectProcessor(threading.Thread):
toLabel = BMConfigParser().get(toAddress, 'label')
if toLabel == '':
toLabel = toAddress
-
try:
decodedMessage = helper_msgcoding.MsgDecode(
messageEncodingType, message)
@@ -868,7 +863,7 @@ class objectProcessor(threading.Thread):
elif broadcastVersion == 5:
embeddedTag = data[readPosition:readPosition + 32]
readPosition += 32
- if embeddedTag not in shared.MyECSubscriptionCryptorObjects:
+ if bytes(embeddedTag) not in shared.MyECSubscriptionCryptorObjects:
logger.debug('We\'re not interested in this broadcast.')
return
# We are interested in this broadcast because of its tag.
@@ -1122,8 +1117,8 @@ class objectProcessor(threading.Thread):
if checksum != hashlib.sha512(payload).digest()[0:4]:
logger.info('ackdata checksum wrong. Not sending ackdata.')
return False
- command = command.rstrip('\x00')
- if command != 'object':
+ command = command.rstrip('\x00'.encode())
+ if command != 'object'.encode():
return False
return True
diff --git a/src/class_singleCleaner.py b/src/class_singleCleaner.py
index e3acff1d..711d8de2 100644
--- a/src/class_singleCleaner.py
+++ b/src/class_singleCleaner.py
@@ -32,7 +32,8 @@ import tr
from bmconfigparser import BMConfigParser
from helper_sql import sqlExecute, sqlQuery
from inventory import Inventory
-from network import BMConnectionPool, StoppableThread
+from network.connectionpool import BMConnectionPool
+from network.threads import StoppableThread
class singleCleaner(StoppableThread):
@@ -136,6 +137,7 @@ class singleCleaner(StoppableThread):
os._exit(1)
# inv/object tracking
+
for connection in BMConnectionPool().connections():
connection.clean()
@@ -199,6 +201,10 @@ def deleteTrashMsgPermonantly():
"""This method is used to delete old messages"""
ndays_before_time = datetime.now() - timedelta(days=30)
old_messages = time.mktime(ndays_before_time.timetuple())
- sqlExecute("delete from sent where folder = 'trash' and lastactiontime <= ?;", int(old_messages))
- sqlExecute("delete from inbox where folder = 'trash' and received <= ?;", int(old_messages))
+ sqlExecute(
+ "delete from sent where folder = 'trash' and lastactiontime <= ?;",
+ int(old_messages))
+ sqlExecute(
+ "delete from inbox where folder = 'trash' and received <= ?;",
+ int(old_messages))
return
diff --git a/src/class_singleWorker.py b/src/class_singleWorker.py
index 0bb110a7..d9f5ba31 100644
--- a/src/class_singleWorker.py
+++ b/src/class_singleWorker.py
@@ -28,10 +28,11 @@ import tr
from addresses import (
calculateInventoryHash, decodeAddress, decodeVarint, encodeVarint
)
+
from bmconfigparser import BMConfigParser
from helper_sql import sqlExecute, sqlQuery
from inventory import Inventory
-from network import StoppableThread
+from network.threads import StoppableThread
# This thread, of which there is only one, does the heavy lifting:
# calculating POWs.
@@ -227,6 +228,7 @@ class singleWorker(StoppableThread):
if log_time:
start_time = time.time()
trialValue, nonce = proofofwork.run(target, initialHash)
+ print("nonce calculated value#############################", nonce)
self.logger.info(
'%s Found proof of work %s Nonce: %s',
log_prefix, trialValue, nonce
@@ -400,7 +402,7 @@ class singleWorker(StoppableThread):
TTL = int(28 * 24 * 60 * 60 + helper_random.randomrandrange(-300, 300))
embeddedTime = int(time.time() + TTL)
payload = pack('>Q', (embeddedTime))
- payload += '\x00\x00\x00\x01' # object type: pubkey
+ payload += '\x00\x00\x00\x01'.encode() # object type: pubkey
payload += encodeVarint(addressVersionNumber) # Address version number
payload += encodeVarint(streamNumber)
dataToEncrypt = protocol.getBitfield(myAddress)
@@ -419,10 +421,10 @@ class singleWorker(StoppableThread):
dataToEncrypt += pubSigningKey + pubEncryptionKey
- dataToEncrypt += encodeVarint(BMConfigParser().getint(
- myAddress, 'noncetrialsperbyte'))
- dataToEncrypt += encodeVarint(BMConfigParser().getint(
- myAddress, 'payloadlengthextrabytes'))
+ dataToEncrypt += encodeVarint(int(BMConfigParser().get(
+ myAddress, 'noncetrialsperbyte')))
+ dataToEncrypt += encodeVarint(int(BMConfigParser().get(
+ myAddress, 'payloadlengthextrabytes')))
# When we encrypt, we'll use a hash of the data
# contained in an address as a decryption key. This way
@@ -453,7 +455,7 @@ class singleWorker(StoppableThread):
inventoryHash = calculateInventoryHash(payload)
objectType = 1
- Inventory()[inventoryHash] = (
+ Inventory()._realInventory[inventoryHash] = (
objectType, streamNumber, payload, embeddedTime,
doubleHashOfAddressData[32:]
)
@@ -809,7 +811,6 @@ class singleWorker(StoppableThread):
highlevelcrypto.makeCryptor(
hexlify(privEncryptionKey))
)
-
for value in Inventory().by_type_and_tag(1, toTag):
# if valid, this function also puts it
# in the pubkeys table.
@@ -855,17 +856,14 @@ class singleWorker(StoppableThread):
self.requestPubKey(toaddress)
# on with the next msg on which we can do some work
continue
-
# At this point we know that we have the necessary pubkey
# in the pubkeys table.
-
TTL *= 2**retryNumber
if TTL > 28 * 24 * 60 * 60:
TTL = 28 * 24 * 60 * 60
# add some randomness to the TTL
TTL = int(TTL + helper_random.randomrandrange(-300, 300))
embeddedTime = int(time.time() + TTL)
-
# if we aren't sending this to ourselves or a chan
if not BMConfigParser().has_section(toaddress):
shared.ackdataForWhichImWatching[ackdata] = 0
@@ -875,22 +873,23 @@ class singleWorker(StoppableThread):
tr._translate(
"MainWindow",
"Looking up the receiver\'s public key"))
- ))
+ ))
self.logger.info('Sending a message.')
- self.logger.debug(
- 'First 150 characters of message: %s',
- repr(message[:150])
- )
+ # self.logger.debug(
+ # 'First 150 characters of message: %s',
+ # repr(message[:150])
+ # )
# Let us fetch the recipient's public key out of
# our database. If the required proof of work difficulty
# is too hard then we'll abort.
+
queryreturn = sqlQuery(
'SELECT transmitdata FROM pubkeys WHERE address=?',
toaddress)
for row in queryreturn: # pylint: disable=redefined-outer-name
pubkeyPayload, = row
-
+
# The pubkey message is stored with the following items
# all appended:
# -address version
@@ -914,7 +913,7 @@ class singleWorker(StoppableThread):
# if receiver is a mobile device who expects that their
# address RIPE is included unencrypted on the front of
- # the message..
+ # the message..
if protocol.isBitSetWithinBitfield(behaviorBitfield, 30):
# if we are Not willing to include the receiver's
# RIPE hash on the message..
@@ -951,9 +950,8 @@ class singleWorker(StoppableThread):
pubEncryptionKeyBase256 = pubkeyPayload[
readPosition:readPosition + 64]
readPosition += 64
-
# Let us fetch the amount of work required by the recipient.
- if toAddressVersionNumber == 2:
+ if toAddressVersionNumber == 2:
requiredAverageProofOfWorkNonceTrialsPerByte = \
defaults.networkDefaultProofOfWorkNonceTrialsPerByte
requiredPayloadLengthExtraBytes = \
@@ -967,6 +965,7 @@ class singleWorker(StoppableThread):
"There is no required difficulty for"
" version 2 addresses like this."))
))
+
elif toAddressVersionNumber >= 3:
requiredAverageProofOfWorkNonceTrialsPerByte, \
varintLength = decodeVarint(
@@ -993,7 +992,6 @@ class singleWorker(StoppableThread):
requiredAverageProofOfWorkNonceTrialsPerByte,
requiredPayloadLengthExtraBytes
)
-
queues.UISignalQueue.put(
(
'updateSentItemStatusByAckdata',
@@ -1018,17 +1016,15 @@ class singleWorker(StoppableThread):
)
)
)
-
if status != 'forcepow':
- maxacceptablenoncetrialsperbyte = BMConfigParser().getint(
- 'bitmessagesettings', 'maxacceptablenoncetrialsperbyte')
- maxacceptablepayloadlengthextrabytes = BMConfigParser().getint(
- 'bitmessagesettings', 'maxacceptablepayloadlengthextrabytes')
+ maxacceptablenoncetrialsperbyte = int(BMConfigParser().get(
+ 'bitmessagesettings', 'maxacceptablenoncetrialsperbyte'))
+ maxacceptablepayloadlengthextrabytes = int(BMConfigParser().get(
+ 'bitmessagesettings', 'maxacceptablepayloadlengthextrabytes'))
cond1 = maxacceptablenoncetrialsperbyte and \
requiredAverageProofOfWorkNonceTrialsPerByte > maxacceptablenoncetrialsperbyte
cond2 = maxacceptablepayloadlengthextrabytes and \
requiredPayloadLengthExtraBytes > maxacceptablepayloadlengthextrabytes
-
if cond1 or cond2:
# The demanded difficulty is more than
# we are willing to do.
@@ -1056,7 +1052,6 @@ class singleWorker(StoppableThread):
self.logger.debug(
'First 150 characters of message: %r', message[:150])
behaviorBitfield = protocol.getBitfield(fromaddress)
-
try:
privEncryptionKeyBase58 = BMConfigParser().get(
toaddress, 'privencryptionkey')
@@ -1093,7 +1088,6 @@ class singleWorker(StoppableThread):
"MainWindow",
"Doing work necessary to send message."))
))
-
# Now we can start to assemble our message.
payload = encodeVarint(fromAddressVersionNumber)
payload += encodeVarint(fromStreamNumber)
@@ -1101,7 +1095,6 @@ class singleWorker(StoppableThread):
# that can be expected from me. (See
# https://bitmessage.org/wiki/Protocol_specification#Pubkey_bitfield_features)
payload += protocol.getBitfield(fromaddress)
-
# We need to convert our private keys to public keys in order
# to include them.
try:
@@ -1118,9 +1111,7 @@ class singleWorker(StoppableThread):
" (your address) in the keys.dat file."))
))
continue
-
payload += pubSigningKey + pubEncryptionKey
-
if fromAddressVersionNumber >= 3:
# If the receiver of our message is in our address book,
# subscriptions list, or whitelist then we will allow them to
@@ -1133,11 +1124,10 @@ class singleWorker(StoppableThread):
payload += encodeVarint(
defaults.networkDefaultPayloadLengthExtraBytes)
else:
- payload += encodeVarint(BMConfigParser().getint(
- fromaddress, 'noncetrialsperbyte'))
- payload += encodeVarint(BMConfigParser().getint(
- fromaddress, 'payloadlengthextrabytes'))
-
+ payload += encodeVarint(int(BMConfigParser().get(
+ fromaddress, 'noncetrialsperbyte')))
+ payload += encodeVarint(int(BMConfigParser().get(
+ fromaddress, 'payloadlengthextrabytes')))
# This hash will be checked by the receiver of the message
# to verify that toRipe belongs to them. This prevents
# a Surreptitious Forwarding Attack.
@@ -1168,8 +1158,8 @@ class singleWorker(StoppableThread):
fullAckPayload = self.generateFullAckMessage(
ackdata, toStreamNumber, TTL)
payload += encodeVarint(len(fullAckPayload))
- payload += fullAckPayload
- dataToSign = pack('>Q', embeddedTime) + '\x00\x00\x00\x02' + \
+ payload += fullAckPayload if isinstance(fullAckPayload,bytes) else fullAckPayload.encode()
+ dataToSign = pack('>Q', embeddedTime) + '\x00\x00\x00\x02'.encode() + \
encodeVarint(1) + encodeVarint(toStreamNumber) + payload
signature = highlevelcrypto.sign(dataToSign, privSigningKeyHex)
payload += encodeVarint(len(signature))
@@ -1178,7 +1168,7 @@ class singleWorker(StoppableThread):
# We have assembled the data that will be encrypted.
try:
encrypted = highlevelcrypto.encrypt(
- payload, "04" + hexlify(pubEncryptionKeyBase256)
+ payload, "04".encode() + hexlify(pubEncryptionKeyBase256)
)
except:
sqlExecute(
@@ -1195,9 +1185,8 @@ class singleWorker(StoppableThread):
).arg(l10n.formatTimestamp()))
))
continue
-
encryptedPayload = pack('>Q', embeddedTime)
- encryptedPayload += '\x00\x00\x00\x02' # object type: msg
+ encryptedPayload += '\x00\x00\x00\x02'.encode() # object type: msg
encryptedPayload += encodeVarint(1) # msg version
encryptedPayload += encodeVarint(toStreamNumber) + encrypted
target = 2 ** 64 / (
@@ -1211,17 +1200,16 @@ class singleWorker(StoppableThread):
))
self.logger.info(
'(For msg message) Doing proof of work. Total required'
- ' difficulty: %f. Required small message difficulty: %f.',
- float(requiredAverageProofOfWorkNonceTrialsPerByte) /
+ ' difficulty: {}. Required small message difficulty: {}.'.format
+ (float(requiredAverageProofOfWorkNonceTrialsPerByte) /
defaults.networkDefaultProofOfWorkNonceTrialsPerByte,
float(requiredPayloadLengthExtraBytes) /
- defaults.networkDefaultPayloadLengthExtraBytes
+ defaults.networkDefaultPayloadLengthExtraBytes)
)
powStartTime = time.time()
initialHash = hashlib.sha512(encryptedPayload).digest()
trialValue, nonce = proofofwork.run(target, initialHash)
- print("nonce calculated value#############################", nonce)
self.logger.info(
'(For msg message) Found proof of work %s Nonce: %s',
trialValue, nonce
@@ -1234,7 +1222,6 @@ class singleWorker(StoppableThread):
)
except:
pass
-
encryptedPayload = pack('>Q', nonce) + encryptedPayload
# Sanity check. The encryptedPayload size should never be
@@ -1248,10 +1235,11 @@ class singleWorker(StoppableThread):
len(encryptedPayload)
)
continue
-
inventoryHash = calculateInventoryHash(encryptedPayload)
objectType = 2
- Inventory()[inventoryHash] = (
+ inventoryHashlist = (
+ objectType, toStreamNumber,encryptedPayload, embeddedTime, '')
+ Inventory()._realInventory[inventoryHash] = (
objectType, toStreamNumber, encryptedPayload, embeddedTime, '')
if BMConfigParser().has_section(toaddress) or \
not protocol.checkBitfield(behaviorBitfield, protocol.BITFIELD_DOESACK):
@@ -1260,7 +1248,7 @@ class singleWorker(StoppableThread):
ackdata,
tr._translate(
"MainWindow",
- "Message sent. Sent at %1"
+ "Mobileessage sent. Sent at %1"
).arg(l10n.formatTimestamp()))))
else:
# not sending to a chan or one of my addresses
@@ -1278,7 +1266,6 @@ class singleWorker(StoppableThread):
hexlify(inventoryHash)
)
queues.invQueue.put((toStreamNumber, inventoryHash))
-
# Update the sent message in the sent table with the
# necessary information.
if BMConfigParser().has_section(toaddress) or \
@@ -1294,7 +1281,6 @@ class singleWorker(StoppableThread):
inventoryHash, newStatus, retryNumber + 1,
sleepTill, int(time.time()), ackdata
)
-
# If we are sending to ourselves or a chan, let's put
# the message in our own inbox.
if BMConfigParser().has_section(toaddress):
@@ -1332,7 +1318,6 @@ class singleWorker(StoppableThread):
toAddress
)
return
-
queryReturn = sqlQuery(
'''SELECT retrynumber FROM sent WHERE toaddress=? '''
''' AND (status='doingpubkeypow' OR status='awaitingpubkey') '''
@@ -1347,10 +1332,9 @@ class singleWorker(StoppableThread):
)
return
retryNumber = queryReturn[0][0]
-
- if addressVersionNumber <= 3:
+ if addressVersionNumber <= 3:
state.neededPubkeys[toAddress] = 0
- elif addressVersionNumber >= 4:
+ elif addressVersionNumber >= 4:
# If the user just clicked 'send' then the tag
# (and other information) will already be in the
# neededPubkeys dictionary. But if we are recovering
@@ -1383,7 +1367,7 @@ class singleWorker(StoppableThread):
TTL = TTL + helper_random.randomrandrange(-300, 300)
embeddedTime = int(time.time() + TTL)
payload = pack('>Q', embeddedTime)
- payload += '\x00\x00\x00\x00' # object type: getpubkey
+ payload += '\x00\x00\x00\x00'.encode() # object type: getpubkey
payload += encodeVarint(addressVersionNumber)
payload += encodeVarint(streamNumber)
if addressVersionNumber <= 3:
@@ -1406,16 +1390,14 @@ class singleWorker(StoppableThread):
"MainWindow",
"Doing work necessary to request encryption key."))
))
-
payload = self._doPOWDefaults(payload, TTL)
-
inventoryHash = calculateInventoryHash(payload)
objectType = 1
- Inventory()[inventoryHash] = (
+ Inventory()._realInventory[inventoryHash] = (
objectType, streamNumber, payload, embeddedTime, '')
+ # Inventory()._realInventory[inventoryHashlist]
self.logger.info('sending inv (for the getpubkey message)')
queues.invQueue.put((streamNumber, inventoryHash))
-
# wait 10% past expiration
sleeptill = int(time.time() + TTL * 1.1)
sqlExecute(
@@ -1424,7 +1406,6 @@ class singleWorker(StoppableThread):
''' WHERE toaddress=? AND (status='doingpubkeypow' OR '''
''' status='awaitingpubkey') ''',
int(time.time()), retryNumber + 1, sleeptill, toAddress)
-
queues.UISignalQueue.put((
'updateStatusBar',
tr._translate(
diff --git a/src/class_smtpDeliver.py b/src/class_smtpDeliver.py
index 4f8422cc..4f82ee4a 100644
--- a/src/class_smtpDeliver.py
+++ b/src/class_smtpDeliver.py
@@ -2,7 +2,6 @@
SMTP client thread for delivering emails
"""
# pylint: disable=unused-variable
-
import smtplib
import urlparse
from email.header import Header
@@ -51,10 +50,12 @@ class smtpDeliver(StoppableThread):
ackData, message = data
elif command == 'displayNewInboxMessage':
inventoryHash, toAddress, fromAddress, subject, body = data
- dest = BMConfigParser().safeGet("bitmessagesettings", "smtpdeliver", '')
+ dest = BMConfigParser().safeGet(
+ "bitmessagesettings", "smtpdeliver", '')
if dest == '':
continue
try:
+ # pylint: disable=deprecated-lambda
u = urlparse.urlparse(dest)
to = urlparse.parse_qs(u.query)['to']
client = smtplib.SMTP(u.hostname, u.port)
@@ -67,7 +68,9 @@ class smtpDeliver(StoppableThread):
lambda x: x == toAddress, BMConfigParser().addresses())
)
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:
msg['To'] = toAddress + '@' + SMTPDOMAIN
client.ehlo()
@@ -81,7 +84,8 @@ class smtpDeliver(StoppableThread):
except:
self.logger.error('smtp delivery error', exc_info=True)
elif command == 'displayNewSentMessage':
- toAddress, fromLabel, fromAddress, subject, message, ackdata = data
+ toAddress, fromLabel, fromAddress, subject, message, ackdata = \
+ data
elif command == 'updateNetworkStatusTab':
pass
elif command == 'updateNumberOfMessagesProcessed':
diff --git a/src/class_sqlThread.py b/src/class_sqlThread.py
index 7e9eb6c5..6bfdcb25 100644
--- a/src/class_sqlThread.py
+++ b/src/class_sqlThread.py
@@ -82,9 +82,11 @@ class sqlThread(threading.Thread):
# If the settings version is equal to 2 or 3 then the
# sqlThread will modify the pubkeys table and change
# the settings version to 4.
- settingsversion = BMConfigParser().getint(
- 'bitmessagesettings', 'settingsversion')
-
+ # settingsversion = BMConfigParser().getint('bitmessagesettings', 'settingsversion')
+ # In the Python3 I am below condition converting into int
+ # settingsversion = int(BMConfigParser().get('bitmessagesettings', 'settingsversion') \
+ # if BMConfigParser().get('bitmessagesettings', 'settingsversion') else 0)
+ settingsversion = BMConfigParser().safeGetInt('bitmessagesettings', 'settingsvesion')
# People running earlier versions of PyBitmessage do not have the
# usedpersonally field in their pubkeys table. Let's add it.
if settingsversion == 2:
@@ -211,7 +213,8 @@ class sqlThread(threading.Thread):
parameters = ''
self.cur.execute(item, parameters)
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(
'In messages.dat database, adding tag field to'
' the inventory table.')
@@ -569,6 +572,7 @@ class sqlThread(threading.Thread):
rowcount = 0
# print 'item', item
# print 'parameters', parameters
+ # if 'inbox' in item:
try:
self.cur.execute(item, parameters)
rowcount = self.cur.rowcount
diff --git a/src/debug.py b/src/debug.py
index b9aaf394..99994d22 100644
--- a/src/debug.py
+++ b/src/debug.py
@@ -35,7 +35,7 @@ Logging is thread-safe so you don't have to worry about locks,
just import and log.
"""
-import ConfigParser
+import configparser
import logging
import logging.config
import os
@@ -73,7 +73,7 @@ def configureLogging():
False,
'Loaded logger configuration from %s' % logging_config
)
- except (OSError, ConfigParser.NoSectionError):
+ except (OSError, configparser.NoSectionError):
if os.path.isfile(logging_config):
fail_msg = \
'Failed to load logger configuration from %s, using default' \
@@ -148,7 +148,11 @@ def resetLogging():
# !
-preconfigured, msg = configureLogging()
+try:
+ preconfigured, msg = configureLogging()
+ if msg:
+ logger.log(logging.WARNING if preconfigured else logging.INFO, msg)
+
+except:
+ pass
logger = logging.getLogger('default')
-if msg:
- logger.log(logging.WARNING if preconfigured else logging.INFO, msg)
diff --git a/src/depends.py b/src/depends.py
index 82529269..ead33cae 100755
--- a/src/depends.py
+++ b/src/depends.py
@@ -366,6 +366,7 @@ def check_pyqt():
Here we are checking for PyQt4 with its version, as for it require
PyQt 4.8 or later.
"""
+
QtCore = try_import(
'PyQt4.QtCore', 'PyBitmessage requires PyQt 4.8 or later and Qt 4.7 or later.')
@@ -421,11 +422,11 @@ def check_dependencies(verbose=False, optional=False):
'PyBitmessage requires Python 2.7.4 or greater'
' (but not Python 3+)')
has_all_dependencies = False
- if sys.hexversion >= 0x3000000:
- logger.error(
- 'PyBitmessage does not support Python 3+. Python 2.7.4'
- ' or greater is required.')
- has_all_dependencies = False
+ # if sys.hexversion >= 0x3000000:
+ # logger.error(
+ # 'PyBitmessage does not support Python 3+. Python 2.7.4'
+ # ' or greater is required.')
+ # has_all_dependencies = False
check_functions = [check_ripemd160, check_sqlite, check_openssl]
if optional:
diff --git a/src/helper_ackPayload.py b/src/helper_ackPayload.py
index d30f4c0d..060161ed 100644
--- a/src/helper_ackPayload.py
+++ b/src/helper_ackPayload.py
@@ -22,7 +22,7 @@ def genAckPayload(streamNumber=1, stealthLevel=0):
- level 1: a getpubkey request for a (random) dummy key hash
- level 2: a standard message, encrypted to a random pubkey
"""
- if stealthLevel == 2: # Generate privacy-enhanced payload
+ if stealthLevel == 2: # Generate privacy-enhanced payload
# Generate a dummy privkey and derive the pubkey
dummyPubKeyHex = highlevelcrypto.privToPub(
hexlify(helper_random.randomBytes(32)))
@@ -35,12 +35,12 @@ def genAckPayload(streamNumber=1, stealthLevel=0):
acktype = 2 # message
version = 1
- elif stealthLevel == 1: # Basic privacy payload (random getpubkey)
+ elif stealthLevel == 1: # Basic privacy payload (random getpubkey)
ackdata = helper_random.randomBytes(32)
acktype = 0 # getpubkey
version = 4
- else: # Minimum viable payload (non stealth)
+ else: # Minimum viable payload (non stealth)
ackdata = helper_random.randomBytes(32)
acktype = 2 # message
version = 1
diff --git a/src/helper_msgcoding.py b/src/helper_msgcoding.py
index 76dad423..70f6ad2e 100644
--- a/src/helper_msgcoding.py
+++ b/src/helper_msgcoding.py
@@ -99,14 +99,14 @@ class MsgDecode(object):
def decodeExtended(self, data):
"""Handle extended encoding"""
dc = zlib.decompressobj()
- tmp = ""
+ tmp = bytes()
while len(tmp) <= BMConfigParser().safeGetInt("zlib", "maxsize"):
try:
got = dc.decompress(
data, BMConfigParser().safeGetInt("zlib", "maxsize") +
1 - len(tmp))
# EOF
- if got == "":
+ if got == bytes():
break
tmp += got
data = dc.unconsumed_tail
@@ -128,7 +128,6 @@ class MsgDecode(object):
except KeyError:
logger.error("Message type missing")
raise MsgDecodeException("Message type missing")
-
msgObj = messagetypes.constructObject(tmp)
if msgObj is None:
raise MsgDecodeException("Malformed message")
@@ -142,7 +141,7 @@ class MsgDecode(object):
def decodeSimple(self, data):
"""Handle simple encoding"""
- bodyPositionIndex = string.find(data, '\nBody:')
+ bodyPositionIndex = bytes.find(data, '\nBody:'.encode())
if bodyPositionIndex > 1:
subject = data[8:bodyPositionIndex]
# Only save and show the first 500 characters of the subject.
diff --git a/src/helper_search.py b/src/helper_search.py
index 69acec43..2384ff01 100644
--- a/src/helper_search.py
+++ b/src/helper_search.py
@@ -7,6 +7,7 @@ try:
haveQt = True
except ImportError:
haveQt = False
+# pylint: disable=too-many-arguments
def search_translate(context, text):
@@ -18,7 +19,7 @@ def search_translate(context, text):
def search_sql(xAddress="toaddress", account=None, folder="inbox", where=None, what=None, unreadOnly=False):
"""Perform a search in mailbox tables"""
- # pylint: disable=too-many-arguments, too-many-branches
+ # pylint: disable=too-many-branches
if what is not None and what != "":
what = "%" + what + "%"
if where == search_translate("MainWindow", "To"):
@@ -75,7 +76,6 @@ def search_sql(xAddress="toaddress", account=None, folder="inbox", where=None, w
def check_match(toAddress, fromAddress, subject, message, where=None, what=None):
"""Check if a single message matches a filter (used when new messages are added to messagelists)"""
- # pylint: disable=too-many-arguments
if what is not None and what != "":
if where in (search_translate("MainWindow", "To"), search_translate("MainWindow", "All")):
if what.lower() not in toAddress.lower():
diff --git a/src/helper_sent.py b/src/helper_sent.py
index bc3362e8..47fc5bb4 100644
--- a/src/helper_sent.py
+++ b/src/helper_sent.py
@@ -1,7 +1,6 @@
"""
Insert values into sent table
"""
-
from helper_sql import sqlExecute
diff --git a/src/helper_sql.py b/src/helper_sql.py
index 9b5dc29d..f848ee24 100644
--- a/src/helper_sql.py
+++ b/src/helper_sql.py
@@ -16,8 +16,8 @@ SQLite objects can only be used from one thread.
or isn't thread-safe.
"""
-import Queue
import threading
+import queue as Queue
sqlSubmitQueue = Queue.Queue()
"""the queue for SQL"""
@@ -29,7 +29,6 @@ sqlLock = threading.Lock()
def sqlQuery(sqlStatement, *args):
"""
Query sqlite and return results
-
:param str sqlStatement: SQL statement string
:param list args: SQL query parameters
:rtype: list
@@ -102,7 +101,7 @@ def sqlStoredProcedure(procName):
sqlLock.release()
-class SqlBulkExecute(object):
+class SqlBulkExecute(object): # pylint: disable=no-init
"""This is used when you have to execute the same statement in a cycle."""
def __enter__(self):
diff --git a/src/helper_startup.py b/src/helper_startup.py
index 8374261d..997e58e3 100644
--- a/src/helper_startup.py
+++ b/src/helper_startup.py
@@ -129,7 +129,9 @@ def loadConfig():
def updateConfig():
"""Save the config"""
config = BMConfigParser()
- settingsversion = config.getint('bitmessagesettings', 'settingsversion')
+ # Used python2.7
+ # settingsversion = int(BMConfigParser().get('bitmessagesettings', 'settingsversion') \
+ settingsversion = BMConfigParser().safeGetInt('bitmessagesettings', 'settingsvesion')
if settingsversion == 1:
config.set('bitmessagesettings', 'socksproxytype', 'none')
config.set('bitmessagesettings', 'sockshostname', 'localhost')
diff --git a/src/highlevelcrypto.py b/src/highlevelcrypto.py
index f392fe4a..ad073e47 100644
--- a/src/highlevelcrypto.py
+++ b/src/highlevelcrypto.py
@@ -19,17 +19,18 @@ def makeCryptor(privkey):
"""Return a private `.pyelliptic.ECC` instance"""
private_key = a.changebase(privkey, 16, 256, minlen=32)
public_key = pointMult(private_key)
- privkey_bin = '\x02\xca\x00\x20' + private_key
- pubkey_bin = '\x02\xca\x00\x20' + public_key[1:-32] + '\x00\x20' + public_key[-32:]
- cryptor = pyelliptic.ECC(
- curve='secp256k1', privkey=privkey_bin, pubkey=pubkey_bin)
+ privkey_bin = '\x02\xca\x00\x20'.encode('raw_unicode_escape') + private_key
+ pubkey_bin = '\x02\xca\x00\x20'.encode(
+ 'raw_unicode_escape') + public_key[1:-32] + '\x00\x20'.encode(
+ 'utf-8') + public_key[-32:]
+ cryptor = pyelliptic.ECC(curve='secp256k1', privkey=privkey_bin, pubkey=pubkey_bin)
return cryptor
def hexToPubkey(pubkey):
"""Convert a pubkey from hex to binary"""
pubkey_raw = a.changebase(pubkey[2:], 16, 256, minlen=64)
- pubkey_bin = '\x02\xca\x00 ' + pubkey_raw[:32] + '\x00 ' + pubkey_raw[32:]
+ pubkey_bin = '\x02\xca\x00 '.encode('raw_unicode_escape') + pubkey_raw[:32] + '\x00 '.encode() + pubkey_raw[32:]
return pubkey_bin
@@ -53,6 +54,7 @@ def encrypt(msg, hexPubkey):
def decrypt(msg, hexPrivkey):
+ print("SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS#################################################")
"""Decrypts message with hex private key"""
return makeCryptor(hexPrivkey).decrypt(msg)
diff --git a/src/knownnodes.py b/src/knownnodes.py
index bb588fcb..48194d9d 100644
--- a/src/knownnodes.py
+++ b/src/knownnodes.py
@@ -46,12 +46,18 @@ def json_serialize_knownnodes(output):
Reorganize knownnodes dict and write it as JSON to output
"""
_serialized = []
- for stream, peers in knownNodes.iteritems():
- for peer, info in peers.iteritems():
+ for stream, peers in iter(knownNodes.items()):
+ for peer, info in iter(peers.items()):
info.update(rating=round(info.get('rating', 0), 2))
- _serialized.append({
- 'stream': stream, 'peer': peer._asdict(), 'info': info
- })
+ # pylint: disable=unidiomatic-typecheck
+ if type(peer[0]) != bytes:
+ _serialized.append({'stream': stream, 'peer': peer._asdict(), 'info': info})
+ else:
+ from collections import OrderedDict
+ _serialized.append({
+ 'stream': stream,
+ 'peer': OrderedDict({'host': str(peer[0].decode()), 'port': int(peer[1])}),
+ 'info': info})
json.dump(_serialized, output, indent=4)
@@ -90,7 +96,7 @@ def saveKnownNodes(dirName=None):
if dirName is None:
dirName = state.appdata
with knownNodesLock:
- with open(os.path.join(dirName, 'knownnodes.dat'), 'wb') as output:
+ with open(os.path.join(dirName, 'knownnodes.dat'), 'w') as output:
json_serialize_knownnodes(output)
@@ -121,7 +127,7 @@ def readKnownNodes():
except ValueError:
source.seek(0)
pickle_deserialize_old_knownnodes(source)
- except (IOError, OSError, KeyError, EOFError):
+ except (IOError, OSError, KeyError, EOFError, pickle.UnpicklingError):
logger.debug(
'Failed to read nodes from knownnodes.dat', exc_info=True)
createDefaultKnownNodes()
@@ -143,7 +149,7 @@ def increaseRating(peer):
increaseAmount = 0.1
maxRating = 1
with knownNodesLock:
- for stream in knownNodes.keys():
+ for stream in [key for key in knownNodes.keys()]:
try:
knownNodes[stream][peer]["rating"] = min(
knownNodes[stream][peer]["rating"] + increaseAmount,
diff --git a/src/l10n.py b/src/l10n.py
index 7a78525b..2ea836b3 100644
--- a/src/l10n.py
+++ b/src/l10n.py
@@ -64,20 +64,31 @@ else:
if time_format != DEFAULT_TIME_FORMAT:
try:
# Check day names
- for i in xrange(7):
- unicode(time.strftime(time_format, (0, 0, 0, 0, 0, 0, i, 0, 0)), encoding)
+ new_time_format = time_format
+ import sys
+ if sys.version_info >= (3, 0, 0) and time_format == '%%c':
+ time_format = '%c'
+ for i in range(7):
+ # this work for python2.7
+ # unicode(time.strftime(time_format, (0, 0, 0, 0, 0, 0, i, 0, 0)), encoding)
+ # this code for the python3
+ (time.strftime(time_format, (0, 0, 0, 0, 0, 0, i, 0, 0))).encode()
# Check month names
- for i in xrange(1, 13):
- unicode(time.strftime(time_format, (0, i, 0, 0, 0, 0, 0, 0, 0)), encoding)
+ for i in range(1, 13):
+ # unicode(time.strftime(time_format, (0, i, 0, 0, 0, 0, 0, 0, 0)), encoding)
+ (time.strftime(time_format, (0, i, 0, 0, 0, 0, 0, 0, 0))).encode()
+
# Check AM/PM
- unicode(time.strftime(time_format, (0, 0, 0, 11, 0, 0, 0, 0, 0)), encoding)
- unicode(time.strftime(time_format, (0, 0, 0, 13, 0, 0, 0, 0, 0)), encoding)
+ (time.strftime(time_format, (0, 0, 0, 11, 0, 0, 0, 0, 0))).encode()
+ (time.strftime(time_format, (0, 0, 0, 13, 0, 0, 0, 0, 0))).encode()
# Check DST
- unicode(time.strftime(time_format, (0, 0, 0, 0, 0, 0, 0, 0, 1)), encoding)
+ (time.strftime(time_format, (0, 0, 0, 0, 0, 0, 0, 0, 1))).encode()
+
except:
logger.exception('Could not decode locale formatted timestamp')
time_format = DEFAULT_TIME_FORMAT
encoding = DEFAULT_ENCODING
+ time_format = new_time_format
def setlocale(category, newlocale):
@@ -111,7 +122,8 @@ def formatTimestamp(timestamp=None, as_unicode=True):
timestring = time.strftime(time_format)
if as_unicode:
- return unicode(timestring, encoding)
+ return (timestring.encode('utf-8'))
+ # return unicode(timestring, encoding)
return timestring
diff --git a/src/main.py b/src/main.py
index a3257062..22ea7c3e 100644
--- a/src/main.py
+++ b/src/main.py
@@ -1,6 +1,5 @@
"""This module is for thread start."""
import state
-from bitmessagemain import main
if __name__ == '__main__':
state.kivy = True
diff --git a/src/messagetypes/__init__.py b/src/messagetypes/__init__.py
index 97ce693a..54d32794 100644
--- a/src/messagetypes/__init__.py
+++ b/src/messagetypes/__init__.py
@@ -1,7 +1,6 @@
import logging
from importlib import import_module
from os import listdir, path
-from string import lower
try:
from kivy.utils import platform
except:
@@ -16,7 +15,7 @@ logger = logging.getLogger('default')
class MsgBase(object): # pylint: disable=too-few-public-methods
"""Base class for message types"""
def __init__(self):
- self.data = {"": lower(type(self).__name__)}
+ self.data = {"": (type(self).__name__).lower()}
def constructObject(data):
diff --git a/src/messagetypes/message.py b/src/messagetypes/message.py
index 27bba13a..2480df70 100644
--- a/src/messagetypes/message.py
+++ b/src/messagetypes/message.py
@@ -14,13 +14,17 @@ class Message(MsgBase):
"""Decode a message"""
# UTF-8 and variable type validator
if isinstance(data["subject"], str):
- self.subject = unicode(data["subject"], 'utf-8', 'replace')
+ # Unicode is depreciated
+ self.subject =data["subject"]
else:
- self.subject = unicode(str(data["subject"]), 'utf-8', 'replace')
+ # Unicode is depreciated
+ self.subject = str(data["subject"])
if isinstance(data["body"], str):
- self.body = unicode(data["body"], 'utf-8', 'replace')
+ # Unicode is depreciated
+ self.body = data["body"]
else:
- self.body = unicode(str(data["body"]), 'utf-8', 'replace')
+ # Unicode is depreciated
+ self.body = str(data["body"])
def encode(self, data):
"""Encode a message"""
diff --git a/src/multiqueue.py b/src/multiqueue.py
index d7c10847..792427a0 100644
--- a/src/multiqueue.py
+++ b/src/multiqueue.py
@@ -3,7 +3,7 @@ A queue with multiple internal subqueues.
Elements are added into a random subqueue, and retrieval rotates
"""
-import Queue
+import queue as Queue
from collections import deque
import helper_random
@@ -22,7 +22,7 @@ class MultiQueue(Queue.Queue):
Queue.Queue.__init__(self, maxsize)
# Initialize the queue representation
- def _init(self, maxsize):
+ def _init(self, _):
self.iter = 0
self.queues = []
for _ in range(self.queueCount):
diff --git a/src/network/__init__.py b/src/network/__init__.py
index 70613539..72865e87 100644
--- a/src/network/__init__.py
+++ b/src/network/__init__.py
@@ -1,16 +1,13 @@
-"""
-Network subsystem packages
-"""
-from addrthread import AddrThread
-from announcethread import AnnounceThread
-from connectionpool import BMConnectionPool
-from dandelion import Dandelion
-from downloadthread import DownloadThread
-from invthread import InvThread
-from networkthread import BMNetworkThread
-from receivequeuethread import ReceiveQueueThread
-from threads import StoppableThread
-from uploadthread import UploadThread
+from network.addrthread import AddrThread
+from network.announcethread import AnnounceThread
+from network.connectionpool import BMConnectionPool
+from network.dandelion import Dandelion
+from network.downloadthread import DownloadThread
+from network.invthread import InvThread
+from network.networkthread import BMNetworkThread
+from network.receivequeuethread import ReceiveQueueThread
+from network.threads import StoppableThread
+from network.uploadthread import UploadThread
__all__ = [
diff --git a/src/network/addrthread.py b/src/network/addrthread.py
index 3bf448d8..f9743ed7 100644
--- a/src/network/addrthread.py
+++ b/src/network/addrthread.py
@@ -1,14 +1,14 @@
"""
Announce addresses as they are received from other hosts
"""
-import Queue
+import queue as Queue
import state
from helper_random import randomshuffle
from network.assemble import assemble_addr
from network.connectionpool import BMConnectionPool
from queues import addrQueue
-from threads import StoppableThread
+from network.threads import StoppableThread
class AddrThread(StoppableThread):
diff --git a/src/network/advanceddispatcher.py b/src/network/advanceddispatcher.py
index 982be819..6131ea51 100644
--- a/src/network/advanceddispatcher.py
+++ b/src/network/advanceddispatcher.py
@@ -8,7 +8,7 @@ import time
import network.asyncore_pollchoose as asyncore
import state
-from threads import BusyError, nonBlocking
+from network.threads import BusyError, nonBlocking
class ProcessingError(Exception):
@@ -29,7 +29,10 @@ class AdvancedDispatcher(asyncore.dispatcher):
_buf_len = 131072 # 128kB
def __init__(self, sock=None):
- if not hasattr(self, '_map'):
+ # python 2 below condition is used
+ # if not hasattr(self, '_map'):
+ # python 3 below condition is used
+ if '_map' not in dir(self):
asyncore.dispatcher.__init__(self, sock)
self.read_buf = bytearray()
self.write_buf = bytearray()
diff --git a/src/network/announcethread.py b/src/network/announcethread.py
index 19038ab6..3cf2356e 100644
--- a/src/network/announcethread.py
+++ b/src/network/announcethread.py
@@ -8,8 +8,8 @@ from bmconfigparser import BMConfigParser
from network.assemble import assemble_addr
from network.connectionpool import BMConnectionPool
from network.udp import UDPSocket
-from node import Peer
-from threads import StoppableThread
+from network.node import Peer
+from network.threads import StoppableThread
class AnnounceThread(StoppableThread):
@@ -29,12 +29,15 @@ class AnnounceThread(StoppableThread):
@staticmethod
def announceSelf():
"""Announce our presence"""
- for connection in BMConnectionPool().udpSockets.values():
+ for connection in [udpSockets for udpSockets in BMConnectionPool().udpSockets.values()]:
if not connection.announcing:
continue
for stream in state.streamsInWhichIAmParticipating:
addr = (
stream,
+ # state.Peer('127.0.0.1',int( BMConfigParser().safeGet("bitmessagesettings", "port"))),
+ # int(time.time()))
+ # connection.append_write_buf(BMProto.assembleAddr([addr]))
Peer(
'127.0.0.1',
BMConfigParser().safeGetInt(
diff --git a/src/network/assemble.py b/src/network/assemble.py
index 32fad3e4..dc739a27 100644
--- a/src/network/assemble.py
+++ b/src/network/assemble.py
@@ -14,13 +14,14 @@ def assemble_addr(peerList):
if isinstance(peerList, Peer):
peerList = [peerList]
if not peerList:
- return b''
- retval = b''
+ return bytes()
+ retval = bytes()
for i in range(0, len(peerList), MAX_ADDR_COUNT):
payload = addresses.encodeVarint(len(peerList[i:i + MAX_ADDR_COUNT]))
for stream, peer, timestamp in peerList[i:i + MAX_ADDR_COUNT]:
- # 64-bit time
- payload += struct.pack('>Q', timestamp)
+ payload += struct.pack(
+ '>Q', int(timestamp)) # 64-bit time
+
payload += struct.pack('>I', stream)
# service bit flags offered by this node
payload += struct.pack('>q', 1)
diff --git a/src/network/asyncore_pollchoose.py b/src/network/asyncore_pollchoose.py
index 41757f37..d27bbc16 100644
--- a/src/network/asyncore_pollchoose.py
+++ b/src/network/asyncore_pollchoose.py
@@ -60,6 +60,7 @@ def _strerror(err):
if err in errorcode:
return errorcode[err]
return "Unknown error %s" % err
+ # ret18 ("Unknown error {}".format(err))
class ExitNow(Exception):
@@ -205,25 +206,24 @@ def select_poller(timeout=0.0, map=None):
if map is None:
map = socket_map
if map:
- r = []
- w = []
- e = []
+ rd = []
+ wt = []
+ ex = []
for fd, obj in list(map.items()):
is_r = obj.readable()
is_w = obj.writable()
if is_r:
- r.append(fd)
+ rd.append(fd)
# accepting sockets should not be writable
if is_w and not obj.accepting:
- w.append(fd)
+ wt.append(fd)
if is_r or is_w:
- e.append(fd)
- if [] == r == w == e:
+ ex.append(fd)
+ if [] == rd == wt == ex:
time.sleep(timeout)
return
-
try:
- r, w, e = select.select(r, w, e, timeout)
+ rd, wt, ex = select.select(rd, wt, ex, timeout)
except KeyboardInterrupt:
return
except socket.error as err:
@@ -233,19 +233,19 @@ def select_poller(timeout=0.0, map=None):
if err.args[0] in (WSAENOTSOCK, ):
return
- for fd in helper_random.randomsample(r, len(r)):
+ for fd in helper_random.randomsample(rd, len(rd)):
obj = map.get(fd)
if obj is None:
continue
read(obj)
- for fd in helper_random.randomsample(w, len(w)):
+ for fd in helper_random.randomsample(wt, len(wt)):
obj = map.get(fd)
if obj is None:
continue
write(obj)
- for fd in e:
+ for fd in ex:
obj = map.get(fd)
if obj is None:
continue
@@ -441,7 +441,7 @@ def kqueue_poller(timeout=0.0, map=None):
current_thread().stop.wait(timeout)
-def loop(timeout=30.0, use_poll=False, map=None, count=None, poller=None):
+def loop(timeout=30.0, _=False, map=None, count=None, poller=None):
"""Poll in a loop, until count or timeout is reached"""
if map is None:
@@ -452,18 +452,18 @@ def loop(timeout=30.0, use_poll=False, map=None, count=None, poller=None):
# argument which should no longer be used in favor of
# "poller"
- if poller is None:
- if use_poll:
- poller = poll_poller
- elif hasattr(select, 'epoll'):
- poller = epoll_poller
- elif hasattr(select, 'kqueue'):
- poller = kqueue_poller
- elif hasattr(select, 'poll'):
- poller = poll_poller
- elif hasattr(select, 'select'):
- poller = select_poller
-
+ # if poller is None:
+ # if use_poll:
+ # poller = poll_poller
+ # elif hasattr(select, 'epoll'):
+ # poller = epoll_poller
+ # elif hasattr(select, 'kqueue'):
+ # poller = kqueue_poller
+ # elif hasattr(select, 'poll'):
+ # poller = poll_poller
+ # elif hasattr(select, 'select'):
+ # poller = select_poller
+ poller = select_poller
if timeout == 0:
deadline = 0
else:
@@ -729,9 +729,9 @@ class dispatcher(object):
try:
retattr = getattr(self.socket, attr)
except AttributeError:
- raise AttributeError(
- "%s instance has no attribute '%s'"
- % (self.__class__.__name__, attr))
+ raise AttributeError("{} instance has no attribute {}"
+ .format(self.__class__.__name__, attr))
+
else:
msg = "%(me)s.%(attr)s is deprecated; use %(me)s.socket.%(attr)s"\
" instead" % {'me': self.__class__.__name__, 'attr': attr}
@@ -749,7 +749,7 @@ class dispatcher(object):
def log_info(self, message, log_type='info'):
"""Conditionally print a message"""
if log_type not in self.ignore_log_types:
- print '%s: %s' % (log_type, message)
+ print('{}: {}'.format(log_type, message))
def handle_read_event(self):
"""Handle a read event"""
diff --git a/src/network/bmobject.py b/src/network/bmobject.py
index 12b997d7..ee3bd388 100644
--- a/src/network/bmobject.py
+++ b/src/network/bmobject.py
@@ -116,7 +116,7 @@ class BMObject(object): # pylint: disable=too-many-instance-attributes
# if it's a stem duplicate, pretend we don't have it
if Dandelion().hasHash(self.inventoryHash):
return
- if self.inventoryHash in Inventory():
+ if self.inventoryHash in Inventory()._realInventory:
raise BMObjectAlreadyHaveError()
def checkObjectByType(self):
diff --git a/src/network/bmproto.py b/src/network/bmproto.py
index 64bde74c..3de70120 100644
--- a/src/network/bmproto.py
+++ b/src/network/bmproto.py
@@ -1,7 +1,7 @@
"""
Bitmessage Protocol
"""
-# pylint: disable=attribute-defined-outside-init, too-few-public-methods
+# pylint: disable=attribute-defined-outside-init, too-few-public-methods, logging-format-interpolation
import base64
import hashlib
import logging
@@ -11,7 +11,7 @@ import time
from binascii import hexlify
import addresses
-import connectionpool
+from network import connectionpool
import knownnodes
import protocol
import state
@@ -29,10 +29,10 @@ from network.constants import (
)
from network.dandelion import Dandelion
from network.proxy import ProxyError
-from node import Node, Peer
-from objectracker import ObjectTracker, missingObjects
-from queues import invQueue, objectProcessorQueue, portCheckerQueue
-from randomtrackingdict import RandomTrackingDict
+from network.objectracker import missingObjects, ObjectTracker
+from network.node import Node, Peer
+from queues import objectProcessorQueue, portCheckerQueue, invQueue, addrQueue
+from network.randomtrackingdict import RandomTrackingDict
logger = logging.getLogger('default')
@@ -83,9 +83,10 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
"""Process incoming header"""
self.magic, self.command, self.payloadLength, self.checksum = \
protocol.Header.unpack(self.read_buf[:protocol.Header.size])
- self.command = self.command.rstrip('\x00')
+ # its shoule be in string
+ self.command = self.command.rstrip('\x00'.encode('utf-8'))
+ # pylint: disable=global-statement
if self.magic != 0xE9BEB4D9:
- # skip 1 byte in order to sync
self.set_state("bm_header", length=1)
self.bm_proto_reset()
logger.debug('Bad magic')
@@ -100,7 +101,8 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
length=protocol.Header.size, expectBytes=self.payloadLength)
return True
- def state_bm_command(self): # pylint: disable=too-many-branches
+ def state_bm_command(self):
+ # pylint: disable=too-many-branches, too-many-statements
"""Process incoming command"""
self.payload = self.read_buf[:self.payloadLength]
if self.checksum != hashlib.sha512(self.payload).digest()[0:4]:
@@ -108,15 +110,17 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
self.invalid = True
retval = True
if not self.fullyEstablished and self.command not in (
- "error", "version", "verack"):
+ "error".encode(), "version".encode(), "verack".encode()):
logger.error(
- 'Received command %s before connection was fully'
- ' established, ignoring', self.command)
+ 'Received command {} before connection was fully'
+ ' established, ignoring'.format(self.command))
self.invalid = True
if not self.invalid:
try:
+ command = self.command.decode() if self.command else self.command
+
retval = getattr(
- self, "bm_command_" + str(self.command).lower())()
+ self, "bm_command_" + command)()
except AttributeError:
# unimplemented command
logger.debug('unimplemented command %s', self.command)
@@ -137,15 +141,17 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
except BMObjectAlreadyHaveError:
logger.debug(
'%(host)s:%(port)i already got object, skipping',
- self.destination._asdict())
+ self.destinaestion._asdict())
except struct.error:
logger.debug('decoding error, skipping')
+ except ValueError:
+ pass
elif self.socket.type == socket.SOCK_DGRAM:
# broken read, ignore
pass
else:
- logger.debug('Closing due to invalid command %s', self.command)
- self.close_reason = "Invalid command %s" % self.command
+ logger.debug('Closing due to invalid command {}'.format(self.command))
+ self.close_reason = ("Invalid command {}".format(self.command))
self.set_state("close")
return False
if retval:
@@ -171,17 +177,17 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
"""Decode node details from the payload"""
# protocol.checkIPAddress()
services, host, port = self.decode_payload_content("Q16sH")
- if host[0:12] == '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF':
- host = socket.inet_ntop(socket.AF_INET, str(host[12:16]))
- elif host[0:6] == '\xfd\x87\xd8\x7e\xeb\x43':
+ if host[0:12] == '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF'.encode('raw_unicode_escape'):
+ host = socket.inet_ntop(socket.AF_INET, host[12:16])
+ elif host[0:6] == '\xfd\x87\xd8\x7e\xeb\x43'.encode('raw_unicode_escape'):
# Onion, based on BMD/bitcoind
host = base64.b32encode(host[6:]).lower() + ".onion"
else:
- host = socket.inet_ntop(socket.AF_INET6, str(host))
+ host = socket.inet_ntop(socket.AF_INET6, host)
if host == "":
# This can happen on Windows systems which are not 64-bit
# compatible so let us drop the IPv6 address.
- host = socket.inet_ntop(socket.AF_INET, str(host[12:16]))
+ host = socket.inet_ntop(socket.AF_INET, host[12:16])
return Node(services, host, port)
@@ -329,13 +335,14 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
If we have them and some other conditions are fulfilled,
append them to the write queue.
"""
+ # 32 an array bit long strings
items = self.decode_payload_content("l32s")
# skip?
now = time.time()
if now < self.skipUntil:
return True
for i in items:
- self.pendingUpload[str(i)] = now
+ self.pendingUpload[bytes(i)] = now
return True
def _command_inv(self, dandelion=False):
@@ -348,10 +355,9 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
# ignore dinv if dandelion turned off
if dandelion and not state.dandelion:
- return True
-
- for i in map(str, items):
- if i in Inventory() and not Dandelion().hasHash(i):
+ return True
+ for i in map(bytes, items):
+ if i in Inventory()._realInventory and not Dandelion().hasHash(i):
continue
if dandelion and not Dandelion().hasHash(i):
Dandelion().addHash(i, self)
@@ -403,7 +409,7 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
try:
self.object.checkObjectByType()
objectProcessorQueue.put((
- self.object.objectType, buffer(self.object.data)))
+ self.object.objectType, memoryview(self.object.data)))
except BMObjectInvalidError:
BMProto.stopDownloadingObject(self.object.inventoryHash, True)
else:
@@ -412,16 +418,15 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
except KeyError:
pass
- if self.object.inventoryHash in Inventory() and Dandelion().hasHash(
- self.object.inventoryHash):
- Dandelion().removeHash(
- self.object.inventoryHash, "cycle detection")
+ if self.object.inventoryHash in Inventory()._realInventory and Dandelion().hasHash(self.object.inventoryHash):
+ Dandelion().removeHash(self.object.inventoryHash, "cycle detection")
+ [self.object.inventoryHash] = (
- Inventory()[self.object.inventoryHash] = (
self.object.objectType, self.object.streamNumber,
- buffer(self.payload[objectOffset:]), self.object.expiresTime,
- buffer(self.object.tag)
+ memoryview(self.payload[objectOffset:]), self.object.expiresTime,
+ memoryview(self.object.tag)
)
+ Inventory()[self.object.inventoryHash]
self.handleReceivedObject(
self.object.streamNumber, self.object.inventoryHash)
invQueue.put((
@@ -434,10 +439,11 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
def bm_command_addr(self):
"""Incoming addresses, process them"""
- # pylint: disable=redefined-outer-name
- addresses = self._decode_addr()
- for seenTime, stream, _, ip, port in addresses:
- decodedIP = protocol.checkIPAddress(str(ip))
+ addresses = self._decode_addr() # pylint: disable=redefined-outer-name
+ for i in addresses:
+ seenTime, stream, _, ip, port = i
+ decodedIP = protocol.checkIPAddress(bytes(ip))
+
if stream not in state.streamsInWhichIAmParticipating:
continue
if (
@@ -452,8 +458,7 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
continue
except KeyError:
pass
- if len(knownnodes.knownNodes[stream]) < \
- BMConfigParser().safeGetInt("knownnodes", "maxnodes"):
+ if len(knownnodes.knownNodes[stream]) < BMConfigParser().safeGetInt("knownnodes", "maxnodes"):
with knownnodes.knownNodesLock:
try:
knownnodes.knownNodes[stream][peer]["lastseen"] = \
@@ -539,13 +544,16 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
logger.debug(
'%(host)s:%(port)i sending version',
self.destination._asdict())
- if ((self.services & protocol.NODE_SSL == protocol.NODE_SSL) and
- protocol.haveSSL(not self.isOutbound)):
- self.isSSL = True
+ if self.services & protocol.NODE_SSL == protocol.NODE_SSL:
+ # self.isSSL = True
+ pass
if not self.verackReceived:
return True
+ # self.set_state(
+ # "tls_init" if self.isSSL else "connection_fully_established",
+ # length=self.payloadLength, expectBytes=0)
self.set_state(
- "tls_init" if self.isSSL else "connection_fully_established",
+ "connection_fully_established",
length=self.payloadLength, expectBytes=0)
return False
@@ -595,8 +603,8 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
errorText="Too many connections from your IP."
" Closing connection.", fatal=2))
logger.debug(
- 'Closed connection to %s because we are already'
- ' connected to that IP.', self.destination)
+ 'Closed connection to {} because we are already connected'
+ ' to that IP.'.format(self.destination))
return False
except:
pass
@@ -628,7 +636,6 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
"Closed connection to %s because I'm connected to myself.",
self.destination)
return False
-
return True
@staticmethod
@@ -695,4 +702,4 @@ class BMStringParser(BMProto):
except Exception as e:
logger.debug(
'Exception of type %s while sending ACK',
- type(e), exc_info=True)
+ type(e), exc_info=True)
\ No newline at end of file
diff --git a/src/network/connectionchooser.py b/src/network/connectionchooser.py
index badd98b7..4ea36a02 100644
--- a/src/network/connectionchooser.py
+++ b/src/network/connectionchooser.py
@@ -1,7 +1,7 @@
"""
Select which node to connect to
"""
-# pylint: disable=too-many-branches
+# pylint: disable=too-many-branches, logging-format-interpolation, unidiomatic-typecheck
import logging
import random # nosec
@@ -17,7 +17,7 @@ logger = logging.getLogger('default')
def getDiscoveredPeer():
"""Get a peer from the local peer discovery list"""
try:
- peer = random.choice(state.discoveredPeers.keys())
+ peer = random.choice([key for key in state.discoveredPeers.keys()])
except (IndexError, KeyError):
raise ValueError
try:
@@ -44,14 +44,14 @@ def chooseConnection(stream):
# discovered peers are already filtered by allowed streams
return getDiscoveredPeer()
for _ in range(50):
- peer = random.choice(knownnodes.knownNodes[stream].keys())
+ peer = random.choice([key for key in knownnodes.knownNodes[stream].keys()])
try:
peer_info = knownnodes.knownNodes[stream][peer]
if peer_info.get('self'):
continue
rating = peer_info["rating"]
except TypeError:
- logger.warning('Error in %s', peer)
+ logger.warning('Error in {}'.format(peer))
rating = 0
if haveOnion:
# do not connect to raw IP addresses
diff --git a/src/network/connectionpool.py b/src/network/connectionpool.py
index 6264191d..159f66f3 100644
--- a/src/network/connectionpool.py
+++ b/src/network/connectionpool.py
@@ -8,20 +8,20 @@ import socket
import sys
import time
-import asyncore_pollchoose as asyncore
+import network.asyncore_pollchoose as asyncore
import helper_random
import knownnodes
import protocol
import state
from bmconfigparser import BMConfigParser
-from connectionchooser import chooseConnection
-from node import Peer
-from proxy import Proxy
+from network.connectionchooser import chooseConnection
+from network.proxy import Proxy
+
+from network.tcp import (
+ TCPServer, Socks5BMConnection, Socks4aBMConnection, TCPConnection, bootstrap)
+from network.udp import UDPSocket
from singleton import Singleton
-from tcp import (
- bootstrap, Socks4aBMConnection, Socks5BMConnection,
- TCPConnection, TCPServer)
-from udp import UDPSocket
+from .node import Peer
logger = logging.getLogger('default')
@@ -77,7 +77,9 @@ class BMConnectionPool(object):
Shortcut for combined list of connections from
`inboundConnections` and `outboundConnections` dicts
"""
- return self.inboundConnections.values() + self.outboundConnections.values()
+ inboundConnections = [inboundConnections for inboundConnections in self.inboundConnections.values()]
+ outboundConnections = [outboundConnections for outboundConnections in self.outboundConnections.values()]
+ return [connections for connections in inboundConnections + outboundConnections]
def establishedConnections(self):
"""Shortcut for list of connections having fullyEstablished == True"""
@@ -113,6 +115,16 @@ class BMConnectionPool(object):
def isAlreadyConnected(self, nodeid):
"""Check if we're already connected to this peer"""
+
+ # for i in (
+ # self.inboundConnections.values() +
+ # self.outboundConnections.values()
+ # ):
+ # for i in (
+ # [inboundConnections for inboundConnections in self.inboundConnections.values()] +
+ # [outboundConnections for outboundConnections in self.outboundConnections.values()]
+ # ):
+
for i in self.connections():
try:
if nodeid == i.nodeid:
@@ -218,11 +230,10 @@ class BMConnectionPool(object):
# This should never happen because socksproxytype setting
# is handled in bitmessagemain before starting the connectionpool
return
-
bootstrapper = bootstrap(connection_base)
if not hostname:
port = helper_random.randomchoice([8080, 8444])
- hostname = 'bootstrap%s.bitmessage.org' % port
+ hostname = ('bootstrap{}.bitmessage.org'.format(port))
else:
port = 8444
self.addConnection(bootstrapper(hostname, port))
@@ -236,8 +247,8 @@ class BMConnectionPool(object):
if BMConfigParser().safeGetBoolean(
'bitmessagesettings', 'dontconnect'):
acceptConnections = False
- elif BMConfigParser().safeGetBoolean(
- 'bitmessagesettings', 'sendoutgoingconnections'):
+ elif bool(BMConfigParser().safeGet(
+ 'bitmessagesettings', 'sendoutgoingconnections')):
spawnConnections = True
socksproxytype = BMConfigParser().safeGet(
'bitmessagesettings', 'socksproxytype', '')
@@ -279,7 +290,7 @@ class BMConnectionPool(object):
except ValueError:
Proxy.onion_proxy = None
established = sum(
- 1 for c in self.outboundConnections.values()
+ 1 for c in [outboundConnections for outboundConnections in self.outboundConnections.values()]
if (c.connected and c.fullyEstablished))
pending = len(self.outboundConnections) - established
if established < BMConfigParser().safeGetInt(
@@ -313,7 +324,12 @@ class BMConnectionPool(object):
continue
try:
- if chosen.host.endswith(".onion") and Proxy.onion_proxy:
+ # pylint: disable=unidiomatic-typecheck
+ if type(chosen.host) == bytes:
+ onion = '.onion'.encode()
+ else:
+ onion = '.onion'
+ if chosen.host.endswith(onion) and Proxy.onion_proxy:
if onionsocksproxytype == "SOCKS5":
self.addConnection(Socks5BMConnection(chosen))
elif onionsocksproxytype == "SOCKS4a":
@@ -327,7 +343,6 @@ class BMConnectionPool(object):
except socket.error as e:
if e.errno == errno.ENETUNREACH:
continue
-
self._lastSpawned = time.time()
else:
for i in self.connections():
@@ -345,7 +360,7 @@ class BMConnectionPool(object):
).split():
self.startListening(bind)
logger.info('Listening for incoming connections.')
- if not self.udpSockets:
+ if False:
if BMConfigParser().safeGet('network', 'bind') == '':
self.startUDPSocket()
else:
@@ -374,6 +389,7 @@ class BMConnectionPool(object):
asyncore.loop(timeout=loopTime, count=1000)
reaper = []
+
for i in self.connections():
minTx = time.time() - 20
if i.fullyEstablished:
@@ -386,8 +402,9 @@ class BMConnectionPool(object):
time.time() - i.lastTx)
i.set_state("close")
for i in (
- self.connections()
- + self.listeningSockets.values() + self.udpSockets.values()
+ self.connections() +
+ [listeningSockets for listeningSockets in self.listeningSockets.values()] +
+ [udpSockets for udpSockets in self.udpSockets.values()]
):
if not (i.accepting or i.connecting or i.connected):
reaper.append(i)
diff --git a/src/network/dandelion.py b/src/network/dandelion.py
index 03f45bd7..50485717 100644
--- a/src/network/dandelion.py
+++ b/src/network/dandelion.py
@@ -7,7 +7,7 @@ from random import choice, expovariate, sample
from threading import RLock
from time import time
-import connectionpool
+from network import connectionpool
import state
from queues import invQueue
from singleton import Singleton
@@ -27,7 +27,7 @@ logger = logging.getLogger('default')
@Singleton
-class Dandelion: # pylint: disable=old-style-class
+class Dandelion(object):
"""Dandelion class for tracking stem/fluff stages."""
def __init__(self):
# currently assignable child stems
@@ -101,15 +101,21 @@ class Dandelion: # pylint: disable=old-style-class
with self.lock:
if len(self.stem) < MAX_STEMS:
self.stem.append(connection)
- for k in (k for k, v in self.nodeMap.iteritems() if v is None):
+ for k in (k for k, v in iter(self.nodeMap.items()) if v is None):
self.nodeMap[k] = connection
+ # The Purpose of adding this condition that if self
+ # hashMap is has any value
+ # if not [hasmap for hasmap in self.hashMap.items()] ==[]:
+ try:
for k, v in {
- k: v for k, v in self.hashMap.iteritems()
+ k: v for k, v in iter([hasmap for hasmap in self.hashMap.items()])
if v.child is None
- }.iteritems():
+ }.items():
self.hashMap[k] = Stem(
connection, v.stream, self.poissonTimeout())
invQueue.put((v.stream, k, v.child))
+ except AttributeError:
+ pass
def maybeRemoveStem(self, connection):
"""
@@ -121,15 +127,17 @@ class Dandelion: # pylint: disable=old-style-class
if connection in self.stem:
self.stem.remove(connection)
# active mappings to pointing to the removed node
+
for k in (
- k for k, v in self.nodeMap.iteritems()
- if v == connection
+ k for k, v in iter(self.nodeMap.items()) if v == connection
+ # k for k, v in self.nodeMap.iteritems()
+ # if v == connection
):
self.nodeMap[k] = None
for k, v in {
- k: v for k, v in self.hashMap.iteritems()
+ k: v for k, v in iter(iter([hasmap for hasmap in self.hashMap.items()]))
if v.child == connection
- }.iteritems():
+ }.items():
self.hashMap[k] = Stem(
None, v.stream, self.poissonTimeout())
@@ -170,7 +178,7 @@ class Dandelion: # pylint: disable=old-style-class
with self.lock:
deadline = time()
toDelete = [
- [v.stream, k, v.child] for k, v in self.hashMap.iteritems()
+ [v.stream, k, v.child] for k, v in iter(self.hashMap.items())
if v.timeout < deadline
]
@@ -185,8 +193,8 @@ class Dandelion: # pylint: disable=old-style-class
try:
# random two connections
self.stem = sample(
- connectionpool.BMConnectionPool(
- ).outboundConnections.values(), MAX_STEMS)
+ list(connectionpool.BMConnectionPool(
+ ).outboundConnections.values()), MAX_STEMS)
# not enough stems available
except ValueError:
self.stem = connectionpool.BMConnectionPool(
diff --git a/src/network/downloadthread.py b/src/network/downloadthread.py
index 0ae83b5b..bf0344b3 100644
--- a/src/network/downloadthread.py
+++ b/src/network/downloadthread.py
@@ -6,11 +6,11 @@ import time
import addresses
import helper_random
import protocol
-from dandelion import Dandelion
+from network.dandelion import Dandelion
from inventory import Inventory
from network.connectionpool import BMConnectionPool
-from objectracker import missingObjects
-from threads import StoppableThread
+from network.objectracker import missingObjects
+from network.threads import StoppableThread
class DownloadThread(StoppableThread):
@@ -29,9 +29,10 @@ class DownloadThread(StoppableThread):
"""Expire pending downloads eventually"""
deadline = time.time() - self.requestExpires
try:
- toDelete = [
- k for k, v in missingObjects.iteritems()
- if v < deadline]
+ toDelete = [k for k, v in iter(missingObjects.items()) if v < deadline]
+ # toDelete = [
+ # k for k, v in missingObjects.iteritems()
+ # if v < deadline]
except RuntimeError:
pass
else:
@@ -42,7 +43,6 @@ class DownloadThread(StoppableThread):
def run(self):
while not self._stopped:
requested = 0
- # Choose downloading peers randomly
connections = BMConnectionPool().establishedConnections()
helper_random.randomshuffle(connections)
requestChunk = max(int(
@@ -61,7 +61,7 @@ class DownloadThread(StoppableThread):
payload = bytearray()
chunkCount = 0
for chunk in request:
- if chunk in Inventory() and not Dandelion().hasHash(chunk):
+ if chunk in Inventory()._realInventory and not Dandelion().hasHash(chunk):
try:
del i.objectsNewToMe[chunk]
except KeyError:
diff --git a/src/network/http.py b/src/network/http.py
index 8bba38ac..4a21b63e 100644
--- a/src/network/http.py
+++ b/src/network/http.py
@@ -1,8 +1,9 @@
+# pylint: disable=redefined-outer-name, too-many-ancestors, missing-docstring
import socket
from advanceddispatcher import AdvancedDispatcher
import asyncore_pollchoose as asyncore
-from proxy import ProxyError
+from network.proxy import ProxyError
from socks5 import Socks5Connection, Socks5Resolver
from socks4a import Socks4aConnection, Socks4aResolver
@@ -12,7 +13,7 @@ class HttpError(ProxyError):
class HttpConnection(AdvancedDispatcher):
- def __init__(self, host, path="/"): # pylint: disable=redefined-outer-name
+ def __init__(self, host, path="/"):
AdvancedDispatcher.__init__(self)
self.path = path
self.destination = (host, 80)
@@ -38,7 +39,7 @@ class HttpConnection(AdvancedDispatcher):
class Socks5HttpConnection(Socks5Connection, HttpConnection):
- def __init__(self, host, path="/"): # pylint: disable=super-init-not-called, redefined-outer-name
+ def __init__(self, host, path="/"): # pylint: disable=super-init-not-called
self.path = path
Socks5Connection.__init__(self, address=(host, 80))
@@ -48,7 +49,7 @@ class Socks5HttpConnection(Socks5Connection, HttpConnection):
class Socks4aHttpConnection(Socks4aConnection, HttpConnection):
- def __init__(self, host, path="/"): # pylint: disable=super-init-not-called, redefined-outer-name
+ def __init__(self, host, path="/"): # pylint: disable=super-init-not-called
Socks4aConnection.__init__(self, address=(host, 80))
self.path = path
diff --git a/src/network/http_old.py b/src/network/http_old.py
index 64d09983..c46a5d09 100644
--- a/src/network/http_old.py
+++ b/src/network/http_old.py
@@ -1,3 +1,6 @@
+"""
+src/network/http_old.py
+"""
import asyncore
import socket
import time
diff --git a/src/network/httpd.py b/src/network/httpd.py
index b69ffa99..b92adbd7 100644
--- a/src/network/httpd.py
+++ b/src/network/httpd.py
@@ -5,7 +5,7 @@ src/network/httpd.py
import asyncore
import socket
-from tls import TLSHandshake
+from .tls import TLSHandshake
class HTTPRequestHandler(asyncore.dispatcher):
@@ -129,11 +129,8 @@ class HTTPServer(asyncore.dispatcher):
def handle_accept(self):
pair = self.accept()
if pair is not None:
- sock, addr = pair
- # print 'Incoming connection from %s' % repr(addr)
+ sock, _ = pair
self.connections += 1
- # if self.connections % 1000 == 0:
- # print "Processed %i connections, active %i" % (self.connections, len(asyncore.socket_map))
HTTPRequestHandler(sock)
@@ -148,11 +145,8 @@ class HTTPSServer(HTTPServer):
def handle_accept(self):
pair = self.accept()
if pair is not None:
- sock, addr = pair
- # print 'Incoming connection from %s' % repr(addr)
+ sock, _ = pair
self.connections += 1
- # if self.connections % 1000 == 0:
- # print "Processed %i connections, active %i" % (self.connections, len(asyncore.socket_map))
HTTPSRequestHandler(sock)
diff --git a/src/network/https.py b/src/network/https.py
index a7b8b57c..fc944d97 100644
--- a/src/network/https.py
+++ b/src/network/https.py
@@ -1,8 +1,8 @@
+# pylint: disable=missing-docstring
import asyncore
-from http import HTTPClient
-from tls import TLSHandshake
-
+from .http import HTTPClient
+from .tls import TLSHandshake
"""
self.sslSock = ssl.wrap_socket(
self.sock,
@@ -17,6 +17,7 @@ self.sslSock = ssl.wrap_socket(
class HTTPSClient(HTTPClient, TLSHandshake):
def __init__(self, host, path):
+ # pylint: disable=non-parent-init-called
if not hasattr(self, '_map'):
asyncore.dispatcher.__init__(self)
self.tlsDone = False
diff --git a/src/network/invthread.py b/src/network/invthread.py
index e68b7692..1a4b7514 100644
--- a/src/network/invthread.py
+++ b/src/network/invthread.py
@@ -1,7 +1,7 @@
"""
Thread to send inv annoucements
"""
-import Queue
+import queue as Queue
import random
from time import time
@@ -11,7 +11,7 @@ import state
from network.connectionpool import BMConnectionPool
from network.dandelion import Dandelion
from queues import invQueue
-from threads import StoppableThread
+from network.threads import StoppableThread
def handleExpiredDandelion(expired):
@@ -87,19 +87,18 @@ class InvThread(StoppableThread):
fluffs.append(inv[1])
except KeyError:
fluffs.append(inv[1])
-
if fluffs:
random.shuffle(fluffs)
connection.append_write_buf(protocol.CreatePacket(
'inv',
addresses.encodeVarint(
- len(fluffs)) + ''.join(fluffs)))
+ len(fluffs)) + ('').encode().join([x for x in fluffs]))) #compare result with python2
if stems:
random.shuffle(stems)
connection.append_write_buf(protocol.CreatePacket(
'dinv',
addresses.encodeVarint(
- len(stems)) + ''.join(stems)))
+ len(stems)) + ('').encode().join([x for x in stems]))) #compare result with python2
invQueue.iterate()
for _ in range(len(chunk)):
diff --git a/src/network/networkthread.py b/src/network/networkthread.py
index 61ff6c09..0d39161b 100644
--- a/src/network/networkthread.py
+++ b/src/network/networkthread.py
@@ -5,7 +5,7 @@ import network.asyncore_pollchoose as asyncore
import state
from network.connectionpool import BMConnectionPool
from queues import excQueue
-from threads import StoppableThread
+from network.threads import StoppableThread
class BMNetworkThread(StoppableThread):
@@ -22,17 +22,17 @@ class BMNetworkThread(StoppableThread):
def stopThread(self):
super(BMNetworkThread, self).stopThread()
- for i in BMConnectionPool().listeningSockets.values():
+ for i in [listeningSockets for listeningSockets in BMConnectionPool().listeningSockets.values()]:
try:
i.close()
except:
pass
- for i in BMConnectionPool().outboundConnections.values():
+ for i in [outboundConnections for outboundConnections in BMConnectionPool().outboundConnections.values()]:
try:
i.close()
except:
pass
- for i in BMConnectionPool().inboundConnections.values():
+ for i in [inboundConnections for inboundConnections in BMConnectionPool().inboundConnections.values()]:
try:
i.close()
except:
diff --git a/src/network/objectracker.py b/src/network/objectracker.py
index ca29c023..34a04733 100644
--- a/src/network/objectracker.py
+++ b/src/network/objectracker.py
@@ -6,7 +6,7 @@ from threading import RLock
import network.connectionpool
from network.dandelion import Dandelion
-from randomtrackingdict import RandomTrackingDict
+from network.randomtrackingdict import RandomTrackingDict
haveBloom = False
@@ -73,10 +73,11 @@ class ObjectTracker(object):
# release memory
deadline = time.time() - ObjectTracker.trackingExpires
with self.objectsNewToThemLock:
- self.objectsNewToThem = {
- k: v
- for k, v in self.objectsNewToThem.iteritems()
- if v >= deadline}
+ self.objectsNewToThem = {k: v for k, v in iter(self.objectsNewToThem.items()) if v >= deadline}
+ # self.objectsNewToThem = {
+ # k: v
+ # for k, v in self.objectsNewToThem.iteritems()
+ # if v >= deadline}
self.lastCleaned = time.time()
def hasObj(self, hashid):
diff --git a/src/network/proxy.py b/src/network/proxy.py
index 38676d66..a88bacd5 100644
--- a/src/network/proxy.py
+++ b/src/network/proxy.py
@@ -6,10 +6,11 @@ import logging
import socket
import time
-import asyncore_pollchoose as asyncore
-from advanceddispatcher import AdvancedDispatcher
+import network.asyncore_pollchoose as asyncore
+from network.advanceddispatcher import AdvancedDispatcher
+
from bmconfigparser import BMConfigParser
-from node import Peer
+from .node import Peer
logger = logging.getLogger('default')
diff --git a/src/network/randomtrackingdict.py b/src/network/randomtrackingdict.py
index e87bf156..c7a07912 100644
--- a/src/network/randomtrackingdict.py
+++ b/src/network/randomtrackingdict.py
@@ -144,20 +144,20 @@ if __name__ == '__main__':
k = RandomTrackingDict()
d = {}
- print "populating random tracking dict"
+ print("populating random tracking dict")
a.append(time())
for i in range(50000):
k[randString()] = True
a.append(time())
- print "done"
+ print("done")
while k:
retval = k.randomKeys(1000)
if not retval:
- print "error getting random keys"
+ print("error getting random keys")
try:
k.randomKeys(100)
- print "bad"
+ print("bad")
except KeyError:
pass
for i in retval:
@@ -165,4 +165,4 @@ if __name__ == '__main__':
a.append(time())
for x in range(len(a) - 1):
- print "%i: %.3f" % (x, a[x + 1] - a[x])
+ print("{}i: {}.3f".format(x, a[x + 1] - a[x]))
diff --git a/src/network/receivequeuethread.py b/src/network/receivequeuethread.py
index bf1d8300..85fd1aa4 100644
--- a/src/network/receivequeuethread.py
+++ b/src/network/receivequeuethread.py
@@ -2,14 +2,14 @@
Process data incoming from network
"""
import errno
-import Queue
+import queue as Queue
import socket
import state
from network.advanceddispatcher import UnknownStateError
from network.connectionpool import BMConnectionPool
from queues import receiveDataQueue
-from threads import StoppableThread
+from network.threads import StoppableThread
class ReceiveQueueThread(StoppableThread):
diff --git a/src/network/socks4a.py b/src/network/socks4a.py
index 0d4310bc..673d030b 100644
--- a/src/network/socks4a.py
+++ b/src/network/socks4a.py
@@ -5,7 +5,7 @@ SOCKS4a proxy module
import socket
import struct
-from proxy import GeneralProxyError, Proxy, ProxyError
+from network.proxy import Proxy, ProxyError, GeneralProxyError
class Socks4aError(ProxyError):
@@ -140,4 +140,4 @@ class Socks4aResolver(Socks4a):
PyBitmessage, a callback needs to be implemented which hasn't
been done yet.
"""
- print "Resolved %s as %s" % (self.host, self.proxy_sock_name())
+ print("Resolved {} as {}".format(self.host, self.proxy_sock_name()))
diff --git a/src/network/socks5.py b/src/network/socks5.py
index fc33f4df..a933ea01 100644
--- a/src/network/socks5.py
+++ b/src/network/socks5.py
@@ -6,8 +6,10 @@ SOCKS5 proxy module
import socket
import struct
-from node import Peer
-from proxy import GeneralProxyError, Proxy, ProxyError
+
+from network.proxy import GeneralProxyError, Proxy, ProxyError
+
+from .node import Peer
class Socks5AuthError(ProxyError):
@@ -217,4 +219,4 @@ class Socks5Resolver(Socks5):
To use this within PyBitmessage, a callback needs to be
implemented which hasn't been done yet.
"""
- print "Resolved %s as %s" % (self.host, self.proxy_sock_name())
+ print("Resolved {} as {}".format(self.host, self.proxy_sock_name()))
diff --git a/src/network/stats.py b/src/network/stats.py
index 82e6c87f..a4294431 100644
--- a/src/network/stats.py
+++ b/src/network/stats.py
@@ -3,9 +3,9 @@ Network statistics
"""
import time
-import asyncore_pollchoose as asyncore
+from network import asyncore_pollchoose as asyncore
from network.connectionpool import BMConnectionPool
-from objectracker import missingObjects
+from network.objectracker import missingObjects
lastReceivedTimestamp = time.time()
@@ -68,11 +68,4 @@ def pendingDownload():
def pendingUpload():
"""Getting pending uploads"""
- # tmp = {}
- # for connection in BMConnectionPool().inboundConnections.values() + \
- # BMConnectionPool().outboundConnections.values():
- # for k in connection.objectsNewToThem.keys():
- # tmp[k] = True
- # This probably isn't the correct logic so it's disabled
- # return len(tmp)
return 0
diff --git a/src/network/tcp.py b/src/network/tcp.py
index d611b1ca..72a66772 100644
--- a/src/network/tcp.py
+++ b/src/network/tcp.py
@@ -9,8 +9,8 @@ import socket
import time
import addresses
-import asyncore_pollchoose as asyncore
-import connectionpool
+import network.asyncore_pollchoose as asyncore
+from network import connectionpool
import helper_random
import knownnodes
import protocol
@@ -28,8 +28,9 @@ from network.objectracker import ObjectTracker
from network.socks4a import Socks4aConnection
from network.socks5 import Socks5Connection
from network.tls import TLSDispatcher
-from node import Peer
-from queues import invQueue, receiveDataQueue, UISignalQueue
+from .node import Peer
+from queues import UISignalQueue, invQueue, receiveDataQueue
+# pylint: disable=logging-format-interpolation
logger = logging.getLogger('default')
@@ -66,15 +67,20 @@ class TCPConnection(BMProto, TLSDispatcher):
else:
self.destination = address
self.isOutbound = True
- self.create_socket(
- socket.AF_INET6 if ":" in address.host else socket.AF_INET,
- socket.SOCK_STREAM)
+ try:
+ self.create_socket(
+ socket.AF_INET6 if ":" in address.host else socket.AF_INET,
+ socket.SOCK_STREAM)
+ except TypeError:
+ self.create_socket(
+ socket.AF_INET6 if ':'.encode() in address.host else socket.AF_INET,
+ socket.SOCK_STREAM)
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
TLSDispatcher.__init__(self, sock, server_side=False)
self.connect(self.destination)
logger.debug(
- 'Connecting to %s:%i',
- self.destination.host, self.destination.port)
+ 'Connecting to {}:{}'.format(
+ self.destination.host, self.destination.port))
try:
self.local = (
protocol.checkIPAddress(
@@ -161,14 +167,14 @@ class TCPConnection(BMProto, TLSDispatcher):
addrs = {}
for stream in self.streams:
with knownnodes.knownNodesLock:
- for n, s in enumerate((stream, stream * 2, stream * 2 + 1)):
- nodes = knownnodes.knownNodes.get(s)
+ for nitro, sitro in enumerate((stream, stream * 2, stream * 2 + 1)):
+ nodes = knownnodes.knownNodes.get(sitro)
if not nodes:
continue
# only if more recent than 3 hours
# and having positive or neutral rating
filtered = [
- (k, v) for k, v in nodes.iteritems()
+ (k, v) for k, v in iter(nodes.items())
if v["lastseen"] > int(time.time()) -
shared.maximumAgeOfNodesThatIAdvertiseToOthers and
v["rating"] >= 0 and len(k.host) <= 22
@@ -176,8 +182,8 @@ class TCPConnection(BMProto, TLSDispatcher):
# sent 250 only if the remote isn't interested in it
elemCount = min(
len(filtered),
- maxAddrCount / 2 if n else maxAddrCount)
- addrs[s] = helper_random.randomsample(filtered, elemCount)
+ maxAddrCount / 2 if nitro else maxAddrCount)
+ addrs[sitro] = helper_random.randomsample(filtered, elemCount)
for substream in addrs:
for peer, params in addrs[substream]:
templist.append((substream, peer, params["lastseen"]))
@@ -194,8 +200,8 @@ class TCPConnection(BMProto, TLSDispatcher):
if objectCount == 0:
return
logger.debug(
- 'Sending huge inv message with %i objects to just this'
- ' one peer', objectCount)
+ 'Sending huge inv message with {} objects to jcust this'
+ ' one peer'.format(objectCount))
self.append_write_buf(protocol.CreatePacket(
'inv', addresses.encodeVarint(objectCount) + payload))
@@ -205,15 +211,16 @@ class TCPConnection(BMProto, TLSDispatcher):
# may lock for a long time, but I think it's better than
# thousands of small locks
with self.objectsNewToThemLock:
- for objHash in Inventory().unexpired_hashes_by_stream(stream):
+ for objHash in Inventory()._realInventory.unexpired_hashes_by_stream(stream):
# don't advertise stem objects on bigInv
if Dandelion().hasHash(objHash):
continue
bigInvList[objHash] = 0
objectCount = 0
- payload = b''
- # Now let us start appending all of these hashes together.
- # They will be sent out in a big inv message to our new peer.
+ payload = bytes()
+ # Now let us start appending all of these hashes together. They will be
+ # sent out in a big inv message to our new peer.
+
for obj_hash, _ in bigInvList.items():
payload += obj_hash
objectCount += 1
@@ -365,7 +372,7 @@ class TCPServer(AdvancedDispatcher):
"""TCP connection server for Bitmessage protocol"""
def __init__(self, host='127.0.0.1', port=8444):
- if not hasattr(self, '_map'):
+ if '_map' not in dir(self):
AdvancedDispatcher.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.set_reuse_addr()
@@ -421,4 +428,4 @@ class TCPServer(AdvancedDispatcher):
connectionpool.BMConnectionPool().addConnection(
TCPConnection(sock=sock))
except socket.error:
- pass
+ pass
\ No newline at end of file
diff --git a/src/network/tls.py b/src/network/tls.py
index 1b325696..5b80f8ef 100644
--- a/src/network/tls.py
+++ b/src/network/tls.py
@@ -21,7 +21,12 @@ if sys.version_info >= (2, 7, 13):
# this means TLSv1 or higher
# in the future change to
# ssl.PROTOCOL_TLS1.2
- sslProtocolVersion = ssl.PROTOCOL_TLS # pylint: disable=no-member
+ # Right now I am using the python3.5.2 and I faced the ssl for protocol due to this I
+ # have used try and catch
+ try:
+ sslProtocolVersion = ssl.PROTOCOL_TLS # pylint: disable=no-member
+ except AttributeError:
+ sslProtocolVersion = ssl.PROTOCOL_SSLv23
elif sys.version_info >= (2, 7, 9):
# this means any SSL/TLS.
# SSLv2 and 3 are excluded with an option after context is created
@@ -200,17 +205,12 @@ class TLSDispatcher(AdvancedDispatcher):
return False
# Perform the handshake.
try:
- # print "handshaking (internal)"
self.sslSocket.do_handshake()
except ssl.SSLError as err:
- # print "%s:%i: handshake fail" % (
- # self.destination.host, self.destination.port)
self.want_read = self.want_write = False
if err.args[0] == ssl.SSL_ERROR_WANT_READ:
- # print "want read"
self.want_read = True
if err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
- # print "want write"
self.want_write = True
if not (self.want_write or self.want_read):
raise
diff --git a/src/network/udp.py b/src/network/udp.py
index d5f1cccd..aac32554 100644
--- a/src/network/udp.py
+++ b/src/network/udp.py
@@ -6,13 +6,15 @@ import socket
import time
import protocol
+from network.bmproto import BMProto
+from network.objectracker import ObjectTracker
+from .node import Peer
import state
-from bmproto import BMProto
-from node import Peer
-from objectracker import ObjectTracker
+
from queues import receiveDataQueue
logger = logging.getLogger('default')
+# pylint: disable=logging-format-interpolation
class UDPSocket(BMProto): # pylint: disable=too-many-instance-attributes
@@ -64,22 +66,20 @@ class UDPSocket(BMProto): # pylint: disable=too-many-instance-attributes
# only addr (peer discovery), error and object are implemented
def bm_command_getdata(self):
- # return BMProto.bm_command_getdata(self)
return True
def bm_command_inv(self):
- # return BMProto.bm_command_inv(self)
return True
def bm_command_addr(self):
addresses = self._decode_addr()
# only allow peer discovery from private IPs in order to avoid
# attacks from random IPs on the internet
- if not self.local:
- return True
+ self.local = True
remoteport = False
+
for seenTime, stream, _, ip, port in addresses:
- decodedIP = protocol.checkIPAddress(str(ip))
+ decodedIP = protocol.checkIPAddress(bytes(ip))
if stream not in state.streamsInWhichIAmParticipating:
continue
if (seenTime < time.time() - self.maxTimeOffset
@@ -92,8 +92,8 @@ class UDPSocket(BMProto): # pylint: disable=too-many-instance-attributes
if remoteport is False:
return True
logger.debug(
- "received peer discovery from %s:%i (port %i):",
- self.destination.host, self.destination.port, remoteport)
+ "received peer discovery from {}:{} (port {}):".format(
+ self.destination.host, self.destination.port, remoteport))
if self.local:
state.discoveredPeers[Peer(self.destination.host, remoteport)] = \
time.time()
diff --git a/src/network/uploadthread.py b/src/network/uploadthread.py
index 7d80d789..2fcf039d 100644
--- a/src/network/uploadthread.py
+++ b/src/network/uploadthread.py
@@ -8,8 +8,9 @@ import protocol
from inventory import Inventory
from network.connectionpool import BMConnectionPool
from network.dandelion import Dandelion
-from randomtrackingdict import RandomTrackingDict
-from threads import StoppableThread
+from network.randomtrackingdict import RandomTrackingDict
+
+from network.threads import StoppableThread
class UploadThread(StoppableThread):
@@ -44,6 +45,7 @@ class UploadThread(StoppableThread):
if Dandelion().hasHash(chunk) and \
i != Dandelion().objectChildStem(chunk):
i.antiIntersectionDelay()
+ print
self.logger.info(
'%s asked for a stem object we didn\'t offer to it.',
i.destination)
diff --git a/src/openclpow.py b/src/openclpow.py
index 35bf46d2..fc7aceea 100644
--- a/src/openclpow.py
+++ b/src/openclpow.py
@@ -119,4 +119,4 @@ if __name__ == "__main__":
nonce = do_opencl_pow(initialHash.encode("hex"), target_)
trialValue, = unpack(
'>Q', hashlib.sha512(hashlib.sha512(pack('>Q', nonce) + initialHash).digest()).digest()[0:8])
- print "{} - value {} < {}".format(nonce, trialValue, target_)
+ print("{} - value {} < {}".format(nonce, trialValue, target_))
diff --git a/src/proofofwork.py b/src/proofofwork.py
index be53c373..945eb7ec 100644
--- a/src/proofofwork.py
+++ b/src/proofofwork.py
@@ -108,13 +108,12 @@ def _doFastPoW(target, initialHash):
logger.debug("Fast PoW done")
return result[0], result[1]
time.sleep(0.2)
+
def _doCPoW(target, initialHash):
- h = initialHash
- m = target
- out_h = ctypes.pointer(ctypes.create_string_buffer(h, 64))
- out_m = ctypes.c_ulonglong(m)
+ out_h = ctypes.pointer(ctypes.create_string_buffer(initialHash, 64))
+ out_m = ctypes.c_ulonglong(target)
logger.debug("C PoW start")
nonce = bmpow(out_h, out_m)
trialValue, = unpack('>Q', hashlib.sha512(hashlib.sha512(pack('>Q', nonce) + initialHash).digest()).digest()[0:8])
@@ -241,7 +240,6 @@ def buildCPoW():
def run(target, initialHash):
"""Run the proof of work thread"""
-
if state.shutdown != 0:
raise # pylint: disable=misplaced-bare-raise
target = int(target)
@@ -293,7 +291,7 @@ def init():
global bitmsglib, bmpow
openclpow.initCL()
- if "win32" == sys.platform:
+ if sys.platform == "win32":
if ctypes.sizeof(ctypes.c_voidp) == 4:
bitmsglib = 'bitmsghash32.dll'
else:
@@ -322,7 +320,7 @@ def init():
elif platform == "android":
try:
bso = ctypes.CDLL('libbitmsghash.so')
- except Exception as e:
+ except Exception:
bso = None
else:
@@ -332,7 +330,7 @@ def init():
import glob
try:
bso = ctypes.CDLL(glob.glob(os.path.join(
- paths.codePath(), "bitmsghash", "bitmsghash*.so"
+ paths.codePath(), " ", "bitmsghash*.so"
))[0])
except (OSError, IndexError):
bso = None
diff --git a/src/protocol.py b/src/protocol.py
index 4f2d0856..80f5f615 100644
--- a/src/protocol.py
+++ b/src/protocol.py
@@ -2,7 +2,7 @@
Low-level protocol-related functions.
"""
# pylint: disable=too-many-boolean-expressions,too-many-return-statements
-# pylint: disable=too-many-locals,too-many-statements
+# pylint: disable=too-many-locals,too-many-statements,logging-format-interpolation
import base64
import hashlib
@@ -65,6 +65,7 @@ Header = Struct('!L12sL4s')
VersionPacket = Struct('>LqQ20s4s36sH')
# Bitfield
+# pylint: disable=unidiomatic-typecheck
def getBitfield(address):
@@ -96,11 +97,20 @@ def isBitSetWithinBitfield(fourByteString, n):
def encodeHost(host):
"""Encode a given host to be used in low-level socket operations"""
- if host.find('.onion') > -1:
- return '\xfd\x87\xd8\x7e\xeb\x43' + base64.b32decode(
- host.split(".")[0], True)
- elif host.find(':') == -1:
- return '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF' + \
+ if type(host) == bytes:
+ onion = 'onion'.encode()
+ colon = ':'.encode()
+ full_stop = '.'.encode()
+ else:
+ onion = 'onion'
+ colon = ':'
+ full_stop = '.'
+ if host.find(onion) > -1:
+ return '\xfd\x87\xd8\x7e\xeb\x43'.encode(
+ 'raw_unicode_escape') + base64.b32decode(
+ host.split(full_stop)[0], True)
+ elif host.find(colon) == -1:
+ return '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF'.encode('raw_unicode_escape') + \
socket.inet_aton(host)
return socket.inet_pton(socket.AF_INET6, host)
@@ -143,16 +153,14 @@ def network_group(host):
def checkIPAddress(host, private=False):
- """
- Returns hostStandardFormat if it is a valid IP address,
- otherwise returns False
- """
- if host[0:12] == '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF':
+
+ """Returns hostStandardFormat if it is a valid IP address, otherwise returns False"""
+ if host[0:12] == '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF'.encode('raw_unicode_escape'):
hostStandardFormat = socket.inet_ntop(socket.AF_INET, host[12:])
return checkIPv4Address(host[12:], hostStandardFormat, private)
- elif host[0:6] == '\xfd\x87\xd8\x7e\xeb\x43':
+ elif host[0:6] == '\xfd\x87\xd8\x7e\xeb\x43'.encode('raw_unicode_escape'):
# Onion, based on BMD/bitcoind
- hostStandardFormat = base64.b32encode(host[6:]).lower() + ".onion"
+ hostStandardFormat = base64.b32encode(host[6:]) + ".onion".encode()
if private:
return False
return hostStandardFormat
@@ -169,27 +177,27 @@ def checkIPAddress(host, private=False):
def checkIPv4Address(host, hostStandardFormat, private=False):
- """
- Returns hostStandardFormat if it is an IPv4 address,
- otherwise returns False
- """
- if host[0] == '\x7F': # 127/8
+
+ """Returns hostStandardFormat if it is an IPv4 address, otherwise returns False"""
+
+ if host[0] == '\x7F'.encode('raw_unicode_escape'): # 127/8
if not private:
logger.debug(
'Ignoring IP address in loopback range: %s',
hostStandardFormat)
return hostStandardFormat if private else False
- if host[0] == '\x0A': # 10/8
+ if host[0] == '\x0A'.encode('raw_unicode_escape'): # 10/8
if not private:
logger.debug(
'Ignoring IP address in private range: %s', hostStandardFormat)
return hostStandardFormat if private else False
- if host[0:2] == '\xC0\xA8': # 192.168/16
+ if host[0:2] == '\xC0\xA8'.encode('raw_unicode_escape'): # 192.168/16
if not private:
logger.debug(
'Ignoring IP address in private range: %s', hostStandardFormat)
return hostStandardFormat if private else False
- if host[0:2] >= '\xAC\x10' and host[0:2] < '\xAC\x20': # 172.16/12
+ # 172.16/12
+ if host[0:2] >= '\xAC\x10'.encode('raw_unicode_escape') and host[0:2] < '\xAC\x20'.encode('raw_unicode_escape'):
if not private:
logger.debug(
'Ignoring IP address in private range: %s', hostStandardFormat)
@@ -198,22 +206,20 @@ def checkIPv4Address(host, hostStandardFormat, private=False):
def checkIPv6Address(host, hostStandardFormat, private=False):
- """
- Returns hostStandardFormat if it is an IPv6 address,
- otherwise returns False
- """
- if host == ('\x00' * 15) + '\x01':
+ """Returns hostStandardFormat if it is an IPv6 address, otherwise returns False"""
+ if host == ('\x00'.encode() * 15) + '\x01'.encode():
+
if not private:
- logger.debug('Ignoring loopback address: %s', hostStandardFormat)
+ logger.debug('Ignoring loopback address: {}'.format(hostStandardFormat))
return False
if host[0] == '\xFE' and (ord(host[1]) & 0xc0) == 0x80:
if not private:
- logger.debug('Ignoring local address: %s', hostStandardFormat)
+ logger.debug('Ignoring local address: {}'.format(hostStandardFormat))
return hostStandardFormat if private else False
- if (ord(host[0]) & 0xfe) == 0xfc:
+ if (ord(host[0:1]) & 0xfe) == 0xfc:
if not private:
- logger.debug(
- 'Ignoring unique local address: %s', hostStandardFormat)
+ logger.debug('Ignoring unique local address: {}'.format(hostStandardFormat))
+
return hostStandardFormat if private else False
return False if private else hostStandardFormat
@@ -225,6 +231,7 @@ def haveSSL(server=False):
python < 2.7.9's ssl library does not support ECDSA server due to
missing initialisation of available curves, but client works ok
"""
+ return False
if not server:
return True
elif sys.version_info >= (2, 7, 9):
@@ -269,7 +276,7 @@ def isProofOfWorkSufficient(
if TTL < 300:
TTL = 300
POW, = unpack('>Q', hashlib.sha512(hashlib.sha512(
- data[:8] + hashlib.sha512(data[8:]).digest()
+ bytes(data[:8]) + hashlib.sha512(data[8:]).digest()
).digest()).digest()[0:8])
return POW <= 2 ** 64 / (
nonceTrialsPerByte * (
@@ -281,24 +288,20 @@ def isProofOfWorkSufficient(
def CreatePacket(command, payload=''):
- """Construct and return a packet"""
+ """Construct and return a number of bytes from a payload"""
+ payload = payload if type(payload) in [bytes, bytearray] else payload.encode()
payload_length = len(payload)
checksum = hashlib.sha512(payload).digest()[0:4]
-
- b = bytearray(Header.size + payload_length)
- Header.pack_into(b, 0, 0xE9BEB4D9, command, payload_length, checksum)
- b[Header.size:] = payload
- return bytes(b)
+ byte = bytearray(Header.size + payload_length)
+ Header.pack_into(byte, 0, 0xE9BEB4D9, command.encode(), payload_length, checksum)
+ byte[Header.size:] = payload
+ return bytes(byte)
-def assembleVersionMessage(
- remoteHost, remotePort, participatingStreams, server=False, nodeid=None
-):
- """
- Construct the payload of a version message,
- return the resulting bytes of running `CreatePacket` on it
- """
- payload = ''
+def assembleVersionMessage(remoteHost, remotePort, participatingStreams, server=False, nodeid=None):
+ """Construct the payload of a version message, return the resultng bytes of running CreatePacket() on it"""
+ payload = bytes()
+
payload += pack('>L', 3) # protocol version.
# bitflags of the services I offer.
payload += pack(
@@ -331,10 +334,10 @@ def assembleVersionMessage(
(NODE_SSL if haveSSL(server) else 0) |
(NODE_DANDELION if state.dandelion else 0)
)
- # = 127.0.0.1. This will be ignored by the remote host.
- # The actual remote connected IP will be used.
- payload += '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF' + pack(
- '>L', 2130706433)
+ # = 127.0.0.1. This will be ignored by the remote host. The actual remote connected IP will be used.
+ # python3 need to check
+ payload += '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF'.encode('raw_unicode_escape') + pack('>L', 2130706433)
+
# we have a separate extPort and incoming over clearnet
# or outgoing through clearnet
extport = BMConfigParser().safeGetInt('bitmessagesettings', 'extport')
@@ -345,11 +348,9 @@ def assembleVersionMessage(
):
payload += pack('>H', extport)
elif checkSocksIP(remoteHost) and server: # incoming connection over Tor
- payload += pack(
- '>H', BMConfigParser().getint('bitmessagesettings', 'onionport'))
+ payload += pack('>H', int(BMConfigParser().safeGet('bitmessagesettings', 'onionport')))
else: # no extport and not incoming over Tor
- payload += pack(
- '>H', BMConfigParser().getint('bitmessagesettings', 'port'))
+ payload += pack('>H', int(BMConfigParser().safeGet('bitmessagesettings', 'port')))
if nodeid is not None:
payload += nodeid[0:8]
@@ -357,7 +358,7 @@ def assembleVersionMessage(
payload += eightBytesOfRandomDataUsedToDetectConnectionsToSelf
userAgent = '/PyBitmessage:' + softwareVersion + '/'
payload += encodeVarint(len(userAgent))
- payload += userAgent
+ payload += userAgent.encode()
# Streams
payload += encodeVarint(len(participatingStreams))
@@ -380,9 +381,9 @@ def assembleErrorMessage(fatal=0, banTime=0, inventoryVector='', errorText=''):
payload = encodeVarint(fatal)
payload += encodeVarint(banTime)
payload += encodeVarint(len(inventoryVector))
- payload += inventoryVector
+ payload += inventoryVector.encode() if type(payload) == bytes else inventoryVector
payload += encodeVarint(len(errorText))
- payload += errorText
+ payload += errorText.encode() if type(payload) == bytes else errorText
return CreatePacket('error', payload)
@@ -430,7 +431,7 @@ def decryptAndCheckPubkeyPayload(data, address):
encryptedData = data[readPosition:]
# Let us try to decrypt the pubkey
- toAddress, cryptorObject = state.neededPubkeys[tag]
+ toAddress, cryptorObject = state.neededPubkeys[bytes(tag)]
if toAddress != address:
logger.critical(
'decryptAndCheckPubkeyPayload failed due to toAddress'
@@ -443,6 +444,7 @@ def decryptAndCheckPubkeyPayload(data, address):
# That sort of address-malleability should have been caught
# by the UI or API and an error given to the user.
return 'failed'
+ print("WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW#################################################")
try:
decryptedData = cryptorObject.decrypt(encryptedData)
except:
@@ -450,13 +452,13 @@ def decryptAndCheckPubkeyPayload(data, address):
# but tagged it with a tag for which we are watching.
logger.info('Pubkey decryption was unsuccessful.')
return 'failed'
-
readPosition = 0
# bitfieldBehaviors = decryptedData[readPosition:readPosition + 4]
readPosition += 4
- publicSigningKey = '\x04' + decryptedData[readPosition:readPosition + 64]
+ print("working fine till here#################################################################")
+ publicSigningKey = '\x04'.encode() + decryptedData[readPosition:readPosition + 64]
readPosition += 64
- publicEncryptionKey = '\x04' + decryptedData[readPosition:readPosition + 64]
+ publicEncryptionKey = '\x04'.encode() + decryptedData[readPosition:readPosition + 64]
readPosition += 64
specifiedNonceTrialsPerByteLength = decodeVarint(
decryptedData[readPosition:readPosition + 10])[1]
@@ -470,7 +472,6 @@ def decryptAndCheckPubkeyPayload(data, address):
decryptedData[readPosition:readPosition + 10])
readPosition += signatureLengthLength
signature = decryptedData[readPosition:readPosition + signatureLength]
-
if not highlevelcrypto.verify(
signedData, signature, hexlify(publicSigningKey)):
logger.info(
@@ -479,11 +480,9 @@ def decryptAndCheckPubkeyPayload(data, address):
logger.info(
'ECDSA verify passed (within decryptAndCheckPubkeyPayload)')
-
sha = hashlib.new('sha512')
sha.update(publicSigningKey + publicEncryptionKey)
embeddedRipe = RIPEMD160Hash(sha.digest()).digest()
-
if embeddedRipe != ripe:
# Although this pubkey object had the tag were were looking for
# and was encrypted with the correct encryption key,
@@ -502,9 +501,9 @@ def decryptAndCheckPubkeyPayload(data, address):
addressVersion, streamNumber, hexlify(ripe),
hexlify(publicSigningKey), hexlify(publicEncryptionKey)
)
-
t = (address, addressVersion, storedData, int(time.time()), 'yes')
sqlExecute('''INSERT INTO pubkeys VALUES (?,?,?,?,?)''', *t)
+ print("successful Insertion of pubkey hurray#################################################")
return 'successful'
except varintDecodeError:
logger.info(
diff --git a/src/pyelliptic/arithmetic.py b/src/pyelliptic/arithmetic.py
index 83e634ad..f6690a25 100644
--- a/src/pyelliptic/arithmetic.py
+++ b/src/pyelliptic/arithmetic.py
@@ -29,11 +29,13 @@ def get_code_string(base):
elif base == 10:
return '0123456789'
elif base == 16:
- return "0123456789abcdef"
+ return ("0123456789abcdef").encode()
elif base == 58:
return "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
elif base == 256:
- return ''.join([chr(x) for x in range(256)])
+ # raw_unicode_escape is used because in the python3 after range(161) its genreate
+ # the speical character so avoiding that function we have used the raw_unicode method
+ return bytes(range(0, 256))
else:
raise ValueError("Invalid base!")
@@ -41,10 +43,10 @@ def get_code_string(base):
def encode(val, base, minlen=0):
"""Returns the encoded string"""
code_string = get_code_string(base)
- result = ""
+ result = str.encode('') if type(code_string) is bytes else ''
while val > 0:
- result = code_string[val % base] + result
- val /= base
+ result = code_string[val % base:val % base + 1] + result
+ val = val // base
if len(result) < minlen:
result = code_string[0] * (minlen - len(result)) + result
return result
@@ -58,7 +60,7 @@ def decode(string, base):
string = string.lower()
while string:
result *= base
- result += code_string.find(string[0])
+ result += code_string.find(string[0:1])
string = string[1:]
return result
diff --git a/src/pyelliptic/cipher.py b/src/pyelliptic/cipher.py
index 4057e169..52348232 100644
--- a/src/pyelliptic/cipher.py
+++ b/src/pyelliptic/cipher.py
@@ -6,7 +6,7 @@ Symmetric Encryption
# Copyright (C) 2011 Yann GUIBET
# See LICENSE for details.
-from openssl import OpenSSL
+from .openssl import OpenSSL
# pylint: disable=redefined-builtin
diff --git a/src/pyelliptic/ecc.py b/src/pyelliptic/ecc.py
index a7f5a6b7..eff7486e 100644
--- a/src/pyelliptic/ecc.py
+++ b/src/pyelliptic/ecc.py
@@ -10,9 +10,9 @@ Asymmetric cryptography using elliptic curves
from hashlib import sha512
from struct import pack, unpack
-from cipher import Cipher
-from hash import equals, hmac_sha256
-from openssl import OpenSSL
+from pyelliptic.cipher import Cipher
+from pyelliptic.hash import equals, hmac_sha256
+from pyelliptic.openssl import OpenSSL
class ECC(object):
@@ -62,7 +62,6 @@ class ECC(object):
self.curve = OpenSSL.get_curve(curve)
else:
self.curve = curve
-
if pubkey_x is not None and pubkey_y is not None:
self._set_keys(pubkey_x, pubkey_y, raw_privkey)
elif pubkey is not None:
@@ -294,7 +293,6 @@ class ECC(object):
if (OpenSSL.EC_KEY_set_private_key(key, priv_key)) == 0:
raise Exception(
"[OpenSSL] EC_KEY_set_private_key FAIL ...")
-
group = OpenSSL.EC_KEY_get0_group(key)
pub_key = OpenSSL.EC_POINT_new(group)
diff --git a/src/pyelliptic/hash.py b/src/pyelliptic/hash.py
index f098d631..70c9a6ce 100644
--- a/src/pyelliptic/hash.py
+++ b/src/pyelliptic/hash.py
@@ -4,7 +4,7 @@ Wrappers for hash functions from OpenSSL.
# Copyright (C) 2011 Yann GUIBET
# See LICENSE for details.
-from openssl import OpenSSL
+from .openssl import OpenSSL
# For python3
diff --git a/src/pyelliptic/openssl.py b/src/pyelliptic/openssl.py
index 7cf1e2c5..20d2100f 100644
--- a/src/pyelliptic/openssl.py
+++ b/src/pyelliptic/openssl.py
@@ -82,7 +82,7 @@ class _OpenSSL(object):
"""Build the wrapper"""
self._lib = ctypes.CDLL(library)
self._version, self._hexversion, self._cflags = get_version(self._lib)
- self._libreSSL = self._version.startswith("LibreSSL")
+ self._libreSSL = (self._version).decode("utf-8").startswith("OpenSSL")
self.pointer = ctypes.pointer
self.c_int = ctypes.c_int
@@ -723,6 +723,7 @@ def loadOpenSSL():
libdir.append('libssl.so')
libdir.append('libcrypto.so.1.0.0')
libdir.append('libssl.so.1.0.0')
+ libdir.append('libcrypto.so.1.0.2')
if 'linux' in sys.platform or 'darwin' in sys.platform or 'bsd' in sys.platform:
try:
libdir.append(find_library('ssl'))
diff --git a/src/queues.py b/src/queues.py
index 7d9e284a..bbd13fb7 100644
--- a/src/queues.py
+++ b/src/queues.py
@@ -1,6 +1,6 @@
"""Most of the queues used by bitmessage threads are defined here."""
+import queue as Queue
-import Queue
import threading
import time
@@ -21,6 +21,7 @@ class ObjectProcessorQueue(Queue.Queue):
self.curSize = 0
def put(self, item, block=True, timeout=None):
+ """Putting values in queues"""
while self.curSize >= self.maxSize:
time.sleep(1)
with self.sizeLock:
@@ -28,6 +29,7 @@ class ObjectProcessorQueue(Queue.Queue):
Queue.Queue.put(self, item, block, timeout)
def get(self, block=True, timeout=None):
+ """Getting values from queues"""
item = Queue.Queue.get(self, block, timeout)
with self.sizeLock:
self.curSize -= len(item[1])
diff --git a/src/semaphores.py b/src/semaphores.py
index 04120fe7..960d86a9 100644
--- a/src/semaphores.py
+++ b/src/semaphores.py
@@ -1,3 +1,3 @@
from threading import Semaphore
-kivyuisignaler = Semaphore(0)
\ No newline at end of file
+kivyuisignaler = Semaphore(0)
diff --git a/src/shared.py b/src/shared.py
index cabc0f40..33bfa388 100644
--- a/src/shared.py
+++ b/src/shared.py
@@ -25,9 +25,8 @@ from addresses import decodeAddress, encodeVarint
from bmconfigparser import BMConfigParser
from debug import logger
from helper_sql import sqlQuery
-
from pyelliptic import arithmetic
-
+# pylint: disable=logging-format-interpolation
verbose = 1
# This is obsolete with the change to protocol v3
@@ -113,23 +112,21 @@ def decodeWalletImportFormat(WIFstring):
"""
fullString = arithmetic.changebase(WIFstring, 58, 256)
privkey = fullString[:-4]
- if fullString[-4:] != \
- hashlib.sha256(hashlib.sha256(privkey).digest()).digest()[:4]:
+ if fullString[-4:] != hashlib.sha256(hashlib.sha256(privkey).digest()).digest()[:4]:
logger.critical(
'Major problem! When trying to decode one of your'
' private keys, the checksum failed. Here are the first'
- ' 6 characters of the PRIVATE key: %s',
- str(WIFstring)[:6]
+ ' 6 characters of the PRIVATE key: {}'.format(str(WIFstring)[:6])
)
+
os._exit(0) # pylint: disable=protected-access
- # return ""
- elif privkey[0] == '\x80': # checksum passed
+ if privkey[0:1] == '\x80'.encode()[1:]: # checksum passed
return privkey[1:]
logger.critical(
'Major problem! When trying to decode one of your private keys,'
' the checksum passed but the key doesn\'t begin with hex 80.'
- ' Here is the PRIVATE key: %s', WIFstring
+ ' Here is the PRIVATE key: {}'.format(WIFstring)
)
os._exit(0) # pylint: disable=protected-access
@@ -147,7 +144,7 @@ def reloadMyAddressHashes():
state.appdata, 'keys.dat'))
hasEnabledKeys = False
for addressInKeysFile in BMConfigParser().addresses():
- isEnabled = BMConfigParser().getboolean(addressInKeysFile, 'enabled')
+ isEnabled = BMConfigParser().safeGet(addressInKeysFile, 'enabled')
if isEnabled:
hasEnabledKeys = True
# status
@@ -195,7 +192,6 @@ def reloadBroadcastSendersForWhichImWatching():
# Now, for all addresses, even version 2 addresses,
# we should create Cryptor objects in a dictionary which we will
# use to attempt to decrypt encrypted broadcast messages.
-
if addressVersionNumber <= 3:
privEncryptionKey = hashlib.sha512(
encodeVarint(addressVersionNumber) +
@@ -220,6 +216,7 @@ def fixPotentiallyInvalidUTF8Data(text):
unicode(text, 'utf-8')
return text
except:
+
return 'Part of the message is corrupt. The message cannot be' \
' displayed the normal way.\n\n' + repr(text)
@@ -246,7 +243,7 @@ def checkSensitiveFilePermissions(filename):
shell=True,
stderr=subprocess.STDOUT
)
- if 'fuseblk' in fstype:
+ if 'fuseblk'.encode() in fstype:
logger.info(
'Skipping file permissions check for %s.'
' Filesystem fuseblk detected.', filename)
diff --git a/src/shutdown.py b/src/shutdown.py
index dbc2af04..bba7c870 100644
--- a/src/shutdown.py
+++ b/src/shutdown.py
@@ -1,6 +1,6 @@
"""shutdown function"""
import os
-import Queue
+import queue as Queue
import threading
import time
diff --git a/src/singleinstance.py b/src/singleinstance.py
index b061cbff..2936e49b 100644
--- a/src/singleinstance.py
+++ b/src/singleinstance.py
@@ -75,7 +75,7 @@ class singleinstance(object):
fcntl.lockf(self.fp, fcntl.LOCK_EX | fcntl.LOCK_NB)
self.lockPid = os.getpid()
except IOError:
- print 'Another instance of this application is already running'
+ print('Another instance of this application is already running')
sys.exit(-1)
else:
pidLine = "%i\n" % self.lockPid
@@ -97,9 +97,8 @@ class singleinstance(object):
fcntl.lockf(self.fp, fcntl.LOCK_UN)
except Exception:
pass
-
return
- print "Cleaning up lockfile"
+ print("Cleaning up lockfile")
try:
if sys.platform == 'win32':
if hasattr(self, 'fd'):
diff --git a/src/state.py b/src/state.py
index 16bc016e..c8ab8bf4 100644
--- a/src/state.py
+++ b/src/state.py
@@ -1,43 +1,30 @@
"""
-Global runtime variables.
+src/state.py
+=================================
"""
import collections
neededPubkeys = {}
streamsInWhichIAmParticipating = []
-
+# For UPnP
extPort = None
-"""For UPnP"""
-
+# for Tor hidden service
socksIP = None
-"""for Tor hidden service"""
-
-appdata = ''
-"""holds the location of the application data storage directory"""
-
+# Network protocols availability, initialised below
+networkProtocolAvailability = None
+appdata = '' # holds the location of the application data storage directory
+# Set to 1 by the doCleanShutdown function.
+# Used to tell the proof of work worker threads to exit.
shutdown = 0
-"""
-Set to 1 by the `.shutdown.doCleanShutdown` function.
-Used to tell the threads to exit.
-"""
-
# Component control flags - set on startup, do not change during runtime
# The defaults are for standalone GUI (default operating mode)
-enableNetwork = True
-"""enable network threads"""
-enableObjProc = True
-"""enable object processing thread"""
-enableAPI = True
-"""enable API (if configured)"""
-enableGUI = True
-"""enable GUI (QT or ncurses)"""
-enableSTDIO = False
-"""enable STDIO threads"""
+enableNetwork = True # enable network threads
+enableObjProc = True # enable object processing threads
+enableAPI = True # enable API (if configured)
+enableGUI = True # enable GUI (QT or ncurses)
+enableSTDIO = False # enable STDIO threads
curses = False
-
-sqlReady = False
-"""set to true by `.threads.sqlThread` when ready for processing"""
-
+sqlReady = False # set to true by sqlTread when ready for processing
maximumNumberOfHalfOpenConnections = 0
invThread = None
addrThread = None
@@ -68,8 +55,6 @@ def resetNetworkProtocolAvailability():
resetNetworkProtocolAvailability()
-discoveredPeers = {}
-
dandelion = 0
testmode = False
diff --git a/src/storage/filesystem.py b/src/storage/filesystem.py
index b19d9272..b9421f9d 100644
--- a/src/storage/filesystem.py
+++ b/src/storage/filesystem.py
@@ -8,7 +8,7 @@ from os import listdir, makedirs, path, remove, rmdir
from threading import RLock
from paths import lookupAppdataFolder
-from storage import InventoryItem, InventoryStorage
+from storage.storage import InventoryStorage, InventoryItem
class FilesystemInventory(InventoryStorage):
@@ -162,7 +162,7 @@ class FilesystemInventory(InventoryStorage):
newInventory[streamNumber][hashId] = InventoryItem(
objectType, streamNumber, None, expiresTime, tag)
except KeyError:
- print "error loading %s" % (hexlify(hashId))
+ print ("error loading {}".format((hexlify(hashId))))
self._inventory = newInventory
# for i, v in self._inventory.items():
# print "loaded stream: %s, %i items" % (i, len(v))
diff --git a/src/storage/sqlite.py b/src/storage/sqlite.py
index 0992c00e..912caf0d 100644
--- a/src/storage/sqlite.py
+++ b/src/storage/sqlite.py
@@ -5,8 +5,9 @@ import sqlite3
import time
from threading import RLock
-from helper_sql import SqlBulkExecute, sqlExecute, sqlQuery
-from storage import InventoryItem, InventoryStorage
+
+from helper_sql import sqlQuery, SqlBulkExecute, sqlExecute
+from storage.storage import InventoryStorage, InventoryItem
class SqliteInventory(InventoryStorage): # pylint: disable=too-many-ancestors
@@ -38,7 +39,7 @@ class SqliteInventory(InventoryStorage): # pylint: disable=too-many-ancestors
return False
self._objects[hash_] = rows[0][0]
return True
-
+
def __getitem__(self, hash_):
with self.lock:
if hash_ in self._inventory:
@@ -48,7 +49,7 @@ class SqliteInventory(InventoryStorage): # pylint: disable=too-many-ancestors
' FROM inventory WHERE hash=?', sqlite3.Binary(hash_))
if not rows:
raise KeyError(hash_)
- return InventoryItem(*rows[0])
+ return InventoryItem(*rows[0])
def __setitem__(self, hash_, value):
with self.lock:
@@ -87,9 +88,10 @@ class SqliteInventory(InventoryStorage): # pylint: disable=too-many-ancestors
t = int(time.time())
hashes = [x for x, value in self._inventory.items()
if value.stream == stream and value.expires > t]
- hashes += (str(payload) for payload, in sqlQuery(
+ hashes += (payload for payload, in sqlQuery(
'SELECT hash FROM inventory WHERE streamnumber=?'
' AND expirestime>?', stream, t))
+ # print('sqlllllllllllllllllllllllllllllllllll',hashes)
return hashes
def flush(self):
diff --git a/src/suravata.py b/src/suravata.py
deleted file mode 100644
index 18541989..00000000
--- a/src/suravata.py
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/env python
-# Import the libraries.
-import pdb;pdb.set_trace()
-import pydenticon100000000000000000000000
-import hashlib
-# Set-up some test data.
-users = ["alice", "bob", "eve", "dave"]
-# Set-up a list of foreground colours (taken from Sigil).
-foreground = ["rgb(45,79,255)",
- "rgb(254,180,44)",
- "rgb(226,121,234)",
- "rgb(30,179,253)",
- "rgb(232,77,65)",
- "rgb(49,203,115)",
- "rgb(141,69,170)"]
-# Set-up a background colour (taken from Sigil).
-background = "rgb(224,224,224)"
-# Set-up the padding (top, bottom, left, right) in pixels.
-padding = (20, 20, 20, 20)
-# Instantiate a generator that will create 5x5 block identicons using SHA1
-# digest.
-generator = pydenticon.Generator(5, 5, digest=hashlib.sha1, foreground=foreground, background=background)
-
-# identicon_ascii = generator.generate("john.doe@example.com", 200, 200,
-# output_format="ascii")
-
-# print identicon_ascii
-for user in users:
- identicon = generator.generate(user, 200, 200, padding=padding, output_format="png")
- filename = user + ".png"
- with open(filename, "wb") as f:
- f.write(identicon)
\ No newline at end of file
diff --git a/src/tests/core.py b/src/tests/core.py
index d56076c3..7b89e5b0 100644
--- a/src/tests/core.py
+++ b/src/tests/core.py
@@ -5,7 +5,7 @@ Tests for core and those that do not work outside
import os
import pickle # nosec
-import Queue
+import queue as Queue
import random # nosec
import string
import time
diff --git a/src/tests/test_networkgroup.py b/src/tests/test_networkgroup.py
index 76cfb033..14e61a8e 100644
--- a/src/tests/test_networkgroup.py
+++ b/src/tests/test_networkgroup.py
@@ -10,6 +10,7 @@ class TestNetworkGroup(unittest.TestCase):
"""
def test_network_group(self):
"""Test various types of network groups"""
+ # pylint: disable=import-error
from pybitmessage.protocol import network_group
test_ip = '1.2.3.4'
diff --git a/src/tr.py b/src/tr.py
index 9f531a99..f3498037 100644
--- a/src/tr.py
+++ b/src/tr.py
@@ -6,17 +6,17 @@ import os
import state
-class translateClass:
+class translateClass(object):
"""
This is used so that the translateText function can be used
when we are in daemon mode and not using any QT functions.
"""
- # pylint: disable=old-style-class,too-few-public-methods
+ # pylint: disable=too-few-public-methods
def __init__(self, context, text):
self.context = context
self.text = text
- def arg(self, argument): # pylint: disable=unused-argument
+ def arg(self, _):
"""Replace argument placeholders"""
if '%' in self.text:
return translateClass(self.context, self.text.replace('%', '', 1))
@@ -25,8 +25,7 @@ class translateClass:
return self.text
-def _translate(context, text, disambiguation=None, encoding=None, n=None):
- # pylint: disable=unused-argument
+def _translate(context, text, disambiguation=None, encoding=None, n=None): # pylint: disable=unused-argument
return translateText(context, text, n)
@@ -40,13 +39,13 @@ def translateText(context, text, n=None):
try:
from PyQt4 import QtCore, QtGui
except Exception as err:
- print 'PyBitmessage requires PyQt unless you want to run it as a daemon'\
- ' and interact with it using the API.'\
- ' You can download PyQt from http://www.riverbankcomputing.com/software/pyqt/download'\
- ' or by searching Google for \'PyQt Download\'.'\
- ' If you want to run in daemon mode, see https://bitmessage.org/wiki/Daemon'
- print 'Error message:', err
+ print('PyBitmessage requires PyQt unless you want to run it as a daemon and interact with it using the API\
+ .You can download PyQt from http://www.riverbankcomputing.com/software/pyqt/download\
+ or by searching Google for \'PyQt Download\'.\
+ If you want to run in daemon mode, see https://bitmessage.org/wiki/Daemon')
+ print('Error message:', err)
os._exit(0) # pylint: disable=protected-access
+
if n is None:
return QtGui.QApplication.translate(context, text)
return QtGui.QApplication.translate(context, text, None, QtCore.QCoreApplication.CodecForTr, n)
diff --git a/src/upnp.py b/src/upnp.py
index 99000413..93753de3 100644
--- a/src/upnp.py
+++ b/src/upnp.py
@@ -1,8 +1,8 @@
-# pylint: disable=too-many-statements,too-many-branches,protected-access,no-self-use
-"""
+"""
Complete UPnP port forwarding implementation in separate thread.
Reference: http://mattscodecave.com/posts/using-python-and-upnp-to-forward-a-port
"""
+# pylint: disable=too-many-statements,too-many-branches,protected-access,no-self-use
import httplib
import socket
@@ -18,8 +18,9 @@ import state
import tr
from bmconfigparser import BMConfigParser
from debug import logger
-from network import BMConnectionPool, StoppableThread
+from network.connectionpool import BMConnectionPool
from network.node import Peer
+from network.threads import StoppableThread
def createRequestXML(service, action, arguments=None):
@@ -82,6 +83,7 @@ class UPnPError(Exception):
class Router: # pylint: disable=old-style-class
"""Encapulate routing"""
+
name = ""
path = ""
address = None
@@ -151,7 +153,6 @@ class Router: # pylint: disable=old-style-class
def DeletePortMapping(self, externalPort, protocol):
"""Delete UPnP port mapping"""
-
resp = self.soapRequest(self.upnp_schema + ':1', 'DeletePortMapping', [
('NewRemoteHost', ''),
('NewExternalPort', str(externalPort)),
@@ -162,16 +163,12 @@ class Router: # pylint: disable=old-style-class
def GetExternalIPAddress(self):
"""Get the external address"""
-
- resp = self.soapRequest(
- self.upnp_schema + ':1', 'GetExternalIPAddress')
+ resp = self.soapRequest(self.upnp_schema + ':1', 'GetExternalIPAddress')
dom = parseString(resp.read())
- return dom.getElementsByTagName(
- 'NewExternalIPAddress')[0].childNodes[0].data
+ return dom.getElementsByTagName('NewExternalIPAddress')[0].childNodes[0].data
def soapRequest(self, service, action, arguments=None):
"""Make a request to a router"""
-
conn = httplib.HTTPConnection(self.routerPath.hostname, self.routerPath.port)
conn.request(
'POST',
@@ -222,7 +219,6 @@ class uPnPThread(StoppableThread):
def run(self):
"""Start the thread to manage UPnP activity"""
-
logger.debug("Starting UPnP thread")
logger.debug("Local IP: %s", self.localIP)
lastSent = 0
@@ -260,16 +256,12 @@ class uPnPThread(StoppableThread):
self.routers.append(newRouter)
self.createPortMapping(newRouter)
try:
- self_peer = Peer(
- newRouter.GetExternalIPAddress(),
- self.extPort
- )
+ self_peer = Peer(newRouter.GetExternalIPAddress(), self.extPort)
except:
logger.debug('Failed to get external IP')
else:
with knownnodes.knownNodesLock:
- knownnodes.addKnownNode(
- 1, self_peer, is_self=True)
+ knownnodes.addKnownNode(1, self_peer, is_self=True)
queues.UISignalQueue.put(('updateStatusBar', tr._translate(
"MainWindow", 'UPnP port mapping established on port %1'
).arg(str(self.extPort))))
@@ -295,12 +287,12 @@ class uPnPThread(StoppableThread):
deleted = True
self.deletePortMapping(router)
if deleted:
- queues.UISignalQueue.put(('updateStatusBar', tr._translate("MainWindow", 'UPnP port mapping removed')))
+ queues.UISignalQueue.put(
+ ('updateStatusBar', tr._translate("MainWindow", 'UPnP port mapping removed')))
logger.debug("UPnP thread done")
def getLocalIP(self):
"""Get the local IP of the node"""
-
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
s.connect((uPnPThread.GOOGLE_DNS, 1))
@@ -308,7 +300,6 @@ class uPnPThread(StoppableThread):
def sendSearchRouter(self):
"""Querying for UPnP services"""
-
ssdpRequest = "M-SEARCH * HTTP/1.1\r\n" + \
"HOST: %s:%d\r\n" % (uPnPThread.SSDP_ADDR, uPnPThread.SSDP_PORT) + \
"MAN: \"ssdp:discover\"\r\n" + \
@@ -323,7 +314,6 @@ class uPnPThread(StoppableThread):
def createPortMapping(self, router):
"""Add a port mapping"""
-
for i in range(50):
try:
localIP = self.localIP
@@ -335,10 +325,7 @@ class uPnPThread(StoppableThread):
extPort = randint(32767, 65535)
logger.debug(
"Attempt %i, requesting UPnP mapping for %s:%i on external port %i",
- i,
- localIP,
- self.localPort,
- extPort)
+ i, localIP, self.localPort, extPort)
router.AddPortMapping(extPort, self.localPort, localIP, 'TCP', 'BitMessage')
self.extPort = extPort
BMConfigParser().set('bitmessagesettings', 'extport', str(extPort))