mirror of
https://github.com/koreader/koreader
synced 2024-11-10 01:10:34 +00:00
VocabBuilder.koplugin: better handling of word context (#12469)
Closes #12465.
This commit is contained in:
parent
04aa0cbde3
commit
33525a80a0
@ -6,7 +6,7 @@ local logger = require("logger")
|
||||
|
||||
local db_location = DataStorage:getSettingsDir() .. "/vocabulary_builder.sqlite3"
|
||||
|
||||
local DB_SCHEMA_VERSION = 20221002
|
||||
local DB_SCHEMA_VERSION = 20240905
|
||||
local VOCABULARY_DB_SCHEMA = [[
|
||||
-- To store looked up words
|
||||
CREATE TABLE IF NOT EXISTS "vocabulary" (
|
||||
@ -19,6 +19,7 @@ local VOCABULARY_DB_SCHEMA = [[
|
||||
"prev_context" TEXT,
|
||||
"next_context" TEXT,
|
||||
"streak_count" INTEGER NOT NULL DEFAULT 0,
|
||||
"highlight" TEXT,
|
||||
PRIMARY KEY("word")
|
||||
);
|
||||
CREATE TABLE IF NOT EXISTS "title" (
|
||||
@ -98,6 +99,10 @@ function VocabularyBuilder:createDB()
|
||||
UPDATE vocabulary SET streak_count = review_count; ]])
|
||||
if not ok then log(re) end
|
||||
end
|
||||
if db_version < 20240905 then
|
||||
ok, re = pcall(db_conn.exec, db_conn, "ALTER TABLE vocabulary ADD highlight TEXT;")
|
||||
if not ok then log(re) end
|
||||
end
|
||||
|
||||
db_conn:exec("CREATE INDEX IF NOT EXISTS title_id_index ON vocabulary(title_id);")
|
||||
-- Update version
|
||||
@ -170,6 +175,7 @@ function VocabularyBuilder:_select_items(items, start_idx, reload_time, search_t
|
||||
item.review_count = math.max(0, tonumber(results.review_count[i]))
|
||||
item.streak_count = math.max(0, tonumber(results.streak_count[i]))
|
||||
item.book_title = results.name[i] or ""
|
||||
item.highlight = results.highlight[i]
|
||||
item.create_time = tonumber( results.create_time[i])
|
||||
item.review_time = nil --use this field to flag change
|
||||
item.due_time = tonumber(results.due_time[i])
|
||||
@ -278,17 +284,18 @@ function VocabularyBuilder:insertOrUpdate(entry)
|
||||
stmt:step()
|
||||
stmt:clearbind():reset()
|
||||
|
||||
stmt = conn:prepare([[INSERT INTO vocabulary (word, title_id, create_time, due_time, review_time, prev_context, next_context)
|
||||
VALUES (?, (SELECT id FROM title WHERE name = ?), ?, ?, ?, ?, ?)
|
||||
stmt = conn:prepare([[INSERT INTO vocabulary (word, title_id, create_time, due_time, review_time, prev_context, next_context, highlight)
|
||||
VALUES (?, (SELECT id FROM title WHERE name = ?), ?, ?, ?, ?, ?, ?)
|
||||
ON CONFLICT(word) DO UPDATE SET title_id = excluded.title_id,
|
||||
create_time = excluded.create_time,
|
||||
review_count = MAX(review_count-1, 0),
|
||||
streak_count = 0,
|
||||
due_time = ?,
|
||||
prev_context = ifnull(excluded.prev_context, prev_context),
|
||||
next_context = ifnull(excluded.next_context, next_context);]]);
|
||||
next_context = ifnull(excluded.next_context, next_context),
|
||||
highlight = ifnull(excluded.highlight, highlight);]]);
|
||||
stmt:bind(entry.word, entry.book_title, entry.time, entry.time+300, entry.time,
|
||||
entry.prev_context, entry.next_context, entry.time+300)
|
||||
entry.prev_context, entry.next_context, entry.highlight, entry.time+300)
|
||||
stmt:step()
|
||||
stmt:clearbind():reset()
|
||||
conn:close()
|
||||
@ -396,6 +403,9 @@ function VocabularyBuilder.onSync(local_path, cached_path, income_path)
|
||||
return true
|
||||
end
|
||||
|
||||
-- Handle possible inconsistensies in db version
|
||||
pcall(conn_income.exec, conn_income, "ALTER TABLE vocabulary ADD highlight TEXT;")
|
||||
|
||||
local sql = "attach '" .. income_path:gsub("'", "''") .."' as income_db;"
|
||||
-- then we try to open cached db
|
||||
local conn_cached = SQ3.open(cached_path)
|
||||
@ -451,8 +461,8 @@ function VocabularyBuilder.onSync(local_path, cached_path, income_path)
|
||||
|
||||
-- Then we merge the income_db's contents into the local db
|
||||
INSERT INTO vocabulary
|
||||
(word, create_time, review_time, due_time, review_count, prev_context, next_context, title_id, streak_count)
|
||||
SELECT word, create_time, review_time, due_time, review_count, prev_context, next_context, title_id, streak_count
|
||||
(word, create_time, review_time, due_time, review_count, prev_context, next_context, title_id, streak_count, highlight)
|
||||
SELECT word, create_time, review_time, due_time, review_count, prev_context, next_context, title_id, streak_count, highlight
|
||||
FROM income_db.vocabulary WHERE true
|
||||
ON CONFLICT(word) DO UPDATE SET
|
||||
due_time = MAX(due_time, excluded.due_time),
|
||||
@ -462,6 +472,7 @@ function VocabularyBuilder.onSync(local_path, cached_path, income_path)
|
||||
END,
|
||||
prev_context = ifnull(excluded.prev_context, prev_context),
|
||||
next_context = ifnull(excluded.next_context, next_context),
|
||||
highlight = ifnull(excluded.highlight, highlight),
|
||||
streak_count = CASE
|
||||
WHEN review_time > excluded.review_time THEN streak_count
|
||||
ELSE excluded.streak_count
|
||||
|
@ -504,6 +504,7 @@ Individual word info dialogue widget
|
||||
--]]--
|
||||
local WordInfoDialog = FocusManager:extend{
|
||||
title = nil,
|
||||
highlighted_word = nil,
|
||||
book_title = nil,
|
||||
dates = nil,
|
||||
padding = Size.padding.large,
|
||||
@ -642,7 +643,7 @@ function WordInfoDialog:init()
|
||||
VerticalSpan:new{width= Size.padding.default},
|
||||
has_context and
|
||||
TextBoxWidget:new{
|
||||
text = "..." .. (self.prev_context or ""):gsub("\n", " ") .. "【" ..self.title.."】" .. (self.next_context or ""):gsub("\n", " ") .. "...",
|
||||
text = "..." .. (self.prev_context or ""):gsub("\n", " ") .. "【" ..(self.highlighted_word or self.title).."】" .. (self.next_context or ""):gsub("\n", " ") .. "...",
|
||||
width = width,
|
||||
face = Font:getFace("smallffont"),
|
||||
alignment = self.title_align or "left",
|
||||
@ -1041,6 +1042,7 @@ end
|
||||
function VocabItemWidget:showMore()
|
||||
local dialogue = WordInfoDialog:new{
|
||||
title = self.item.word,
|
||||
highlighted_word = self.item.highlight,
|
||||
book_title = self.item.book_title,
|
||||
dates = _("Added on") .. " " .. os.date("%Y-%m-%d", self.item.create_time) .. " | " ..
|
||||
_("Review scheduled at") .. " " .. os.date("%Y-%m-%d %H:%M", self.item.due_time),
|
||||
@ -2068,15 +2070,20 @@ function VocabBuilder:onWordLookedUp(word, title, is_manual)
|
||||
if self.widget and self.widget.current_lookup_word == word then return true end
|
||||
local prev_context
|
||||
local next_context
|
||||
local highlight
|
||||
if settings.with_context and self.ui.highlight then
|
||||
prev_context, next_context = self.ui.highlight:getSelectedWordContext(15)
|
||||
if self.ui.highlight.selected_text and self.ui.highlight.selected_text.text then
|
||||
highlight = util.cleanupSelectedText(self.ui.highlight.selected_text.text)
|
||||
end
|
||||
end
|
||||
DB:insertOrUpdate({
|
||||
book_title = title,
|
||||
time = os.time(),
|
||||
word = word,
|
||||
prev_context = prev_context,
|
||||
next_context = next_context
|
||||
next_context = next_context,
|
||||
highlight = highlight ~= word and highlight or nil
|
||||
})
|
||||
return true
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user