mirror of
https://github.com/koreader/koreader.git
synced 2025-08-10 00:52:38 +00:00
Custom book covers (#10329)
This commit is contained in:
@@ -868,7 +868,7 @@ function FileManager:pasteHere(file)
|
||||
local function infoCopyFile()
|
||||
if self:copyRecursive(orig_file, dest_path) then
|
||||
if is_file then
|
||||
DocSettings:update(orig_file, dest_file, true)
|
||||
DocSettings:updateLocation(orig_file, dest_file, true)
|
||||
end
|
||||
return true
|
||||
else
|
||||
@@ -882,7 +882,7 @@ function FileManager:pasteHere(file)
|
||||
local function infoMoveFile()
|
||||
if self:moveFile(orig_file, dest_path) then
|
||||
if is_file then
|
||||
DocSettings:update(orig_file, dest_file)
|
||||
DocSettings:updateLocation(orig_file, dest_file)
|
||||
require("readhistory"):updateItemByPath(orig_file, dest_file) -- (will update "lastfile" if needed)
|
||||
end
|
||||
ReadCollection:updateItemByPath(orig_file, dest_file)
|
||||
@@ -1005,7 +1005,7 @@ function FileManager:deleteFile(file, is_file)
|
||||
end
|
||||
if ok and not err then
|
||||
if is_file then
|
||||
DocSettings:update(file)
|
||||
DocSettings:updateLocation(file)
|
||||
require("readhistory"):fileDeleted(file)
|
||||
end
|
||||
ReadCollection:removeItemByPath(file, not is_file)
|
||||
@@ -1054,7 +1054,7 @@ function FileManager:renameFile(file, basename, is_file)
|
||||
local function doRenameFile()
|
||||
if self:moveFile(file, dest) then
|
||||
if is_file then
|
||||
DocSettings:update(file, dest)
|
||||
DocSettings:updateLocation(file, dest)
|
||||
require("readhistory"):updateItemByPath(file, dest) -- (will update "lastfile" if needed)
|
||||
end
|
||||
ReadCollection:updateItemByPath(file, dest)
|
||||
|
||||
@@ -3,11 +3,13 @@ This module provides a way to display book information (filename and book metada
|
||||
]]
|
||||
|
||||
local BD = require("ui/bidi")
|
||||
local ButtonDialog = require("ui/widget/buttondialog")
|
||||
local DocSettings = require("docsettings")
|
||||
local DocumentRegistry = require("document/documentregistry")
|
||||
local InfoMessage = require("ui/widget/infomessage")
|
||||
local UIManager = require("ui/uimanager")
|
||||
local WidgetContainer = require("ui/widget/container/widgetcontainer")
|
||||
local ffiutil = require("ffi/util")
|
||||
local filemanagerutil = require("apps/filemanager/filemanagerutil")
|
||||
local lfs = require("libs/libkoreader-lfs")
|
||||
local util = require("util")
|
||||
@@ -32,7 +34,8 @@ function BookInfo:addToMainMenu(menu_items)
|
||||
}
|
||||
end
|
||||
|
||||
function BookInfo:show(file, book_props)
|
||||
function BookInfo:show(file, book_props, metadata_updated_caller_callback)
|
||||
self.updated = nil
|
||||
local kv_pairs = {}
|
||||
|
||||
-- File section
|
||||
@@ -101,11 +104,24 @@ function BookInfo:show(file, book_props)
|
||||
end
|
||||
table.insert(kv_pairs, { prop_text, prop })
|
||||
end
|
||||
-- cover image
|
||||
local is_doc = self.document and true or false
|
||||
local viewCoverImage = function()
|
||||
self:onShowBookCover(file)
|
||||
self.custom_book_cover = DocSettings:findCoverFile(file)
|
||||
table.insert(kv_pairs, {
|
||||
_("Cover image:"),
|
||||
_("Tap to display"),
|
||||
callback = function() self:onShowBookCover(file, true) end,
|
||||
separator = is_doc and not self.custom_book_cover,
|
||||
})
|
||||
-- custom cover image
|
||||
if self.custom_book_cover then
|
||||
table.insert(kv_pairs, {
|
||||
_("Custom cover image:"),
|
||||
_("Tap to display"),
|
||||
callback = function() self:onShowBookCover(file) end,
|
||||
separator = is_doc,
|
||||
})
|
||||
end
|
||||
table.insert(kv_pairs, { _("Cover image:"), _("Tap to display"), callback=viewCoverImage, separator=is_doc })
|
||||
|
||||
-- Page section
|
||||
if is_doc then
|
||||
@@ -119,13 +135,37 @@ function BookInfo:show(file, book_props)
|
||||
end
|
||||
|
||||
local KeyValuePage = require("ui/widget/keyvaluepage")
|
||||
local widget = KeyValuePage:new{
|
||||
self.kvp_widget = KeyValuePage:new{
|
||||
title = _("Book information"),
|
||||
value_overflow_align = "right",
|
||||
kv_pairs = kv_pairs,
|
||||
values_lang = values_lang,
|
||||
close_callback = function()
|
||||
if self.updated then
|
||||
local FileManager = require("apps/filemanager/filemanager")
|
||||
local fm_ui = FileManager.instance
|
||||
local ui = self.ui or fm_ui
|
||||
if not ui then
|
||||
local ReaderUI = require("apps/reader/readerui")
|
||||
ui = ReaderUI.instance
|
||||
end
|
||||
if ui and ui.coverbrowser then
|
||||
ui.coverbrowser:deleteBookInfo(file)
|
||||
end
|
||||
if fm_ui then
|
||||
fm_ui:onRefresh()
|
||||
end
|
||||
if metadata_updated_caller_callback then
|
||||
metadata_updated_caller_callback()
|
||||
end
|
||||
end
|
||||
end,
|
||||
title_bar_left_icon = "appbar.menu",
|
||||
title_bar_left_icon_tap_callback = function()
|
||||
self:showCustomMenu(file, book_props, metadata_updated_caller_callback)
|
||||
end,
|
||||
}
|
||||
UIManager:show(widget)
|
||||
UIManager:show(self.kvp_widget)
|
||||
end
|
||||
|
||||
function BookInfo:getBookProps(file, book_props, no_open_document)
|
||||
@@ -194,11 +234,10 @@ function BookInfo:onShowBookInfo()
|
||||
local doc_props = self.ui.doc_settings:readSetting("doc_props")
|
||||
-- Make a copy, so we don't add "pages" to the original doc_props
|
||||
-- that will be saved at some point by ReaderUI.
|
||||
local book_props = {}
|
||||
local book_props = { pages = self.ui.doc_settings:readSetting("doc_pages") }
|
||||
for k, v in pairs(doc_props) do
|
||||
book_props[k] = v
|
||||
end
|
||||
book_props.pages = self.ui.doc_settings:readSetting("doc_pages")
|
||||
self:show(self.document.file, book_props)
|
||||
end
|
||||
|
||||
@@ -227,35 +266,109 @@ function BookInfo:onShowBookDescription(description, file)
|
||||
end
|
||||
end
|
||||
|
||||
function BookInfo:onShowBookCover(file)
|
||||
local document
|
||||
if file then
|
||||
document = DocumentRegistry:openDocument(file)
|
||||
if document and document.loadDocument then -- CreDocument
|
||||
document:loadDocument(false) -- load only metadata
|
||||
end
|
||||
function BookInfo:onShowBookCover(file, force_orig)
|
||||
local cover_bb = self:getCoverImage(self.document, file, force_orig)
|
||||
if cover_bb then
|
||||
local ImageViewer = require("ui/widget/imageviewer")
|
||||
local imgviewer = ImageViewer:new{
|
||||
image = cover_bb,
|
||||
with_title_bar = false,
|
||||
fullscreen = true,
|
||||
}
|
||||
UIManager:show(imgviewer)
|
||||
else
|
||||
document = self.document
|
||||
UIManager:show(InfoMessage:new{
|
||||
text = _("No cover image available."),
|
||||
})
|
||||
end
|
||||
if document then
|
||||
local cover_bb = document:getCoverPageImage()
|
||||
if cover_bb then
|
||||
local ImageViewer = require("ui/widget/imageviewer")
|
||||
local imgviewer = ImageViewer:new{
|
||||
image = cover_bb,
|
||||
with_title_bar = false,
|
||||
fullscreen = true,
|
||||
}
|
||||
UIManager:show(imgviewer)
|
||||
end
|
||||
|
||||
function BookInfo:getCoverImage(doc, file, force_orig)
|
||||
local cover_bb
|
||||
-- check for a custom cover (orig cover is forcibly requested in "Book information" only)
|
||||
if not force_orig then
|
||||
local custom_cover = DocSettings:findCoverFile(file or (doc and doc.file))
|
||||
if custom_cover then
|
||||
local cover_doc = DocumentRegistry:openDocument(custom_cover)
|
||||
if cover_doc then
|
||||
cover_bb = cover_doc:getCoverPageImage()
|
||||
cover_doc:close()
|
||||
return cover_bb
|
||||
end
|
||||
end
|
||||
end
|
||||
-- orig cover
|
||||
local is_doc = doc and true or false
|
||||
if not is_doc then
|
||||
doc = DocumentRegistry:openDocument(file)
|
||||
if doc and doc.loadDocument then -- CreDocument
|
||||
doc:loadDocument(false) -- load only metadata
|
||||
end
|
||||
end
|
||||
if doc then
|
||||
cover_bb = doc:getCoverPageImage()
|
||||
if not is_doc then
|
||||
doc:close()
|
||||
end
|
||||
end
|
||||
return cover_bb
|
||||
end
|
||||
|
||||
function BookInfo:setCustomBookCover(file, book_props, metadata_updated_caller_callback)
|
||||
local function kvp_update()
|
||||
if self.ui then
|
||||
self.ui.doc_settings:getCoverFile(true) -- reset cover file cache
|
||||
end
|
||||
self.updated = true
|
||||
self.kvp_widget:onClose()
|
||||
if self.document then
|
||||
self:onShowBookInfo()
|
||||
else
|
||||
UIManager:show(InfoMessage:new{
|
||||
text = _("No cover image available."),
|
||||
})
|
||||
end
|
||||
if not self.document then
|
||||
document:close()
|
||||
self:show(file, book_props, metadata_updated_caller_callback)
|
||||
end
|
||||
end
|
||||
if self.custom_book_cover then -- reset custom cover
|
||||
local ConfirmBox = require("ui/widget/confirmbox")
|
||||
local confirm_box = ConfirmBox:new{
|
||||
text = _("Reset custom cover?\nImage file will be deleted."),
|
||||
ok_text = _("Reset"),
|
||||
ok_callback = function()
|
||||
if os.remove(self.custom_book_cover) then
|
||||
DocSettings:removeSidecarDir(file, util.splitFilePathName(self.custom_book_cover))
|
||||
kvp_update()
|
||||
end
|
||||
end,
|
||||
}
|
||||
UIManager:show(confirm_box)
|
||||
else -- choose an image and set custom cover
|
||||
local PathChooser = require("ui/widget/pathchooser")
|
||||
local path_chooser = PathChooser:new{
|
||||
select_directory = false,
|
||||
file_filter = function(filename)
|
||||
return util.arrayContains(DocSettings.cover_ext, util.getFileNameSuffix(filename))
|
||||
end,
|
||||
onConfirm = function(image_file)
|
||||
local sidecar_dir
|
||||
local sidecar_file = DocSettings:findCoverFile(file) -- existing cover file
|
||||
if sidecar_file then
|
||||
os.remove(sidecar_file)
|
||||
else -- no existing cover, get metadata file path
|
||||
sidecar_file = DocSettings:hasSidecarFile(file, true) -- new sdr locations only
|
||||
end
|
||||
if sidecar_file then
|
||||
sidecar_dir = util.splitFilePathName(sidecar_file)
|
||||
else -- no sdr folder, create new
|
||||
sidecar_dir = DocSettings:getSidecarDir(file)
|
||||
util.makePath(sidecar_dir)
|
||||
end
|
||||
local new_cover_file = sidecar_dir .. "/" .. "cover." .. util.getFileNameSuffix(image_file)
|
||||
if ffiutil.copyFile(image_file, new_cover_file) == nil then
|
||||
kvp_update()
|
||||
end
|
||||
end,
|
||||
}
|
||||
UIManager:show(path_chooser)
|
||||
end
|
||||
end
|
||||
|
||||
function BookInfo:getCurrentPageLineWordCounts()
|
||||
@@ -295,4 +408,26 @@ function BookInfo:getCurrentPageLineWordCounts()
|
||||
return lines_nb, words_nb
|
||||
end
|
||||
|
||||
function BookInfo:showCustomMenu(file, book_props, metadata_updated_caller_callback)
|
||||
local button_dialog
|
||||
local buttons = {{
|
||||
{
|
||||
text = self.custom_book_cover and _("Reset cover image") or _("Set cover image"),
|
||||
align = "left",
|
||||
callback = function()
|
||||
UIManager:close(button_dialog)
|
||||
self:setCustomBookCover(file, book_props, metadata_updated_caller_callback)
|
||||
end,
|
||||
},
|
||||
}}
|
||||
button_dialog = ButtonDialog:new{
|
||||
shrink_unneeded_width = true,
|
||||
buttons = buttons,
|
||||
anchor = function()
|
||||
return self.kvp_widget.title_bar.left_button.image.dimen
|
||||
end,
|
||||
}
|
||||
UIManager:show(button_dialog)
|
||||
end
|
||||
|
||||
return BookInfo
|
||||
|
||||
@@ -958,7 +958,7 @@ function FileManagerMenu:moveBookMetadata()
|
||||
ok_callback = function()
|
||||
UIManager:close(self.menu_container)
|
||||
for _, book in ipairs(books_to_move) do
|
||||
DocSettings:update(book, book)
|
||||
DocSettings:updateLocation(book, book)
|
||||
end
|
||||
FileChooser:refreshPath()
|
||||
end,
|
||||
|
||||
@@ -40,12 +40,8 @@ function filemanagerutil.splitFileNameType(filename)
|
||||
local filename_without_sub_suffix, sub_filetype = util.splitFileNameSuffix(filename_without_suffix)
|
||||
sub_filetype = sub_filetype:lower()
|
||||
local supported_sub_filetypes = { "fb2", "htm", "html", "log", "md", "rtf", "txt", }
|
||||
for _, t in ipairs(supported_sub_filetypes) do
|
||||
if sub_filetype == t then
|
||||
filetype = sub_filetype .. "." .. filetype
|
||||
filename_without_suffix = filename_without_sub_suffix
|
||||
break
|
||||
end
|
||||
if util.arrayContains(supported_sub_filetypes, sub_filetype) then
|
||||
return filename_without_sub_suffix, sub_filetype .. ".zip"
|
||||
end
|
||||
end
|
||||
return filename_without_suffix, filetype
|
||||
@@ -55,7 +51,7 @@ end
|
||||
function filemanagerutil.purgeSettings(file)
|
||||
local file_abs_path = ffiutil.realpath(file)
|
||||
if file_abs_path then
|
||||
DocSettings:open(file_abs_path):purge()
|
||||
return DocSettings:open(file_abs_path):purge()
|
||||
end
|
||||
end
|
||||
|
||||
@@ -138,16 +134,27 @@ function filemanagerutil.genResetSettingsButton(file, caller_callback, button_di
|
||||
return {
|
||||
text = _("Reset"),
|
||||
id = "reset", -- used by covermenu
|
||||
enabled = not button_disabled and DocSettings:hasSidecarFile(ffiutil.realpath(file)),
|
||||
enabled = (not button_disabled and DocSettings:hasSidecarFile(ffiutil.realpath(file))) and true or false,
|
||||
callback = function()
|
||||
local ConfirmBox = require("ui/widget/confirmbox")
|
||||
local confirmbox = ConfirmBox:new{
|
||||
text = T(_("Reset this document?") .. "\n\n%1\n\n" ..
|
||||
_("Document progress, settings, bookmarks, highlights and notes will be permanently lost."),
|
||||
_("Document progress, settings, bookmarks, highlights, notes and custom cover image will be permanently lost."),
|
||||
BD.filepath(file)),
|
||||
ok_text = _("Reset"),
|
||||
ok_callback = function()
|
||||
filemanagerutil.purgeSettings(file)
|
||||
local custom_metadata_purged = filemanagerutil.purgeSettings(file)
|
||||
if custom_metadata_purged then -- refresh coverbrowser cached book info
|
||||
local FileManager = require("apps/filemanager/filemanager")
|
||||
local ui = FileManager.instance
|
||||
if not ui then
|
||||
local ReaderUI = require("apps/reader/readerui")
|
||||
ui = ReaderUI.instance
|
||||
end
|
||||
if ui and ui.coverbrowser then
|
||||
ui.coverbrowser:deleteBookInfo(file)
|
||||
end
|
||||
end
|
||||
require("readhistory"):fileSettingsPurged(file)
|
||||
caller_callback()
|
||||
end,
|
||||
|
||||
@@ -2,6 +2,7 @@ local BookStatusWidget = require("ui/widget/bookstatuswidget")
|
||||
local ButtonDialogTitle = require("ui/widget/buttondialogtitle")
|
||||
local Device = require("device")
|
||||
local Event = require("ui/event")
|
||||
local FileManagerBookInfo = require("apps/filemanager/filemanagerbookinfo")
|
||||
local InfoMessage = require("ui/widget/infomessage")
|
||||
local UIManager = require("ui/uimanager")
|
||||
local WidgetContainer = require("ui/widget/container/widgetcontainer")
|
||||
@@ -198,7 +199,7 @@ end
|
||||
|
||||
function ReaderStatus:onShowBookStatus(before_show_callback)
|
||||
local status_page = BookStatusWidget:new {
|
||||
thumbnail = self.document:getCoverPageImage(),
|
||||
thumbnail = FileManagerBookInfo:getCoverImage(self.document),
|
||||
props = self.document:getProps(),
|
||||
document = self.document,
|
||||
settings = self.settings,
|
||||
|
||||
@@ -12,7 +12,9 @@ local lfs = require("libs/libkoreader-lfs")
|
||||
local logger = require("logger")
|
||||
local util = require("util")
|
||||
|
||||
local DocSettings = LuaSettings:extend{}
|
||||
local DocSettings = LuaSettings:extend{
|
||||
cover_ext = { "png", "jpg", "jpeg", "gif", "tif", "tiff", "svg" },
|
||||
}
|
||||
|
||||
local HISTORY_DIR = DataStorage:getHistoryDir()
|
||||
local DOCSETTINGS_DIR = DataStorage:getDocSettingsDir()
|
||||
@@ -89,13 +91,25 @@ function DocSettings:getSidecarFile(doc_path, force_location)
|
||||
return self:getSidecarDir(doc_path, force_location) .. "/metadata." .. suffix .. ".lua"
|
||||
end
|
||||
|
||||
--- Returns `true` if there is a `metadata.lua` file.
|
||||
--- Returns path of `metadata.lua` file if it exists, or nil.
|
||||
-- @string doc_path path to the document (e.g., `/foo/bar.pdf`)
|
||||
-- @treturn bool
|
||||
function DocSettings:hasSidecarFile(doc_path)
|
||||
return lfs.attributes(self:getSidecarFile(doc_path, "doc"), "mode") == "file"
|
||||
or lfs.attributes(self:getSidecarFile(doc_path, "dir"), "mode") == "file"
|
||||
or lfs.attributes(self:getHistoryPath(doc_path), "mode") == "file"
|
||||
-- @bool no_legacy set to true to skip check of the legacy history file
|
||||
-- @treturn string
|
||||
function DocSettings:hasSidecarFile(doc_path, no_legacy)
|
||||
local sidecar_file = self:getSidecarFile(doc_path, "doc")
|
||||
if lfs.attributes(sidecar_file, "mode") == "file" then
|
||||
return sidecar_file
|
||||
end
|
||||
sidecar_file = self:getSidecarFile(doc_path, "dir")
|
||||
if lfs.attributes(sidecar_file, "mode") == "file" then
|
||||
return sidecar_file
|
||||
end
|
||||
if not no_legacy then
|
||||
sidecar_file = self:getHistoryPath(doc_path)
|
||||
if lfs.attributes(sidecar_file, "mode") == "file" then
|
||||
return sidecar_file
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function DocSettings:getHistoryPath(doc_path)
|
||||
@@ -134,6 +148,43 @@ function DocSettings:getFileFromHistory(hist_name)
|
||||
end
|
||||
end
|
||||
|
||||
--- Returns path to book custom cover file if it exists, or nil.
|
||||
function DocSettings:findCoverFile(doc_path)
|
||||
local location = G_reader_settings:readSetting("document_metadata_folder", "doc")
|
||||
local sidecar_dir = self:getSidecarDir(doc_path, location)
|
||||
local cover_file = self:_findCoverFileInDir(sidecar_dir)
|
||||
if not cover_file then
|
||||
location = location == "doc" and "dir" or "doc"
|
||||
sidecar_dir = self:getSidecarDir(doc_path, location)
|
||||
cover_file = self:_findCoverFileInDir(sidecar_dir)
|
||||
end
|
||||
return cover_file
|
||||
end
|
||||
|
||||
function DocSettings:_findCoverFileInDir(dir)
|
||||
local ok, iter, dir_obj = pcall(lfs.dir, dir)
|
||||
if ok then
|
||||
for f in iter, dir_obj do
|
||||
for _, ext in ipairs(self.cover_ext) do
|
||||
if f == "cover." .. ext then
|
||||
return dir .. "/" .. f
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function DocSettings:getCoverFile(reset_cache)
|
||||
if reset_cache then
|
||||
self.cover_file = nil
|
||||
else
|
||||
if self.cover_file == nil then
|
||||
self.cover_file = DocSettings:findCoverFile(self.data.doc_path) or false
|
||||
end
|
||||
return self.cover_file
|
||||
end
|
||||
end
|
||||
|
||||
--- Opens a document's individual settings (font, margin, dictionary, etc.)
|
||||
-- @string doc_path path to the document (e.g., `/foo/bar.pdf`)
|
||||
-- @treturn DocSettings object
|
||||
@@ -178,9 +229,9 @@ function DocSettings:open(doc_path)
|
||||
-- We get back an array of tables for *existing* candidates, sorted MRU first (insertion order breaks ties).
|
||||
local candidates = buildCandidates(candidates_list)
|
||||
|
||||
local ok, stored
|
||||
local candidate_path, ok, stored
|
||||
for _, t in ipairs(candidates) do
|
||||
local candidate_path = t.path
|
||||
candidate_path = t.path
|
||||
-- Ignore empty files
|
||||
if lfs.attributes(candidate_path, "size") > 0 then
|
||||
ok, stored = pcall(dofile, candidate_path)
|
||||
@@ -196,6 +247,7 @@ function DocSettings:open(doc_path)
|
||||
if ok and stored then
|
||||
new.data = stored
|
||||
new.candidates = candidates
|
||||
new.source_candidate = candidate_path
|
||||
else
|
||||
new.data = {}
|
||||
end
|
||||
@@ -205,7 +257,7 @@ function DocSettings:open(doc_path)
|
||||
end
|
||||
|
||||
--- Serializes settings and writes them to `metadata.lua`.
|
||||
function DocSettings:flush(data)
|
||||
function DocSettings:flush(data, no_cover)
|
||||
-- Depending on the settings, doc_settings are saved to the book folder or
|
||||
-- to koreader/docsettings folder. The latter is also a fallback for read-only book storage.
|
||||
local serials = G_reader_settings:readSetting("document_metadata_folder", "doc") == "doc"
|
||||
@@ -215,8 +267,8 @@ function DocSettings:flush(data)
|
||||
|
||||
local s_out = dump(data or self.data, nil, true)
|
||||
for _, s in ipairs(serials) do
|
||||
util.makePath(s[1])
|
||||
local sidecar_file = s[2]
|
||||
local sidecar_dir, sidecar_file = unpack(s)
|
||||
util.makePath(sidecar_dir)
|
||||
local directory_updated = false
|
||||
if lfs.attributes(sidecar_file, "mode") == "file" then
|
||||
-- As an additional safety measure (to the ffiutil.fsync* calls used below),
|
||||
@@ -244,9 +296,19 @@ function DocSettings:flush(data)
|
||||
ffiutil.fsyncDirectory(sidecar_file)
|
||||
end
|
||||
|
||||
-- move cover file to the metadata file location
|
||||
if not no_cover then
|
||||
local cover_file = self:getCoverFile()
|
||||
if cover_file and util.splitFilePathName(cover_file) ~= sidecar_dir then
|
||||
ffiutil.copyFile(cover_file, sidecar_dir)
|
||||
os.remove(cover_file)
|
||||
self:getCoverFile(true) -- reset cache
|
||||
end
|
||||
end
|
||||
|
||||
self:purge(sidecar_file) -- remove old candidates and empty sidecar folders
|
||||
|
||||
break
|
||||
return sidecar_dir
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -267,30 +329,72 @@ function DocSettings:purge(sidecar_to_keep)
|
||||
end
|
||||
end
|
||||
|
||||
local custom_metadata_purged
|
||||
if not sidecar_to_keep then
|
||||
local cover_file = self:getCoverFile()
|
||||
if cover_file then
|
||||
os.remove(cover_file)
|
||||
self:getCoverFile(true) -- reset cache
|
||||
custom_metadata_purged = true
|
||||
end
|
||||
end
|
||||
if lfs.attributes(self.doc_sidecar_dir, "mode") == "directory" then
|
||||
os.remove(self.doc_sidecar_dir) -- keep parent folders
|
||||
end
|
||||
if lfs.attributes(self.dir_sidecar_dir, "mode") == "directory" then
|
||||
util.removePath(self.dir_sidecar_dir) -- remove empty parent folders
|
||||
end
|
||||
|
||||
return custom_metadata_purged
|
||||
end
|
||||
|
||||
--- Updates sidecar info for file rename/copy/move/delete operations.
|
||||
function DocSettings:update(doc_path, new_doc_path, copy)
|
||||
--- Removes empty sidecar dir.
|
||||
function DocSettings:removeSidecarDir(doc_path, sidecar_dir)
|
||||
if sidecar_dir == self:getSidecarDir(doc_path, "doc") then
|
||||
os.remove(sidecar_dir)
|
||||
else
|
||||
util.removePath(sidecar_dir)
|
||||
end
|
||||
end
|
||||
|
||||
--- Updates sdr location for file rename/copy/move/delete operations.
|
||||
function DocSettings:updateLocation(doc_path, new_doc_path, copy)
|
||||
local doc_settings, new_sidecar_dir
|
||||
|
||||
-- update metadata
|
||||
if self:hasSidecarFile(doc_path) then
|
||||
local doc_settings = DocSettings:open(doc_path)
|
||||
doc_settings = DocSettings:open(doc_path)
|
||||
if new_doc_path then
|
||||
local new_doc_settings = DocSettings:open(new_doc_path)
|
||||
new_doc_settings:flush(doc_settings.data) -- with current "Book metadata folder" setting
|
||||
-- save doc settings to the new location, no cover file yet
|
||||
new_sidecar_dir = new_doc_settings:flush(doc_settings.data, true)
|
||||
else
|
||||
local cache_file_path = doc_settings:readSetting("cache_file_path")
|
||||
if cache_file_path then
|
||||
os.remove(cache_file_path)
|
||||
end
|
||||
end
|
||||
if not copy then
|
||||
doc_settings:purge()
|
||||
end
|
||||
|
||||
-- update cover file
|
||||
if not doc_settings then
|
||||
doc_settings = DocSettings:open(doc_path)
|
||||
end
|
||||
local cover_file = doc_settings:getCoverFile()
|
||||
if cover_file and new_doc_path then
|
||||
if not new_sidecar_dir then
|
||||
new_sidecar_dir = self:getSidecarDir(new_doc_path)
|
||||
util.makePath(new_sidecar_dir)
|
||||
end
|
||||
local _, filename = util.splitFilePathName(cover_file)
|
||||
ffiutil.copyFile(cover_file, new_sidecar_dir .. "/" .. filename)
|
||||
end
|
||||
|
||||
if not copy then
|
||||
doc_settings:purge()
|
||||
end
|
||||
if cover_file then
|
||||
doc_settings:getCoverFile(true) -- reset cache
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ local BottomContainer = require("ui/widget/container/bottomcontainer")
|
||||
local Device = require("device")
|
||||
local DocSettings = require("docsettings")
|
||||
local DocumentRegistry = require("document/documentregistry")
|
||||
local FileManagerBookInfo = require("apps/filemanager/filemanagerbookinfo")
|
||||
local Font = require("ui/font")
|
||||
local Geom = require("ui/geometry")
|
||||
local InfoMessage = require("ui/widget/infomessage")
|
||||
@@ -547,17 +548,7 @@ function Screensaver:setup(event, event_message)
|
||||
end
|
||||
if not excluded then
|
||||
if lastfile and lfs.attributes(lastfile, "mode") == "file" then
|
||||
if ui and ui.document then
|
||||
local doc = ui.document
|
||||
self.image = doc:getCoverPageImage()
|
||||
else
|
||||
local doc = DocumentRegistry:openDocument(lastfile)
|
||||
if doc.loadDocument then -- CreDocument
|
||||
doc:loadDocument(false) -- load only metadata
|
||||
end
|
||||
self.image = doc:getCoverPageImage()
|
||||
doc:close()
|
||||
end
|
||||
self.image = FileManagerBookInfo:getCoverImage(ui and ui.document, lastfile)
|
||||
if self.image == nil then
|
||||
self.screensaver_type = "random_image"
|
||||
end
|
||||
@@ -668,7 +659,7 @@ function Screensaver:show()
|
||||
local doc = ui.document
|
||||
local doc_settings = ui.doc_settings
|
||||
widget = BookStatusWidget:new{
|
||||
thumbnail = doc:getCoverPageImage(),
|
||||
thumbnail = FileManagerBookInfo:getCoverImage(doc),
|
||||
props = doc:getProps(),
|
||||
document = doc,
|
||||
settings = doc_settings,
|
||||
|
||||
@@ -6,7 +6,7 @@ local CalibreMetadata = require("metadata")
|
||||
local ConfirmBox = require("ui/widget/confirmbox")
|
||||
local DataStorage = require("datastorage")
|
||||
local Device = require("device")
|
||||
local DocumentRegistry = require("document/documentregistry")
|
||||
local FileManagerBookInfo = require("apps/filemanager/filemanagerbookinfo")
|
||||
local InputDialog = require("ui/widget/inputdialog")
|
||||
local InfoMessage = require("ui/widget/infomessage")
|
||||
local Menu = require("ui/widget/menu")
|
||||
@@ -272,15 +272,7 @@ end
|
||||
|
||||
function CalibreSearch:onMenuHold(item)
|
||||
if not item.info or item.info:len() <= 0 then return end
|
||||
local thumbnail
|
||||
local doc = DocumentRegistry:openDocument(item.path)
|
||||
if doc then
|
||||
if doc.loadDocument then -- CreDocument
|
||||
doc:loadDocument(false) -- load only metadata
|
||||
end
|
||||
thumbnail = doc:getCoverPageImage()
|
||||
doc:close()
|
||||
end
|
||||
local thumbnail = FileManagerBookInfo:getCoverImage(nil, item.path)
|
||||
local thumbwidth = math.min(240, Screen:getWidth()/3)
|
||||
UIManager:show(InfoMessage:new{
|
||||
text = item.info,
|
||||
|
||||
@@ -4,6 +4,7 @@ local DataStorage = require("datastorage")
|
||||
local Device = require("device")
|
||||
local DocumentRegistry = require("document/documentregistry")
|
||||
local FFIUtil = require("ffi/util")
|
||||
local FileManagerBookInfo = require("apps/filemanager/filemanagerbookinfo")
|
||||
local InfoMessage = require("ui/widget/infomessage")
|
||||
local RenderImage = require("ui/renderimage")
|
||||
local SQ3 = require("lua-ljsqlite3/init")
|
||||
@@ -528,7 +529,7 @@ function BookInfoManager:extractBookInfo(filepath, cover_specs)
|
||||
local spec_max_cover_h = cover_specs.max_cover_h
|
||||
|
||||
dbrow.cover_fetched = 'Y' -- we had a try at getting a cover
|
||||
local cover_bb = document:getCoverPageImage()
|
||||
local cover_bb = FileManagerBookInfo:getCoverImage(document)
|
||||
if cover_bb then
|
||||
dbrow.has_cover = 'Y'
|
||||
dbrow.cover_sizetag = spec_sizetag
|
||||
|
||||
@@ -464,10 +464,13 @@ function CoverMenu:onHistoryMenuHold(item)
|
||||
end
|
||||
end
|
||||
|
||||
-- Replace Book information callback to use directly our bookinfo
|
||||
-- Replace the "Book information" button callback to use directly our bookinfo
|
||||
button = self.histfile_dialog.button_table:getButtonById("book_information")
|
||||
local function when_updated_callback()
|
||||
self:updateItems()
|
||||
end
|
||||
button.callback = function()
|
||||
FileManagerBookInfo:show(file, bookinfo)
|
||||
FileManagerBookInfo:show(file, bookinfo, when_updated_callback)
|
||||
UIManager:close(self.histfile_dialog)
|
||||
end
|
||||
|
||||
@@ -584,10 +587,13 @@ function CoverMenu:onCollectionsMenuHold(item)
|
||||
end
|
||||
end
|
||||
|
||||
-- Replace Book information callback to use directly our bookinfo
|
||||
-- Replace the "Book information" button callback to use directly our bookinfo
|
||||
button = self.collfile_dialog.button_table:getButtonById("book_information")
|
||||
local function when_updated_callback()
|
||||
self:updateItems()
|
||||
end
|
||||
button.callback = function()
|
||||
FileManagerBookInfo:show(file, bookinfo)
|
||||
FileManagerBookInfo:show(file, bookinfo, when_updated_callback)
|
||||
UIManager:close(self.collfile_dialog)
|
||||
end
|
||||
|
||||
|
||||
@@ -672,6 +672,10 @@ function CoverBrowser:getBookInfo(file)
|
||||
return BookInfoManager:getBookInfo(file)
|
||||
end
|
||||
|
||||
function CoverBrowser:deleteBookInfo(file)
|
||||
BookInfoManager:deleteBookInfo(file)
|
||||
end
|
||||
|
||||
function CoverBrowser:extractBooksInDirectory(path)
|
||||
local Trapper = require("ui/trapper")
|
||||
Trapper:wrap(function()
|
||||
|
||||
@@ -107,7 +107,7 @@ function MoveToArchive:commonProcess(is_move_process, moved_done_text)
|
||||
FileManager:copyFileFromTo(document_full_path, self.archive_dir_path)
|
||||
end
|
||||
local dest_file = string.format("%s%s", self.archive_dir_path, filename)
|
||||
DocSettings:update(document_full_path, dest_file, not is_move_process)
|
||||
DocSettings:updateLocation(document_full_path, dest_file, not is_move_process)
|
||||
ReadHistory:updateItemByPath(document_full_path, dest_file) -- (will update "lastfile" if needed)
|
||||
ReadCollection:updateItemByPath(document_full_path, dest_file)
|
||||
UIManager:show(ConfirmBox:new{
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
local http = require("socket.http")
|
||||
local ImageViewer = require("ui/widget/imageviewer")
|
||||
local InfoMessage = require("ui/widget/infomessage")
|
||||
local InputDialog = require("ui/widget/inputdialog")
|
||||
local logger = require("logger")
|
||||
@@ -156,6 +155,7 @@ function OPDSPSE:streamPages(remote_url, count, continue, username, password)
|
||||
end
|
||||
end
|
||||
end})
|
||||
local ImageViewer = require("ui/widget/imageviewer")
|
||||
local viewer = ImageViewer:new{
|
||||
image = page_table,
|
||||
fullscreen = true,
|
||||
|
||||
Reference in New Issue
Block a user