Move fastext nav to page top, fix Settings header, add working search
All checks were successful
Deploy / deploy (push) Successful in 23s
All checks were successful
Deploy / deploy (push) Successful in 23s
- Fastext colour keys now lead every page but the index, since they're the only nav those pages carry; the index keeps them as its closing row since its own body is already the full nav. - Settings page was missing page="settings" in its render_template call, so its header silently fell back to "P100 Index". - Library's search form posted a q param the route never read; it now filters the cached Sonarr/Radarr lists and shows matching tiles. - Discover gained a search bar that queries Ombi (already in front of TMDB/TVDB) and lets you add a result straight to Radarr/Sonarr, showing "Held" instead of a button for anything already in library. - Fixed the Add button's success check, which read d.ok against a response that actually sets d.success — it reported FAILED even when the add worked.
This commit is contained in:
parent
08491c0c9b
commit
abaccaaacd
6 changed files with 172 additions and 16 deletions
100
app.py
100
app.py
|
|
@ -726,6 +726,61 @@ def ombi_get(endpoint):
|
|||
return resp.json()
|
||||
|
||||
|
||||
def _tmdb_poster(path):
|
||||
"""Ombi's movie search returns a bare TMDB path ('/abc123.jpg'), not a
|
||||
usable URL; TV search returns a full TVDB banner URL already."""
|
||||
if not path:
|
||||
return ""
|
||||
if path.startswith("http"):
|
||||
return path
|
||||
return f"https://image.tmdb.org/t/p/w300{path}"
|
||||
|
||||
|
||||
def ombi_search(q, limit=12):
|
||||
"""Movies and TV matching q, via Ombi's own search — it already sits in
|
||||
front of TheMovieDB/TVDB, so this is one call instead of two more API
|
||||
keys. Cross-referenced against the cached Sonarr/Radarr title sets so a
|
||||
title already held shows that instead of an Add button.
|
||||
"""
|
||||
term = q.strip()
|
||||
if not term:
|
||||
return {"status": "ok", "results": []}
|
||||
encoded = requests.utils.quote(term)
|
||||
try:
|
||||
radarr_titles = {t.lower() for t in get_radarr_summary().get("radarr_titles", [])}
|
||||
sonarr_titles = {t.lower() for t in get_sonarr_summary().get("sonarr_titles", [])}
|
||||
results = []
|
||||
try:
|
||||
for m in ombi_get(f"Search/movie/{encoded}")[:limit]:
|
||||
title = m.get("title", "")
|
||||
results.append({
|
||||
"title": title,
|
||||
"year": (m.get("releaseDate") or "")[:4],
|
||||
"poster": _tmdb_poster(m.get("posterPath")),
|
||||
"kind": "Film",
|
||||
"target": "radarr",
|
||||
"held": bool(m.get("available")) or title.lower() in radarr_titles,
|
||||
})
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
for s in ombi_get(f"Search/tv/{encoded}")[:limit]:
|
||||
title = s.get("title", "")
|
||||
results.append({
|
||||
"title": title,
|
||||
"year": (s.get("firstAired") or "")[:4],
|
||||
"poster": s.get("banner") or _tmdb_poster(s.get("posterPath")),
|
||||
"kind": "TV",
|
||||
"target": "sonarr",
|
||||
"held": bool(s.get("available")) or title.lower() in sonarr_titles,
|
||||
})
|
||||
except Exception:
|
||||
pass
|
||||
return {"status": "ok", "results": results}
|
||||
except Exception as e:
|
||||
return {"status": "error", "error": str(e), "results": []}
|
||||
|
||||
|
||||
def _ombi_status_label(available, approved, denied):
|
||||
if denied:
|
||||
return "Denied"
|
||||
|
|
@ -1404,6 +1459,41 @@ def get_recently_added(limit=6):
|
|||
return items
|
||||
|
||||
|
||||
def search_library(q, limit=24):
|
||||
"""Titles in Sonarr/Radarr matching q, case-insensitive substring.
|
||||
|
||||
Filters the same cached lists get_recently_added uses — no new fetch.
|
||||
"""
|
||||
needle = q.strip().lower()
|
||||
if not needle:
|
||||
return []
|
||||
items = []
|
||||
try:
|
||||
for sr in sonarr_series_cached():
|
||||
if needle in sr.get("title", "").lower():
|
||||
items.append({
|
||||
"title": sr.get("title", "Unknown"),
|
||||
"kind": "TV",
|
||||
"year": str(sr.get("year", "")),
|
||||
"poster": _poster_url(sr.get("images")),
|
||||
})
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
for mv in radarr_movies_cached():
|
||||
if needle in mv.get("title", "").lower():
|
||||
items.append({
|
||||
"title": mv.get("title", "Unknown"),
|
||||
"kind": "Film",
|
||||
"year": str(mv.get("year", "")),
|
||||
"poster": _poster_url(mv.get("images")),
|
||||
})
|
||||
except Exception:
|
||||
pass
|
||||
items.sort(key=lambda x: x["title"].lower())
|
||||
return items[:limit]
|
||||
|
||||
|
||||
def get_activity_feed(sabnzbd, ombi, limit=25):
|
||||
"""A single chronological feed assembled from what the fetchers return.
|
||||
|
||||
|
|
@ -1508,9 +1598,11 @@ def watch_page():
|
|||
@login_required
|
||||
def library_page():
|
||||
r = fetch_services(["sonarr", "radarr"])
|
||||
q = request.args.get("q", "").strip()
|
||||
return render_template("library.html", page="library",
|
||||
sonarr=r["sonarr"], radarr=r["radarr"],
|
||||
recently_added=get_recently_added(12))
|
||||
recently_added=get_recently_added(12),
|
||||
q=q, search_results=search_library(q) if q else None)
|
||||
|
||||
|
||||
@app.route("/discover")
|
||||
|
|
@ -1519,9 +1611,11 @@ def discover_page():
|
|||
r = fetch_services(["sonarr", "radarr", "rt_movies", "rt_tv"])
|
||||
sonarr_titles = set(r["sonarr"].get("sonarr_titles", []))
|
||||
radarr_titles = set(r["radarr"].get("radarr_titles", []))
|
||||
q = request.args.get("q", "").strip()
|
||||
return render_template("discover.html", page="discover",
|
||||
rt_movies=_filter_rt(r["rt_movies"], radarr_titles),
|
||||
rt_tv=_filter_rt(r["rt_tv"], sonarr_titles))
|
||||
rt_tv=_filter_rt(r["rt_tv"], sonarr_titles),
|
||||
q=q, search=ombi_search(q) if q else None)
|
||||
|
||||
|
||||
@app.route("/requests")
|
||||
|
|
@ -1760,7 +1854,7 @@ def api_delete_show():
|
|||
@login_required
|
||||
def settings_page():
|
||||
s = load_settings()
|
||||
return render_template("settings.html",
|
||||
return render_template("settings.html", page="settings",
|
||||
timezone=s.get("timezone", "America/New_York"),
|
||||
sonarr_api_key=SONARR_API_KEY,
|
||||
radarr_api_key=RADARR_API_KEY,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue