calibredb: Add a backup_metadata command to manually run the backup to opf from the command line

This commit is contained in:
Kovid Goyal 2012-07-04 10:07:34 +05:30
parent b620da0b26
commit 912e8fbacd
2 changed files with 66 additions and 3 deletions

View File

@ -999,6 +999,55 @@ def command_saved_searches(args, dbpath):
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():
from calibre.library.check_library import CHECKS
parser = get_parser(_('''\
@ -1275,7 +1324,7 @@ COMMANDS = ('list', 'add', 'remove', 'add_format', 'remove_format',
'show_metadata', 'set_metadata', 'export', 'catalog',
'saved_searches', 'add_custom_column', 'custom_columns',
'remove_custom_column', 'set_custom', 'restore_database',
'check_library', 'list_categories')
'check_library', 'list_categories', 'backup_metadata')
def option_parser():

View File

@ -808,18 +808,30 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
pass
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:
book_ids = [x[0] for x in self.conn.get(
'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:
if not self.data.has_id(book_id):
if callback is not None:
callback(book_id, None, False)
continue
path, mi, sequence = self.get_metadata_for_dump(book_id)
if path is None:
if callback is not None:
callback(book_id, mi, False)
continue
try:
raw = metadata_to_opf(mi)
@ -829,6 +841,8 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
self.clear_dirtied(book_id, sequence)
except:
pass
if callback is not None:
callback(book_id, mi, True)
if commit:
self.conn.commit()