Add “searchable” capabilities to OPDS catalogs (#5823)

OPDS catalogs may have search query capabilities. It is very usefull to find a
book in huge catalog, even when they are organized as directories. This commit
provides the possibility to add a %s mark in an OPS catalog URL, that would
trigger a search box when browsing the OPDS in koreader.
pull/5826/head
bateast 4 years ago committed by GitHub
parent e0ce993c61
commit fa94e6bbf6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -7,6 +7,7 @@ local ConfirmBox = require("ui/widget/confirmbox")
local InfoMessage = require("ui/widget/infomessage") local InfoMessage = require("ui/widget/infomessage")
local Menu = require("ui/widget/menu") local Menu = require("ui/widget/menu")
local MultiInputDialog = require("ui/widget/multiinputdialog") local MultiInputDialog = require("ui/widget/multiinputdialog")
local InputDialog = require("ui/widget/inputdialog")
local NetworkMgr = require("ui/network/manager") local NetworkMgr = require("ui/network/manager")
local OPDSParser = require("ui/opdsparser") local OPDSParser = require("ui/opdsparser")
local Screen = require("device").screen local Screen = require("device").screen
@ -68,6 +69,11 @@ function OPDSBrowser:init()
title = "Project Gutenberg", title = "Project Gutenberg",
url = "http://m.gutenberg.org/ebooks.opds/?format=opds", url = "http://m.gutenberg.org/ebooks.opds/?format=opds",
}, },
{
title = "Project Gutenberg [Searchable]",
url = "https://m.gutenberg.org/ebooks/search.mobile/?format=opds&query=%s",
searchable = true,
},
{ {
title = "Feedbooks", title = "Feedbooks",
url = "http://www.feedbooks.com/publicdomain/catalog.atom", url = "http://www.feedbooks.com/publicdomain/catalog.atom",
@ -92,6 +98,11 @@ function OPDSBrowser:init()
title = "Gallica (French)", title = "Gallica (French)",
url = "https://gallica.bnf.fr/opds", url = "https://gallica.bnf.fr/opds",
}, },
{
title = "Gallica [Fr] [Searchable]",
url = "https://gallica.bnf.fr/services/engine/search/opds?operation=searchRetrieve&query=(gallica all \"%s\")",
searchable = true,
}
} }
G_reader_settings:saveSetting("opds_servers", servers) G_reader_settings:saveSetting("opds_servers", servers)
elseif servers[4] and servers[4].title == "Internet Archive" and servers[4].url == "http://bookserver.archive.org/catalog/" then elseif servers[4] and servers[4].title == "Internet Archive" and servers[4].url == "http://bookserver.archive.org/catalog/" then
@ -104,12 +115,14 @@ end
function OPDSBrowser:addServerFromInput(fields) function OPDSBrowser:addServerFromInput(fields)
logger.info("input catalog", fields) logger.info("input catalog", fields)
local servers = G_reader_settings:readSetting("opds_servers") or {} local servers = G_reader_settings:readSetting("opds_servers") or {}
table.insert(servers, { local new_server = {
title = fields[1], title = fields[1],
url = (fields[2]:match("^%a+://") and fields[2] or "http://" .. fields[2]), url = (fields[2]:match("^%a+://") and fields[2] or "http://" .. fields[2]),
searchable = (fields[2]:match("%%s") and true or false),
username = fields[3], username = fields[3],
password = fields[4], password = fields[4],
}) }
table.insert(servers, new_server)
G_reader_settings:saveSetting("opds_servers", servers) G_reader_settings:saveSetting("opds_servers", servers)
self:init() self:init()
end end
@ -243,6 +256,7 @@ function OPDSBrowser:genItemTableFromRoot()
password = server.password, password = server.password,
deletable = true, deletable = true,
editable = true, editable = true,
searchable = server.searchable,
}) })
end end
local calibre_opds = G_reader_settings:readSetting("calibre_opds") or {} local calibre_opds = G_reader_settings:readSetting("calibre_opds") or {}
@ -263,6 +277,7 @@ function OPDSBrowser:genItemTableFromRoot()
password = calibre_opds.password, password = calibre_opds.password,
editable = true, editable = true,
deletable = false, deletable = false,
searchable = false,
}) })
end end
table.insert(item_table, { table.insert(item_table, {
@ -282,7 +297,7 @@ function OPDSBrowser:fetchFeed(item_url, username, password, method)
request['url'] = item_url request['url'] = item_url
request['method'] = method and method or "GET" request['method'] = method and method or "GET"
request['sink'] = ltn12.sink.table(sink) request['sink'] = ltn12.sink.table(sink)
request['headers'] = { Authorization = "Basic " .. mime.b64(auth), ["Host"] = hostname, } request['headers'] = username and { Authorization = "Basic " .. mime.b64(auth), ["Host"] = hostname, } or { ["Host"] = hostname, }
logger.info("request", request) logger.info("request", request)
http.TIMEOUT, https.TIMEOUT = 10, 10 http.TIMEOUT, https.TIMEOUT = 10, 10
local httpRequest = parsed.scheme == 'http' and http.request or https.request local httpRequest = parsed.scheme == 'http' and http.request or https.request
@ -645,6 +660,51 @@ function OPDSBrowser:showDownloads(item)
UIManager:show(self.download_dialog) UIManager:show(self.download_dialog)
end end
function OPDSBrowser:browse(browse_url, username, password)
logger.dbg("Browse opds url", browse_url)
table.insert(self.paths, {
url = browse_url,
username = username,
password = password,
})
if not self:updateCatalog(browse_url, username, password) then
table.remove(self.paths)
end
end
function OPDSBrowser:browseSearchable(browse_url, username, password)
self.search_server_dialog = InputDialog:new{
title = _("Search OPDS catalog"),
input = "",
hint = _("Search string"),
input_hint = _("author:dumas alexandre"),
input_type = "string",
description = _("%s in url will be replaced by your input"),
buttons = {
{
{
text = _("Cancel"),
callback = function()
UIManager:close(self.search_server_dialog)
end,
},
{
text = _("Search"),
is_enter_default = true,
callback = function()
UIManager:close(self.search_server_dialog)
local search = self.search_server_dialog:getInputText():gsub(" ", "+")
local searched_url = browse_url:gsub("%%s", search)
self:browse(searched_url, username, password)
end,
},
}
},
}
UIManager:show(self.search_server_dialog)
self.search_server_dialog:onShowKeyboard()
end
function OPDSBrowser:onMenuSelect(item) function OPDSBrowser:onMenuSelect(item)
-- add catalog -- add catalog
if item.callback then if item.callback then
@ -655,13 +715,10 @@ function OPDSBrowser:onMenuSelect(item)
self:showDownloads(item) self:showDownloads(item)
-- navigation -- navigation
else else
table.insert(self.paths, { if item.searchable then
url = item.url, self:browseSearchable(item.url, item.username, item.password)
username = item.username, else
password = item.password, self:browse(item.url, item.username, item.password)
})
if not self:updateCatalog(item.url, item.username, item.password) then
table.remove(self.paths)
end end
end end
return true return true
@ -674,6 +731,7 @@ function OPDSBrowser:editServerFromInput(item, fields)
if server.title == item.text or server.url == item.url then if server.title == item.text or server.url == item.url then
server.title = fields[1] server.title = fields[1]
server.url = (fields[2]:match("^%a+://") and fields[2] or "http://" .. fields[2]) server.url = (fields[2]:match("^%a+://") and fields[2] or "http://" .. fields[2])
server.searchable = (fields[2]:match("%%s") and true or false)
server.username = fields[3] server.username = fields[3]
server.password = fields[4] server.password = fields[4]
end end

Loading…
Cancel
Save