mirror of
https://github.com/koreader/koreader.git
synced 2025-08-10 00:52:38 +00:00
@@ -4,6 +4,7 @@ local ConfirmBox = require("ui/widget/confirmbox")
|
||||
local Device = require("device")
|
||||
local FileSearcher = require("apps/filemanager/filemanagerfilesearcher")
|
||||
local InputContainer = require("ui/widget/container/inputcontainer")
|
||||
local PluginLoader = require("pluginloader")
|
||||
local Search = require("apps/filemanager/filemanagersearch")
|
||||
local SetDefaults = require("apps/filemanager/filemanagersetdefaults")
|
||||
local UIManager = require("ui/uimanager")
|
||||
@@ -160,6 +161,11 @@ function FileManagerMenu:setUpdateItemTable()
|
||||
SetDefaults:ConfirmSave()
|
||||
end,
|
||||
}
|
||||
self.menu_items.plugin_management = {
|
||||
text = _("Plugin management"),
|
||||
sub_item_table = PluginLoader:genPluginManagerSubItem()
|
||||
}
|
||||
|
||||
self.menu_items.opds_catalog = {
|
||||
text = _("OPDS catalog"),
|
||||
callback = function()
|
||||
|
||||
@@ -155,6 +155,12 @@ function ReaderMenu:setUpdateItemTable()
|
||||
table.remove(self.menu_items.screensaver.sub_item_table, 9)
|
||||
table.insert(self.menu_items.screensaver.sub_item_table, ss_book_settings)
|
||||
end
|
||||
|
||||
local PluginLoader = require("pluginloader")
|
||||
self.menu_items.plugin_management = {
|
||||
text = _("Plugin management"),
|
||||
sub_item_table = PluginLoader:genPluginManagerSubItem()
|
||||
}
|
||||
-- main menu tab
|
||||
-- insert common info
|
||||
for id, common_setting in pairs(require("ui/elements/common_info_menu_table")) do
|
||||
|
||||
@@ -2,8 +2,9 @@ local lfs = require("libs/libkoreader-lfs")
|
||||
local logger = require("logger")
|
||||
|
||||
local DEFAULT_PLUGIN_PATH = "plugins"
|
||||
|
||||
|
||||
local OBSOLETE_PLUGINS = {
|
||||
storagestat = true
|
||||
}
|
||||
|
||||
local function sandboxPluginEventHandlers(plugin)
|
||||
for key, value in pairs(plugin) do
|
||||
@@ -22,12 +23,15 @@ local function sandboxPluginEventHandlers(plugin)
|
||||
end
|
||||
|
||||
|
||||
local PluginLoader = {}
|
||||
local PluginLoader = {
|
||||
show_info = true,
|
||||
}
|
||||
|
||||
function PluginLoader:loadPlugins()
|
||||
if self.plugins then return self.plugins end
|
||||
if self.enabled_plugins then return self.enabled_plugins, self.disabled_plugins end
|
||||
|
||||
self.plugins = {}
|
||||
self.enabled_plugins = {}
|
||||
self.disabled_plugins = {}
|
||||
local lookup_path_list = { DEFAULT_PLUGIN_PATH }
|
||||
local extra_paths = G_reader_settings:readSetting("extra_plugin_paths")
|
||||
if extra_paths then
|
||||
@@ -54,16 +58,17 @@ function PluginLoader:loadPlugins()
|
||||
if type(plugins_disabled) ~= "table" then
|
||||
plugins_disabled = {}
|
||||
end
|
||||
--permanent remove storage stats plugin (#2926)
|
||||
plugins_disabled["storagestat"] = true
|
||||
--disable obsolete plugins
|
||||
for element in pairs(OBSOLETE_PLUGINS) do
|
||||
plugins_disabled[element] = true
|
||||
end
|
||||
for _,lookup_path in ipairs(lookup_path_list) do
|
||||
logger.info('Loading plugins from directory:', lookup_path)
|
||||
for entry in lfs.dir(lookup_path) do
|
||||
local plugin_root = lookup_path.."/"..entry
|
||||
local mode = lfs.attributes(plugin_root, "mode")
|
||||
-- valid koreader plugin directory
|
||||
if mode == "directory" and entry:find(".+%.koplugin$")
|
||||
and not (plugins_disabled and plugins_disabled[entry:sub(1, -10)]) then
|
||||
if mode == "directory" and entry:find(".+%.koplugin$") then
|
||||
local mainfile = plugin_root.."/main.lua"
|
||||
package.path = string.format("%s/?.lua;%s", plugin_root, package_path)
|
||||
package.cpath = string.format("%s/lib/?.so;%s", plugin_root, package_cpath)
|
||||
@@ -73,8 +78,12 @@ function PluginLoader:loadPlugins()
|
||||
elseif type(plugin_module.disabled) ~= "boolean" or not plugin_module.disabled then
|
||||
plugin_module.path = plugin_root
|
||||
plugin_module.name = plugin_module.name or plugin_root:match("/(.-)%.koplugin")
|
||||
sandboxPluginEventHandlers(plugin_module)
|
||||
table.insert(self.plugins, plugin_module)
|
||||
if (plugins_disabled and plugins_disabled[entry:sub(1, -10)]) then
|
||||
table.insert(self.disabled_plugins, plugin_module)
|
||||
else
|
||||
sandboxPluginEventHandlers(plugin_module)
|
||||
table.insert(self.enabled_plugins, plugin_module)
|
||||
end
|
||||
else
|
||||
logger.info("Plugin ", mainfile, " has been disabled.")
|
||||
end
|
||||
@@ -85,14 +94,74 @@ function PluginLoader:loadPlugins()
|
||||
end
|
||||
|
||||
-- set package path for all loaded plugins
|
||||
for _,plugin in ipairs(self.plugins) do
|
||||
for _,plugin in ipairs(self.enabled_plugins) do
|
||||
package.path = string.format("%s;%s/?.lua", package.path, plugin.path)
|
||||
package.cpath = string.format("%s;%s/lib/?.so", package.cpath, plugin.path)
|
||||
end
|
||||
|
||||
table.sort(self.plugins, function(v1,v2) return v1.path < v2.path end)
|
||||
table.sort(self.enabled_plugins, function(v1,v2) return v1.path < v2.path end)
|
||||
|
||||
return self.plugins
|
||||
return self.enabled_plugins, self.disabled_plugins
|
||||
end
|
||||
|
||||
function PluginLoader:genPluginManagerSubItem()
|
||||
local enabled_plugins, disabled_plugins = {}, {}
|
||||
if self.all_plugins == nil then
|
||||
self.all_plugins = {}
|
||||
enabled_plugins, disabled_plugins = self:loadPlugins()
|
||||
end
|
||||
|
||||
for _, plugin in ipairs(enabled_plugins) do
|
||||
local element = {}
|
||||
element.fullname = plugin.fullname or plugin.name
|
||||
element.name = plugin.name
|
||||
element.description = plugin.description
|
||||
element.enable = true
|
||||
table.insert(self.all_plugins, element)
|
||||
end
|
||||
|
||||
for _, plugin in ipairs(disabled_plugins) do
|
||||
local element = {}
|
||||
element.fullname = plugin.fullname or plugin.name
|
||||
element.name = plugin.name
|
||||
element.description = plugin.description
|
||||
element.enable = false
|
||||
if not OBSOLETE_PLUGINS[element.name] then
|
||||
table.insert(self.all_plugins, element)
|
||||
end
|
||||
end
|
||||
table.sort(self.all_plugins, function(v1, v2) return v1.fullname < v2.fullname end)
|
||||
|
||||
local plugin_table = {}
|
||||
for __, plugin in ipairs(self.all_plugins) do
|
||||
table.insert(plugin_table, {
|
||||
text = plugin.fullname,
|
||||
checked_func = function()
|
||||
return plugin.enable
|
||||
end,
|
||||
callback = function()
|
||||
local InfoMessage = require("ui/widget/infomessage")
|
||||
local UIManager = require("ui/uimanager")
|
||||
local _ = require("gettext")
|
||||
local plugins_disabled = G_reader_settings:readSetting("plugins_disabled") or {}
|
||||
plugin.enable = not plugin.enable
|
||||
if plugin.enable then
|
||||
plugins_disabled[plugin.name] = nil
|
||||
else
|
||||
plugins_disabled[plugin.name] = true
|
||||
end
|
||||
G_reader_settings:saveSetting("plugins_disabled", plugins_disabled)
|
||||
if self.show_info then
|
||||
UIManager:show(InfoMessage:new{
|
||||
text = _("This will take effect on next restart."),
|
||||
})
|
||||
self.show_info = false
|
||||
end
|
||||
end,
|
||||
help_text = plugin.description,
|
||||
})
|
||||
end
|
||||
return plugin_table
|
||||
end
|
||||
|
||||
function PluginLoader:createPluginInstance(plugin, attr)
|
||||
|
||||
@@ -58,6 +58,7 @@ local order = {
|
||||
"text_editor",
|
||||
"----------------------------",
|
||||
"more_plugins",
|
||||
"plugin_management",
|
||||
"----------------------------",
|
||||
"advanced_settings",
|
||||
"developer_options",
|
||||
|
||||
@@ -79,6 +79,7 @@ local order = {
|
||||
"text_editor",
|
||||
"----------------------------",
|
||||
"more_plugins",
|
||||
"plugin_management",
|
||||
},
|
||||
more_plugins = {
|
||||
"auto_frontlight",
|
||||
|
||||
@@ -20,6 +20,8 @@ end
|
||||
|
||||
local SSH = WidgetContainer:new{
|
||||
name = 'SSH',
|
||||
fullname = _("SSH"),
|
||||
description = _([[Connect and transfer files to the device using SSH.]]),
|
||||
is_doc_only = false,
|
||||
}
|
||||
|
||||
|
||||
@@ -88,7 +88,9 @@ end
|
||||
AutoFrontlight:init()
|
||||
|
||||
local AutoFrontlightWidget = WidgetContainer:new{
|
||||
name = "AutoFrontlight",
|
||||
name = "autofrontlight",
|
||||
fullname = _("Auto frontlight"),
|
||||
description = _([[Automatically turns the frontlight on and off once brightness in the environment reaches a certain level.]]),
|
||||
}
|
||||
|
||||
function AutoFrontlightWidget:init()
|
||||
|
||||
@@ -111,7 +111,9 @@ end
|
||||
AutoSuspend:init()
|
||||
|
||||
local AutoSuspendWidget = WidgetContainer:new{
|
||||
name = "AutoSuspend",
|
||||
name = "autosuspend",
|
||||
fullname = _("Auto suspend"),
|
||||
description = _([[Suspends the device after a period of inactivity.]]),
|
||||
}
|
||||
|
||||
function AutoSuspendWidget:onInputEvent()
|
||||
|
||||
@@ -3,6 +3,7 @@ local PluginShare = require("pluginshare")
|
||||
local UIManager = require("ui/uimanager")
|
||||
local WidgetContainer = require("ui/widget/container/widgetcontainer")
|
||||
local logger = require("logger")
|
||||
local _ = require("gettext")
|
||||
|
||||
-- BackgroundRunner is an experimental feature to execute non-critical jobs in
|
||||
-- background. A job is defined as a table in PluginShare.backgroundJobs table.
|
||||
@@ -238,6 +239,8 @@ BackgroundRunner:_schedule()
|
||||
|
||||
local BackgroundRunnerWidget = WidgetContainer:new{
|
||||
name = "backgroundrunner",
|
||||
fullname = _("Background runner"),
|
||||
description = _([[Service to other plugins: allows tasks to run regularly in the background.]]),
|
||||
runner = BackgroundRunner,
|
||||
}
|
||||
|
||||
|
||||
@@ -282,6 +282,8 @@ BatteryStat:init()
|
||||
|
||||
local BatteryStatWidget = WidgetContainer:new{
|
||||
name = "batterystat",
|
||||
fullname = _("Battery statistics"),
|
||||
description = _([[Collects and displays battery statistics.]]),
|
||||
}
|
||||
|
||||
function BatteryStatWidget:init()
|
||||
|
||||
@@ -23,6 +23,8 @@ require("ffi/zeromq_h")
|
||||
--]]
|
||||
local CalibreCompanion = InputContainer:new{
|
||||
name = "calibrecompanion",
|
||||
fullname = _("Calibre companion"),
|
||||
description = _([[Send documents from calibre library directly to device via Wi-Fi connection]]),
|
||||
-- calibre companion local port
|
||||
port = 8134,
|
||||
-- calibre broadcast ports used to find calibre server
|
||||
|
||||
@@ -41,7 +41,11 @@ local init_done = false
|
||||
local filemanager_display_mode = false -- not initialized yet
|
||||
local history_display_mode = false -- not initialized yet
|
||||
|
||||
local CoverBrowser = InputContainer:new{}
|
||||
local CoverBrowser = InputContainer:new{
|
||||
name = "coverbrowser",
|
||||
fullname = _("Cover browser"),
|
||||
description = _([[Alternative display modes for file browser and history.]]),
|
||||
}
|
||||
|
||||
function CoverBrowser:init()
|
||||
self.full_featured = true
|
||||
|
||||
@@ -18,6 +18,8 @@ local realpath = require("ffi/util").realpath
|
||||
|
||||
local EvernoteExporter = InputContainer:new{
|
||||
name = "evernote",
|
||||
fullname = _("Evernote"),
|
||||
description = _([[Exports hightlights and notes to the Evernote cloud.]]),
|
||||
login_title = _("Login to Evernote"),
|
||||
notebook_name = _("KOReader Notes"),
|
||||
evernote_domain = nil,
|
||||
|
||||
@@ -9,6 +9,9 @@ local _ = require("gettext")
|
||||
local NetworkMgr = require("ui/network/manager")
|
||||
|
||||
local Goodreads = InputContainer:new {
|
||||
name = "goodreads",
|
||||
fullname = _("Goodreads"),
|
||||
description = _([[Allows browsing and searching the Goodreads database of books.]]),
|
||||
goodreads_key = "",
|
||||
goodreads_secret = "",
|
||||
}
|
||||
|
||||
@@ -9,7 +9,9 @@ local WidgetContainer = require("ui/widget/container/widgetcontainer")
|
||||
local _ = require("gettext")
|
||||
|
||||
local Hello = WidgetContainer:new{
|
||||
name = 'Hello',
|
||||
name = 'hello',
|
||||
fullname = _("Hello"),
|
||||
description = _([[This is a debugging plugin.]]),
|
||||
is_doc_only = false,
|
||||
}
|
||||
|
||||
|
||||
@@ -61,6 +61,8 @@ end
|
||||
|
||||
local KeepAlive = WidgetContainer:new{
|
||||
name = "keepalive",
|
||||
fullname = _("Keep alive"),
|
||||
description = _([[Keeps the device awake to prevent automatic Wi-Fi disconnects.]]),
|
||||
}
|
||||
|
||||
function KeepAlive:init()
|
||||
|
||||
@@ -22,6 +22,8 @@ local swipe_touch_zone_ratio_warmth = { x = 7/8, y = 1/8, w = 1/8, h = 7/8, }
|
||||
|
||||
local KoboLight = WidgetContainer:new{
|
||||
name = 'kobolight',
|
||||
fullname = _("Frontlight gesture controller"),
|
||||
description = _([[Controls the frontlight with gestures on the left border of screen.]]),
|
||||
gestureScale = nil, -- initialized in self:resetLayout()
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,8 @@ end
|
||||
|
||||
local KOSync = InputContainer:new{
|
||||
name = "kosync",
|
||||
fullname = _("Progress sync"),
|
||||
description = _([[Synchronizes your reading progess to a server across your KOReader devices.]]),
|
||||
is_doc_only = true,
|
||||
title = _("Register/login to KOReader server"),
|
||||
|
||||
|
||||
@@ -15,7 +15,11 @@ local util = require("util")
|
||||
local _ = require("gettext")
|
||||
local T = FFIUtil.template
|
||||
|
||||
local NewsDownloader = WidgetContainer:new{}
|
||||
local NewsDownloader = WidgetContainer:new{
|
||||
name = "newsdownloader",
|
||||
fullname = _("News downloader"),
|
||||
description = _([[Retrieves RSS and Atom news entries and saves them as HTML files.]]),
|
||||
}
|
||||
|
||||
local initialized = false
|
||||
local wifi_enabled_before_action = true
|
||||
|
||||
@@ -15,7 +15,9 @@ local Blitbuffer = require("ffi/blitbuffer")
|
||||
|
||||
local PerceptionExpander = Widget:extend{
|
||||
is_enabled = nil,
|
||||
name = "perception_expander",
|
||||
name = "perceptionexpander",
|
||||
fullname = _("Perception expander"),
|
||||
description = _([[Improves your reading speed with the help of two vertical lines over the text.]]),
|
||||
page_counter = 0,
|
||||
shift_each_pages = 100,
|
||||
margin = 0.1,
|
||||
|
||||
@@ -7,6 +7,8 @@ local _ = require("gettext")
|
||||
|
||||
local ReadTimer = WidgetContainer:new{
|
||||
name = "readtimer",
|
||||
fullname = _("Read timer"),
|
||||
description = _([[Shows an alarm after a specified amount of time.]]),
|
||||
time = 0, -- The expected time of alarm if enabled, or 0.
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,11 @@ local util = require("util")
|
||||
local _ = require("gettext")
|
||||
local T = FFIUtil.template
|
||||
|
||||
local Send2Ebook = WidgetContainer:new{}
|
||||
local Send2Ebook = WidgetContainer:new{
|
||||
name = "send2ebook",
|
||||
fullname = _("Send to eBook"),
|
||||
description = _([[Receives articles sent with the Send2Ebook PC/Android application.]]),
|
||||
}
|
||||
|
||||
local initialized = false
|
||||
local wifi_enabled_before_action = true
|
||||
|
||||
@@ -28,6 +28,9 @@ local DEFAULT_MIN_READ_SEC = 5
|
||||
local DEFAULT_MAX_READ_SEC = 120
|
||||
|
||||
local ReaderStatistics = Widget:extend{
|
||||
name = "statistics",
|
||||
fullname = _("Reader statistics"),
|
||||
description = _([[Keeps and displays your reading statistics.]]),
|
||||
page_min_read_sec = DEFAULT_MIN_READ_SEC,
|
||||
page_max_read_sec = DEFAULT_MAX_READ_SEC,
|
||||
start_current_period = 0,
|
||||
|
||||
@@ -240,6 +240,8 @@ SystemStat:init()
|
||||
|
||||
local SystemStatWidget = WidgetContainer:new{
|
||||
name = "systemstat",
|
||||
fullname = _("System statistics"),
|
||||
description = _([[Shows system statistics.]]),
|
||||
}
|
||||
|
||||
function SystemStatWidget:init()
|
||||
|
||||
@@ -11,6 +11,8 @@ local Screen = require("device").screen
|
||||
|
||||
local Terminal = WidgetContainer:new{
|
||||
name = "terminal",
|
||||
fullname = _("Terminal"),
|
||||
description = _([[Executes simple commands and shows their output.]]),
|
||||
dump_file = util.realpath(DataStorage:getDataDir()) .. "/terminal_output.txt",
|
||||
command = "",
|
||||
}
|
||||
|
||||
@@ -17,7 +17,9 @@ local Screen = require("device").screen
|
||||
local T = ffiutil.template
|
||||
|
||||
local TextEditor = WidgetContainer:new{
|
||||
name = "text_editor",
|
||||
name = "texteditor",
|
||||
fullname = _("Text editor"),
|
||||
description = _([[A basic text editor for making small changes to plain text files.]]),
|
||||
settings_file = DataStorage:getSettingsDir() .. "/text_editor.lua",
|
||||
settings = nil, -- loaded only when needed
|
||||
-- how many to display in menu (10x3 pages minus our 3 default menu items):
|
||||
|
||||
@@ -19,6 +19,8 @@ local NetworkMgr = require("ui/network/manager")
|
||||
|
||||
local TimeSync = WidgetContainer:new{
|
||||
name = "timesync",
|
||||
fullname = _("Time sync"),
|
||||
description = _([[Synchronizes the device time with NTP servers.]]),
|
||||
}
|
||||
|
||||
local function currentTime()
|
||||
|
||||
@@ -15,6 +15,8 @@ int rmdir(const char *);
|
||||
require("ffi/zeromq_h")
|
||||
local ZSync = InputContainer:new{
|
||||
name = "zsync",
|
||||
fullname = _("Zsync"),
|
||||
description = _([[Devices in the same Wi-Fi network can transfer documents between each other directly.]]),
|
||||
is_doc_only = true,
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user