add(metadata): filter audible results by library language

This commit is contained in:
Steppenstreuner
2026-08-29 05:05:00 +02:00
parent 714a435e2d
commit e3701ceb43
11 changed files with 99 additions and 12 deletions
+14 -3
View File
@@ -2,6 +2,7 @@ const $ = (sel) => document.querySelector(sel);
const $$ = (sel) => document.querySelectorAll(sel);
let libraries = [];
const LANGUAGE_NAMES = { german: "Deutsch", english: "Englisch" };
async function api(path, opts = {}) {
const resp = await fetch(path, {
@@ -93,6 +94,7 @@ async function loadLibraries() {
(l) => `<tr>
<td>${esc(l.name)}</td><td>${esc(l.media_type)}</td><td>${esc(l.root_path)}</td>
<td class="mono">${esc(l.folder_template)}</td><td class="mono">${esc(l.file_template)}</td>
<td>${l.language ? esc(LANGUAGE_NAMES[l.language] || l.language) : "—"}</td>
<td class="row">
<button class="secondary" data-edit-lib="${l.id}">Bearbeiten</button>
<button class="danger" data-del-lib="${l.id}">Löschen</button>
@@ -127,6 +129,7 @@ function startLibraryEdit(id) {
form.root_path.value = lib.root_path;
form.folder_template.value = lib.folder_template;
form.file_template.value = lib.file_template;
form.language.value = lib.language || "";
form.dataset.editId = lib.id;
$("#lib-form-title").textContent = `Library „${lib.name}“ bearbeiten`;
$("#lib-form-submit").textContent = "Speichern";
@@ -199,7 +202,10 @@ $("#search-form").addEventListener("submit", async (e) => {
searchBtn.disabled = true;
searchBtn.innerHTML = '<span class="spinner"></span> Suche…';
try {
const results = await api(`/api/search?media_type=${type}&q=${encodeURIComponent(q)}`);
const language = $("#search-language").value;
const results = await api(
`/api/search?media_type=${type}&q=${encodeURIComponent(q)}&language=${language}`
);
if (!results.length) {
box.innerHTML = `<p class='muted'>${EMPTY_HINTS[type]}</p>`;
return;
@@ -214,7 +220,7 @@ $("#search-form").addEventListener("submit", async (e) => {
<span>${esc(r.authors)}</span>
${r.narrator ? `<span class="muted">🎙 ${esc(r.narrator)}</span>` : ""}
${r.series && r.media_type ? `<span class="muted">📚 ${esc(r.series)}${r.volume != null ? " #" + r.volume : ""}</span>` : ""}
<span class="muted">${r.year ?? ""} ${r.external_id ? "· " + esc(r.external_id) : ""}</span>
<span class="muted">${r.year ?? ""} ${r.language ? "· " + esc(LANGUAGE_NAMES[r.language] || r.language) : ""} ${r.external_id ? "· " + esc(r.external_id) : ""}</span>
${type === "comic" ? `<input type="number" min="0" placeholder="Band" class="volume" data-vol="${i}">` : ""}
<div class="row">
<select data-lib="${i}">${opts || "<option value=''>— keine Library —</option>"}</select>
@@ -955,8 +961,12 @@ async function runQuickSearch() {
const box = $("#quick-results");
box.innerHTML = "<p class='muted'>Suche läuft…</p>";
try {
// the target library decides the language: an "english" library should not
// offer the German edition of the same book
const lib = libraries.find((l) => String(l.id) === $("#quick-library").value);
const results = await api(
`/api/search?media_type=${item.media_type}&q=${encodeURIComponent($("#quick-q").value)}`
`/api/search?media_type=${item.media_type}&q=${encodeURIComponent($("#quick-q").value)}` +
`&language=${lib?.language || ""}`
);
if (!results.length) {
box.innerHTML = `<p class='muted'>${EMPTY_HINTS[item.media_type]}</p>`;
@@ -970,6 +980,7 @@ async function runQuickSearch() {
r.narrator ? "🎙 " + r.narrator : "",
r.series ? `📚 ${r.series}${r.volume != null ? " #" + r.volume : ""}` : "",
r.year ?? "",
LANGUAGE_NAMES[r.language] || r.language,
].filter(Boolean).map(esc).join(" · ");
return `<div class="card">
${r.cover_url ? `<img src="${esc(r.cover_url)}" alt="" loading="lazy">` : '<div class="nocover">?</div>'}
+11
View File
@@ -30,6 +30,11 @@
<option value="audiobook">Audiobook</option>
<option value="comic">Comic/Manga</option>
</select>
<select id="search-language" title="Nur Audiobooks: Sprache der Ausgabe">
<option value="">Alle Sprachen</option>
<option value="german">Deutsch</option>
<option value="english">Englisch</option>
</select>
<input id="search-q" placeholder="Titel, Autor oder ISBN…" required />
<button type="submit" id="search-btn">Suchen</button>
<button type="button" id="manual-btn" class="secondary">
@@ -237,6 +242,7 @@
<th>Pfad</th>
<th>Ordner-Schema</th>
<th>Datei-Schema</th>
<th>Sprache</th>
<th></th>
</tr>
</thead>
@@ -267,6 +273,11 @@
name="file_template"
placeholder="Datei-Schema (optional)"
class="wide" />
<select name="language" title="Sprache der Ausgaben in dieser Library — filtert die Audible-Suche">
<option value="">Sprache: egal</option>
<option value="german">Deutsch</option>
<option value="english">Englisch</option>
</select>
<button type="submit" id="lib-form-submit">Anlegen</button>
<button type="button" id="lib-form-cancel" class="secondary" hidden>
Abbrechen