local WidgetContainer = require("ui/widget/container/widgetcontainer")
local Dispatcher = require("dispatcher")
local UIManager = require("ui/uimanager")
local InfoMessage = require("ui/widget/infomessage")
local DataStorage = require("datastorage")
local SettingsManager = require("settingsmanager")
local lfs = require("libs/liblfs")
local _ = require("gettext")
local QuotesGenerator = WidgetContainer:extend{
name = "quotes_generator",
align = "center",
font_family = "sans-serif",
}
function QuotesGenerator:onDispatcherRegisterActions()
Dispatcher:registerAction("quotes_generator_open", {
category = "tools",
event = "QuotesGeneratorOpen",
title = _("Générateur de citations"),
general = true,
})
end
function QuotesGenerator:init()
self:onDispatcherRegisterActions()
self.ui.menu:registerSubMenu(_("Générateur de citations"), self:getSubMenu())
end
function QuotesGenerator:getSubMenu()
return {
text = _("Générateur de citations"),
sub_item_table = {
{
text = _("Extraire et générer quotes.lua (14 citations)"),
callback = function()
self:generateQuotes()
end,
},
{
text = _("Style : " .. self.align),
callback = function()
self:toggleAlign()
end,
},
},
}
end
function QuotesGenerator:toggleAlign()
if self.align == "center" then
self.align = "left"
else
self.align = "center"
end
UIManager:show(InfoMessage:new{
text = _("Alignement réglé sur : ") .. self.align,
})
end
-- Récupère la liste des livres terminés enregistrés par KOReader
function QuotesGenerator:getFinishedBooks()
local finished_books = {}
local history = SettingsManager:getSetting("history") or {}
for _, entry in ipairs(history) do
if entry.summary and entry.summary.status == "complete" then
table.insert(finished_books, entry)
elseif entry.file then
-- Vérification alternative via les paramètres individuels du document
local doc_settings = DataStorage:getSettingsDir() .. "/docsettings/"
if entry.status == "complete" or entry.progress == 1 then
table.insert(finished_books, entry)
end
end
end
return finished_books
end
-- Extraire une citation valide depuis un fichier texte ou extrait de livre
function QuotesGenerator:extractQuoteFromBook(file_path)
local file = io.open(file_path, "r")
if not file then return nil end
local content = file:read("*a")
file:close()
if not content or #content == 0 then return nil end
-- Nettoyage sommaire des balises HTML/XML si présent
content = content:gsub("<[^>]+>", " ")
local sentences = {}
for sentence in content:gmatch("[^.!?]+[.!?]") do
local cleaned = sentence:gsub("%s+", " "):match("^%s*(.-)%s*$")
-- Filtrer les phrases de longueur adaptée (80 à 220 caractères)
if cleaned and #cleaned >= 80 and #cleaned <= 220 then
table.insert(sentences, cleaned)
end
end
if #sentences > 0 then
return sentences[math.random(1, #sentences)]
end
return nil
end
function QuotesGenerator:generateQuotes()
local finished = self:getFinishedBooks()
if #finished < 14 then
-- Mélanger la liste disponible si moins de 14 livres uniques
UIManager:show(InfoMessage:new{
text = _("Moins de 14 livres terminés trouvés dans l'historique. Sélection sur la totalité disponible."),
})
end
-- Mélange aléatoire (Fisher-Yates)
math.randomseed(os.time())
for i = #finished, 2, -1 do
local j = math.random(i)
finished[i], finished[j] = finished[j], finished[i]
end
local quotes = {}
local count = 0
for _, book in ipairs(finished) do
if count >= 14 then break end
local title = book.title or book.file:match("([^/]+)%.%w+$") or "Titre inconnu"
local author = book.authors or "Auteur inconnu"
local quote_text = nil
-- Tentative d'extraction du fichier si accessible
if book.file and lfs.attributes(book.file, "mode") == "file" then
quote_text = self:extractQuoteFromBook(book.file)
end
-- Texte de repli si l'extraction directe du binaire/EPUB brut échoue
if not quote_text then
quote_text = "Une lecture achevée laisse toujours une empreinte durable."
end
table.insert(quotes, {
text = quote_text,
title = title,
author = author
})
count = count + 1
end
-- Écriture du fichier target /koreader/settings/simpleui/sui_quotes/quotes.lua
local target_dir = DataStorage:getSettingsDir() .. "/simpleui/sui_quotes"
lfs.mkdir(target_dir)
local target_file = target_dir .. "/quotes.lua"
local f = io.open(target_file, "w")
if not f then
UIManager:show(InfoMessage:new{
text = _("Impossible d'écrire dans ") .. target_file,
})
return
end
f:write("-- Fichier généré automatiquement par quotes_generator\n")
f:write("return {\n")
for _, q in ipairs(quotes) do
-- Formatage HTML/Pango : centré, guillemets anglais ("..."), titre et auteur en gras
local formatted = string.format(
' "<p align=\\"%s\\">“%s”</p>\\n<p align=\\"%s\\"><b>%s</b> — <b>%s</b></p>",\n',
self.align, q.text, self.align, q.title, q.author
)
f:write(formatted)
end
f:write("}\n")
f:close()
UIManager:show(InfoMessage:new{
text = string.format(_("Succès : 14 citations écrites dans %s"), target_file),
})
end
return QuotesGenerator
To embed this project on your website, copy the following code and paste it into your website's HTML: