From c92d94af4d4a2e85b7d7a64c9d1b3e192185930a Mon Sep 17 00:00:00 2001 From: hius07 <62179190+hius07@users.noreply.github.com> Date: Tue, 17 Oct 2023 07:42:07 +0300 Subject: [PATCH] writeToFile: centralize (#11012) --- frontend/docsettings.lua | 36 +++--------------------------------- frontend/luadefaults.lua | 27 ++------------------------- frontend/luasettings.lua | 39 +++++++++++++++++---------------------- frontend/readhistory.lua | 7 +------ frontend/util.lua | 20 ++++++++++++++++++++ 5 files changed, 43 insertions(+), 86 deletions(-) diff --git a/frontend/docsettings.lua b/frontend/docsettings.lua index 52ab683e5..c10360513 100644 --- a/frontend/docsettings.lua +++ b/frontend/docsettings.lua @@ -290,14 +290,6 @@ function DocSettings:open(doc_path) return new end -local function writeToFile(data, file) - file:write("-- we can read Lua syntax here!\nreturn ") - file:write(data) - file:write("\n") - ffiutil.fsyncOpenedFile(file) -- force flush to the storage device - file:close() -end - --- Serializes settings and writes them to `metadata.lua`. function DocSettings:flush(data, no_custom_metadata) -- Depending on the settings, doc_settings are saved to the book folder or @@ -321,29 +313,9 @@ function DocSettings:flush(data, no_custom_metadata) for _, s in ipairs(serials) do 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), - -- we only backup the file to .old when it has not been modified in the last 60 seconds. - -- This should ensure in the case the fsync calls are not supported - -- that the OS may have itself sync'ed that file content in the meantime. - local mtime = lfs.attributes(sidecar_file, "modification") - if mtime < os.time() - 60 then - logger.dbg("DocSettings: Renamed", sidecar_file, "to", sidecar_file .. ".old") - os.rename(sidecar_file, sidecar_file .. ".old") - directory_updated = true -- fsync directory content too below - end - end logger.dbg("DocSettings: Writing to", sidecar_file) - local f_out = io.open(sidecar_file, "w") - if f_out ~= nil then - writeToFile(s_out, f_out) - - if directory_updated then - -- Ensure the file renaming is flushed to storage device - ffiutil.fsyncDirectory(sidecar_file) - end - + local directory_updated = LuaSettings:backup(sidecar_file) + if util.writeToFile(s_out, sidecar_file, true, true, directory_updated) then -- move custom cover file and custom metadata file to the metadata file location if not no_custom_metadata then local metadata_file, filepath, filename @@ -614,9 +586,7 @@ function DocSettings:flushCustomMetadata(doc_path) local s_out = dump(self.data, nil, true) for _, sidecar_dir in ipairs(sidecar_dirs) do util.makePath(sidecar_dir) - local f_out = io.open(sidecar_dir .. "/" .. custom_metadata_filename, "w") - if f_out ~= nil then - writeToFile(s_out, f_out) + if util.writeToFile(s_out, sidecar_dir .. "/" .. custom_metadata_filename, true, true) then new_sidecar_dir = sidecar_dir .. "/" break end diff --git a/frontend/luadefaults.lua b/frontend/luadefaults.lua index e2fc4d820..aca6e525d 100644 --- a/frontend/luadefaults.lua +++ b/frontend/luadefaults.lua @@ -5,7 +5,6 @@ Subclass of LuaSettings dedicated to handling the legacy global constants. local DataStorage = require("datastorage") local LuaSettings = require("luasettings") local dump = require("dump") -local ffiutil = require("ffi/util") local util = require("util") local lfs = require("libs/libkoreader-lfs") local logger = require("logger") @@ -153,30 +152,8 @@ function LuaDefaults:reset() end --- Writes settings to disk. function LuaDefaults:flush() if not self.file then return end - local directory_updated = false - if lfs.attributes(self.file, "mode") == "file" then - -- As an additional safety measure (to the ffiutil.fsync* calls used below), - -- we only backup the file to .old when it has not been modified in the last 60 seconds. - -- This should ensure in the case the fsync calls are not supported - -- that the OS may have itself sync'ed that file content in the meantime. - local mtime = lfs.attributes(self.file, "modification") - if mtime < os.time() - 60 then - os.rename(self.file, self.file .. ".old") - directory_updated = true -- fsync directory content too below - end - end - local f_out = io.open(self.file, "w") - if f_out ~= nil then - f_out:write("-- we can read Lua syntax here!\nreturn ") - f_out:write(dump(self.rw, nil, true)) - f_out:write("\n") - ffiutil.fsyncOpenedFile(f_out) -- force flush to the storage device - f_out:close() - end - if directory_updated then - -- Ensure the file renaming is flushed to storage device - ffiutil.fsyncDirectory(self.file) - end + local directory_updated = self:backup() -- LuaSettings + util.writeToFile(dump(self.rw, nil, true), self.file, true, true, directory_updated) return self end diff --git a/frontend/luasettings.lua b/frontend/luasettings.lua index bc3c06173..6b7796f3d 100644 --- a/frontend/luasettings.lua +++ b/frontend/luasettings.lua @@ -3,9 +3,9 @@ This module handles generic settings as well as KOReader's global settings syste ]] local dump = require("dump") -local ffiutil = require("ffi/util") local lfs = require("libs/libkoreader-lfs") local logger = require("logger") +local util = require("util") local LuaSettings = {} @@ -249,33 +249,28 @@ function LuaSettings:reset(table) return self end ---- Writes settings to disk. -function LuaSettings:flush() - if not self.file then return end - local directory_updated = false - if lfs.attributes(self.file, "mode") == "file" then - -- As an additional safety measure (to the ffiutil.fsync* calls used below), +function LuaSettings:backup(file) + file = file or self.file + local directory_updated + if lfs.attributes(file, "mode") == "file" then + -- As an additional safety measure (to the ffiutil.fsync* calls used in util.writeToFile), -- we only backup the file to .old when it has not been modified in the last 60 seconds. -- This should ensure in the case the fsync calls are not supported -- that the OS may have itself sync'ed that file content in the meantime. - local mtime = lfs.attributes(self.file, "modification") + local mtime = lfs.attributes(file, "modification") if mtime < os.time() - 60 then - os.rename(self.file, self.file .. ".old") - directory_updated = true -- fsync directory content too below + os.rename(file, file .. ".old") + directory_updated = true -- fsync directory content end end - local f_out = io.open(self.file, "w") - if f_out ~= nil then - f_out:write("-- we can read Lua syntax here!\nreturn ") - f_out:write(dump(self.data, nil, true)) - f_out:write("\n") - ffiutil.fsyncOpenedFile(f_out) -- force flush to the storage device - f_out:close() - end - if directory_updated then - -- Ensure the file renaming is flushed to storage device - ffiutil.fsyncDirectory(self.file) - end + return directory_updated +end + +--- Writes settings to disk. +function LuaSettings:flush() + if not self.file then return end + local directory_updated = self:backup() + util.writeToFile(dump(self.data, nil, true), self.file, true, true, directory_updated) return self end diff --git a/frontend/readhistory.lua b/frontend/readhistory.lua index 3a6dec044..9d582e869 100644 --- a/frontend/readhistory.lua +++ b/frontend/readhistory.lua @@ -94,12 +94,7 @@ function ReadHistory:_flush() file = v.file }) end - local f = io.open(history_file, "w") - if f then - f:write("return " .. dump(content) .. "\n") - ffiutil.fsyncOpenedFile(f) -- force flush to the storage device - f:close() - end + util.writeToFile(dump(content), history_file, true, true) self:ensureLastFile() end diff --git a/frontend/util.lua b/frontend/util.lua index cab70d9f1..fe003dbaf 100644 --- a/frontend/util.lua +++ b/frontend/util.lua @@ -1034,6 +1034,26 @@ function util.partialMD5(filepath) return update() end +function util.writeToFile(data, filepath, force_flush, lua_dofile_ready, directory_updated) + if not filepath then return end + if lua_dofile_ready then + local t = { "-- ", filepath, "\nreturn ", data, "\n" } + data = table.concat(t) + end + local file, err = io.open(filepath, "wb") + if not file then + return nil, err + end + file:write(data) + if force_flush then + BaseUtil.fsyncOpenedFile(file) + end + file:close() + if directory_updated then + BaseUtil.fsyncDirectory(filepath) + end + return true +end --[[-- Replaces invalid UTF-8 characters with a replacement string.