mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Create restore command for calibredb
This commit is contained in:
parent
02ce96cd68
commit
42ec47607c
@ -877,8 +877,54 @@ def command_saved_searches(args, dbpath):
|
|||||||
COMMANDS = ('list', 'add', 'remove', 'add_format', 'remove_format',
|
COMMANDS = ('list', 'add', 'remove', 'add_format', 'remove_format',
|
||||||
'show_metadata', 'set_metadata', 'export', 'catalog',
|
'show_metadata', 'set_metadata', 'export', 'catalog',
|
||||||
'saved_searches', 'add_custom_column', 'custom_columns',
|
'saved_searches', 'add_custom_column', 'custom_columns',
|
||||||
'remove_custom_column', 'set_custom')
|
'remove_custom_column', 'set_custom', 'restore_database')
|
||||||
|
|
||||||
|
def restore_database_option_parser():
|
||||||
|
parser = get_parser(_(
|
||||||
|
'''
|
||||||
|
%prog restore_database [options]
|
||||||
|
|
||||||
|
Restore this database from the metadata stored in OPF
|
||||||
|
files in each directory of the calibre library. This is
|
||||||
|
useful if your metadata.db file has been corrupted.
|
||||||
|
|
||||||
|
WARNING: This completely regenrates your datbase. You will
|
||||||
|
lose stored per-book conversion settings and custom recipes.
|
||||||
|
'''))
|
||||||
|
return parser
|
||||||
|
|
||||||
|
def command_restore_database(args, dbpath):
|
||||||
|
from calibre.library.restore import Restore
|
||||||
|
parser = saved_searches_option_parser()
|
||||||
|
opts, args = parser.parse_args(args)
|
||||||
|
if len(args) != 0:
|
||||||
|
parser.print_help()
|
||||||
|
return 1
|
||||||
|
|
||||||
|
class Progress(object):
|
||||||
|
def __init__(self): self.total = 1
|
||||||
|
|
||||||
|
def __call__(self, msg, step):
|
||||||
|
if msg is None:
|
||||||
|
self.total = float(step)
|
||||||
|
else:
|
||||||
|
prints(msg, '...', '%d%%'%int(100*(step/self.total)))
|
||||||
|
r = Restore(dbpath, progress_callback=Progress())
|
||||||
|
r.start()
|
||||||
|
r.join()
|
||||||
|
|
||||||
|
if r.tb is not None:
|
||||||
|
prints('Restoring database failed with error:')
|
||||||
|
prints(r.tb)
|
||||||
|
else:
|
||||||
|
prints('Restoring database succeeded')
|
||||||
|
if r.errors_occurred:
|
||||||
|
name = 'calibre_db_restore_report.txt'
|
||||||
|
open('calibre_db_restore_report.txt',
|
||||||
|
'wb').write(r.report.encode('utf-8'))
|
||||||
|
prints('Some errors occurred. A detailed report was '
|
||||||
|
'saved to', name)
|
||||||
|
send_message()
|
||||||
|
|
||||||
def option_parser():
|
def option_parser():
|
||||||
parser = OptionParser(_(
|
parser = OptionParser(_(
|
||||||
|
@ -23,12 +23,16 @@ NON_EBOOK_EXTENSIONS = frozenset([
|
|||||||
|
|
||||||
class RestoreDatabase(LibraryDatabase2):
|
class RestoreDatabase(LibraryDatabase2):
|
||||||
|
|
||||||
def set_path(self, book_id, *args, **kwargs):
|
def set_path(self, *args, **kwargs):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def dirtied(self, *args, **kwargs):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class Restore(Thread):
|
class Restore(Thread):
|
||||||
|
|
||||||
def __init__(self, library_path, progress_callback=None):
|
def __init__(self, library_path, progress_callback=None):
|
||||||
|
super(Restore, self).__init__()
|
||||||
if isbytestring(library_path):
|
if isbytestring(library_path):
|
||||||
library_path = library_path.decode(filesystem_encoding)
|
library_path = library_path.decode(filesystem_encoding)
|
||||||
self.src_library_path = os.path.abspath(library_path)
|
self.src_library_path = os.path.abspath(library_path)
|
||||||
@ -43,6 +47,7 @@ class Restore(Thread):
|
|||||||
self.books = []
|
self.books = []
|
||||||
self.conflicting_custom_cols = {}
|
self.conflicting_custom_cols = {}
|
||||||
self.failed_restores = []
|
self.failed_restores = []
|
||||||
|
self.tb = None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def errors_occurred(self):
|
def errors_occurred(self):
|
||||||
@ -72,12 +77,15 @@ class Restore(Thread):
|
|||||||
|
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
with TemporaryDirectory('_library_restore') as tdir:
|
try:
|
||||||
self.library_path = tdir
|
with TemporaryDirectory('_library_restore') as tdir:
|
||||||
self.scan_library()
|
self.library_path = tdir
|
||||||
self.create_cc_metadata()
|
self.scan_library()
|
||||||
self.restore_books()
|
self.create_cc_metadata()
|
||||||
self.replace_db()
|
self.restore_books()
|
||||||
|
self.replace_db()
|
||||||
|
except:
|
||||||
|
self.tb = traceback.format_exc()
|
||||||
|
|
||||||
def scan_library(self):
|
def scan_library(self):
|
||||||
for dirpath, dirnames, filenames in os.walk(self.src_library_path):
|
for dirpath, dirnames, filenames in os.walk(self.src_library_path):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user