mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-06-23 15:30:45 -04:00
Windows: Run library restore ina separate process as on some windows machines, running it in the main process causes something in the system to lock the db file.
This commit is contained in:
parent
dd2ef16429
commit
ef3463aa35
@ -17,7 +17,7 @@ class DBRestore(QDialog):
|
||||
|
||||
update_signal = pyqtSignal(object, object)
|
||||
|
||||
def __init__(self, parent, library_path):
|
||||
def __init__(self, parent, library_path, wait_time=2):
|
||||
QDialog.__init__(self, parent)
|
||||
self.l = QVBoxLayout()
|
||||
self.setLayout(self.l)
|
||||
@ -46,7 +46,7 @@ class DBRestore(QDialog):
|
||||
self.restorer.daemon = True
|
||||
|
||||
# Give the metadata backup thread time to stop
|
||||
QTimer.singleShot(2000, self.start)
|
||||
QTimer.singleShot(wait_time * 1000, self.start)
|
||||
|
||||
def start(self):
|
||||
self.restorer.start()
|
||||
@ -117,14 +117,14 @@ def restore_database(db, parent=None):
|
||||
_show_success_msg(r, parent=parent)
|
||||
return True
|
||||
|
||||
def repair_library_at(library_path, parent=None):
|
||||
d = DBRestore(parent, library_path)
|
||||
def repair_library_at(library_path, parent=None, wait_time=2):
|
||||
d = DBRestore(parent, library_path, wait_time=wait_time)
|
||||
d.exec_()
|
||||
if d.rejected:
|
||||
return False
|
||||
r = d.restorer
|
||||
if r.tb is not None:
|
||||
error_dialog(parent, _('Failed'),
|
||||
error_dialog(parent, _('Failed to repair library'),
|
||||
_('Restoring database failed, click Show details to see details'),
|
||||
det_msg=r.tb, show=True)
|
||||
return False
|
||||
|
@ -151,6 +151,29 @@ def repair_library(library_path):
|
||||
from calibre.gui2.dialogs.restore_library import repair_library_at
|
||||
return repair_library_at(library_path)
|
||||
|
||||
def windows_repair(library_path=None):
|
||||
from binascii import hexlify, unhexlify
|
||||
import cPickle, subprocess
|
||||
if library_path:
|
||||
library_path = hexlify(cPickle.dumps(library_path, -1))
|
||||
winutil.prepare_for_restart()
|
||||
os.environ['CALIBRE_REPAIR_CORRUPTED_DB'] = library_path
|
||||
subprocess.Popen([sys.executable])
|
||||
else:
|
||||
try:
|
||||
app = Application([])
|
||||
from calibre.gui2.dialogs.restore_library import repair_library_at
|
||||
library_path = cPickle.loads(unhexlify(os.environ.pop('CALIBRE_REPAIR_CORRUPTED_DB')))
|
||||
done = repair_library_at(library_path, wait_time=4)
|
||||
except Exception:
|
||||
done = False
|
||||
error_dialog(None, _('Failed to repair library'), _(
|
||||
'Could not repair library. Click "Show details" for more information.'), det_msg=traceback.format_exc(), show=True)
|
||||
if done:
|
||||
subprocess.Popen([sys.executable])
|
||||
app.quit()
|
||||
|
||||
|
||||
class EventAccumulator(object):
|
||||
|
||||
def __init__(self):
|
||||
@ -266,6 +289,13 @@ class GuiRunner(QObject):
|
||||
det_msg=traceback.format_exc()
|
||||
)
|
||||
if repair:
|
||||
if iswindows:
|
||||
# On some windows systems the existing db file gets locked
|
||||
# by something when running restore from the main process.
|
||||
# So run the restore in a separate process.
|
||||
windows_repair(self.library_path)
|
||||
self.app.quit()
|
||||
return
|
||||
if repair_library(self.library_path):
|
||||
db = LibraryDatabase(self.library_path)
|
||||
except:
|
||||
@ -455,6 +485,9 @@ def create_listener():
|
||||
return Listener(address=gui_socket_address())
|
||||
|
||||
def main(args=sys.argv):
|
||||
if iswindows and 'CALIBRE_REPAIR_CORRUPTED_DB' in os.environ:
|
||||
windows_repair()
|
||||
return 0
|
||||
gui_debug = None
|
||||
if args[0] == '__CALIBRE_GUI_DEBUG__':
|
||||
gui_debug = args[1]
|
||||
|
Loading…
x
Reference in New Issue
Block a user