mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-08 18:54:09 -04:00
Make report types optional in CLI
This commit is contained in:
parent
81ad156e53
commit
06bcd520b4
@ -6,7 +6,7 @@ __license__ = 'GPL v3'
|
||||
from PyQt4.Qt import QDialog, QVBoxLayout, QTreeWidget, QPushButton, \
|
||||
QDialogButtonBox, QApplication, QTreeWidgetItem
|
||||
|
||||
from calibre.library.check_library import CheckLibrary
|
||||
from calibre.library.check_library import CheckLibrary, CHECKS
|
||||
|
||||
class Item(QTreeWidgetItem):
|
||||
pass
|
||||
@ -71,7 +71,7 @@ class CheckLibraryDialog(QDialog):
|
||||
t.clear()
|
||||
t.setColumnCount(3);
|
||||
t.setHeaderLabels([_('Name'), _('Path from library'), _('Additional Information')])
|
||||
for check in checker.checks:
|
||||
for check in CHECKS:
|
||||
builder(t, checker, check)
|
||||
|
||||
t.setColumnWidth(0, 200)
|
||||
|
@ -15,17 +15,18 @@ EBOOK_EXTENSIONS = frozenset(BOOK_EXTENSIONS)
|
||||
|
||||
NORMALS = frozenset(['metadata.opf', 'cover.jpg'])
|
||||
|
||||
class CheckLibrary(object):
|
||||
CHECKS = [('invalid_titles', _('Invalid titles')),
|
||||
('extra_titles', _('Extra titles')),
|
||||
('invalid_authors', _('Invalid authors')),
|
||||
('extra_authors', _('Extra authors')),
|
||||
('missing_formats', _('Missing book formats')),
|
||||
('extra_formats', _('Extra book formats')),
|
||||
('extra_files', _('Unknown files in book')),
|
||||
('failed_folders', _('Folders raising exception'))
|
||||
]
|
||||
|
||||
checks = [('invalid_titles', _('Invalid titles')),
|
||||
('extra_titles', _('Extra titles')),
|
||||
('invalid_authors', _('Invalid authors')),
|
||||
('extra_authors', _('Extra authors')),
|
||||
('missing_formats', _('Missing book formats')),
|
||||
('extra_formats', _('Extra book formats')),
|
||||
('extra_files', _('Unknown files in book')),
|
||||
('failed_folders', _('Folders raising exception'))
|
||||
]
|
||||
|
||||
class CheckLibrary(object):
|
||||
|
||||
def __init__(self, library_path, db):
|
||||
if isbytestring(library_path):
|
||||
@ -35,7 +36,10 @@ class CheckLibrary(object):
|
||||
|
||||
self.all_authors = frozenset([x[1] for x in db.all_authors()])
|
||||
self.all_ids = frozenset([id for id in db.all_ids()])
|
||||
self.is_case_sensitive = db.is_case_sensitive
|
||||
self.all_dbpaths = frozenset(self.dbpath(id) for id in self.all_ids)
|
||||
self.all_lc_dbpaths = frozenset(self.dbpath(id).lower()
|
||||
for id in self.all_ids)
|
||||
|
||||
self.db_id_regexp = re.compile(r'^.* \((\d+)\)$')
|
||||
self.bad_ext_pat = re.compile(r'[^a-z]+')
|
||||
@ -55,13 +59,6 @@ class CheckLibrary(object):
|
||||
self.extra_formats = []
|
||||
self.extra_files = []
|
||||
|
||||
self.failed_folders = []
|
||||
self.books = []
|
||||
self.conflicting_custom_cols = {}
|
||||
self.failed_restores = []
|
||||
self.mismatched_dirs = []
|
||||
self.successes = 0
|
||||
self.tb = None
|
||||
|
||||
def dbpath(self, id):
|
||||
return self.db.path(id, index_is_id=True)
|
||||
@ -71,34 +68,6 @@ class CheckLibrary(object):
|
||||
return self.failed_folders or self.mismatched_dirs or \
|
||||
self.conflicting_custom_cols or self.failed_restores
|
||||
|
||||
@property
|
||||
def report(self):
|
||||
ans = ''
|
||||
failures = list(self.failed_folders) + [(x['dirpath'], tb) for x, tb in
|
||||
self.failed_restores]
|
||||
if failures:
|
||||
ans += 'Failed to restore the books in the following folders:\n'
|
||||
for dirpath, tb in failures:
|
||||
ans += '\t' + dirpath + ' with error:\n'
|
||||
ans += '\n'.join('\t\t'+x for x in tb.splitlines())
|
||||
ans += '\n\n'
|
||||
|
||||
if self.conflicting_custom_cols:
|
||||
ans += '\n\n'
|
||||
ans += 'The following custom columns were not fully restored:\n'
|
||||
for x in self.conflicting_custom_cols:
|
||||
ans += '\t#'+x+'\n'
|
||||
|
||||
if self.mismatched_dirs:
|
||||
ans += '\n\n'
|
||||
ans += 'The following folders were ignored:\n'
|
||||
for x in self.mismatched_dirs:
|
||||
ans += '\t'+x+'\n'
|
||||
|
||||
|
||||
return ans
|
||||
|
||||
|
||||
def scan_library(self):
|
||||
lib = self.src_library_path
|
||||
for auth_dir in os.listdir(lib):
|
||||
@ -123,10 +92,16 @@ class CheckLibrary(object):
|
||||
|
||||
id = m.group(1)
|
||||
# Third check: the id must be in the DB and the paths must match
|
||||
if int(id) not in self.all_ids or \
|
||||
db_path not in self.all_dbpaths:
|
||||
self.extra_titles.append((title_dir, db_path, []))
|
||||
continue
|
||||
if self.is_case_sensitive:
|
||||
if int(id) not in self.all_ids or \
|
||||
db_path not in self.all_dbpaths:
|
||||
self.extra_titles.append((title_dir, db_path, []))
|
||||
continue
|
||||
else:
|
||||
if int(id) not in self.all_ids or \
|
||||
db_path.lower() not in self.all_lc_dbpaths:
|
||||
self.extra_titles.append((title_dir, db_path, []))
|
||||
continue
|
||||
|
||||
# Record the book to check its formats
|
||||
self.book_dirs.append((db_path, title_dir, id))
|
||||
|
@ -875,19 +875,23 @@ def command_saved_searches(args, dbpath):
|
||||
return 0
|
||||
|
||||
def check_library_option_parser():
|
||||
from calibre.library.custom_columns import CustomColumns
|
||||
from calibre.library.check_library import CHECKS
|
||||
parser = get_parser(_('''\
|
||||
%prog check_library [options]
|
||||
|
||||
Perform some checks on the filesystem representing a library.
|
||||
''').format(', '.join(CustomColumns.CUSTOM_DATA_TYPES)))
|
||||
Perform some checks on the filesystem representing a library. Reports are {0}
|
||||
''').format(', '.join([c[0] for c in CHECKS])))
|
||||
|
||||
parser.add_option('-c', '--csv', default=False, action='store_true',
|
||||
help=_('Output in CSV'))
|
||||
|
||||
parser.add_option('-r', '--report', default=None, dest='report',
|
||||
help=_("Comma-separated list of reports.\n"
|
||||
"Default: all"))
|
||||
return parser
|
||||
|
||||
def command_check_library(args, dbpath):
|
||||
from calibre.library.check_library import CheckLibrary
|
||||
from calibre.library.check_library import CheckLibrary, CHECKS
|
||||
parser = check_library_option_parser()
|
||||
opts, args = parser.parse_args(args)
|
||||
if len(args) != 0:
|
||||
@ -900,6 +904,21 @@ def command_check_library(args, dbpath):
|
||||
if isbytestring(dbpath):
|
||||
dbpath = dbpath.decode(preferred_encoding)
|
||||
|
||||
if opts.report is None:
|
||||
checks = CHECKS
|
||||
else:
|
||||
checks = []
|
||||
for r in opts.report.split(','):
|
||||
found = False
|
||||
for c in CHECKS:
|
||||
if c[0] == r:
|
||||
checks.append(c)
|
||||
found = True
|
||||
break
|
||||
if not found:
|
||||
print _('Unknown report check'), r
|
||||
return 1
|
||||
|
||||
def print_one(checker, check):
|
||||
attr = check[0]
|
||||
list = getattr(checker, attr, None)
|
||||
@ -916,7 +935,7 @@ def command_check_library(args, dbpath):
|
||||
db = LibraryDatabase2(dbpath)
|
||||
checker = CheckLibrary(dbpath, db)
|
||||
checker.scan_library()
|
||||
for check in checker.checks:
|
||||
for check in checks:
|
||||
print_one(checker, check)
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user