diff --git a/Makefile b/Makefile index 3f90446bc..3c7a9911d 100644 --- a/Makefile +++ b/Makefile @@ -79,6 +79,9 @@ endif @echo "[*] Install plugins" @# TODO: link istead of cp? $(RCP) plugins/* $(INSTALL_DIR)/koreader/plugins/ + @# purge deleted plugins + for d in $$(ls $(INSTALL_DIR)/koreader/plugins); do \ + test -d plugins/$$d || rm -rf $(INSTALL_DIR)/koreader/plugins/$$d ; done @echo "[*] Installresources" $(RCP) -pL resources/fonts/* $(INSTALL_DIR)/koreader/fonts/ install -d $(INSTALL_DIR)/koreader/{screenshots,data/{dict,tessdata},fonts/host,ota} diff --git a/frontend/pluginloader.lua b/frontend/pluginloader.lua index fa39a3352..1548e6b70 100644 --- a/frontend/pluginloader.lua +++ b/frontend/pluginloader.lua @@ -1,42 +1,66 @@ local lfs = require("libs/libkoreader-lfs") local logger = require("logger") -local PluginLoader = { - plugin_path = "plugins" -} +local DEFAULT_PLUGIN_PATH = "plugins" + +local PluginLoader = {} function PluginLoader:loadPlugins() if self.plugins then return self.plugins end self.plugins = {} - for f in lfs.dir(self.plugin_path) do - local path = self.plugin_path.."/"..f - local mode = lfs.attributes(path, "mode") - -- valid koreader plugin directory - if mode == "directory" and f:find(".+%.koplugin$") then - local mainfile = path.."/".."main.lua" - local package_path = package.path - local package_cpath = package.cpath - package.path = path.."/?.lua;"..package.path - package.cpath = path.."/lib/?.so;"..package.cpath - local ok, plugin_module = pcall(dofile, mainfile) - if not ok or not plugin_module then - logger.warn("Error when loading", mainfile, plugin_module) - elseif type(plugin_module.disabled) ~= "boolean" or not plugin_module.disabled then + local lookup_path_list = { DEFAULT_PLUGIN_PATH } + local extra_paths = G_reader_settings:readSetting("extra_plugin_paths") + if extra_paths then + if type(extra_paths) == "string" then + extra_paths = { extra_paths } + end + if type(extra_paths) == "table" then + for _,extra_path in ipairs(extra_paths) do + local extra_path_mode = lfs.attributes(extra_path, "mode") + if extra_path_mode == "directory" and extra_path ~= DEFAULT_PLUGIN_PATH then + table.insert(lookup_path_list, extra_path) + end + end + else + logger.err("extra_plugin_paths config only accepts string or table value") + end + end + + -- keep reference to old value so they can be restored later + local package_path = package.path + local package_cpath = package.cpath + + 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$") 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) + local ok, plugin_module = pcall(dofile, mainfile) + if not ok or not plugin_module then + logger.warn("Error when loading", mainfile, plugin_module) + 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") + table.insert(self.plugins, plugin_module) + else + logger.info("Plugin ", mainfile, " has been disabled.") + end package.path = package_path package.cpath = package_cpath - plugin_module.path = path - plugin_module.name = plugin_module.name or path:match("/(.-)%.koplugin") - table.insert(self.plugins, plugin_module) - else - logger.info("Plugin ", mainfile, " has been disabled.") end end end + -- set package path for all loaded plugins for _,plugin in ipairs(self.plugins) do - package.path = package.path..";"..plugin.path.."/?.lua" - package.cpath = package.cpath..";"..plugin.path.."/lib/?.so" + 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) diff --git a/frontend/ui/elements/reader_menu_order.lua b/frontend/ui/elements/reader_menu_order.lua index 1ca403e66..7183bade6 100644 --- a/frontend/ui/elements/reader_menu_order.lua +++ b/frontend/ui/elements/reader_menu_order.lua @@ -23,7 +23,6 @@ local order = { "highlight_options", "change_font", "hyphenation", - "read_timer", }, setting = { "read_from_right_to_left", @@ -43,6 +42,7 @@ local order = { "status_bar", }, tools = { + "read_timer", "calibre_wireless_connection", "evernote", "goodreads", diff --git a/plugins/hello.koplugin/main.lua b/plugins/hello.koplugin/main.lua index aeb5426f0..ddd5ad1cc 100644 --- a/plugins/hello.koplugin/main.lua +++ b/plugins/hello.koplugin/main.lua @@ -1,4 +1,9 @@ -local InfoMessage = require("ui/widget/infomessage") +-- This is a debug plugin, remove the following if block to enable it +if true then + return { disabled = true, } +end + +local InfoMessage = require("ui/widget/infomessage") -- luacheck:ignore local UIManager = require("ui/uimanager") local WidgetContainer = require("ui/widget/container/widgetcontainer") local _ = require("gettext") @@ -6,22 +11,21 @@ local _ = require("gettext") local Hello = WidgetContainer:new{ name = 'Hello', is_doc_only = false, - disabled = true, -- This is a debug plugin } function Hello:init() self.ui.menu:registerToMainMenu(self) end -function Hello:addToMainMenu(tab_item_table) - table.insert(tab_item_table.plugins, { +function Hello:addToMainMenu(menu_items) + menu_items.hello_world = { text = _("Hello World"), callback = function() UIManager:show(InfoMessage:new{ - text = _("Hello, docless plugin world"), + text = _("Hello, plugin world"), }) end, - }) + } end return Hello diff --git a/plugins/kobolight.koplugin/main.lua b/plugins/kobolight.koplugin/main.lua index 6f94aa385..6ff30ac74 100644 --- a/plugins/kobolight.koplugin/main.lua +++ b/plugins/kobolight.koplugin/main.lua @@ -9,7 +9,6 @@ local ConfirmBox = require("ui/widget/confirmbox") local ImageWidget = require("ui/widget/imagewidget") local InfoMessage = require("ui/widget/infomessage") local Notification = require("ui/widget/notification") -local PluginLoader = require("pluginloader") local Screen = require("device").screen local UIManager = require("ui/uimanager") local WidgetContainer = require("ui/widget/container/widgetcontainer") @@ -165,7 +164,7 @@ function KoboLight:addToMainMenu(menu_items) text = _("Frontlight gesture controller"), callback = function() local image = ImageWidget:new{ - file = PluginLoader.plugin_path .. "/kobolight.koplugin/demo.png", + file = self.path .. "/demo.png", height = Screen:getHeight(), width = Screen:getWidth(), scale_factor = 0, diff --git a/plugins/timesync.koplugin/main.lua b/plugins/timesync.koplugin/main.lua index 7c0084c75..5d4f93442 100644 --- a/plugins/timesync.koplugin/main.lua +++ b/plugins/timesync.koplugin/main.lua @@ -1,4 +1,3 @@ - local Device = require("device") local command