mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Finish implementation of the rest of the import books API
This commit is contained in:
parent
213a2136cf
commit
396c4a6131
102
src/calibre/db/adding.py
Normal file
102
src/calibre/db/adding.py
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# vim:fileencoding=utf-8
|
||||||
|
from __future__ import (unicode_literals, division, absolute_import,
|
||||||
|
print_function)
|
||||||
|
|
||||||
|
__license__ = 'GPL v3'
|
||||||
|
__copyright__ = '2013, Kovid Goyal <kovid at kovidgoyal.net>'
|
||||||
|
|
||||||
|
import os
|
||||||
|
from calibre.ebooks import BOOK_EXTENSIONS
|
||||||
|
|
||||||
|
def find_books_in_directory(dirpath, single_book_per_directory):
|
||||||
|
dirpath = os.path.abspath(dirpath)
|
||||||
|
if single_book_per_directory:
|
||||||
|
formats = []
|
||||||
|
for path in os.listdir(dirpath):
|
||||||
|
path = os.path.abspath(os.path.join(dirpath, path))
|
||||||
|
if os.path.isdir(path) or not os.access(path, os.R_OK):
|
||||||
|
continue
|
||||||
|
ext = os.path.splitext(path)[1]
|
||||||
|
if not ext:
|
||||||
|
continue
|
||||||
|
ext = ext[1:].lower()
|
||||||
|
if ext not in BOOK_EXTENSIONS and ext != 'opf':
|
||||||
|
continue
|
||||||
|
formats.append(path)
|
||||||
|
yield formats
|
||||||
|
else:
|
||||||
|
books = {}
|
||||||
|
for path in os.listdir(dirpath):
|
||||||
|
path = os.path.abspath(os.path.join(dirpath, path))
|
||||||
|
if os.path.isdir(path) or not os.access(path, os.R_OK):
|
||||||
|
continue
|
||||||
|
ext = os.path.splitext(path)[1]
|
||||||
|
if not ext:
|
||||||
|
continue
|
||||||
|
ext = ext[1:].lower()
|
||||||
|
if ext not in BOOK_EXTENSIONS:
|
||||||
|
continue
|
||||||
|
|
||||||
|
key = os.path.splitext(path)[0]
|
||||||
|
if key not in books:
|
||||||
|
books[key] = []
|
||||||
|
books[key].append(path)
|
||||||
|
|
||||||
|
for formats in books.values():
|
||||||
|
yield formats
|
||||||
|
|
||||||
|
def import_book_directory_multiple(db, dirpath, callback=None,
|
||||||
|
added_ids=None):
|
||||||
|
from calibre.ebooks.metadata.meta import metadata_from_formats
|
||||||
|
|
||||||
|
duplicates = []
|
||||||
|
for formats in find_books_in_directory(dirpath, False):
|
||||||
|
mi = metadata_from_formats(formats)
|
||||||
|
if mi.title is None:
|
||||||
|
continue
|
||||||
|
if db.has_book(mi):
|
||||||
|
duplicates.append((mi, formats))
|
||||||
|
continue
|
||||||
|
book_id = db.import_book(mi, formats)
|
||||||
|
if added_ids is not None:
|
||||||
|
added_ids.add(book_id)
|
||||||
|
if callable(callback):
|
||||||
|
if callback(mi.title):
|
||||||
|
break
|
||||||
|
return duplicates
|
||||||
|
|
||||||
|
def import_book_directory(db, dirpath, callback=None, added_ids=None):
|
||||||
|
from calibre.ebooks.metadata.meta import metadata_from_formats
|
||||||
|
dirpath = os.path.abspath(dirpath)
|
||||||
|
formats = find_books_in_directory(dirpath, True)
|
||||||
|
formats = list(formats)[0]
|
||||||
|
if not formats:
|
||||||
|
return
|
||||||
|
mi = metadata_from_formats(formats)
|
||||||
|
if mi.title is None:
|
||||||
|
return
|
||||||
|
if db.has_book(mi):
|
||||||
|
return [(mi, formats)]
|
||||||
|
book_id = db.import_book(mi, formats)
|
||||||
|
if added_ids is not None:
|
||||||
|
added_ids.add(book_id)
|
||||||
|
if callable(callback):
|
||||||
|
callback(mi.title)
|
||||||
|
|
||||||
|
def recursive_import(db, root, single_book_per_directory=True,
|
||||||
|
callback=None, added_ids=None):
|
||||||
|
root = os.path.abspath(root)
|
||||||
|
duplicates = []
|
||||||
|
for dirpath in os.walk(root):
|
||||||
|
res = (import_book_directory(db, dirpath[0], callback=callback,
|
||||||
|
added_ids=added_ids) if single_book_per_directory else
|
||||||
|
import_book_directory_multiple(db, dirpath[0],
|
||||||
|
callback=callback, added_ids=added_ids))
|
||||||
|
if res is not None:
|
||||||
|
duplicates.extend(res)
|
||||||
|
if callable(callback):
|
||||||
|
if callback(''):
|
||||||
|
break
|
||||||
|
return duplicates
|
||||||
|
|
@ -11,6 +11,7 @@ from functools import partial
|
|||||||
from future_builtins import zip
|
from future_builtins import zip
|
||||||
|
|
||||||
from calibre.db import _get_next_series_num_for_list, _get_series_values
|
from calibre.db import _get_next_series_num_for_list, _get_series_values
|
||||||
|
from calibre.db.adding import find_books_in_directory, import_book_directory_multiple, import_book_directory, recursive_import
|
||||||
from calibre.db.backend import DB
|
from calibre.db.backend import DB
|
||||||
from calibre.db.cache import Cache
|
from calibre.db.cache import Cache
|
||||||
from calibre.db.categories import CATEGORY_SORTS
|
from calibre.db.categories import CATEGORY_SORTS
|
||||||
@ -160,6 +161,7 @@ class LibraryDatabase(object):
|
|||||||
os.makedirs(path)
|
os.makedirs(path)
|
||||||
return path
|
return path
|
||||||
|
|
||||||
|
# Adding books {{{
|
||||||
def create_book_entry(self, mi, cover=None, add_duplicates=True, force_id=None):
|
def create_book_entry(self, mi, cover=None, add_duplicates=True, force_id=None):
|
||||||
return self.new_api.create_book_entry(mi, cover=cover, add_duplicates=add_duplicates, force_id=force_id)
|
return self.new_api.create_book_entry(mi, cover=cover, add_duplicates=add_duplicates, force_id=force_id)
|
||||||
|
|
||||||
@ -190,6 +192,21 @@ class LibraryDatabase(object):
|
|||||||
self.notify('add', book_ids)
|
self.notify('add', book_ids)
|
||||||
return book_ids[0]
|
return book_ids[0]
|
||||||
|
|
||||||
|
def find_books_in_directory(self, dirpath, single_book_per_directory):
|
||||||
|
return find_books_in_directory(dirpath, single_book_per_directory)
|
||||||
|
|
||||||
|
def import_book_directory_multiple(self, dirpath, callback=None,
|
||||||
|
added_ids=None):
|
||||||
|
return import_book_directory_multiple(self, dirpath, callback=callback, added_ids=added_ids)
|
||||||
|
|
||||||
|
def import_book_directory(self, dirpath, callback=None, added_ids=None):
|
||||||
|
return import_book_directory(self, dirpath, callback=callback, added_ids=added_ids)
|
||||||
|
|
||||||
|
def recursive_import(self, root, single_book_per_directory=True,
|
||||||
|
callback=None, added_ids=None):
|
||||||
|
return recursive_import(self, root, single_book_per_directory=single_book_per_directory, callback=callback, added_ids=added_ids)
|
||||||
|
# }}}
|
||||||
|
|
||||||
# Private interface {{{
|
# Private interface {{{
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
|
@ -37,11 +37,12 @@ from calibre.utils.date import (utcnow, now as nowf, utcfromtimestamp,
|
|||||||
from calibre.utils.config import prefs, tweaks, from_json, to_json
|
from calibre.utils.config import prefs, tweaks, from_json, to_json
|
||||||
from calibre.utils.icu import sort_key, strcmp, lower
|
from calibre.utils.icu import sort_key, strcmp, lower
|
||||||
from calibre.utils.search_query_parser import saved_searches, set_saved_searches
|
from calibre.utils.search_query_parser import saved_searches, set_saved_searches
|
||||||
from calibre.ebooks import BOOK_EXTENSIONS, check_ebook_format
|
from calibre.ebooks import check_ebook_format
|
||||||
from calibre.utils.magick.draw import save_cover_data_to
|
from calibre.utils.magick.draw import save_cover_data_to
|
||||||
from calibre.utils.recycle_bin import delete_file, delete_tree
|
from calibre.utils.recycle_bin import delete_file, delete_tree
|
||||||
from calibre.utils.formatter_functions import load_user_template_functions
|
from calibre.utils.formatter_functions import load_user_template_functions
|
||||||
from calibre.db import _get_next_series_num_for_list, _get_series_values
|
from calibre.db import _get_next_series_num_for_list, _get_series_values
|
||||||
|
from calibre.db.adding import find_books_in_directory, import_book_directory_multiple, import_book_directory, recursive_import
|
||||||
from calibre.db.errors import NoSuchFormat
|
from calibre.db.errors import NoSuchFormat
|
||||||
from calibre.db.lazy import FormatMetadata, FormatsList
|
from calibre.db.lazy import FormatMetadata, FormatsList
|
||||||
from calibre.db.categories import Tag, CATEGORY_SORTS
|
from calibre.db.categories import Tag, CATEGORY_SORTS
|
||||||
@ -3728,95 +3729,18 @@ books_series_link feeds
|
|||||||
return len(books)
|
return len(books)
|
||||||
|
|
||||||
def find_books_in_directory(self, dirpath, single_book_per_directory):
|
def find_books_in_directory(self, dirpath, single_book_per_directory):
|
||||||
dirpath = os.path.abspath(dirpath)
|
return find_books_in_directory(dirpath, single_book_per_directory)
|
||||||
if single_book_per_directory:
|
|
||||||
formats = []
|
|
||||||
for path in os.listdir(dirpath):
|
|
||||||
path = os.path.abspath(os.path.join(dirpath, path))
|
|
||||||
if os.path.isdir(path) or not os.access(path, os.R_OK):
|
|
||||||
continue
|
|
||||||
ext = os.path.splitext(path)[1]
|
|
||||||
if not ext:
|
|
||||||
continue
|
|
||||||
ext = ext[1:].lower()
|
|
||||||
if ext not in BOOK_EXTENSIONS and ext != 'opf':
|
|
||||||
continue
|
|
||||||
formats.append(path)
|
|
||||||
yield formats
|
|
||||||
else:
|
|
||||||
books = {}
|
|
||||||
for path in os.listdir(dirpath):
|
|
||||||
path = os.path.abspath(os.path.join(dirpath, path))
|
|
||||||
if os.path.isdir(path) or not os.access(path, os.R_OK):
|
|
||||||
continue
|
|
||||||
ext = os.path.splitext(path)[1]
|
|
||||||
if not ext:
|
|
||||||
continue
|
|
||||||
ext = ext[1:].lower()
|
|
||||||
if ext not in BOOK_EXTENSIONS:
|
|
||||||
continue
|
|
||||||
|
|
||||||
key = os.path.splitext(path)[0]
|
|
||||||
if key not in books:
|
|
||||||
books[key] = []
|
|
||||||
books[key].append(path)
|
|
||||||
|
|
||||||
for formats in books.values():
|
|
||||||
yield formats
|
|
||||||
|
|
||||||
def import_book_directory_multiple(self, dirpath, callback=None,
|
def import_book_directory_multiple(self, dirpath, callback=None,
|
||||||
added_ids=None):
|
added_ids=None):
|
||||||
from calibre.ebooks.metadata.meta import metadata_from_formats
|
return import_book_directory_multiple(self, dirpath, callback=callback, added_ids=added_ids)
|
||||||
|
|
||||||
duplicates = []
|
|
||||||
for formats in self.find_books_in_directory(dirpath, False):
|
|
||||||
mi = metadata_from_formats(formats)
|
|
||||||
if mi.title is None:
|
|
||||||
continue
|
|
||||||
if self.has_book(mi):
|
|
||||||
duplicates.append((mi, formats))
|
|
||||||
continue
|
|
||||||
book_id = self.import_book(mi, formats)
|
|
||||||
if added_ids is not None:
|
|
||||||
added_ids.add(book_id)
|
|
||||||
if callable(callback):
|
|
||||||
if callback(mi.title):
|
|
||||||
break
|
|
||||||
return duplicates
|
|
||||||
|
|
||||||
def import_book_directory(self, dirpath, callback=None, added_ids=None):
|
def import_book_directory(self, dirpath, callback=None, added_ids=None):
|
||||||
from calibre.ebooks.metadata.meta import metadata_from_formats
|
return import_book_directory(self, dirpath, callback=callback, added_ids=added_ids)
|
||||||
dirpath = os.path.abspath(dirpath)
|
|
||||||
formats = self.find_books_in_directory(dirpath, True)
|
|
||||||
formats = list(formats)[0]
|
|
||||||
if not formats:
|
|
||||||
return
|
|
||||||
mi = metadata_from_formats(formats)
|
|
||||||
if mi.title is None:
|
|
||||||
return
|
|
||||||
if self.has_book(mi):
|
|
||||||
return [(mi, formats)]
|
|
||||||
book_id = self.import_book(mi, formats)
|
|
||||||
if added_ids is not None:
|
|
||||||
added_ids.add(book_id)
|
|
||||||
if callable(callback):
|
|
||||||
callback(mi.title)
|
|
||||||
|
|
||||||
def recursive_import(self, root, single_book_per_directory=True,
|
def recursive_import(self, root, single_book_per_directory=True,
|
||||||
callback=None, added_ids=None):
|
callback=None, added_ids=None):
|
||||||
root = os.path.abspath(root)
|
return recursive_import(self, root, single_book_per_directory=single_book_per_directory, callback=callback, added_ids=added_ids)
|
||||||
duplicates = []
|
|
||||||
for dirpath in os.walk(root):
|
|
||||||
res = (self.import_book_directory(dirpath[0], callback=callback,
|
|
||||||
added_ids=added_ids) if single_book_per_directory else
|
|
||||||
self.import_book_directory_multiple(dirpath[0],
|
|
||||||
callback=callback, added_ids=added_ids))
|
|
||||||
if res is not None:
|
|
||||||
duplicates.extend(res)
|
|
||||||
if callable(callback):
|
|
||||||
if callback(''):
|
|
||||||
break
|
|
||||||
return duplicates
|
|
||||||
|
|
||||||
def add_custom_book_data(self, book_id, name, val):
|
def add_custom_book_data(self, book_id, name, val):
|
||||||
x = self.conn.get('SELECT id FROM books WHERE ID=?', (book_id,), all=False)
|
x = self.conn.get('SELECT id FROM books WHERE ID=?', (book_id,), all=False)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user