Verified Commit 08c839ce authored by WorldTeacher's avatar WorldTeacher
Browse files

fix(logging): enhance logging for batch upload sessions with book ID details

parent 2bc8f3f3
Loading
Loading
Loading
Loading
+29 −25
Original line number Diff line number Diff line
@@ -267,7 +267,11 @@ function APIClient:request(method, path, body, headers)
    end
    
    local error_message = self:extractErrorMessage(response_text, code)
    self:logWarn("BookloreSync API: Request failed:", code, "-", error_message)
    if response_text and response_text ~= "" then
        self:logWarn("BookloreSync API: Request failed:", code, "-", error_message, "| Raw response:", response_text)
    else
        self:logWarn("BookloreSync API: Request failed:", code, "-", error_message, "| Raw response: (empty)")
    end
    
    return false, code, error_message
end
@@ -366,18 +370,10 @@ function APIClient:getBookByHash(book_hash)
    if success and type(response) == "table" then
        self:logInfo("BookloreSync API: Found book, ID:", response.id)
        
        local isbn10 = nil
        local isbn13 = nil
        if response.metadata and type(response.metadata) == "table" then
            isbn10 = response.metadata.isbn10
            isbn13 = response.metadata.isbn13
        end
        
        response.isbn10 = isbn10
        response.isbn13 = isbn13
        response = self:_normalizeBookObject(response)
        
        if isbn10 or isbn13 then
            self:logInfo("BookloreSync API: Book has ISBN-10:", isbn10, "ISBN-13:", isbn13)
        if response.isbn10 or response.isbn13 then
            self:logInfo("BookloreSync API: Book has ISBN-10:", response.isbn10, "ISBN-13:", response.isbn13)
        else
            self:logInfo("BookloreSync API: Book has no ISBN data")
        end
@@ -421,6 +417,9 @@ Submit batch of reading sessions for a single book
Submits multiple sessions in a single request for improved performance.
Automatically falls back to individual uploads if batch endpoint is not available (404).

Uses KOReader x-auth-user/x-auth-key authentication, consistent with the
single-session endpoint.

@param book_id Booklore book ID (number)
@param book_type Book type (string): "EPUB", "PDF", etc.
@param sessions Array of session objects (table), max 100 sessions recommended
@@ -448,6 +447,8 @@ function APIClient:submitSessionBatch(book_id, book_type, sessions)
        sessions = sessions
    }
    
    -- Uses KOReader x-auth-user/x-auth-key auth (injected automatically by request())
    self:logInfo("BookloreSync API: Batch upload auth method: x-auth-user/x-auth-key")
    local success, code, response = self:request("POST", "/api/v1/reading-sessions/batch", payload)
    
    if success then
@@ -780,18 +781,10 @@ function APIClient:getBookByHashWithAuth(book_hash, username, password)
    if success and type(response) == "table" then
        self:logInfo("BookloreSync API: Found book by hash, ID:", response.id)
        
        local isbn10 = nil
        local isbn13 = nil
        if response.metadata and type(response.metadata) == "table" then
            isbn10 = response.metadata.isbn10
            isbn13 = response.metadata.isbn13
        end
        
        response.isbn10 = isbn10
        response.isbn13 = isbn13
        response = self:_normalizeBookObject(response)
        
        if isbn10 or isbn13 then
            self:logInfo("BookloreSync API: Book has ISBN-10:", isbn10, "ISBN-13:", isbn13)
        if response.isbn10 or response.isbn13 then
            self:logInfo("BookloreSync API: Book has ISBN-10:", response.isbn10, "ISBN-13:", response.isbn13)
        end
        
        return true, response
@@ -821,10 +814,15 @@ function APIClient:_urlEncode(str)
end

--[[--
Normalize book object by extracting ISBN from metadata to top level
Normalize book object by promoting fields from nested metadata to top level

Booklore's /api/v1/ endpoints nest title, authors, and ISBNs under a
`metadata` sub-object, while the /api/koreader/ endpoints return them at
the top level. This function promotes the fields so all callers can access
them uniformly as book.title, book.authors, book.isbn10, book.isbn13.

@param book Book object from API
@return table Normalized book object with isbn10/isbn13 at top level
@return table Normalized book object with metadata fields at top level
--]]
function APIClient:_normalizeBookObject(book)
    if not book or type(book) ~= "table" then
@@ -832,6 +830,12 @@ function APIClient:_normalizeBookObject(book)
    end
    
    if book.metadata and type(book.metadata) == "table" then
        if not book.title or book.title == "" then
            book.title = book.metadata.title
        end
        if not book.authors or book.authors == "" then
            book.authors = book.metadata.authors
        end
        if not book.isbn10 then
            book.isbn10 = book.metadata.isbn10
        end
+8 −8
Original line number Diff line number Diff line
@@ -4148,19 +4148,19 @@ function BookloreSync:_uploadSessionsWithBatching(book_id, book_type, sessions)
        end
        
        -- Try batch upload
        self:logInfo("BookloreSync: Attempting batch", batch_num, "of", batch_count, "with", (end_idx - start_idx + 1), "sessions")
        self:logInfo("BookloreSync: Attempting batch", batch_num, "of", batch_count, "with", (end_idx - start_idx + 1), "sessions for booklore_book_id:", book_id)
        local success, message, code = self.api:submitSessionBatch(book_id, book_type, batch_sessions)
        self:logInfo("BookloreSync: Batch", batch_num, "result - success:", tostring(success), "code:", tostring(code or "nil"), "message:", tostring(message or "nil"))
        self:logInfo("BookloreSync: Batch", batch_num, "result - booklore_book_id:", book_id, "success:", tostring(success), "code:", tostring(code or "nil"), "message:", tostring(message or "nil"))
        
        if success then
            for i = start_idx, end_idx do
                self.db:markHistoricalSessionSynced(sessions[i].id)
                synced_count = synced_count + 1
            end
            self:logInfo("BookloreSync: Batch", batch_num, "of", batch_count, "uploaded successfully (" .. (end_idx - start_idx + 1) .. " sessions)")
        elseif code == 404 or code == 403 then
            -- Server doesn't have batch endpoint (404/403) OR book not found (404)
            -- Fallback to individual upload to determine which
            self:logInfo("BookloreSync: Batch", batch_num, "of", batch_count, "uploaded successfully (" .. (end_idx - start_idx + 1) .. " sessions) for booklore_book_id:", book_id)
        elseif code == 404 then
            -- Server doesn't have batch endpoint OR book not found; fallback to
            -- individual upload to determine which
            self:logWarn("BookloreSync: Batch returned", code, "falling back to individual upload for batch", batch_num)
            
            for i = start_idx, end_idx do
@@ -4181,7 +4181,7 @@ function BookloreSync:_uploadSessionsWithBatching(book_id, book_type, sessions)
        else
            -- Other error: all sessions in batch failed
            self:logErr("BookloreSync: Batch upload failed for batch", batch_num, "of", batch_count,
                       "(" .. (end_idx - start_idx + 1) .. " sessions) - Error:", message, "Code:", tostring(code or "nil"))
                       "booklore_book_id:", book_id, "(" .. (end_idx - start_idx + 1) .. " sessions) - Error:", message, "Code:", tostring(code or "nil"))
            failed_count = failed_count + (end_idx - start_idx + 1)
        end
    end