mirror of
https://github.com/bookorbit/bookorbit.git
synced 2026-11-03 08:21:39 -06:00
36bfc6e83d
Introduce a sync coordinator to serialize and prioritize KOReader sync jobs (such as progress sync, highlight sync, library sweep, and update check). Coalesce pending jobs by family to prevent race conditions and redundant network requests. Use a dedicated scheduler for open annotations to handle highlight sync and matching asynchronously on book open. Add a diagnostics menu in the settings to track detailed sync status and provide clear error messages for debugging.
96 lines
3.0 KiB
Lua
96 lines
3.0 KiB
Lua
package.loaded["gettext"] = function(text)
|
|
return text
|
|
end
|
|
|
|
package.loaded["ffi/util"] = {
|
|
template = function(text, ...)
|
|
local values = { ... }
|
|
return (text:gsub("%%(%d+)", function(index)
|
|
return tostring(values[tonumber(index)])
|
|
end))
|
|
end,
|
|
}
|
|
|
|
package.loaded["ui/widget/confirmbox"] = {}
|
|
package.loaded["device"] = {}
|
|
package.loaded["ui/event"] = { new = function() return {} end }
|
|
package.loaded["ui/widget/infomessage"] = { new = function(_, opts) return opts end }
|
|
package.loaded["optmath"] = { roundPercent = function(value) return value end }
|
|
package.loaded["ui/network/manager"] = {}
|
|
|
|
local shown_texts = {}
|
|
package.loaded["ui/uimanager"] = {
|
|
show = function(_, message)
|
|
table.insert(shown_texts, message.text)
|
|
end,
|
|
scheduleIn = function() end,
|
|
unschedule = function() end,
|
|
getElapsedTimeSinceBoot = function() return 0 end,
|
|
}
|
|
package.loaded["logger"] = { dbg = function() end }
|
|
package.loaded["ui/time"] = { s = function(value) return value end }
|
|
|
|
local partial_calls = 0
|
|
package.loaded["util"] = {
|
|
partialMD5 = function(file)
|
|
partial_calls = partial_calls + 1
|
|
return "computed:" .. tostring(file)
|
|
end,
|
|
}
|
|
|
|
package.path = "koreader-plugin/bookorbit.koplugin/?.lua;" .. package.path
|
|
|
|
local ProgressSync = require("bookorbit_progress_sync")
|
|
|
|
local function assertEqual(actual, expected, label)
|
|
if actual ~= expected then
|
|
error(string.format("%s: expected %s, got %s", label, tostring(expected), tostring(actual)))
|
|
end
|
|
end
|
|
|
|
local plugin = {}
|
|
ProgressSync.install(plugin)
|
|
|
|
plugin.ui = {
|
|
document = {
|
|
file = "/tmp/book.epub",
|
|
info = { has_pages = true },
|
|
},
|
|
}
|
|
assertEqual(plugin:getDocumentDigest(), "computed:/tmp/book.epub", "digest computes without doc settings")
|
|
assertEqual(partial_calls, 1, "partial md5 called once")
|
|
|
|
local saved_digest
|
|
plugin.ui.doc_settings = {
|
|
readSetting = function()
|
|
return nil
|
|
end,
|
|
saveSetting = function(_, _, value)
|
|
saved_digest = value
|
|
end,
|
|
}
|
|
assertEqual(plugin:getDocumentDigest(), "computed:/tmp/book.epub", "digest computes with empty doc settings")
|
|
assertEqual(saved_digest, "computed:/tmp/book.epub", "computed digest is cached when possible")
|
|
|
|
plugin.ui.doc_settings = {
|
|
readSetting = function()
|
|
return "cached"
|
|
end,
|
|
}
|
|
assertEqual(plugin:getDocumentDigest(), "cached", "cached digest is returned")
|
|
|
|
plugin.ui = nil
|
|
assertEqual(plugin:getDocumentDigest(), nil, "missing UI returns nil")
|
|
|
|
plugin.isLoggedIn = function()
|
|
return true
|
|
end
|
|
assertEqual(plugin:reconcileProgressBeforeBookSync("digest", function() end), false, "manual book sync rejects missing UI")
|
|
plugin:updateProgress(false, true)
|
|
plugin:getProgress(false, true)
|
|
assertEqual(shown_texts[1], "No reader book is open.", "manual book sync explains missing reader book")
|
|
assertEqual(shown_texts[2], "No reader book is open.", "interactive push explains missing reader book")
|
|
assertEqual(shown_texts[3], "No reader book is open.", "interactive pull explains missing reader book")
|
|
|
|
print("bookorbit_progress_digest_test.lua: ok")
|