diff --git a/plugins/opds.koplugin/opdsbrowser.lua b/plugins/opds.koplugin/opdsbrowser.lua index 0e2fb3e91..1cefa1934 100644 --- a/plugins/opds.koplugin/opdsbrowser.lua +++ b/plugins/opds.koplugin/opdsbrowser.lua @@ -41,6 +41,7 @@ local OPDSBrowser = Menu:extend{ catalog_type = "application/atom%+xml", search_type = "application/opensearchdescription%+xml", + search_template_type = "application/atom%+xml", acquisition_rel = "^http://opds%-spec%.org/acquisition", image_rel = "http://opds-spec.org/image", thumbnail_rel = "http://opds-spec.org/image/thumbnail", @@ -59,11 +60,6 @@ function OPDSBrowser:init() title = "Project Gutenberg", url = "https://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", url = "https://catalog.feedbooks.com/catalog/public_domain.atom", @@ -84,11 +80,6 @@ function OPDSBrowser:init() title = "Gallica (French)", 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) elseif servers[4] and servers[4].title == "Internet Archive" and servers[4].url == "http://bookserver.archive.org/catalog/" then @@ -392,6 +383,19 @@ function OPDSBrowser:genItemTableFromURL(item_url, username, password) return self:genItemTableFromCatalog(catalog, item_url, username, password) end +function OPDSBrowser:getSearchTemplate(osd_url, username, password) + -- parse search descriptor + local search_descriptor = self:parseFeed(osd_url, username, password) + if search_descriptor and search_descriptor.OpenSearchDescription and search_descriptor.OpenSearchDescription.Url then + for _, candidate in ipairs(search_descriptor.OpenSearchDescription.Url) do + if candidate.type and candidate.template and candidate.type:find(self.search_template_type) then + return candidate.template:gsub('{searchTerms}', '%%s') + end + end + end +end + + function OPDSBrowser:genItemTableFromCatalog(catalog, item_url, username, password) local item_table = {} if not catalog then @@ -408,12 +412,25 @@ function OPDSBrowser:genItemTableFromCatalog(catalog, item_url, username, passwo if feed.link then for _, link in ipairs(feed.link) do if link.type ~= nil then - if link.type:find(self.catalog_type) or - link.type:find(self.search_type) then + if link.type:find(self.catalog_type) then if link.rel and link.href then hrefs[link.rel] = build_href(link.href) end end + if link.type:find(self.search_type) then + if link.href then + local stpl = self:getSearchTemplate(link.href, username, password) + -- insert the search item + local item = {} + item.acquisitions = {} + item.text = "Search" + item.callback = function() + self:browseSearchable(stpl, username, password) + end + + table.insert(item_table, item) + end + end end end end diff --git a/plugins/opds.koplugin/opdsparser.lua b/plugins/opds.koplugin/opdsparser.lua index d92bae9a9..20ee727ed 100644 --- a/plugins/opds.koplugin/opdsparser.lua +++ b/plugins/opds.koplugin/opdsparser.lua @@ -47,7 +47,7 @@ function OPDSParser:createFlatXTable(xlex, curr_element) -- if it does, if it's a table, add to it -- if it doesn't, then add a table local tab = self:createFlatXTable(xlex) - if txt == "entry" or txt == "link" then + if txt == "entry" or txt == "link" or txt == "Url" then if curr_element[txt] == nil then curr_element[txt] = {} end diff --git a/spec/unit/opds_spec.lua b/spec/unit/opds_spec.lua index 10927e8da..6fe6db7f7 100644 --- a/spec/unit/opds_spec.lua +++ b/spec/unit/opds_spec.lua @@ -273,30 +273,37 @@ describe("OPDS module #nocov", function() describe("OPDS browser module", function() describe("URL generation", function() + it("should generate search item", function() + local catalog = OPDSParser:parse(navigation_sample) + local item_table = OPDSBrowser:genItemTableFromCatalog(catalog, "http://m.gutenberg.org/ebooks.opds/?format=opds") + + assert.truthy(item_table) + assert.are.same(item_table[1].title, "Search") + end) it("should generate URL on rel=subsection", function() local catalog = OPDSParser:parse(navigation_sample) local item_table = OPDSBrowser:genItemTableFromCatalog(catalog, "http://m.gutenberg.org/ebooks.opds/?format=opds") assert.truthy(item_table) - assert.are.same(item_table[1].title, "Popular") - assert.are.same(item_table[1].url, "http://m.gutenberg.org/ebooks/search.opds/?sort_order=downloads") + assert.are.same(item_table[2].title, "Popular") + assert.are.same(item_table[2].url, "http://m.gutenberg.org/ebooks/search.opds/?sort_order=downloads") end) it("should generate URL on rel=popular and rel=new", function() local catalog = OPDSParser:parse(popular_new_sample) local item_table = OPDSBrowser:genItemTableFromCatalog(catalog, "http://www.feedbooks.com/publicdomain/catalog.atom") assert.truthy(item_table) - assert.are.same(item_table[1].title, "Most Popular") - assert.are.same(item_table[1].url, "http://www.feedbooks.com/books/top.atom") - assert.are.same(item_table[2].title, "Recently Added") - assert.are.same(item_table[2].url, "http://www.feedbooks.com/books/recent.atom") + assert.are.same(item_table[2].title, "Most Popular") + assert.are.same(item_table[2].url, "http://www.feedbooks.com/books/top.atom") + assert.are.same(item_table[3].title, "Recently Added") + assert.are.same(item_table[3].url, "http://www.feedbooks.com/books/recent.atom") end) it("should use the main URL for faceted links as long as faceted links aren't properly supported", function() local catalog = OPDSParser:parse(facet_sample) local item_table = OPDSBrowser:genItemTableFromCatalog(catalog, "http://flibusta.net/opds") assert.truthy(item_table) - assert.are.same(item_table[1].url, "http://flibusta.net/opds/author/75357") + assert.are.same(item_table[2].url, "http://flibusta.net/opds/author/75357") end) end) @@ -305,7 +312,7 @@ describe("OPDS module #nocov", function() local item_table = OPDSBrowser:genItemTableFromCatalog(catalog, "http://flibusta.net/opds") assert.truthy(item_table) - assert.are_not.same(item_table[1].image, "http://flibusta.net/opds/author/75357") + assert.are_not.same(item_table[2].image, "http://flibusta.net/opds/author/75357") end) end) end)