mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
calibredb: Add a backup_metadata command to manually run the backup to opf from the command line
This commit is contained in:
parent
b620da0b26
commit
912e8fbacd
@ -999,6 +999,55 @@ def command_saved_searches(args, dbpath):
|
|||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
def backup_metadata_option_parser():
|
||||||
|
parser = get_parser(_('''\
|
||||||
|
%prog backup_metadata [options]
|
||||||
|
|
||||||
|
Backup the metadata stored in the database into individual OPF files in each
|
||||||
|
books directory. This normally happens automatically, but you can run this
|
||||||
|
command to force re-generation of the OPF files, with the --all option.
|
||||||
|
|
||||||
|
Note that there is normally no need to do this, as the OPF files are backed up
|
||||||
|
automatically, every time metadata is changed.
|
||||||
|
'''))
|
||||||
|
parser.add_option('--all', default=False, action='store_true',
|
||||||
|
help=_('Normally, this command only operates on books that have'
|
||||||
|
' out of date OPF files. This option makes it operate on all'
|
||||||
|
' books.'))
|
||||||
|
return parser
|
||||||
|
|
||||||
|
class BackupProgress(object):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.total = 0
|
||||||
|
self.count = 0
|
||||||
|
|
||||||
|
def __call__(self, book_id, mi, ok):
|
||||||
|
if mi is True:
|
||||||
|
self.total = book_id
|
||||||
|
else:
|
||||||
|
self.count += 1
|
||||||
|
prints(u'%.1f%% %s - %s'%((self.count*100)/float(self.total),
|
||||||
|
book_id, mi.title))
|
||||||
|
|
||||||
|
def command_backup_metadata(args, dbpath):
|
||||||
|
parser = backup_metadata_option_parser()
|
||||||
|
opts, args = parser.parse_args(args)
|
||||||
|
if len(args) != 0:
|
||||||
|
parser.print_help()
|
||||||
|
return 1
|
||||||
|
|
||||||
|
if opts.library_path is not None:
|
||||||
|
dbpath = opts.library_path
|
||||||
|
if isbytestring(dbpath):
|
||||||
|
dbpath = dbpath.decode(preferred_encoding)
|
||||||
|
db = LibraryDatabase2(dbpath)
|
||||||
|
book_ids = None
|
||||||
|
if opts.all:
|
||||||
|
book_ids = db.all_ids()
|
||||||
|
db.dump_metadata(book_ids=book_ids, callback=BackupProgress())
|
||||||
|
|
||||||
|
|
||||||
def check_library_option_parser():
|
def check_library_option_parser():
|
||||||
from calibre.library.check_library import CHECKS
|
from calibre.library.check_library import CHECKS
|
||||||
parser = get_parser(_('''\
|
parser = get_parser(_('''\
|
||||||
@ -1275,7 +1324,7 @@ 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', 'restore_database',
|
'remove_custom_column', 'set_custom', 'restore_database',
|
||||||
'check_library', 'list_categories')
|
'check_library', 'list_categories', 'backup_metadata')
|
||||||
|
|
||||||
|
|
||||||
def option_parser():
|
def option_parser():
|
||||||
|
@ -808,18 +808,30 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def dump_metadata(self, book_ids=None, remove_from_dirtied=True,
|
def dump_metadata(self, book_ids=None, remove_from_dirtied=True,
|
||||||
commit=True):
|
commit=True, callback=None):
|
||||||
'''
|
'''
|
||||||
Write metadata for each record to an individual OPF file
|
Write metadata for each record to an individual OPF file. If callback
|
||||||
|
is not None, it is called once at the start with the number of book_ids
|
||||||
|
being processed. And once for every book_id, with arguments (book_id,
|
||||||
|
mi, ok).
|
||||||
'''
|
'''
|
||||||
if book_ids is None:
|
if book_ids is None:
|
||||||
book_ids = [x[0] for x in self.conn.get(
|
book_ids = [x[0] for x in self.conn.get(
|
||||||
'SELECT book FROM metadata_dirtied', all=True)]
|
'SELECT book FROM metadata_dirtied', all=True)]
|
||||||
|
|
||||||
|
if callback is not None:
|
||||||
|
book_ids = tuple(book_ids)
|
||||||
|
callback(len(book_ids), True, False)
|
||||||
|
|
||||||
for book_id in book_ids:
|
for book_id in book_ids:
|
||||||
if not self.data.has_id(book_id):
|
if not self.data.has_id(book_id):
|
||||||
|
if callback is not None:
|
||||||
|
callback(book_id, None, False)
|
||||||
continue
|
continue
|
||||||
path, mi, sequence = self.get_metadata_for_dump(book_id)
|
path, mi, sequence = self.get_metadata_for_dump(book_id)
|
||||||
if path is None:
|
if path is None:
|
||||||
|
if callback is not None:
|
||||||
|
callback(book_id, mi, False)
|
||||||
continue
|
continue
|
||||||
try:
|
try:
|
||||||
raw = metadata_to_opf(mi)
|
raw = metadata_to_opf(mi)
|
||||||
@ -829,6 +841,8 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
|||||||
self.clear_dirtied(book_id, sequence)
|
self.clear_dirtied(book_id, sequence)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
if callback is not None:
|
||||||
|
callback(book_id, mi, True)
|
||||||
if commit:
|
if commit:
|
||||||
self.conn.commit()
|
self.conn.commit()
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user