From 49f9620236cf559501a3046980f9c576414682a8 Mon Sep 17 00:00:00 2001 From: Muzahid Date: Thu, 4 Mar 2021 19:45:41 +0530 Subject: [PATCH] Add sqlite functions while versioning --- src/addresses.py | 26 +- src/bitmessagecli.py | 614 ++++++++++++++------------- src/bmconfigparser.py | 130 ++++-- src/class_sqlThread.py | 59 ++- src/debug.py | 21 +- src/helper_random.py | 7 +- src/helper_sql.py | 22 +- src/helper_startup.py | 18 +- src/multiqueue.py | 12 +- src/namecoin.py | 2 +- src/queues.py | 14 +- src/singleinstance.py | 4 +- src/tests/sql/create_function.sql | 9 + src/tests/test_api.py | 3 + src/tests/test_blindsig.py | 3 + src/tests/test_config_process.py | 3 + src/tests/test_randomtrackingdict.py | 3 + src/tests/test_sqlthread.py | 75 ++++ src/tr.py | 12 +- 19 files changed, 635 insertions(+), 402 deletions(-) create mode 100644 src/tests/sql/create_function.sql create mode 100644 src/tests/test_sqlthread.py diff --git a/src/addresses.py b/src/addresses.py index e21acd1f..1ac5ea40 100644 --- a/src/addresses.py +++ b/src/addresses.py @@ -2,6 +2,7 @@ Operations with addresses """ # pylint: disable=redefined-outer-name,inconsistent-return-statements +import sys import hashlib import logging from binascii import hexlify, unhexlify @@ -149,18 +150,31 @@ def encodeAddress(version, stream, ripe): 'Programming error in encodeAddress: The length of' ' a given ripe hash was not 20.' ) - if ripe[:2] == b'\x00\x00': - ripe = ripe[2:] - elif ripe[:1] == b'\x00': - ripe = ripe[1:] + + if isinstance(ripe, str): + if ripe[:2] == '\x00\x00': + ripe = ripe[2:] + elif ripe[:1] == '\x00': + ripe = ripe[1:] + else: + if ripe[:2] == b'\x00\x00': + ripe = ripe[2:] + elif ripe[:1] == b'\x00': + ripe = ripe[1:] elif version == 4: if len(ripe) != 20: raise Exception( 'Programming error in encodeAddress: The length of' ' a given ripe hash was not 20.') - ripe = ripe.lstrip(b'\x00') + ripe = ripe.lstrip('\x00') - storedBinaryData = encodeVarint(version) + encodeVarint(stream) + ripe + if sys.version_info[0] == 3: + if isinstance(ripe, str): + storedBinaryData = encodeVarint(version) + encodeVarint(stream) + ripe.encode('utf-8') + else: + storedBinaryData = encodeVarint(version) + encodeVarint(stream) + ripe + else: + storedBinaryData = encodeVarint(version) + encodeVarint(stream) + ripe # Generate the checksum sha = hashlib.new('sha512') diff --git a/src/bitmessagecli.py b/src/bitmessagecli.py index 01dbc9bb..bd6e1e46 100644 --- a/src/bitmessagecli.py +++ b/src/bitmessagecli.py @@ -38,7 +38,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 +46,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 +55,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 +96,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 +114,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 +136,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 +149,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 +168,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 +206,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 +220,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 +249,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 +281,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 +300,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 +328,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 +405,7 @@ def bmSettings(): usrPrompt = 1 main() else: - print "Invalid input." + print ("Invalid input.") usrPrompt = 1 main() @@ -433,10 +433,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 +444,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 +456,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 +490,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 +506,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 +532,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 +554,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 +572,7 @@ def listAdd(): if len(label) > 19: label = label[:16] + '...' - print ''.join([ + print (''.join([ ' |', str(addNum).ljust(3), '|', @@ -584,13 +584,13 @@ def listAdd(): '|', enabled.ljust(7), '|', - ]) + ])) - print ''.join([ + print (''.join([ ' ', 74 * '-', '\n', - ]) + ])) def genAdd(lbl, deterministic, passphrase, numOfAdd, addVNum, streamNum, ripe): @@ -603,7 +603,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 +614,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 +646,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 +667,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 +694,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 +759,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 +771,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 +795,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 +805,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 +828,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 +845,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 +868,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 +878,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 +901,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 +916,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 +926,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 +943,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 +956,37 @@ 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']) + print (' 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 (' 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 (''.join([ + # ' Last Action Time:', + # datetime.datetime.fromtimestamp( + # float(outboxMessages['sentMessages'][msgNum]['lastActionTime'])).strftime('%Y-%m-%d %H:%M:%S'), + # ])) + 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 +997,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 +1040,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 +1062,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 +1102,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 +1124,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 +1146,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 +1185,7 @@ def delMsg(msgNum): msgAck = api.trashMessage(msgId) except: - print '\n Connection Error\n' + print ('\n Connection Error\n') usrPrompt = 0 main() @@ -1197,7 +1202,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 +1238,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 +1253,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 +1268,18 @@ def listAddressBookEntries(): if "API Error" in response: return getAPIErrorCode(response) addressBook = json.loads(response) - print - print ' --------------------------------------------------------------' - print ' | Label | Address |' - 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 (' --------------------------------------------------------------') except: - print '\n Connection Error\n' + print ('\n Connection Error\n') usrPrompt = 0 main() @@ -1292,7 +1294,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 +1309,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 +1333,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 +1348,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 +1361,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 +1377,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: @@ -1384,22 +1386,22 @@ def markAllMessagesUnread(): def clientStatus(): - """Print the client status""" + """Print (the client status""" global usrPrompt 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 +1411,7 @@ def shutdown(): api.shutdown() except socket.error: pass - print "\nShutdown command relayed\n" + print ("\nShutdown command relayed\n") def UI(usrInput): @@ -1418,75 +1420,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 +1510,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 +1528,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 +1574,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 +1605,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 +1624,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 +1640,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 +1659,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 +1674,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 +1686,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 +1702,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 +1731,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 +1739,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 +1765,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 +1773,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 +1808,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 +1818,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 +1843,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 +1855,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/bmconfigparser.py b/src/bmconfigparser.py index be7b3e87..083b164a 100644 --- a/src/bmconfigparser.py +++ b/src/bmconfigparser.py @@ -53,18 +53,16 @@ BMConfigDefaults = { @Singleton class BMConfigParser(SafeConfigParser): - """ - Singleton class inherited from :class:`ConfigParser.SafeConfigParser` - with additional methods specific to bitmessage config. + Singleton class inherited from :class:`ConfigParser.SafeConfigParser` + 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) @@ -73,20 +71,20 @@ class BMConfigParser(SafeConfigParser): def get(self, section, option, raw=False, vars=None): if sys.version_info[0] == 3: # pylint: disable=arguments-differ - try: + try: if section == "bitmessagesettings" and option == "timeformat": return ConfigParser.ConfigParser.get( - self, section, option) + self, section, option, raw=True, vars=vars) try: return self._temp[section][option] except KeyError: pass return ConfigParser.ConfigParser.get( - self, section, option) - except ConfigParser.InterpolationError: + self, section, option, raw=True, vars=vars) + except ConfigParser.InterpolationError: return ConfigParser.ConfigParser.get( - self, section, option) - except (ConfigParser.NoSectionError, ConfigParser.NoOptionError) as e: + self, section, option, raw=True, vars=vars) + except (ConfigParser.NoSectionError, ConfigParser.NoOptionError) as e: try: return BMConfigDefaults[section][option] except (KeyError, ValueError, AttributeError): @@ -122,6 +120,10 @@ class BMConfigParser(SafeConfigParser): def safeGetBoolean(self, section, field): """Return value as boolean, False on exceptions""" try: + # Used in the python2.7 + # return self.getboolean(section, field) + # Used in the python3.5.2 + # print(config, section, field) return self.getboolean(section, field) except (ConfigParser.NoSectionError, ConfigParser.NoOptionError, ValueError, AttributeError): @@ -131,7 +133,10 @@ class BMConfigParser(SafeConfigParser): """Return value as integer, default on exceptions, 0 if default missing""" try: - return self.getint(section, field) + # 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 @@ -145,43 +150,71 @@ class BMConfigParser(SafeConfigParser): 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) - @staticmethod - def addresses(): - """Return a list of local bitmessage addresses (from section labels)""" - return [ - x for x in BMConfigParser().sections() if x.startswith('BM-')] + if sys.version_info[0] == 3: + @staticmethod + def addresses(hidden=False): + """Return a list of local bitmessage addresses (from section labels)""" + return [x for x in BMConfigParser().sections() if x.startswith('BM-') and ( + hidden or not BMConfigParser().safeGetBoolean(x, 'hidden'))] - def _reset(self): - """Reset current config. There doesn't appear to be a built in - method for this""" - sections = self.sections() - for x in sections: - self.remove_section(x) + def 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, + self[section][option] + ): + try: + newVal = BMConfigDefaults[section][option] + except ConfigParser.NoSectionError: + continue + except KeyError: + continue + ConfigParser.ConfigParser.set( + self, section, option, newVal) + except ConfigParser.InterpolationError: + continue - def read(self, filenames): - """Read config and populate defaults""" - self._reset() - 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) - ): - try: - newVal = BMConfigDefaults[section][option] - except KeyError: - continue - ConfigParser.ConfigParser.set( - self, section, option, newVal) - except ConfigParser.InterpolationError: - continue + else: + @staticmethod + def addresses(): + """Return a list of local bitmessage addresses (from section labels)""" + return [ + x for x in BMConfigParser().sections() if x.startswith('BM-')] + + def _reset(self): + """Reset current config. There doesn't appear to be a built in + method for this""" + sections = self.sections() + for x in sections: + self.remove_section(x) + + def read(self, filenames): + """Read config and populate defaults""" + self._reset() + 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) + ): + try: + newVal = BMConfigDefaults[section][option] + except KeyError: + continue + ConfigParser.ConfigParser.set( + self, section, option, newVal) + except ConfigParser.InterpolationError: + continue def save(self): """Save the runtime config onto the filesystem""" @@ -198,8 +231,8 @@ class BMConfigParser(SafeConfigParser): # The backup failed. This can happen if the file # 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: @@ -208,7 +241,11 @@ class BMConfigParser(SafeConfigParser): def validate(self, section, option, value): """Input validator interface (using factory pattern)""" try: - return getattr(self, 'validate_%s_%s' % (section, option))(value) + if sys.version_info[0] == 3: + return getattr(self, 'validate_{}_{}'.format( + section, option))(value) + else: + return getattr(self, 'validate_%s_%s' % (section, option))(value) except AttributeError: return True @@ -222,4 +259,3 @@ class BMConfigParser(SafeConfigParser): if value < 0 or value > 8: return False return True - diff --git a/src/class_sqlThread.py b/src/class_sqlThread.py index 84188408..d2a0d2ec 100644 --- a/src/class_sqlThread.py +++ b/src/class_sqlThread.py @@ -9,15 +9,28 @@ import sys import threading import time -import helper_sql -import helper_startup -import paths -import queues -import state -import tr -from bmconfigparser import BMConfigParser -from debug import logger -# pylint: disable=attribute-defined-outside-init,protected-access +if sys.version_info[0] == 3: + from . import helper_sql + from . import helper_startup + from . import paths + from . import queues + from . import state + from . import tr + from .bmconfigparser import BMConfigParser + from .debug import logger + # pylint: disable=attribute-defined-outside-init,protected-access + from .addresses import encodeAddress +else: + import helper_sql + import helper_startup + import paths + import queues + import state + import tr + from bmconfigparser import BMConfigParser + from debug import logger + # pylint: disable=attribute-defined-outside-init,protected-access + from addresses import encodeAddress class sqlThread(threading.Thread): @@ -35,6 +48,9 @@ class sqlThread(threading.Thread): self.cur.execute('PRAGMA secure_delete = true') + # call create_function for encode address + self.create_function() + try: self.cur.execute( '''CREATE TABLE inbox (msgid blob, toaddress text, fromaddress text, subject text,''' @@ -325,6 +341,7 @@ class sqlThread(threading.Thread): # We'll also need a `sleeptill` field and a `ttl` field. Also we # can combine the pubkeyretrynumber and msgretrynumber into one. + item = '''SELECT value FROM settings WHERE key='version';''' parameters = '' self.cur.execute(item, parameters) @@ -358,16 +375,11 @@ class sqlThread(threading.Thread): logger.debug('In messages.dat database, adding address field to the pubkeys table.') # We're going to have to calculate the address for each row in the pubkeys # table. Then we can take out the hash field. - self.cur.execute('''ALTER TABLE pubkeys ADD address text DEFAULT '' ''') - self.cur.execute('''SELECT hash, addressversion FROM pubkeys''') - queryResult = self.cur.fetchall() - from addresses import encodeAddress - for row in queryResult: - addressHash, addressVersion = row - address = encodeAddress(addressVersion, 1, hash) - item = '''UPDATE pubkeys SET address=? WHERE hash=?;''' - parameters = (address, addressHash) - self.cur.execute(item, parameters) + self.cur.execute('''ALTER TABLE pubkeys ADD address text DEFAULT '' ;''') + + # replica for loop to update hashed address + self.cur.execute('''UPDATE pubkeys SET address=(enaddr(pubkeys.addressversion, 1, hash)); ''') + # Now we can remove the hash field from the pubkeys table. self.cur.execute( '''CREATE TEMPORARY TABLE pubkeys_backup''' @@ -622,3 +634,12 @@ class sqlThread(threading.Thread): helper_sql.sqlReturnQueue.put((self.cur.fetchall(), rowcount)) # helper_sql.sqlSubmitQueue.task_done() + + def create_function(self): + # create_function + try: + self.conn.create_function("enaddr", 3, func=encodeAddress, deterministic=True) + except (TypeError, sqlite3.NotSupportedError) as err: + logger.debug( + "Got error while pass deterministic in sqlite create function {}, Passing 3 params".format(err)) + self.conn.create_function("enaddr", 3, encodeAddress) diff --git a/src/debug.py b/src/debug.py index cab07275..3acd8e2c 100644 --- a/src/debug.py +++ b/src/debug.py @@ -35,14 +35,26 @@ Logging is thread-safe so you don't have to worry about locks, just import and log. """ -import ConfigParser +# import ConfigParser +import sys +if sys.version_info[0] == 3: + # python 3 + import configparser as ConfigParser +else: + # python 2 + import ConfigParser + import logging import logging.config import os import sys -import helper_startup -import state +if sys.version_info[0] == 3: + from . import helper_startup + from . import state +else: + import helper_startup + import state helper_startup.loadConfig() @@ -74,7 +86,7 @@ def configureLogging(): False, 'Loaded logger configuration from %s' % logging_config ) - except (OSError, ConfigParser.NoSectionError): + except (OSError, ConfigParser.NoSectionError, KeyError): if os.path.isfile(logging_config): fail_msg = \ 'Failed to load logger configuration from %s, using default' \ @@ -149,6 +161,7 @@ def resetLogging(): # ! + preconfigured, msg = configureLogging() logger = logging.getLogger('default') if msg: diff --git a/src/helper_random.py b/src/helper_random.py index 9a29d5e2..55e41e12 100644 --- a/src/helper_random.py +++ b/src/helper_random.py @@ -2,8 +2,11 @@ import os import random - -from pyelliptic.openssl import OpenSSL +import sys +if sys.version_info[0] == 3: + from .pyelliptic.openssl import OpenSSL +else: + from pyelliptic.openssl import OpenSSL NoneType = type(None) diff --git a/src/helper_sql.py b/src/helper_sql.py index 043bccf2..5bd2f0f7 100644 --- a/src/helper_sql.py +++ b/src/helper_sql.py @@ -16,9 +16,17 @@ SQLite objects can only be used from one thread. or isn't thread-safe. """ -import Queue + +# import Queue +import sys +if sys.version_info[0] == 3: + import queue as Queue #python3 +else: + import Queue #python2 + import threading + sqlSubmitQueue = Queue.Queue() """the queue for SQL""" sqlReturnQueue = Queue.Queue() @@ -105,11 +113,23 @@ def sqlExecute(sql_statement, *args): return rowcount +def sqlExecuteScript(sql_statement): + """Execute SQL script statement""" + + statements = sql_statement.split(";") + with SqlBulkExecute() as sql: + for q in statements: + sql.execute("{}".format(q)) + + def sqlStoredProcedure(procName): """Schedule procName to be run""" assert sql_available sql_lock.acquire() sqlSubmitQueue.put(procName) + if procName == "exit": + sqlSubmitQueue.task_done() + sqlSubmitQueue.put("terminate") sql_lock.release() diff --git a/src/helper_startup.py b/src/helper_startup.py index fcd12aa4..332fe058 100644 --- a/src/helper_startup.py +++ b/src/helper_startup.py @@ -10,11 +10,19 @@ import sys import time from distutils.version import StrictVersion -import defaults -import helper_random -import paths -import state -from bmconfigparser import BMConfigParser +import sys +if sys.version_info[0] == 3: + from . import defaults + from . import helper_random + from . import paths + from . import state + from .bmconfigparser import BMConfigParser +else: + import defaults + import helper_random + import paths + import state + from bmconfigparser import BMConfigParser try: from plugins.plugin import get_plugin diff --git a/src/multiqueue.py b/src/multiqueue.py index d7c10847..886d693d 100644 --- a/src/multiqueue.py +++ b/src/multiqueue.py @@ -3,10 +3,18 @@ A queue with multiple internal subqueues. Elements are added into a random subqueue, and retrieval rotates """ -import Queue +import sys +if sys.version_info[0] == 3: + import queue as Queue +else: + import Queue + from collections import deque -import helper_random +if sys.version_info[0] == 3: + from . import helper_random +else: + import helper_random class MultiQueue(Queue.Queue): diff --git a/src/namecoin.py b/src/namecoin.py index ae2bde79..cf9081cd 100644 --- a/src/namecoin.py +++ b/src/namecoin.py @@ -174,7 +174,7 @@ class namecoinConnection(object): message = ('failed', tr._translate("MainWindow", 'Couldn\'t understand NMControl.')) else: - print "Unsupported Namecoin type" + print ("Unsupported Namecoin type") sys.exit(1) return message diff --git a/src/queues.py b/src/queues.py index 7d9e284a..40ebcdad 100644 --- a/src/queues.py +++ b/src/queues.py @@ -1,11 +1,19 @@ """Most of the queues used by bitmessage threads are defined here.""" -import Queue +import sys +if sys.version_info[0] == 3: + import queue as Queue +else: + import Queue + import threading import time -from multiqueue import MultiQueue - +import sys +if sys.version_info[0] == 3: + from .multiqueue import MultiQueue +else: + from multiqueue import MultiQueue class ObjectProcessorQueue(Queue.Queue): """Special queue class using lock for `.threads.objectProcessor`""" diff --git a/src/singleinstance.py b/src/singleinstance.py index d0a0871c..09ca2e9a 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 @@ -99,7 +99,7 @@ class singleinstance(object): pass return - print "Cleaning up lockfile" + print ("Cleaning up lockfile") try: if sys.platform == 'win32': if hasattr(self, 'fd'): diff --git a/src/tests/sql/create_function.sql b/src/tests/sql/create_function.sql new file mode 100644 index 00000000..cc59904b --- /dev/null +++ b/src/tests/sql/create_function.sql @@ -0,0 +1,9 @@ +CREATE TABLE `testhash` ( + `addressversion` int DEFAULT NULL, + `hash` blob DEFAULT NULL, + `address` text DEFAULT NULL, + UNIQUE(address) ON CONFLICT IGNORE +); + +INSERT INTO testhash (addressversion, hash) VALUES(4, "21122112211221122112"); + diff --git a/src/tests/test_api.py b/src/tests/test_api.py index 43c97233..1d8891a8 100644 --- a/src/tests/test_api.py +++ b/src/tests/test_api.py @@ -5,6 +5,9 @@ Tests using API. import base64 import json import time +from .common import skip_python3 + +skip_python3() try: # nosec from xmlrpclib import ServerProxy, ProtocolError diff --git a/src/tests/test_blindsig.py b/src/tests/test_blindsig.py index 4994d87c..76902347 100644 --- a/src/tests/test_blindsig.py +++ b/src/tests/test_blindsig.py @@ -4,6 +4,9 @@ Test for ECC blind signatures import os import unittest from hashlib import sha256 +from .common import skip_python3 + +skip_python3() from pybitmessage.pyelliptic import ECCBlind, ECCBlindChain, OpenSSL diff --git a/src/tests/test_config_process.py b/src/tests/test_config_process.py index f3cf19f2..0a612759 100644 --- a/src/tests/test_config_process.py +++ b/src/tests/test_config_process.py @@ -6,6 +6,9 @@ import os import tempfile from pybitmessage.bmconfigparser import BMConfigParser from .test_process import TestProcessProto +from .common import skip_python3 + +skip_python3() class TestProcessConfig(TestProcessProto): diff --git a/src/tests/test_randomtrackingdict.py b/src/tests/test_randomtrackingdict.py index bb66c0e2..606b88d1 100644 --- a/src/tests/test_randomtrackingdict.py +++ b/src/tests/test_randomtrackingdict.py @@ -5,6 +5,9 @@ import random import unittest from time import time +from .common import skip_python3 + +skip_python3() class TestRandomTrackingDict(unittest.TestCase): diff --git a/src/tests/test_sqlthread.py b/src/tests/test_sqlthread.py new file mode 100644 index 00000000..079aea92 --- /dev/null +++ b/src/tests/test_sqlthread.py @@ -0,0 +1,75 @@ +""" + Test for sqlThread +""" + +import os +import unittest +from ..helper_sql import sqlStoredProcedure, sql_ready, sqlExecute, SqlBulkExecute, sqlQuery, sqlExecuteScript +from ..class_sqlThread import (sqlThread) +from ..addresses import encodeAddress + +import threading + +class TestSqlThread(unittest.TestCase): + """ + Test case for SQLThread + """ + + # query file path + root_path = os.path.dirname(os.path.dirname(__file__)) + + + + @classmethod + def setUpClass(cls): + # Start SQL thread + sqlLookup = sqlThread() + sqlLookup.daemon = True + sqlLookup.start() + sql_ready.wait() + + + @classmethod + def setUp(cls): + tables = list(sqlQuery("select name from sqlite_master where type is 'table'")) + with SqlBulkExecute() as sql: + for q in tables: + sql.execute("drop table if exists %s" % q) + + @classmethod + def tearDown(cls): + pass + + @classmethod + def tearDownClass(cls): + sqlStoredProcedure('exit') + for thread in threading.enumerate(): + if thread.name == "SQL": + thread.join() + + def initialise_database(self, file): + """ + Initialise DB + """ + with open(os.path.join(self.root_path, "tests/sql/{}.sql".format(file)), 'r') as sql_as_string: + # sql_as_string = open(os.path.join(self.root_path, "tests/sql/{}.sql".format(file))).read() + sql_as_string = sql_as_string.read() + sqlExecuteScript(sql_as_string) + + def test_create_function(self): + # call create function + encoded_str = encodeAddress(4, 1, "21122112211221122112") + + # Initialise Database + self.initialise_database("create_function") + + sqlExecute('''INSERT INTO testhash (addressversion, hash) VALUES(4, "21122112211221122112")''') + # call function in query + + # sqlExecute('''UPDATE testhash SET address=(enaddr(testhash.addressversion, 1, hash)) WHERE hash=testhash.hash''') + sqlExecute('''UPDATE testhash SET address=(enaddr(testhash.addressversion, 1, hash));''') + + # Assertion + query = sqlQuery('''select * from testhash;''') + self.assertEqual(query[0][-1], encoded_str, "test case fail for create_function") + sqlExecute('''DROP TABLE testhash''') diff --git a/src/tr.py b/src/tr.py index ac76ef4b..19dca6d4 100644 --- a/src/tr.py +++ b/src/tr.py @@ -3,7 +3,11 @@ Translating text """ import os -import state +import sys +if sys.version_info[0] == 3: + from . import state +else: + import state class translateClass: @@ -40,12 +44,12 @@ 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'\ + 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 + ' 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)