mirror of
https://github.com/koreader/koreader.git
synced 2025-08-10 00:52:38 +00:00
refactoring: use Document API getCoverPageImage to get cover image
This commit is contained in:
@@ -1,14 +1,15 @@
|
||||
local CenterContainer = require("ui/widget/container/centercontainer")
|
||||
local InputContainer = require("ui/widget/container/inputcontainer")
|
||||
local DocumentRegistry = require("document/documentregistry")
|
||||
local InputDialog = require("ui/widget/inputdialog")
|
||||
local InfoMessage = require("ui/widget/infomessage")
|
||||
local Screensaver = require("ui/screensaver")
|
||||
local lfs = require("libs/libkoreader-lfs")
|
||||
local UIManager = require("ui/uimanager")
|
||||
local Menu = require("ui/widget/menu")
|
||||
local Screen = require("ui/screen")
|
||||
local util = require("ffi/util")
|
||||
local Font = require("ui/font")
|
||||
local DEBUG = require("dbg")
|
||||
local _ = require("gettext")
|
||||
|
||||
local calibre = "metadata.calibre"
|
||||
@@ -40,19 +41,23 @@ local Search = InputContainer:new{
|
||||
|
||||
local function findcalibre(root)
|
||||
local t = nil
|
||||
for entity in lfs.dir(root) do
|
||||
if t then
|
||||
break
|
||||
else
|
||||
if entity ~= "." and entity ~= ".." then
|
||||
local fullPath=root .. "/" .. entity
|
||||
local mode = lfs.attributes(fullPath,"mode")
|
||||
if mode == "file" then
|
||||
if entity == calibre or entity == "." .. calibre then
|
||||
t = root .. "/" .. entity
|
||||
-- protect lfs.dir which will raise error on no-permission directory
|
||||
local ok, iter, dir_obj = pcall(lfs.dir, root)
|
||||
if ok then
|
||||
for entity in iter, dir_obj do
|
||||
if t then
|
||||
break
|
||||
else
|
||||
if entity ~= "." and entity ~= ".." then
|
||||
local fullPath=root .. "/" .. entity
|
||||
local mode = lfs.attributes(fullPath,"mode")
|
||||
if mode == "file" then
|
||||
if entity == calibre or entity == "." .. calibre then
|
||||
t = root .. "/" .. entity
|
||||
end
|
||||
elseif mode == "directory" then
|
||||
t = findcalibre(fullPath)
|
||||
end
|
||||
elseif mode == "directory" then
|
||||
t = findcalibre(fullPath)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -61,15 +66,16 @@ local function findcalibre(root)
|
||||
end
|
||||
|
||||
function Search:getCalibre()
|
||||
-- check if we find the calibre file
|
||||
-- check 1st file
|
||||
-- check if we find the calibre file
|
||||
-- check 1st file
|
||||
if SEARCH_LIBRARY_PATH == nil then
|
||||
self.metafile_1 = findcalibre("/mnt")
|
||||
if not self.metafile_1 then
|
||||
self.error = "SEARCH_LIBRARY_PATH in DEFAULTS.LUA is not set!"
|
||||
else
|
||||
settings_changed = true
|
||||
end
|
||||
DEBUG("search Calibre database")
|
||||
self.metafile_1 = findcalibre("/mnt")
|
||||
if not self.metafile_1 then
|
||||
self.error = "SEARCH_LIBRARY_PATH in DEFAULTS.LUA is not set!"
|
||||
else
|
||||
settings_changed = true
|
||||
end
|
||||
else
|
||||
if string.sub(SEARCH_LIBRARY_PATH,string.len(SEARCH_LIBRARY_PATH)) ~= "/" then
|
||||
SEARCH_LIBRARY_PATH = SEARCH_LIBRARY_PATH .. "/"
|
||||
@@ -77,6 +83,7 @@ function Search:getCalibre()
|
||||
if io.open(SEARCH_LIBRARY_PATH .. calibre,"r") == nil then
|
||||
if io.open(SEARCH_LIBRARY_PATH .. "." .. calibre,"r") == nil then
|
||||
self.error = SEARCH_LIBRARY_PATH .. calibre .. " not found!"
|
||||
DEBUG(self.error)
|
||||
else
|
||||
self.metafile_1 = SEARCH_LIBRARY_PATH .. "." .. calibre
|
||||
end
|
||||
@@ -94,7 +101,7 @@ function Search:getCalibre()
|
||||
end
|
||||
end
|
||||
end
|
||||
-- check 2nd file
|
||||
-- check 2nd file
|
||||
local dummy
|
||||
|
||||
if string.sub(SEARCH_LIBRARY_PATH2,string.len(SEARCH_LIBRARY_PATH2)) ~= "/" then
|
||||
@@ -471,8 +478,19 @@ function Search:onMenuHold(item)
|
||||
end
|
||||
item.notchecked = false
|
||||
end
|
||||
local thumbnail = nil
|
||||
local doc = DocumentRegistry:openDocument(item.path)
|
||||
if doc then
|
||||
thumbnail = doc:getCoverPageImage()
|
||||
doc:close()
|
||||
end
|
||||
local thumbwidth = math.min(240, Screen:getWidth()/3)
|
||||
UIManager:show(InfoMessage:new{text = item.info,image = Screensaver:getCoverPicture(item.path), image_width = thumbwidth,image_height = thumbwidth/2*3})
|
||||
UIManager:show(InfoMessage:new{
|
||||
text = item.info,
|
||||
image = thumbnail,
|
||||
image_width = thumbwidth,
|
||||
image_height = thumbwidth/2*3
|
||||
})
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@@ -102,6 +102,10 @@ function DjvuDocument:getPageDimensions(pageno, zoom, rotation)
|
||||
return self.koptinterface:getPageDimensions(self, pageno, zoom, rotation)
|
||||
end
|
||||
|
||||
function DjvuDocument:getCoverPageImage()
|
||||
return self.koptinterface:getCoverPageImage(self)
|
||||
end
|
||||
|
||||
function DjvuDocument:renderPage(pageno, rect, zoom, rotation, gamma, render_mode)
|
||||
return self.koptinterface:renderPage(self, pageno, rect, zoom, rotation, gamma, render_mode)
|
||||
end
|
||||
|
||||
@@ -212,6 +212,10 @@ function Document:getOCRWord(pageno, rect)
|
||||
return nil
|
||||
end
|
||||
|
||||
function Document:getCoverPageImage()
|
||||
return nil
|
||||
end
|
||||
|
||||
function Document:renderPage(pageno, rect, zoom, rotation, gamma, render_mode)
|
||||
local hash = "renderpg|"..self.file.."|"..pageno.."|"..zoom.."|"..rotation.."|"..gamma.."|"..render_mode
|
||||
local page_size = self:getPageDimensions(pageno, zoom, rotation)
|
||||
|
||||
@@ -248,6 +248,16 @@ function KoptInterface:getRFPageDimensions(doc, pageno, zoom, rotation)
|
||||
return Geom:new{ w = fullwidth, h = fullheight }
|
||||
end
|
||||
|
||||
--[[
|
||||
get first page image
|
||||
--]]
|
||||
function KoptInterface:getCoverPageImage(doc)
|
||||
local tile = self:renderPage(doc, 1, nil, 1, 0, 1, 0)
|
||||
if tile then
|
||||
return tile.bb
|
||||
end
|
||||
end
|
||||
|
||||
function KoptInterface:renderPage(doc, pageno, rect, zoom, rotation, gamma, render_mode)
|
||||
if doc.configurable.text_wrap == 1 then
|
||||
return self:renderReflowedPage(doc, pageno, rect, zoom, rotation, render_mode)
|
||||
|
||||
@@ -210,6 +210,10 @@ function PdfDocument:getPageDimensions(pageno, zoom, rotation)
|
||||
return self.koptinterface:getPageDimensions(self, pageno, zoom, rotation)
|
||||
end
|
||||
|
||||
function PdfDocument:getCoverPageImage()
|
||||
return self.koptinterface:getCoverPageImage(self)
|
||||
end
|
||||
|
||||
function PdfDocument:renderPage(pageno, rect, zoom, rotation, gamma, render_mode)
|
||||
return self.koptinterface:renderPage(self, pageno, rect, zoom, rotation, gamma, render_mode)
|
||||
end
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
local DocumentRegistry = require("document/documentregistry")
|
||||
local UIManager = require("ui/uimanager")
|
||||
local Screen = require("ui/screen")
|
||||
local DEBUG = require("dbg")
|
||||
@@ -6,132 +7,24 @@ local _ = require("gettext")
|
||||
local Screensaver = {
|
||||
}
|
||||
|
||||
function Screensaver:getCoverPicture(file)
|
||||
local contentopf
|
||||
local contentpath
|
||||
local epub_folder = "temp/epub"
|
||||
|
||||
local function check_extension(cover)
|
||||
if cover then
|
||||
local itype = string.lower(string.match(cover, ".+%.([^.]+)") or "")
|
||||
if not (itype == "png" or itype == "jpg" or itype == "jpeg") then
|
||||
cover = nil
|
||||
end
|
||||
end
|
||||
return cover
|
||||
end
|
||||
|
||||
local function getValue(zipfile,which_line,to_find,excludecheck)
|
||||
local f = io.open(zipfile,"r")
|
||||
local i
|
||||
|
||||
if f then
|
||||
local line = f:read()
|
||||
while line and not i do
|
||||
i = line:lower():find(which_line:lower()) -- found something
|
||||
if i then
|
||||
f.close()
|
||||
line = line:match(to_find .. "\"([^\"]+)\".*")
|
||||
if not excludecheck then line = check_extension(line) end
|
||||
if line then
|
||||
return line
|
||||
else
|
||||
i = nil
|
||||
end
|
||||
end
|
||||
if not i then line = f:read() end
|
||||
end
|
||||
f.close()
|
||||
function Screensaver:getCoverImage(file)
|
||||
local ImageWidget = require("ui/widget/imagewidget")
|
||||
local doc = DocumentRegistry:openDocument(file)
|
||||
if doc then
|
||||
local image = doc:getCoverPageImage()
|
||||
doc:close()
|
||||
if image then
|
||||
return ImageWidget:new{
|
||||
image = image,
|
||||
width = Screen:getWidth(),
|
||||
height = Screen:getHeight(),
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
local function guess(extension)
|
||||
local cover = contentpath .. "Images/cover." .. extension
|
||||
pcall(os.execute("unzip \"" .. file .. "\" \"" .. cover .. "\" -oq -d " .. epub_folder))
|
||||
cover = epub_folder .. "/" .. cover
|
||||
if not io.open(cover,"r") then
|
||||
cover = nil
|
||||
end
|
||||
return cover
|
||||
end
|
||||
|
||||
local function try_content_opf(which_line,to_find,addimage)
|
||||
local cover = getValue(epub_folder .. "/" .. contentopf,which_line,to_find)
|
||||
local imageadd
|
||||
if cover then
|
||||
if addimage then
|
||||
imageadd = "Images/"
|
||||
else
|
||||
imageadd = ""
|
||||
end
|
||||
cover = contentpath .. imageadd .. cover
|
||||
pcall(os.execute("unzip \"" .. file .. "\" \"" .. cover .. "\" -oq -d " .. epub_folder))
|
||||
cover = epub_folder .. "/" .. cover
|
||||
if not io.open(cover,"r") then cover = nil end
|
||||
end
|
||||
return check_extension(cover)
|
||||
end
|
||||
|
||||
local function checkoldfile(cover)
|
||||
if io.open(cover) then
|
||||
return cover
|
||||
end
|
||||
end
|
||||
|
||||
local cover
|
||||
|
||||
local oldfile = "temp/" .. file:gsub("/","#") .. "."
|
||||
|
||||
cover = checkoldfile(oldfile .. "jpg")
|
||||
if not cover then cover = checkoldfile(oldfile .. "jpeg") end
|
||||
if not cover then cover = checkoldfile(oldfile .. "png") end
|
||||
|
||||
if not cover then
|
||||
|
||||
if file then
|
||||
pcall(lfs.mkdir("temp"))
|
||||
pcall(os.execute("rm -rf " .. epub_folder))
|
||||
pcall(lfs.mkdir(epub_folder))
|
||||
pcall(os.execute("unzip \"" .. file .. "\" cover.jpeg -oq -d " .. epub_folder))
|
||||
if io.open(epub_folder .. "/cover.jpeg","r") then -- picture in main folder
|
||||
cover = epub_folder .. "/cover.jpeg" -- found one
|
||||
else
|
||||
pcall(os.execute("unzip \"" .. file .. "\" \"META-INF/container.xml\" -oq -d " .. epub_folder)) -- read container.xml
|
||||
contentopf = getValue(epub_folder .. "/META-INF/container.xml","^%s*<rootfile ","full[-]path=",true)
|
||||
if contentopf then
|
||||
contentpath = contentopf:match("(.*)[/][^/]+")
|
||||
if contentpath then
|
||||
contentpath = contentpath .. "/"
|
||||
else
|
||||
contentpath = ""
|
||||
end
|
||||
pcall(os.execute("unzip \"" .. file .. "\" \"" .. contentopf .. "\" -oq -d " .. epub_folder)) -- read content.opf
|
||||
|
||||
cover = try_content_opf("^%s*<meta name=\"cover\"","content=",true) -- Make Room
|
||||
if not cover then cover = try_content_opf('id="cover',"item href=",false) end -- Kishon
|
||||
if not cover then cover = try_content_opf("cover","href=",true) end
|
||||
if not cover then cover = try_content_opf("cover","=",true) end
|
||||
if not cover then cover = try_content_opf("cover","=",false) end
|
||||
|
||||
if not cover then guess("jpg") end
|
||||
if not cover then guess("jpeg") end
|
||||
if not cover then guess("png") end
|
||||
end
|
||||
end
|
||||
end
|
||||
cover=check_extension(cover)
|
||||
if cover then
|
||||
oldfile = oldfile .. string.lower(string.match(cover, ".+%.([^.]+)"))
|
||||
pcall(os.execute('mv "' .. cover .. '" "' .. oldfile .. '"'))
|
||||
cover = oldfile
|
||||
pcall(os.execute('find temp/#mnt#* -mtime +30 -exec rm -v {} \\;'))
|
||||
end
|
||||
pcall(os.execute("rm -rf " .. epub_folder))
|
||||
end
|
||||
return cover
|
||||
end
|
||||
|
||||
function Screensaver:getRandomPicture(dir)
|
||||
function Screensaver:getRandomImage(dir)
|
||||
local ImageWidget = require("ui/widget/imagewidget")
|
||||
local pics = {}
|
||||
local i = 0
|
||||
math.randomseed(os.time())
|
||||
@@ -144,35 +37,36 @@ function Screensaver:getRandomPicture(dir)
|
||||
end
|
||||
end
|
||||
end
|
||||
return pics[math.random(i)]
|
||||
local image = pics[math.random(i)]
|
||||
if image then
|
||||
image = dir .. image
|
||||
if lfs.attributes(image, "mode") == "file" then
|
||||
return ImageWidget:new{
|
||||
file = image,
|
||||
width = Screen:getWidth(),
|
||||
height = Screen:getHeight(),
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Screensaver:show()
|
||||
DEBUG("show screensaver")
|
||||
local InfoMessage = require("ui/widget/infomessage")
|
||||
local ImageWidget = require("ui/widget/imagewidget")
|
||||
local file = nil
|
||||
-- first check book cover image
|
||||
if KOBO_SCREEN_SAVER_LAST_BOOK then
|
||||
file = self:getCoverPicture(G_reader_settings:readSetting("lastfile"))
|
||||
-- then screensaver image
|
||||
local lastfile = G_reader_settings:readSetting("lastfile")
|
||||
self.suspend_msg = self:getCoverImage(lastfile)
|
||||
-- then screensaver directory image
|
||||
elseif type(KOBO_SCREEN_SAVER) == "string" then
|
||||
file = KOBO_SCREEN_SAVER
|
||||
local file = KOBO_SCREEN_SAVER
|
||||
if lfs.attributes(file, "mode") == "directory" then
|
||||
if string.sub(file,string.len(file)) ~= "/" then
|
||||
file = file .. "/"
|
||||
end
|
||||
local dummy = self:getRandomPicture(file)
|
||||
if dummy then file = file .. dummy end
|
||||
self.suspend_msg = self:getRandomImage(file)
|
||||
end
|
||||
end
|
||||
if file and lfs.attributes(file, "mode") == "file" then
|
||||
self.suspend_msg = ImageWidget:new{
|
||||
file = file,
|
||||
width = Screen:getWidth(),
|
||||
height = Screen:getHeight(),
|
||||
}
|
||||
end
|
||||
-- fallback to suspended message
|
||||
if not self.suspend_msg then
|
||||
self.suspend_msg = InfoMessage:new{ text = _("Suspended") }
|
||||
|
||||
@@ -27,6 +27,7 @@ ImageWidget shows an image from a file
|
||||
--]]
|
||||
local ImageWidget = Widget:new{
|
||||
file = nil,
|
||||
image = nil,
|
||||
invert = nil,
|
||||
dim = nil,
|
||||
hide = nil,
|
||||
@@ -36,7 +37,11 @@ local ImageWidget = Widget:new{
|
||||
_bb = nil
|
||||
}
|
||||
|
||||
function ImageWidget:_render()
|
||||
function ImageWidget:_loadimage()
|
||||
self._bb = self.image
|
||||
end
|
||||
|
||||
function ImageWidget:_loadfile()
|
||||
local itype = string.lower(string.match(self.file, ".+%.([^.]+)") or "")
|
||||
if itype == "png" or itype == "jpg" or itype == "jpeg"
|
||||
or itype == "tiff" then
|
||||
@@ -58,6 +63,16 @@ function ImageWidget:_render()
|
||||
else
|
||||
error("Image file type not supported.")
|
||||
end
|
||||
end
|
||||
|
||||
function ImageWidget:_render()
|
||||
if self.image then
|
||||
self:_loadimage()
|
||||
elseif self.file then
|
||||
self:_loadfile()
|
||||
else
|
||||
error("cannot render image")
|
||||
end
|
||||
local w, h = self._bb:getWidth(), self._bb:getHeight()
|
||||
if (self.width and self.width ~= w) or (self.height and self.height ~= h) then
|
||||
self._bb = self._bb:scale(self.width or w, self.height or h)
|
||||
@@ -92,4 +107,11 @@ function ImageWidget:paintTo(bb, x, y)
|
||||
end
|
||||
end
|
||||
|
||||
function ImageWidget:free()
|
||||
if self.image then
|
||||
self.image:free()
|
||||
self.image = nil
|
||||
end
|
||||
end
|
||||
|
||||
return ImageWidget
|
||||
|
||||
@@ -26,10 +26,6 @@ local InfoMessage = InputContainer:new{
|
||||
}
|
||||
|
||||
function InfoMessage:init()
|
||||
if not self.image then
|
||||
self.image_width = nil
|
||||
self.image_height = nil
|
||||
end
|
||||
if Device:hasKeys() then
|
||||
self.key_events = {
|
||||
AnyKeyPressed = { { Input.group.Any },
|
||||
@@ -48,6 +44,18 @@ function InfoMessage:init()
|
||||
}
|
||||
}
|
||||
end
|
||||
local image_widget = nil
|
||||
if self.image then
|
||||
image_widget = ImageWidget:new{
|
||||
image = self.image,
|
||||
width = self.image_width,
|
||||
height = self.image_height,
|
||||
}
|
||||
else
|
||||
image_widget = ImageWidget:new{
|
||||
file = "resources/info-i.png",
|
||||
}
|
||||
end
|
||||
-- we construct the actual content here because self.text is only available now
|
||||
self[1] = CenterContainer:new{
|
||||
dimen = Screen:getSize(),
|
||||
@@ -56,11 +64,7 @@ function InfoMessage:init()
|
||||
background = 0,
|
||||
HorizontalGroup:new{
|
||||
align = "center",
|
||||
ImageWidget:new{
|
||||
file = self.image or "resources/info-i.png",
|
||||
width = self.image_width,
|
||||
height = self.image_height
|
||||
},
|
||||
image_widget,
|
||||
HorizontalSpan:new{ width = 10 },
|
||||
TextBoxWidget:new{
|
||||
text = self.text,
|
||||
|
||||
Reference in New Issue
Block a user