Compare commits

...

2 Commits

Author SHA1 Message Date
Michael Goodnow
11e5b49a72 Merge branch 'forceprocess-file' into 'master'
Allow postprocess startdir to be a file

See merge request LazyLibrarian/LazyLibrarian!1790
2026-02-05 12:09:48 +00:00
phil.borman@gmail.com
8ee9f64347 Better fix for #2945 provider api access 2026-02-05 13:06:01 +01:00
8 changed files with 22 additions and 19 deletions

View File

@ -1,3 +1,5 @@
[![Buy Me a Coffee](https://img.icons8.com/?size=24&id=gEtADbEGxPM2&format=png&color=000000) Buy Me a Coffee](https://buymeacoffee.com/philbormang)
## LazyLibrarian ## LazyLibrarian
LazyLibrarian is a program to follow authors and grab metadata for all your digital reading needs. LazyLibrarian is a program to follow authors and grab metadata for all your digital reading needs.
It uses a combination of [HardCover](https://hardcover.app) [OpenLibrary](https://openlibrary.org/) [Librarything](https://www.librarything.com/) [GoodReads](https://www.goodreads.com) and optionally [GoogleBooks](https://www.googleapis.com/books/v1/) as sources for author info and book info. License: GNU GPL v3 It uses a combination of [HardCover](https://hardcover.app) [OpenLibrary](https://openlibrary.org/) [Librarything](https://www.librarything.com/) [GoodReads](https://www.goodreads.com) and optionally [GoogleBooks](https://www.googleapis.com/books/v1/) as sources for author info and book info. License: GNU GPL v3
@ -53,3 +55,5 @@ LinuxServer : https://hub.docker.com/r/linuxserver/lazylibrarian/
The docker package includes ghostscript for magazine cover generation and calibredb (via optional variable) The docker package includes ghostscript for magazine cover generation and calibredb (via optional variable)
LinuxServer docker is multi-arch and works on X86_64, armhf and aarch64 (calibredb only available on X86_64) LinuxServer docker is multi-arch and works on X86_64, armhf and aarch64 (calibredb only available on X86_64)
The dockers can be upgraded using the lazylibrarian internal upgrade mechanism The dockers can be upgraded using the lazylibrarian internal upgrade mechanism
[![Buy Me a Coffee](https://img.icons8.com/?size=24&id=gEtADbEGxPM2&format=png&color=000000) Buy Me a Coffee](https://buymeacoffee.com/philbormang)

View File

@ -2257,7 +2257,7 @@ class Api:
if source in lazylibrarian.INFOSOURCES.keys(): if source in lazylibrarian.INFOSOURCES.keys():
this_source = lazylibrarian.INFOSOURCES[source] this_source = lazylibrarian.INFOSOURCES[source]
ap = this_source['api'] ap = this_source['api']()
res = ap.find_author_id(authorname=authorname) res = ap.find_author_id(authorname=authorname)
self.data = str(res) self.data = str(res)
@ -2281,7 +2281,7 @@ class Api:
return return
authordata = db.select(f"SELECT AuthorName from authors WHERE {key}='' or {key} is null") authordata = db.select(f"SELECT AuthorName from authors WHERE {key}='' or {key} is null")
api = this_source['api'] api = this_source['api']()
for author in authordata: for author in authordata:
res = api.find_author_id(authorname=author['AuthorName']) res = api.find_author_id(authorname=author['AuthorName'])
if res.get('authorid'): if res.get('authorid'):
@ -2299,7 +2299,7 @@ class Api:
authorname = format_author_name(kwargs['name'], postfix=get_list(CONFIG.get_csv('NAME_POSTFIX'))) authorname = format_author_name(kwargs['name'], postfix=get_list(CONFIG.get_csv('NAME_POSTFIX')))
this_source = lazylibrarian.INFOSOURCES[CONFIG['BOOK_API']] this_source = lazylibrarian.INFOSOURCES[CONFIG['BOOK_API']]
api = this_source['api'] api = this_source['api']()
myqueue = Queue() myqueue = Queue()
search_api = threading.Thread(target=api.find_results, search_api = threading.Thread(target=api.find_results,
name=f"API-{this_source['src']}RESULTS", name=f"API-{this_source['src']}RESULTS",
@ -2315,7 +2315,7 @@ class Api:
return return
this_source = lazylibrarian.INFOSOURCES[CONFIG['BOOK_API']] this_source = lazylibrarian.INFOSOURCES[CONFIG['BOOK_API']]
api = this_source['api'] api = this_source['api']()
myqueue = Queue() myqueue = Queue()
search_api = threading.Thread(target=api.find_results, search_api = threading.Thread(target=api.find_results,
name=f"API-{this_source['src']}RESULTS", name=f"API-{this_source['src']}RESULTS",
@ -2371,7 +2371,7 @@ class Api:
self.data = 'Missing parameter: id' self.data = 'Missing parameter: id'
return return
this_source = lazylibrarian.INFOSOURCES[CONFIG['BOOK_API']] this_source = lazylibrarian.INFOSOURCES[CONFIG['BOOK_API']]
api = this_source['api'] api = this_source['api']()
if 'wait' in kwargs: if 'wait' in kwargs:
self.data = api.add_bookid_to_db(kwargs['id'], None, None, "Added by API") self.data = api.add_bookid_to_db(kwargs['id'], None, None, "Added by API")
else: else:

View File

@ -929,8 +929,7 @@ def search_for(searchterm, source=None):
source = CONFIG['BOOK_API'] source = CONFIG['BOOK_API']
searchinglogger.debug(f"{source} {searchterm}") searchinglogger.debug(f"{source} {searchterm}")
this_source = lazylibrarian.INFOSOURCES[source] this_source = lazylibrarian.INFOSOURCES[source]
api = this_source['api'] api = this_source['api']()
api.__init__()
if CONFIG[this_source['enabled']]: if CONFIG[this_source['enabled']]:
myqueue = Queue() myqueue = Queue()
search_api = threading.Thread(target=api.find_results, search_api = threading.Thread(target=api.find_results,

View File

@ -105,7 +105,7 @@ def get_book_meta(fdir, reason="get_book_meta"):
if not existing_book: if not existing_book:
logger.debug(f"Searching {CONFIG['BOOK_API']} for {bookid}") logger.debug(f"Searching {CONFIG['BOOK_API']} for {bookid}")
this_source = lazylibrarian.INFOSOURCES[CONFIG['BOOK_API']] this_source = lazylibrarian.INFOSOURCES[CONFIG['BOOK_API']]
api = this_source['api'] api = this_source['api']()
_ = api.add_bookid_to_db(bookid, None, None, reason) _ = api.add_bookid_to_db(bookid, None, None, reason)
existing_book = db.match(cmd, (bookid,)) existing_book = db.match(cmd, (bookid,))
db.close() db.close()
@ -1039,7 +1039,7 @@ def library_scan(startdir=None, library='eBook', authid=None, remove=True):
f"Metadata bookid [{bookid}] not found in database, trying to add...") f"Metadata bookid [{bookid}] not found in database, trying to add...")
this_source = lazylibrarian.INFOSOURCES[CONFIG['BOOK_API']] this_source = lazylibrarian.INFOSOURCES[CONFIG['BOOK_API']]
api = this_source['api'] api = this_source['api']()
book_id = eval(this_source['book_key']) book_id = eval(this_source['book_key'])
if book_id: if book_id:
src = this_source['src'] src = this_source['src']
@ -1160,7 +1160,7 @@ def library_scan(startdir=None, library='eBook', authid=None, remove=True):
else: else:
logger.debug(f"Adding {bookid} [{bookauthor}] on rescan for {booktitle}") logger.debug(f"Adding {bookid} [{bookauthor}] on rescan for {booktitle}")
this_source = lazylibrarian.INFOSOURCES[source] this_source = lazylibrarian.INFOSOURCES[source]
api = this_source['api'] api = this_source['api']()
_ = api.add_bookid_to_db(bookid, reason=f"Librarysync {source} " _ = api.add_bookid_to_db(bookid, reason=f"Librarysync {source} "
f"rescan {bookauthor}") f"rescan {bookauthor}")
if language and language != "Unknown": if language and language != "Unknown":

View File

@ -276,7 +276,7 @@ def process_book_from_dir(source_dir=None, library="eBook", bookid=None):
if not book: if not book:
logger.warning(f"Bookid [{bookid}] not found in database, trying to add...") logger.warning(f"Bookid [{bookid}] not found in database, trying to add...")
this_source = lazylibrarian.INFOSOURCES[CONFIG["BOOK_API"]] this_source = lazylibrarian.INFOSOURCES[CONFIG["BOOK_API"]]
api = this_source["api"] api = this_source["api"]()
_ = api.add_bookid_to_db(bookid, None, None, f"Added by book_from_dir {source_dir}") _ = api.add_bookid_to_db(bookid, None, None, f"Added by book_from_dir {source_dir}")
# see if it's there now... # see if it's there now...
book = db.match("SELECT * from books where BookID=?", (bookid,)) book = db.match("SELECT * from books where BookID=?", (bookid,))

View File

@ -330,15 +330,15 @@ class StartupLazyLibrarian:
def build_sources(): def build_sources():
info_sources = { info_sources = {
'OpenLibrary': {'src': 'OL', 'author_key': 'ol_id', 'book_key': 'ol_id', 'enabled': 'OL_API', 'OpenLibrary': {'src': 'OL', 'author_key': 'ol_id', 'book_key': 'ol_id', 'enabled': 'OL_API',
'api': ol.OpenLibrary(), 'has_subs': 0}, 'api': ol.OpenLibrary, 'has_subs': 0},
'GoodReads': {'src': 'GR', 'author_key': 'gr_id', 'book_key': 'gr_id', 'enabled': 'GR_API', 'GoodReads': {'src': 'GR', 'author_key': 'gr_id', 'book_key': 'gr_id', 'enabled': 'GR_API',
'api': gr.GoodReads(), 'has_subs': 0}, 'api': gr.GoodReads, 'has_subs': 0},
'HardCover': {'src': 'HC', 'author_key': 'hc_id', 'book_key': 'hc_id', 'enabled': 'HC_API', 'HardCover': {'src': 'HC', 'author_key': 'hc_id', 'book_key': 'hc_id', 'enabled': 'HC_API',
'api': hc.HardCover(), 'has_subs': 1}, 'api': hc.HardCover, 'has_subs': 1},
'GoogleBooks': {'src': 'GB', 'author_key': 'authorid', 'book_key': 'gb_id', 'enabled': 'GB_API', 'GoogleBooks': {'src': 'GB', 'author_key': 'authorid', 'book_key': 'gb_id', 'enabled': 'GB_API',
'api': gb.GoogleBooks(), 'has_subs': 1}, 'api': gb.GoogleBooks, 'has_subs': 1},
'DNB': {'src': 'DN', 'author_key': 'authorid', 'book_key': 'dnb_id', 'enabled': 'DNB_API', 'DNB': {'src': 'DN', 'author_key': 'authorid', 'book_key': 'dnb_id', 'enabled': 'DNB_API',
'api': dnb.DNB(), 'has_subs': 1}, 'api': dnb.DNB, 'has_subs': 1},
} }
adminlogger = logging.getLogger('special.admin') adminlogger = logging.getLogger('special.admin')
adminlogger.debug(info_sources) adminlogger.debug(info_sources)

View File

@ -3374,7 +3374,7 @@ class WebInterface:
update_totals(author_id) update_totals(author_id)
else: else:
this_source = lazylibrarian.INFOSOURCES[CONFIG['BOOK_API']] this_source = lazylibrarian.INFOSOURCES[CONFIG['BOOK_API']]
api = this_source['api'] api = this_source['api']()
t = threading.Thread(target=api.add_bookid_to_db, t = threading.Thread(target=api.add_bookid_to_db,
name=f"{this_source['src']}-BOOK", name=f"{this_source['src']}-BOOK",
args=[bookid, ebook_status, audio_status, "Added by user"]) args=[bookid, ebook_status, audio_status, "Added by user"])
@ -4388,7 +4388,7 @@ class WebInterface:
args.pop(arg, None) args.pop(arg, None)
this_source = lazylibrarian.INFOSOURCES[CONFIG['BOOK_API']] this_source = lazylibrarian.INFOSOURCES[CONFIG['BOOK_API']]
api = this_source['api'] api = this_source['api']()
ids = set(args.keys()) ids = set(args.keys())
if action in ['AddBook', 'AddAudio', 'AddBoth']: if action in ['AddBook', 'AddAudio', 'AddBoth']:
wantbook = "Wanted" if action in ['AddBook', 'AddBoth'] else 'Skipped' wantbook = "Wanted" if action in ['AddBook', 'AddBoth'] else 'Skipped'

View File

@ -1,6 +1,6 @@
[GENERAL] [GENERAL]
no_ipv6 = True no_ipv6 = True
imp_preflang = en-US, en, eng, English, en-GB imp_preflang = eng, en-GB, en, en-US, English
http_ext_timeout = 100 http_ext_timeout = 100
ebook_dir = ./testdata/eBooks ebook_dir = ./testdata/eBooks
audio_dir = ./testdata/Audiobooks audio_dir = ./testdata/Audiobooks