support switching to and from portable mode without restarting

This commit is contained in:
Jonathan Warren 2013-05-03 15:53:38 -04:00
parent caf9890bd1
commit 05c49a31cd
3 changed files with 36 additions and 39 deletions

View File

@ -300,7 +300,7 @@ class receiveDataThread(threading.Thread):
print 'Could not delete', self.HOST, 'from shared.connectedHostsList.', err print 'Could not delete', self.HOST, 'from shared.connectedHostsList.', err
shared.UISignalQueue.put(('updateNetworkStatusTab','no data')) shared.UISignalQueue.put(('updateNetworkStatusTab','no data'))
shared.printLock.acquire() 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() shared.printLock.release()
def processData(self): def processData(self):
@ -2425,8 +2425,29 @@ class sqlThread(threading.Thread):
if item == 'commit': if item == 'commit':
self.conn.commit() self.conn.commit()
elif item == 'exit': elif item == 'exit':
self.conn.close()
print 'sqlThread exiting gracefully.' print 'sqlThread exiting gracefully.'
return 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: else:
parameters = shared.sqlSubmitQueue.get() parameters = shared.sqlSubmitQueue.get()
#print 'item', item #print 'item', item
@ -3710,17 +3731,17 @@ alreadyAttemptedConnectionsListLock = threading.Lock()
eightBytesOfRandomDataUsedToDetectConnectionsToSelf = pack('>Q',random.randrange(1, 18446744073709551615)) eightBytesOfRandomDataUsedToDetectConnectionsToSelf = pack('>Q',random.randrange(1, 18446744073709551615))
neededPubkeys = {} neededPubkeys = {}
successfullyDecryptMessageTimings = [] #A list of the amounts of time it took to successfully decrypt msg messages 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. 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. 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: if useVeryEasyProofOfWorkForTesting:
shared.networkDefaultProofOfWorkNonceTrialsPerByte = shared.networkDefaultProofOfWorkNonceTrialsPerByte / 16 shared.networkDefaultProofOfWorkNonceTrialsPerByte = int(shared.networkDefaultProofOfWorkNonceTrialsPerByte / 16)
shared.networkDefaultPayloadLengthExtraBytes = shared.networkDefaultPayloadLengthExtraBytes / 7000 shared.networkDefaultPayloadLengthExtraBytes = int(shared.networkDefaultPayloadLengthExtraBytes / 7000)
if __name__ == "__main__": if __name__ == "__main__":
signal.signal(signal.SIGINT, signal_handler) signal.signal(signal.SIGINT, signal_handler)
#signal.signal(signal.SIGINT, signal.SIG_DFL) #signal.signal(signal.SIGINT, signal.SIG_DFL)
# Check the Major version, the first element in the array # Check the Major version, the first element in the array
if sqlite3.sqlite_version_info[0] < 3: 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 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') shared.config.read('keys.dat')
try: try:
shared.config.get('bitmessagesettings', 'settingsversion') shared.config.get('bitmessagesettings', 'settingsversion')
#settingsFileExistsInProgramDirectory = True
print 'Loading config files from same directory as program' print 'Loading config files from same directory as program'
shared.appdata = '' shared.appdata = ''
except: except:
#Could not load the keys.dat file in the program directory. Perhaps it is in the appdata directory. #Could not load the keys.dat file in the program directory. Perhaps it is in the appdata directory.
shared.appdata = shared.lookupAppdataFolder() shared.appdata = shared.lookupAppdataFolder()
#if not os.path.exists(shared.appdata):
# os.makedirs(shared.appdata)
shared.config = ConfigParser.SafeConfigParser() shared.config = ConfigParser.SafeConfigParser()
shared.config.read(shared.appdata + 'keys.dat') shared.config.read(shared.appdata + 'keys.dat')
try: try:
@ -3795,29 +3812,6 @@ if __name__ == "__main__":
with open(shared.appdata + 'keys.dat', 'wb') as configfile: with open(shared.appdata + 'keys.dat', 'wb') as configfile:
shared.config.write(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: try:
#We shouldn't have to use the shared.knownNodesLock because this had better be the only thread accessing knownNodes right now. #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') pickleFile = open(shared.appdata + 'knownnodes.dat', 'rb')

View File

@ -21,6 +21,7 @@ from time import strftime, localtime, gmtime
import time import time
import os import os
from pyelliptic.openssl import OpenSSL from pyelliptic.openssl import OpenSSL
import pickle
class MyForm(QtGui.QMainWindow): class MyForm(QtGui.QMainWindow):
def __init__(self, parent=None): def __init__(self, parent=None):
@ -1150,8 +1151,10 @@ class MyForm(QtGui.QMainWindow):
pass 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... 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 #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: with open('keys.dat', 'wb') as configfile:
shared.config.write(configfile) shared.config.write(configfile)
#Write the knownnodes.dat file to disk in the new location #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 + 'keys.dat')
os.remove(shared.appdata + 'knownnodes.dat') os.remove(shared.appdata + 'knownnodes.dat')
shared.appdata = '' 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... 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() shared.appdata = shared.lookupAppdataFolder()
if not os.path.exists(shared.appdata): if not os.path.exists(shared.appdata):
os.makedirs(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 #Write the keys.dat file to disk in the new location
with open(shared.appdata + 'keys.dat', 'wb') as configfile: with open(shared.appdata + 'keys.dat', 'wb') as configfile:
shared.config.write(configfile) shared.config.write(configfile)
@ -1181,7 +1185,6 @@ class MyForm(QtGui.QMainWindow):
shared.knownNodesLock.release() shared.knownNodesLock.release()
os.remove('keys.dat') os.remove('keys.dat')
os.remove('knownnodes.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): def click_radioButtonBlacklist(self):

View File

@ -37,16 +37,16 @@ def lookupAppdataFolder():
from os import path, environ from os import path, environ
if sys.platform == 'darwin': if sys.platform == 'darwin':
if "HOME" in environ: 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: else:
print 'Could not find home folder, please report this message and your OS X version to the BitMessage Github.' print 'Could not find home folder, please report this message and your OS X version to the BitMessage Github.'
sys.exit() sys.exit()
elif 'win32' in sys.platform or 'win64' in sys.platform: elif 'win32' in sys.platform or 'win64' in sys.platform:
appdata = path.join(environ['APPDATA'], APPNAME) + '\\' dataFolder = path.join(environ['APPDATA'], APPNAME) + '\\'
else: else:
appdata = path.expanduser(path.join("~", "." + APPNAME + "/")) dataFolder = path.expanduser(path.join("~", "." + APPNAME + "/"))
return appdata return dataFolder
def isAddressInMyAddressBook(address): def isAddressInMyAddressBook(address):
t = (address,) t = (address,)