From 05c49a31cd71f68bd634eea7f29043edc71dfd89 Mon Sep 17 00:00:00 2001 From: Jonathan Warren Date: Fri, 3 May 2013 15:53:38 -0400 Subject: [PATCH] support switching to and from portable mode without restarting --- src/bitmessagemain.py | 56 ++++++++++++++++-------------------- src/bitmessageqt/__init__.py | 11 ++++--- src/shared.py | 8 +++--- 3 files changed, 36 insertions(+), 39 deletions(-) diff --git a/src/bitmessagemain.py b/src/bitmessagemain.py index adeb657f..9f371865 100755 --- a/src/bitmessagemain.py +++ b/src/bitmessagemain.py @@ -300,7 +300,7 @@ class receiveDataThread(threading.Thread): print 'Could not delete', self.HOST, 'from shared.connectedHostsList.', err shared.UISignalQueue.put(('updateNetworkStatusTab','no data')) shared.printLock.acquire() - print 'The size of the shared.connectedHostsList is now:', len(shared.connectedHostsList) + print 'The size of the connectedHostsList is now:', len(shared.connectedHostsList) shared.printLock.release() def processData(self): @@ -2425,8 +2425,29 @@ class sqlThread(threading.Thread): if item == 'commit': self.conn.commit() elif item == 'exit': + self.conn.close() print 'sqlThread exiting gracefully.' return + elif item == 'movemessagstoprog': + shared.printLock.acquire() + print 'the sqlThread is moving the messages.dat file to the local program directory.' + shared.printLock.release() + self.conn.commit() + self.conn.close() + shutil.move(shared.lookupAppdataFolder()+'messages.dat','messages.dat') + self.conn = sqlite3.connect('messages.dat' ) + self.conn.text_factory = str + self.cur = self.conn.cursor() + elif item == 'movemessagstoappdata': + shared.printLock.acquire() + print 'the sqlThread is moving the messages.dat file to the Appdata folder.' + shared.printLock.release() + self.conn.commit() + self.conn.close() + shutil.move('messages.dat',shared.lookupAppdataFolder()+'messages.dat') + self.conn = sqlite3.connect(shared.appdata + 'messages.dat' ) + self.conn.text_factory = str + self.cur = self.conn.cursor() else: parameters = shared.sqlSubmitQueue.get() #print 'item', item @@ -3710,17 +3731,17 @@ alreadyAttemptedConnectionsListLock = threading.Lock() eightBytesOfRandomDataUsedToDetectConnectionsToSelf = pack('>Q',random.randrange(1, 18446744073709551615)) neededPubkeys = {} successfullyDecryptMessageTimings = [] #A list of the amounts of time it took to successfully decrypt msg messages -#apiSignalQueue = Queue.Queue() #The singleAPI thread uses this queue to pass messages to a QT thread which can emit signals to do things like display a message in the UI. apiAddressGeneratorReturnQueue = Queue.Queue() #The address generator thread uses this queue to get information back to the API thread. alreadyAttemptedConnectionsListResetTime = int(time.time()) #used to clear out the alreadyAttemptedConnectionsList periodically so that we will retry connecting to hosts to which we have already tried to connect. if useVeryEasyProofOfWorkForTesting: - shared.networkDefaultProofOfWorkNonceTrialsPerByte = shared.networkDefaultProofOfWorkNonceTrialsPerByte / 16 - shared.networkDefaultPayloadLengthExtraBytes = shared.networkDefaultPayloadLengthExtraBytes / 7000 + shared.networkDefaultProofOfWorkNonceTrialsPerByte = int(shared.networkDefaultProofOfWorkNonceTrialsPerByte / 16) + shared.networkDefaultPayloadLengthExtraBytes = int(shared.networkDefaultPayloadLengthExtraBytes / 7000) if __name__ == "__main__": signal.signal(signal.SIGINT, signal_handler) #signal.signal(signal.SIGINT, signal.SIG_DFL) + # Check the Major version, the first element in the array if sqlite3.sqlite_version_info[0] < 3: print 'This program requires sqlite version 3 or higher because 2 and lower cannot store NULL values. I see version:', sqlite3.sqlite_version_info @@ -3731,15 +3752,11 @@ if __name__ == "__main__": shared.config.read('keys.dat') try: shared.config.get('bitmessagesettings', 'settingsversion') - #settingsFileExistsInProgramDirectory = True print 'Loading config files from same directory as program' shared.appdata = '' except: #Could not load the keys.dat file in the program directory. Perhaps it is in the appdata directory. shared.appdata = shared.lookupAppdataFolder() - #if not os.path.exists(shared.appdata): - # os.makedirs(shared.appdata) - shared.config = ConfigParser.SafeConfigParser() shared.config.read(shared.appdata + 'keys.dat') try: @@ -3795,29 +3812,6 @@ if __name__ == "__main__": with open(shared.appdata + 'keys.dat', 'wb') as configfile: shared.config.write(configfile) - #Let us now see if we should move the messages.dat file. There is an option in the settings to switch 'Portable Mode' on or off. Most of the files are moved instantly, but the messages.dat file cannot be moved while it is open. Now that it is not open we can move it now! - try: - shared.config.getboolean('bitmessagesettings', 'movemessagstoprog') - #If we have reached this point then we must move the messages.dat file from the appdata folder to the program folder - print 'Moving messages.dat from its old location in the application data folder to its new home along side the program.' - shutil.move(lookupAppdataFolder()+'messages.dat','messages.dat') - shared.config.remove_option('bitmessagesettings', 'movemessagstoprog') - with open(shared.appdata + 'keys.dat', 'wb') as configfile: - shared.config.write(configfile) - except: - pass - try: - shared.config.getboolean('bitmessagesettings', 'movemessagstoappdata') - #If we have reached this point then we must move the messages.dat file from the appdata folder to the program folder - print 'Moving messages.dat from its old location next to the program to its new home in the application data folder.' - shutil.move('messages.dat',lookupAppdataFolder()+'messages.dat') - shared.config.remove_option('bitmessagesettings', 'movemessagstoappdata') - with open(shared.appdata + 'keys.dat', 'wb') as configfile: - shared.config.write(configfile) - except: - pass - - try: #We shouldn't have to use the shared.knownNodesLock because this had better be the only thread accessing knownNodes right now. pickleFile = open(shared.appdata + 'knownnodes.dat', 'rb') diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index 7e99db8a..52dba18a 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -21,6 +21,7 @@ from time import strftime, localtime, gmtime import time import os from pyelliptic.openssl import OpenSSL +import pickle class MyForm(QtGui.QMainWindow): def __init__(self, parent=None): @@ -1150,8 +1151,10 @@ class MyForm(QtGui.QMainWindow): pass if shared.appdata != '' and self.settingsDialogInstance.ui.checkBoxPortableMode.isChecked(): #If we are NOT using portable mode now but the user selected that we should... - shared.config.set('bitmessagesettings','movemessagstoprog','true') #Tells bitmessage to move the messages.dat file to the program directory the next time the program starts. #Write the keys.dat file to disk in the new location + shared.sqlLock.acquire() + shared.sqlSubmitQueue.put('movemessagstoprog') + shared.sqlLock.release() with open('keys.dat', 'wb') as configfile: shared.config.write(configfile) #Write the knownnodes.dat file to disk in the new location @@ -1163,13 +1166,14 @@ class MyForm(QtGui.QMainWindow): os.remove(shared.appdata + 'keys.dat') os.remove(shared.appdata + 'knownnodes.dat') shared.appdata = '' - QMessageBox.about(self, "Restart", "Bitmessage has moved most of your config files to the program directory but you must restart Bitmessage to move the last file (the file which holds messages).") if shared.appdata == '' and not self.settingsDialogInstance.ui.checkBoxPortableMode.isChecked(): #If we ARE using portable mode now but the user selected that we shouldn't... shared.appdata = shared.lookupAppdataFolder() if not os.path.exists(shared.appdata): os.makedirs(shared.appdata) - shared.config.set('bitmessagesettings','movemessagstoappdata','true') #Tells bitmessage to move the messages.dat file to the appdata directory the next time the program starts. + shared.sqlLock.acquire() + shared.sqlSubmitQueue.put('movemessagstoappdata') + shared.sqlLock.release() #Write the keys.dat file to disk in the new location with open(shared.appdata + 'keys.dat', 'wb') as configfile: shared.config.write(configfile) @@ -1181,7 +1185,6 @@ class MyForm(QtGui.QMainWindow): shared.knownNodesLock.release() os.remove('keys.dat') os.remove('knownnodes.dat') - QMessageBox.about(self, "Restart", "Bitmessage has moved most of your config files to the application data directory but you must restart Bitmessage to move the last file (the file which holds messages).") def click_radioButtonBlacklist(self): diff --git a/src/shared.py b/src/shared.py index 2a138cc7..0eb7fa18 100644 --- a/src/shared.py +++ b/src/shared.py @@ -37,16 +37,16 @@ def lookupAppdataFolder(): from os import path, environ if sys.platform == 'darwin': if "HOME" in environ: - appdata = path.join(os.environ["HOME"], "Library/Application support/", APPNAME) + '/' + dataFolder = path.join(os.environ["HOME"], "Library/Application support/", APPNAME) + '/' else: print 'Could not find home folder, please report this message and your OS X version to the BitMessage Github.' sys.exit() elif 'win32' in sys.platform or 'win64' in sys.platform: - appdata = path.join(environ['APPDATA'], APPNAME) + '\\' + dataFolder = path.join(environ['APPDATA'], APPNAME) + '\\' else: - appdata = path.expanduser(path.join("~", "." + APPNAME + "/")) - return appdata + dataFolder = path.expanduser(path.join("~", "." + APPNAME + "/")) + return dataFolder def isAddressInMyAddressBook(address): t = (address,)