mirror of
https://github.com/9001/copyparty.git
synced 2026-02-20 09:19:58 +10:00
opds: add opensearch support (#1287)
tested with Moon Reader and Koreader; based on: https://specs.opds.io/opds-1.2#3-search https://github.com/koreader/koreader/pull/7380 Signed-off-by: Brandon Philips <brandon@ifup.org>
This commit is contained in:
@@ -7412,12 +7412,70 @@ class HttpCli(object):
|
||||
dirs.sort(key=itemgetter("name"))
|
||||
|
||||
if is_opds:
|
||||
# OpenSearch Description format requires a full-qualified URL and a "Short Name" under 16 characters
|
||||
# which will be the longname truncated in the template.
|
||||
# Relevant specs:
|
||||
# https://specs.opds.io/opds-1.2#3-search
|
||||
# https://developer.mozilla.org/en-US/docs/Web/XML/Guides/OpenSearch
|
||||
if "osd" in self.uparam:
|
||||
j2a["longname"] = "%s %s" % (self.args.bname, self.vpath)
|
||||
j2a["search_url"] = self.args.SRS + vpath
|
||||
|
||||
xml = self.j2s("opds_osd", **j2a)
|
||||
self.reply(
|
||||
xml.encode("utf-8"), mime="application/opensearchdescription+xml"
|
||||
)
|
||||
return True
|
||||
|
||||
if "q" in self.uparam:
|
||||
q = self.uparam["q"]
|
||||
idx = self.conn.get_u2idx()
|
||||
if not idx:
|
||||
raise Pebkac(500, "indexer not available")
|
||||
|
||||
# generate a raw query similar to web interface for multiple words
|
||||
r = " and ".join(("name like *%s*" % (x,)) for x in q.split())
|
||||
|
||||
hits, _, _ = idx.search(self.uname, [self.vn], r, 1000)
|
||||
|
||||
files = []
|
||||
dirs = []
|
||||
|
||||
prefix = quotep(vpath + "/" if vpath else "")
|
||||
|
||||
for h in hits:
|
||||
rp = h["rp"]
|
||||
if not rp.startswith(prefix):
|
||||
continue
|
||||
|
||||
zd = datetime.fromtimestamp(h["ts"], UTC)
|
||||
dt = "%04d-%02d-%02d %02d:%02d:%02d" % (
|
||||
zd.year,
|
||||
zd.month,
|
||||
zd.day,
|
||||
zd.hour,
|
||||
zd.minute,
|
||||
zd.second,
|
||||
)
|
||||
|
||||
item = {
|
||||
"href": self.args.SRS + rp,
|
||||
"name": unquotep(rp[len(prefix) :].split("?")[0]),
|
||||
"sz": h["sz"],
|
||||
"dt": dt,
|
||||
"ts": h["ts"],
|
||||
}
|
||||
files.append(item)
|
||||
|
||||
# exclude files which don't match --opds-exts
|
||||
allowed_exts = vf.get("opds_exts") or self.args.opds_exts
|
||||
if allowed_exts:
|
||||
files = [
|
||||
x for x in files if x["name"].rsplit(".", 1)[-1] in allowed_exts
|
||||
]
|
||||
|
||||
j2a["opds_osd"] = "%s%s?opds&osd" % (self.args.SRS, quotep(vpath))
|
||||
|
||||
for item in dirs:
|
||||
href = item["href"]
|
||||
href += ("&" if "?" in href else "?") + "opds"
|
||||
|
||||
@@ -188,6 +188,7 @@ class HttpSrv(object):
|
||||
]
|
||||
self.j2 = {x: env.get_template(x + ".html") for x in jn}
|
||||
self.j2["opds"] = env.get_template("opds.xml")
|
||||
self.j2["opds_osd"] = env.get_template("opds_osd.xml")
|
||||
self.prism = has_resource(self.E, "web/deps/prism.js.gz")
|
||||
|
||||
if self.args.ipu:
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<feed xmlns="http://www.w3.org/2005/Atom">
|
||||
<link rel="search"
|
||||
href="{{ opds_osd | e }}"
|
||||
type="application/opensearchdescription+xml"/>
|
||||
{%- for d in dirs %}
|
||||
<entry>
|
||||
<title>{{ d.name }}</title>
|
||||
<title>{{ d.name | e }}</title>
|
||||
<link rel="subsection"
|
||||
href="{{ d.href | e }}"
|
||||
type="application/atom+xml;profile=opds-catalog"/>
|
||||
@@ -11,7 +14,7 @@
|
||||
{%- endfor %}
|
||||
{%- for f in files %}
|
||||
<entry>
|
||||
<title>{{ f.name }}</title>
|
||||
<title>{{ f.name | e }}</title>
|
||||
<updated>{{ f.iso8601 }}</updated>
|
||||
<link rel="http://opds-spec.org/acquisition"
|
||||
href="{{ f.href | e }}"
|
||||
@@ -28,4 +31,4 @@
|
||||
{%- endif %}
|
||||
</entry>
|
||||
{%- endfor %}
|
||||
</feed>
|
||||
</feed>
|
||||
|
||||
6
copyparty/web/opds_osd.xml
Normal file
6
copyparty/web/opds_osd.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
|
||||
<ShortName>{{ longname | truncate(16) | e }}</ShortName>
|
||||
<Description>{{ longname | e }}</Description>
|
||||
<Url type="application/atom+xml;profile=opds-catalog" template="{{ search_url }}?opds&q={searchTerms}"/>
|
||||
</OpenSearchDescription>
|
||||
@@ -102,6 +102,7 @@ copyparty/web/mde.html,
|
||||
copyparty/web/mde.js,
|
||||
copyparty/web/msg.html,
|
||||
copyparty/web/opds.xml,
|
||||
copyparty/web/opds_osd.xml,
|
||||
copyparty/web/rups.css,
|
||||
copyparty/web/rups.html,
|
||||
copyparty/web/rups.js,
|
||||
|
||||
Reference in New Issue
Block a user