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

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