Reader: inspect zip file content to choose provider (#12902)

This commit is contained in:
hius07
2024-12-19 09:41:19 +02:00
committed by GitHub
parent e503cc4b9c
commit 15f5dbef83
7 changed files with 68 additions and 58 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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()