Compare commits
2 Commits
2b1da2bdd7
...
e1d478e086
| Author | SHA1 | Date | |
|---|---|---|---|
| e1d478e086 | |||
| d41dceaa57 |
+46
-44
@@ -1240,6 +1240,52 @@ def opds_reading_list(slug: str, page: int = 1, _=Depends(require_basic)):
|
|||||||
return Response(content=xml, media_type="application/atom+xml;profile=opds-catalog")
|
return Response(content=xml, media_type="application/atom+xml;profile=opds-catalog")
|
||||||
|
|
||||||
|
|
||||||
|
# ---- OpenSearch (descriptor) + Search results (OPDS 1.x) ----
|
||||||
|
# NOTE: These MUST be registered before the /opds/{path:path} catch-all below,
|
||||||
|
# otherwise the catch-all swallows /opds/search and /opds/search.xml.
|
||||||
|
@app.get("/opds/search.xml", response_class=Response)
|
||||||
|
def opensearch_description(_=Depends(require_basic)):
|
||||||
|
tpl = env.get_template("search-description.xml.j2")
|
||||||
|
xml = tpl.render(base=SERVER_BASE.rstrip("/"))
|
||||||
|
return Response(content=xml, media_type="application/opensearchdescription+xml")
|
||||||
|
|
||||||
|
@app.get("/opds/search", response_class=Response)
|
||||||
|
def opds_search(query: str | None = Query(None, alias="query"),
|
||||||
|
page: int | None = Query(None),
|
||||||
|
request: Request = None,
|
||||||
|
_=Depends(require_basic)):
|
||||||
|
term = (query or "").strip()
|
||||||
|
if not term:
|
||||||
|
return browse(path="", page=1)
|
||||||
|
|
||||||
|
items = PAGE_SIZE
|
||||||
|
pg = max(1, int(page or 1))
|
||||||
|
offset = (pg - 1) * items
|
||||||
|
|
||||||
|
conn = db.connect()
|
||||||
|
try:
|
||||||
|
rows = db.search_q(conn, term, items, offset)
|
||||||
|
total = db.search_count(conn, term)
|
||||||
|
finally:
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
entries_xml = [_entry_xml_from_row(r) for r in rows]
|
||||||
|
self_href = f"/opds/search?query={quote(term)}&page={pg}"
|
||||||
|
next_href = f"/opds/search?query={quote(term)}&page={pg+1}" if (offset + len(rows)) < total else None
|
||||||
|
|
||||||
|
xml = _feed(
|
||||||
|
entries_xml,
|
||||||
|
title=f"Search: {term}",
|
||||||
|
self_href=self_href,
|
||||||
|
next_href=next_href,
|
||||||
|
os_total=total,
|
||||||
|
os_start=offset + 1 if total > 0 else 0,
|
||||||
|
os_items=items,
|
||||||
|
search_href="/opds/search.xml",
|
||||||
|
start_href_override="/opds",
|
||||||
|
)
|
||||||
|
return Response(content=xml, media_type="application/atom+xml;profile=opds-catalog")
|
||||||
|
|
||||||
# Catch-all browse route - MUST come after specific /opds routes
|
# Catch-all browse route - MUST come after specific /opds routes
|
||||||
@app.get("/opds/{path:path}", response_class=Response)
|
@app.get("/opds/{path:path}", response_class=Response)
|
||||||
def browse(path: str, page: int = 1, _=Depends(require_basic)):
|
def browse(path: str, page: int = 1, _=Depends(require_basic)):
|
||||||
@@ -1286,50 +1332,6 @@ def browse(path: str, page: int = 1, _=Depends(require_basic)):
|
|||||||
def root(_=Depends(require_basic)):
|
def root(_=Depends(require_basic)):
|
||||||
return browse(path="", page=1)
|
return browse(path="", page=1)
|
||||||
|
|
||||||
# ---- OpenSearch (descriptor) + Search results (OPDS 1.x) ----
|
|
||||||
@app.get("/opds/search.xml", response_class=Response)
|
|
||||||
def opensearch_description(_=Depends(require_basic)):
|
|
||||||
tpl = env.get_template("search-description.xml.j2")
|
|
||||||
xml = tpl.render(base=SERVER_BASE.rstrip("/"))
|
|
||||||
return Response(content=xml, media_type="application/opensearchdescription+xml")
|
|
||||||
|
|
||||||
@app.get("/opds/search", response_class=Response)
|
|
||||||
def opds_search(query: str | None = Query(None, alias="query"),
|
|
||||||
page: int | None = Query(None),
|
|
||||||
request: Request = None,
|
|
||||||
_=Depends(require_basic)):
|
|
||||||
term = (query or "").strip()
|
|
||||||
if not term:
|
|
||||||
return browse(path="", page=1)
|
|
||||||
|
|
||||||
items = PAGE_SIZE
|
|
||||||
pg = max(1, int(page or 1))
|
|
||||||
offset = (pg - 1) * items
|
|
||||||
|
|
||||||
conn = db.connect()
|
|
||||||
try:
|
|
||||||
rows = db.search_q(conn, term, items, offset)
|
|
||||||
total = db.search_count(conn, term)
|
|
||||||
finally:
|
|
||||||
conn.close()
|
|
||||||
|
|
||||||
entries_xml = [_entry_xml_from_row(r) for r in rows]
|
|
||||||
self_href = f"/opds/search?query={quote(term)}&page={pg}"
|
|
||||||
next_href = f"/opds/search?query={quote(term)}&page={pg+1}" if (offset + len(rows)) < total else None
|
|
||||||
|
|
||||||
xml = _feed(
|
|
||||||
entries_xml,
|
|
||||||
title=f"Search: {term}",
|
|
||||||
self_href=self_href,
|
|
||||||
next_href=next_href,
|
|
||||||
os_total=total,
|
|
||||||
os_start=offset + 1 if total > 0 else 0,
|
|
||||||
os_items=items,
|
|
||||||
search_href="/opds/search.xml",
|
|
||||||
start_href_override="/opds",
|
|
||||||
)
|
|
||||||
return Response(content=xml, media_type="application/atom+xml;profile=opds-catalog")
|
|
||||||
|
|
||||||
# -------------------- File endpoints --------------------
|
# -------------------- File endpoints --------------------
|
||||||
def _abspath(rel: str) -> Path:
|
def _abspath(rel: str) -> Path:
|
||||||
"""
|
"""
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@ services:
|
|||||||
comicopds:
|
comicopds:
|
||||||
build: .
|
build: .
|
||||||
ports:
|
ports:
|
||||||
- "8080:8080"
|
- "8382:8080"
|
||||||
environment:
|
environment:
|
||||||
CONTENT_BASE_DIR: /library
|
CONTENT_BASE_DIR: /library
|
||||||
PAGE_SIZE: "50"
|
PAGE_SIZE: "50"
|
||||||
|
|||||||
Reference in New Issue
Block a user