refactoring: use Document API getCoverPageImage to get cover image

pull/854/head
chrox 10 years ago
parent 40bddf0735
commit 0bc3eadcae

@ -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()
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 {} \\;'))
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
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,

Loading…
Cancel
Save