diff --git a/README.md b/README.md index 58aef3f..7d8bf19 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,10 @@ docker compose up -d --build | `WORDARR_DOWNLOAD_DIR` | `/mnt/downloads` | Gescannter Download-Ordner | | `WORDARR_CONFIG_DIR` | `/config` | Ablage der SQLite-DB | +## Sprachen + +Jede Library kann eine **Sprache** tragen (`Deutsch`/`Englisch`, Default: egal). Audible liefert zu jedem Titel die Sprache mit, deshalb zeigt die Suche für eine englische Library nur englische Ausgaben und für eine deutsche nur deutsche — praktisch, wenn dieselbe Reihe in beiden Sprachen in getrennten Libraries liegt (*A Song of Ice and Fire* vs. *Das Lied von Eis und Feuer*). Gesucht wird dann auch auf dem passenden Marktplatz (`audible.com` bzw. `audible.de`), was die Trefferqualität deutlich hebt. Im Tab *Suche* lässt sich die Sprache zusätzlich frei filtern; im Import-Dialog kommt sie automatisch aus der gewählten Ziel-Library. + ## Namensschemata Pro Library konfigurierbar (Tab *Libraries*), Platzhalter: `{Author}` `{Authors}` `{Title}` `{Year}` `{Series}` `{Volume}`. diff --git a/static/app.js b/static/app.js index 44e2986..8629a9b 100644 --- a/static/app.js +++ b/static/app.js @@ -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) => ` ${esc(l.name)}${esc(l.media_type)}${esc(l.root_path)} ${esc(l.folder_template)}${esc(l.file_template)} + ${l.language ? esc(LANGUAGE_NAMES[l.language] || l.language) : "—"} @@ -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 = ' 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 = `

${EMPTY_HINTS[type]}

`; return; @@ -214,7 +220,7 @@ $("#search-form").addEventListener("submit", async (e) => { ${esc(r.authors)} ${r.narrator ? `🎙 ${esc(r.narrator)}` : ""} ${r.series && r.media_type ? `📚 ${esc(r.series)}${r.volume != null ? " #" + r.volume : ""}` : ""} - ${r.year ?? ""} ${r.external_id ? "· " + esc(r.external_id) : ""} + ${r.year ?? ""} ${r.language ? "· " + esc(LANGUAGE_NAMES[r.language] || r.language) : ""} ${r.external_id ? "· " + esc(r.external_id) : ""} ${type === "comic" ? `` : ""}
@@ -955,8 +961,12 @@ async function runQuickSearch() { const box = $("#quick-results"); box.innerHTML = "

Suche läuft…

"; 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 = `

${EMPTY_HINTS[item.media_type]}

`; @@ -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 `
${r.cover_url ? `` : '
?
'} diff --git a/static/index.html b/static/index.html index 4f5a843..9be7586 100644 --- a/static/index.html +++ b/static/index.html @@ -30,6 +30,11 @@ +