mirror of
https://github.com/koreader/koreader.git
synced 2025-12-13 20:36:53 +01:00
Reader: inspect zip file content to choose provider (#12902)
This commit is contained in:
@@ -1549,9 +1549,8 @@ function FileManager:showOpenWithDialog(file)
|
||||
end
|
||||
|
||||
function FileManager:openFile(file, provider, doc_caller_callback, aux_caller_callback)
|
||||
if provider == nil then
|
||||
provider = DocumentRegistry:getProvider(file, true) -- include auxiliary
|
||||
end
|
||||
local is_provider_forced = provider ~= nil
|
||||
provider = provider or DocumentRegistry:getProvider(file, true) -- include auxiliary
|
||||
if provider and provider.order then -- auxiliary
|
||||
if aux_caller_callback then
|
||||
aux_caller_callback()
|
||||
@@ -1566,7 +1565,7 @@ function FileManager:openFile(file, provider, doc_caller_callback, aux_caller_ca
|
||||
doc_caller_callback()
|
||||
end
|
||||
local ReaderUI = require("apps/reader/readerui")
|
||||
ReaderUI:showReader(file, provider)
|
||||
ReaderUI:showReader(file, provider, nil, is_provider_forced)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -88,6 +88,20 @@ function ReaderTypeset:onReadSettings(config)
|
||||
self.ui.document:setNightmodeImages(self.configurable.nightmode_images == 1)
|
||||
end
|
||||
|
||||
function ReaderTypeset:onReaderReady()
|
||||
-- Initial detection of fb2 may be wrong
|
||||
local doc_format = self.ui.document:getDocumentFormat()
|
||||
local is_fb2 = doc_format:sub(1, 11) == "FictionBook"
|
||||
if self.ui.document.is_fb2 ~= is_fb2 then
|
||||
self.ui.document.is_fb2 = is_fb2
|
||||
self.ui.document.default_css = is_fb2 and "./data/fb2.css" or "./data/epub.css"
|
||||
if self.ui.document.is_new then
|
||||
local css = G_reader_settings:readSetting(is_fb2 and "copt_fb2_css" or "copt_css")
|
||||
self:setStyleSheet(css or self.ui.document.default_css)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function ReaderTypeset:onSaveSettings()
|
||||
self.ui.doc_settings:saveSetting("css", self.css)
|
||||
end
|
||||
|
||||
@@ -124,6 +124,7 @@ function ReaderUI:init()
|
||||
end
|
||||
|
||||
self.doc_settings = DocSettings:open(self.document.file)
|
||||
self.document.is_new = self.doc_settings:readSetting("doc_props") == nil
|
||||
-- Handle local settings migration
|
||||
SettingsMigration:migrateSettings(self.doc_settings)
|
||||
|
||||
@@ -590,10 +591,9 @@ end
|
||||
--- @note: Will sanely close existing FileManager/ReaderUI instance for you!
|
||||
--- This is the *only* safe way to instantiate a new ReaderUI instance!
|
||||
--- (i.e., don't look at the testsuite, which resorts to all kinds of nasty hacks).
|
||||
function ReaderUI:showReader(file, provider, seamless)
|
||||
function ReaderUI:showReader(file, provider, seamless, is_provider_forced)
|
||||
logger.dbg("show reader ui")
|
||||
|
||||
file = ffiUtil.realpath(file)
|
||||
if lfs.attributes(file, "mode") ~= "file" then
|
||||
UIManager:show(InfoMessage:new{
|
||||
text = T(_("File '%1' does not exist."), BD.filepath(filemanagerutil.abbreviate(file)))
|
||||
@@ -601,20 +601,58 @@ function ReaderUI:showReader(file, provider, seamless)
|
||||
return
|
||||
end
|
||||
|
||||
if not DocumentRegistry:hasProvider(file) and provider == nil then
|
||||
if provider == nil and DocumentRegistry:hasProvider(file) then
|
||||
provider = DocumentRegistry:getProvider(file)
|
||||
end
|
||||
if provider ~= nil then
|
||||
provider = self:extendProvider(file, provider, is_provider_forced)
|
||||
end
|
||||
if provider and provider.provider then
|
||||
-- We can now signal the existing ReaderUI/FileManager instances that it's time to go bye-bye...
|
||||
UIManager:broadcastEvent(Event:new("ShowingReader"))
|
||||
self:showReaderCoroutine(file, provider, seamless)
|
||||
else
|
||||
UIManager:show(InfoMessage:new{
|
||||
text = T(_("File '%1' is not supported."), BD.filepath(filemanagerutil.abbreviate(file)))
|
||||
})
|
||||
self:showFileManager(file)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
-- We can now signal the existing ReaderUI/FileManager instances that it's time to go bye-bye...
|
||||
UIManager:broadcastEvent(Event:new("ShowingReader"))
|
||||
provider = provider or DocumentRegistry:getProvider(file)
|
||||
if provider.provider then
|
||||
self:showReaderCoroutine(file, provider, seamless)
|
||||
function ReaderUI:extendProvider(file, provider, is_provider_forced)
|
||||
-- If file extension is single "zip", check the archive content and choose the appropriate provider,
|
||||
-- except when the provider choice is forced in the "Open with" dialog.
|
||||
-- Also pass to crengine is_fb2 property, based on the archive content (single "zip" extension),
|
||||
-- or on the original file double extension ("fb2.zip" etc).
|
||||
local _, file_type = filemanagerutil.splitFileNameType(file) -- supports double-extension
|
||||
if file_type == "zip" then
|
||||
-- read the content of zip-file and get extension of the 1st file
|
||||
local std_out = io.popen("unzip -qql \"" .. file .. "\"")
|
||||
if std_out then
|
||||
local size, ext
|
||||
for line in std_out:lines() do
|
||||
size, ext = string.match(line, "%s+(%d+)%s+.+%.([^.]+)")
|
||||
if size and ext then break end
|
||||
end
|
||||
std_out:close()
|
||||
if ext ~= nil then
|
||||
file_type = ext:lower()
|
||||
end
|
||||
end
|
||||
if not is_provider_forced then
|
||||
local providers = DocumentRegistry:getProviders("dummy." .. file_type)
|
||||
if providers then
|
||||
for _, p in ipairs(providers) do
|
||||
if p.provider.provider == "crengine" or p.provider.provider == "mupdf" then -- only these can unzip
|
||||
provider = p.provider
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
provider.is_fb2 = file_type:sub(1, 2) == "fb"
|
||||
return provider
|
||||
end
|
||||
|
||||
function ReaderUI:showReaderCoroutine(file, provider, seamless)
|
||||
|
||||
@@ -67,7 +67,7 @@ local CreDocument = Document:extend{
|
||||
"Noto Sans",
|
||||
},
|
||||
|
||||
default_css = "./data/cr3.css",
|
||||
default_css = nil,
|
||||
provider = "crengine",
|
||||
provider_name = "Cool Reader Engine",
|
||||
|
||||
@@ -77,20 +77,6 @@ local CreDocument = Document:extend{
|
||||
last_linear_page = nil,
|
||||
}
|
||||
|
||||
-- NuPogodi, 20.05.12: inspect the zipfile content
|
||||
function CreDocument:zipContentExt(fname)
|
||||
local std_out = io.popen("unzip ".."-qql \""..fname.."\"")
|
||||
if std_out then
|
||||
local size, ext
|
||||
for line in std_out:lines() do
|
||||
size, ext = string.match(line, "%s+(%d+)%s+.+%.([^.]+)")
|
||||
if size and ext then break end
|
||||
end
|
||||
std_out:close()
|
||||
if ext then return string.lower(ext) end
|
||||
end
|
||||
end
|
||||
|
||||
function CreDocument:cacheInit()
|
||||
-- remove legacy cr3cache directory
|
||||
if lfs.attributes("./cr3cache", "mode") == "directory" then
|
||||
@@ -170,13 +156,6 @@ function CreDocument:init()
|
||||
self.flows = {}
|
||||
self.page_in_flow = {}
|
||||
|
||||
local file_type = string.lower(string.match(self.file, ".+%.([^.]+)") or "")
|
||||
if file_type == "zip" then
|
||||
-- NuPogodi, 20.05.12: read the content of zip-file
|
||||
-- and return extension of the 1st file
|
||||
file_type = self:zipContentExt(self.file) or "unknown"
|
||||
end
|
||||
|
||||
-- June 2018: epub.css has been cleaned to be more conforming to HTML specs
|
||||
-- and to not include class name based styles (with conditional compatibility
|
||||
-- styles for previously opened documents). It should be usable on all
|
||||
@@ -184,11 +163,7 @@ function CreDocument:init()
|
||||
-- The other css files (htm.css, rtf.css...) have not been updated in the
|
||||
-- same way, and are kept as-is for when a previously opened document
|
||||
-- requests one of them.
|
||||
self.default_css = "./data/epub.css"
|
||||
if file_type == "fb2" or file_type == "fb3" then
|
||||
self.default_css = "./data/fb2.css"
|
||||
self.is_fb2 = true -- FB2 won't look good with any html-oriented stylesheet
|
||||
end
|
||||
self.default_css = self.is_fb2 and "./data/fb2.css" or "./data/epub.css"
|
||||
|
||||
-- This mode must be the same as the default one set as ReaderView.view_mode
|
||||
self._view_mode = G_defaults:readSetting("DCREREADER_VIEW_MODE") == "scroll" and self.SCROLL_VIEW_MODE or self.PAGE_VIEW_MODE
|
||||
|
||||
@@ -67,24 +67,9 @@ function Document:_init()
|
||||
self.info = {
|
||||
-- whether the document is pageable
|
||||
has_pages = false,
|
||||
-- whether words can be provided
|
||||
has_words = false,
|
||||
-- whether hyperlinks can be provided
|
||||
has_hyperlinks = false,
|
||||
-- whether (native to format) annotations can be provided
|
||||
has_annotations = false,
|
||||
|
||||
-- whether pages can be rotated
|
||||
is_rotatable = false,
|
||||
|
||||
number_of_pages = 0,
|
||||
-- if not pageable, length of the document in pixels
|
||||
doc_height = 0,
|
||||
|
||||
-- other metadata
|
||||
title = "",
|
||||
author = "",
|
||||
date = ""
|
||||
}
|
||||
|
||||
-- Should be updated by a call to Document.updateColorRendering(self) in subclasses
|
||||
|
||||
@@ -91,7 +91,7 @@ end
|
||||
|
||||
function DocSettingTweak:onDocSettingsLoad(doc_settings, document)
|
||||
-- check that the document has not been opened yet & and that we have defaults to customize
|
||||
if doc_settings.data.doc_props == nil and directory_defaults.data ~= nil then
|
||||
if document.is_new and directory_defaults.data ~= nil then
|
||||
local base = G_reader_settings:readSetting("home_dir") or filemanagerutil.getDefaultDir()
|
||||
local directory = FFIUtil.dirname(document.file)
|
||||
-- check if folder matches our defaults to override
|
||||
|
||||
@@ -2,7 +2,6 @@ local ConfirmBox = require("ui/widget/confirmbox")
|
||||
local DataStorage = require("datastorage")
|
||||
local Device = require("device")
|
||||
local Dispatcher = require("dispatcher")
|
||||
local DocSettings = require("docsettings")
|
||||
local InfoMessage = require("ui/widget/infomessage")
|
||||
local InputDialog = require("ui/widget/inputdialog")
|
||||
local LuaSettings = require("luasettings")
|
||||
@@ -964,7 +963,7 @@ function Profiles:executeAutoExecDocConditional(event)
|
||||
for profile_name, conditions in pairs(self.autoexec[event]) do
|
||||
if self.data[profile_name] then
|
||||
local do_execute
|
||||
if not conditions.is_new or not DocSettings:hasSidecarFile(self.document.file) then
|
||||
if not conditions.is_new or self.document.is_new then
|
||||
for condition, trigger in pairs(conditions) do
|
||||
if condition == "orientation" then
|
||||
local mode = Screen:getRotationMode()
|
||||
|
||||
Reference in New Issue
Block a user