Unverified Commit 5389cd88 authored by WorldTeacher's avatar WorldTeacher
Browse files

feat(isbn): extract ISBN from KOReader doc settings and use as fallback for book lookup

parent 8bfe89c1
Loading
Loading
Loading
Loading
Loading
+79 −8
Original line number Diff line number Diff line
@@ -3425,6 +3425,60 @@ function BookloreSync:getBookIdByHash(book_hash)
    return book_id, isbn10, isbn13
end

--[[--
Extract ISBN from KOReader doc settings for a given file.

Checks the "identifiers" setting (a string that may contain multiple
identifiers, e.g. "isbn:9781423137139,uuid:abc-123") for an isbn: entry.

Uses the live in-memory self.ui.doc_settings when available (required at
book-open time, since KOReader has not yet flushed settings to the .sdr
sidecar). Falls back to loading from disk via metadata_extractor for
contexts where the document is no longer open.

ISBN-13 is preferred; ISBN-10 is used as a fallback.

@param file_path string Full path to the document file
@return string|nil Raw ISBN digits (without "isbn:" prefix), or nil if not found
--]]
function BookloreSync:_extractIsbnFromDocSettings(file_path)
    local doc_settings
    if self.ui and self.ui.doc_settings then
        self:logDbg("BookloreSync: Using live in-memory doc_settings for ISBN extraction")
        doc_settings = self.ui.doc_settings
    else
        self:logDbg("BookloreSync: Falling back to on-disk sidecar for ISBN extraction")
        doc_settings = self.metadata_extractor:loadDocSettings(file_path)
    end

    if not doc_settings then
        self:logDbg("BookloreSync: No doc settings found for ISBN extraction")
        return nil
    end

    local doc_props = doc_settings:readSetting("doc_props")
    if type(doc_props) ~= "table" then
        self:logDbg("BookloreSync: No doc_props found in doc settings")
        return nil
    end

    local identifiers = doc_props.identifiers
    if type(identifiers) ~= "string" then
        self:logDbg("BookloreSync: No identifiers string found in doc_props")
        return nil
    end

    local isbn = identifiers:match("isbn:(%d%d%d%d%d%d%d%d%d%d%d%d%d)")
              or identifiers:match("isbn:(%d%d%d%d%d%d%d%d%d%d)")
    if isbn then
        self:logInfo("BookloreSync: Found ISBN in doc settings:", isbn)
        return isbn
    end

    self:logInfo("BookloreSync: No ISBN entry found in identifiers:", identifiers)
    return nil
end

--[[--
Start tracking a reading session

@@ -3492,8 +3546,24 @@ function BookloreSync:startSession()
                        self:logInfo("BookloreSync: Book has ISBN-10:", isbn10, "ISBN-13:", isbn13)
                    end
                else
                    self:logInfo("BookloreSync: Book not found on server (not in library)")
                    -- First-time hash lookup returned no match — inform the user.
                    self:logInfo("BookloreSync: Book not found on server by hash, trying ISBN fallback")
                    local isbn = self:_extractIsbnFromDocSettings(file_path)
                    if isbn then
                        self:logInfo("BookloreSync: Attempting ISBN lookup for:", isbn)
                        local isbn_success, isbn_result = self.api:lookupBookByIsbn(
                            isbn, self.booklore_username, self.booklore_password)
                        if isbn_success then
                            book_id = isbn_result
                            self:logInfo("BookloreSync: Book ID resolved via ISBN lookup:", book_id)
                        else
                            self:logWarn("BookloreSync: ISBN lookup failed or no results")
                            UIManager:show(InfoMessage:new{
                                text    = _("No match found based on hash or ISBN.\nDoes this book exist in your Booklore library?"),
                                timeout = 5,
                            })
                        end
                    else
                        self:logInfo("BookloreSync: No ISBN available in doc settings")
                        -- We only show this when actually connected so we know the server
                        -- was reached and genuinely has no book with this hash.
                        UIManager:show(InfoMessage:new{
@@ -3501,6 +3571,7 @@ function BookloreSync:startSession()
                            timeout = 5,
                        })
                    end
                end
            else
                self:logInfo("BookloreSync: No network connection, skipping server lookup")
                self:logInfo("BookloreSync: Book will be cached locally and resolved when online")