You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
koreader/plugins/calibre.koplugin/main.lua

341 lines
12 KiB
Lua

--[[
This plugin implements KOReader integration with *some* calibre features:
- metadata search
- wireless transfers
This module handles the UI part of the plugin.
--]]
local BD = require("ui/bidi")
local CalibreSearch = require("search")
local CalibreWireless = require("wireless")
local Dispatcher = require("dispatcher")
local InfoMessage = require("ui/widget/infomessage")
local LuaSettings = require("luasettings")
local UIManager = require("ui/uimanager")
local WidgetContainer = require("ui/widget/container/widgetcontainer")
local _ = require("gettext")
local T = require("ffi/util").template
local Calibre = WidgetContainer:new{
name = "calibre",
is_doc_only = false,
}
function Calibre:onCalibreSearch()
CalibreSearch:ShowSearch()
return true
end
function Calibre:onCalibreBrowseTags()
CalibreSearch.search_value = ""
CalibreSearch:find("tags", 1)
return true
end
function Calibre:onCalibreBrowseSeries()
CalibreSearch.search_value = ""
CalibreSearch:find("series", 1)
return true
end
function Calibre:onNetworkDisconnected()
self:closeWirelessConnection()
end
function Calibre:onSuspend()
self:closeWirelessConnection()
end
function Calibre:onClose()
self:closeWirelessConnection()
end
function Calibre:closeWirelessConnection()
if CalibreWireless.calibre_socket then
CalibreWireless:disconnect()
end
end
function Calibre:onDispatcherRegisterActions()
Dispatcher:registerAction("calibre_search", { category="none", event="CalibreSearch", title=_("Search in calibre metadata"), device=true,})
Dispatcher:registerAction("calibre_browse_tags", { category="none", event="CalibreBrowseTags", title=_("Browse all calibre tags"), device=true,})
Dispatcher:registerAction("calibre_browse_series", { category="none", event="CalibreBrowseSeries", title=_("Browse all calibre series"), device=true, separator=true,})
end
function Calibre:init()
CalibreWireless:init()
self:onDispatcherRegisterActions()
self.ui.menu:registerToMainMenu(self)
end
function Calibre:addToMainMenu(menu_items)
menu_items.calibre = {
-- its name is "calibre", but all our top menu items are uppercase.
text = _("Calibre"),
sub_item_table = {
{
text_func = function()
if CalibreWireless.calibre_socket then
return _("Disconnect")
else
return _("Connect")
end
end,
separator = true,
enabled_func = function()
return G_reader_settings:nilOrTrue("calibre_wireless")
end,
callback = function()
if not CalibreWireless.calibre_socket then
CalibreWireless:connect()
else
CalibreWireless:disconnect()
end
end,
},
{ text = _("Search settings"),
keep_menu_open = true,
sub_item_table = self:getSearchMenuTable(),
},
{
text = _("Wireless settings"),
keep_menu_open = true,
sub_item_table = self:getWirelessMenuTable(),
},
}
}
-- insert the metadata search
if G_reader_settings:isTrue("calibre_search_from_reader") or not self.ui.view then
menu_items.find_book_in_calibre_catalog = {
text = _("Find a book via calibre metadata"),
callback = function()
CalibreSearch:ShowSearch()
end
}
end
end
-- search options available from UI
function Calibre:getSearchMenuTable()
return {
{
text = _("Manage libraries"),
separator = true,
keep_menu_open = true,
sub_item_table_func = function()
local result = {}
-- append previous scanned dirs to the list.
local cache = LuaSettings:open(CalibreSearch.cache_libs.path)
for path, _ in pairs(cache.data) do
table.insert(result, {
text = path,
keep_menu_open = true,
checked_func = function()
return cache:isTrue(path)
end,
callback = function()
cache:toggle(path)
cache:flush()
CalibreSearch:invalidateCache()
end,
})
end
-- if there's no result then no libraries are stored
if #result == 0 then
table.insert(result, {
text = _("No calibre libraries"),
enabled = false
})
end
table.insert(result, 1, {
text = _("Rescan disk for calibre libraries"),
separator = true,
callback = function()
CalibreSearch:prompt()
end,
})
return result
end,
},
{
text = _("Enable searches in the reader"),
checked_func = function()
return G_reader_settings:isTrue("calibre_search_from_reader")
end,
callback = function()
G_reader_settings:toggle("calibre_search_from_reader")
UIManager:show(InfoMessage:new{
text = _("This will take effect on next restart."),
})
end,
},
{
text = _("Store metadata in cache"),
checked_func = function()
return G_reader_settings:nilOrTrue("calibre_search_cache_metadata")
end,
callback = function()
G_reader_settings:flipNilOrTrue("calibre_search_cache_metadata")
end,
},
{
text = _("Case sensitive search"),
checked_func = function()
return not G_reader_settings:nilOrTrue("calibre_search_case_insensitive")
end,
callback = function()
G_reader_settings:flipNilOrTrue("calibre_search_case_insensitive")
end,
},
{
text = _("Search by title"),
checked_func = function()
return G_reader_settings:nilOrTrue("calibre_search_find_by_title")
end,
callback = function()
G_reader_settings:flipNilOrTrue("calibre_search_find_by_title")
end,
},
{
text = _("Search by authors"),
checked_func = function()
return G_reader_settings:nilOrTrue("calibre_search_find_by_authors")
end,
callback = function()
G_reader_settings:flipNilOrTrue("calibre_search_find_by_authors")
end,
},
{
text = _("Search by path"),
checked_func = function()
return G_reader_settings:nilOrTrue("calibre_search_find_by_path")
end,
callback = function()
G_reader_settings:flipNilOrTrue("calibre_search_find_by_path")
end,
},
}
end
-- wireless options available from UI
function Calibre:getWirelessMenuTable()
local function isEnabled()
local enabled = G_reader_settings:nilOrTrue("calibre_wireless")
return enabled and not CalibreWireless.calibre_socket
end
return {
{
text = _("Enable wireless client"),
separator = true,
enabled_func = function()
return not CalibreWireless.calibre_socket
end,
checked_func = function()
return G_reader_settings:nilOrTrue("calibre_wireless")
end,
callback = function()
G_reader_settings:flipNilOrTrue("calibre_wireless")
end,
},
{
text = _("Set password"),
enabled_func = isEnabled,
callback = function()
CalibreWireless:setPassword()
end,
},
{
text = _("Set inbox folder"),
enabled_func = isEnabled,
callback = function()
CalibreWireless:setInboxDir()
end,
},
{
text_func = function()
local address = _("automatic")
if G_reader_settings:has("calibre_wireless_url") then
address = G_reader_settings:readSetting("calibre_wireless_url")
address = string.format("%s:%s", address["address"], address["port"])
end
return T(_("Server address (%1)"), BD.ltr(address))
end,
enabled_func = isEnabled,
sub_item_table = {
{
text = _("Automatic"),
checked_func = function()
return G_reader_settings:hasNot("calibre_wireless_url")
end,
callback = function()
G_reader_settings:delSetting("calibre_wireless_url")
end,
},
{
text = _("Manual"),
checked_func = function()
return G_reader_settings:has("calibre_wireless_url")
end,
callback = function(touchmenu_instance)
local MultiInputDialog = require("ui/widget/multiinputdialog")
local url_dialog
local calibre_url = G_reader_settings:readSetting("calibre_wireless_url")
local calibre_url_address, calibre_url_port
if calibre_url then
calibre_url_address = calibre_url["address"]
calibre_url_port = calibre_url["port"]
end
url_dialog = MultiInputDialog:new{
title = _("Set custom calibre address"),
fields = {
{
text = calibre_url_address,
input_type = "string",
hint = _("IP Address"),
},
{
text = calibre_url_port,
input_type = "number",
hint = _("Port"),
},
},
buttons = {
{
{
text = _("Cancel"),
callback = function()
UIManager:close(url_dialog)
end,
},
{
text = _("OK"),
callback = function()
local fields = url_dialog:getFields()
if fields[1] ~= "" then
local port = tonumber(fields[2])
if not port or port < 1 or port > 65355 then
--default port
port = 9090
end
G_reader_settings:saveSetting("calibre_wireless_url", {address = fields[1], port = port })
end
UIManager:close(url_dialog)
if touchmenu_instance then touchmenu_instance:updateItems() end
end,
},
},
},
}
UIManager:show(url_dialog)
url_dialog:onShowKeyboard()
end,
},
},
},
}
end
return Calibre