add(metadata): chose and request entity while scanning download/

This commit is contained in:
Steppenstreuner
2026-08-28 14:08:02 +02:00
parent 0299895869
commit c03bd4a2e2
3 changed files with 118 additions and 1 deletions
+98 -1
View File
@@ -292,13 +292,110 @@ function renderImportTable() {
<td><input type="checkbox" data-check="${i}" ${item.suggested_request_id ? "checked" : ""}></td>
<td class="mono">${esc(item.name)}${item.is_dir ? " 📁" : ""}</td>
<td>${esc(item.media_type)}</td>
<td><select data-select="${i}"><option value="">— überspringen —</option>${opts}</select></td>
<td class="row">
<select data-select="${i}"><option value="">— überspringen —</option>${opts}</select>
<button class="secondary" data-quick="${i}" title="Metadaten suchen und Anfrage direkt verbinden">🔍</button>
</td>
<td>${item.suggested_request_id ? item.score : "—"}</td>
</tr>`;
})
.join("");
table.hidden = false;
$("#import-btn").hidden = false;
tbody.querySelectorAll("[data-quick]").forEach((b) =>
b.addEventListener("click", () => openQuickDialog(parseInt(b.dataset.quick)))
);
}
// ---- quick request from a scanned file ----
let quickItemIndex = null;
function cleanFileName(name) {
return name
.replace(/[._\-\[\]()]+/g, " ")
.replace(/\b(mp3|m4b|flac|epub|pdf|cbz|cbr|retail|unabridged|kompl.*)\b/gi, " ")
.replace(/\s+/g, " ")
.trim();
}
function openQuickDialog(i) {
quickItemIndex = i;
const item = scanItems[i];
$("#quick-file").textContent = item.name;
$("#quick-q").value = cleanFileName(item.name);
$("#quick-library").innerHTML =
libOptions(item.media_type) || "<option value=''>— keine Library —</option>";
$("#quick-results").innerHTML = "";
$("#quick-dialog").showModal();
runQuickSearch();
}
async function runQuickSearch() {
const item = scanItems[quickItemIndex];
const box = $("#quick-results");
box.innerHTML = "<p class='muted'>Suche läuft…</p>";
try {
const results = await api(
`/api/search?media_type=${item.media_type}&q=${encodeURIComponent($("#quick-q").value)}`
);
if (!results.length) { box.innerHTML = "<p class='muted'>Keine Treffer — Suchbegriff anpassen.</p>"; return; }
box.innerHTML = results
.map(
(r, j) => `<div class="card">
${r.cover_url ? `<img src="${esc(r.cover_url)}" alt="">` : '<div class="nocover">?</div>'}
<div class="card-body">
<strong>${esc(r.title)}</strong>
<span>${esc(r.authors)}</span>
<span class="muted">${r.year ?? ""}</span>
<div class="row"><button data-pick="${j}">Anfragen &amp; verbinden</button></div>
</div>
</div>`
)
.join("");
box.querySelectorAll("[data-pick]").forEach((btn) =>
btn.addEventListener("click", () => pickQuickResult(results[btn.dataset.pick]))
);
} catch (err) {
box.innerHTML = "";
toast(err.message, true);
}
}
$("#quick-search-form").addEventListener("submit", (e) => {
e.preventDefault();
runQuickSearch();
});
$("#quick-close").addEventListener("click", () => $("#quick-dialog").close());
async function pickQuickResult(r) {
const libId = $("#quick-library").value;
if (!libId) { toast("Erst eine Library für diesen Typ anlegen", true); return; }
const i = quickItemIndex;
try {
const req = await api("/api/requests", {
method: "POST",
body: JSON.stringify({
library_id: parseInt(libId),
title: r.title, authors: r.authors, external_id: r.external_id,
year: r.year, series: r.series, cover_url: r.cover_url,
}),
});
missingReqs.push(req);
// add the new request to every dropdown of the same media type, then link this row
const item = scanItems[i];
scanItems.forEach((it, j) => {
if (it.media_type !== item.media_type) return;
const sel = document.querySelector(`[data-select="${j}"]`);
const opt = document.createElement("option");
opt.value = req.id;
opt.textContent = `${req.title}${req.authors} (${req.library_name})`;
sel.appendChild(opt);
});
document.querySelector(`[data-select="${i}"]`).value = req.id;
document.querySelector(`[data-check="${i}"]`).checked = true;
$("#quick-dialog").close();
toast(`${req.title}" angefragt und verbunden`);
} catch (err) { toast(err.message, true); }
}
$("#import-btn").addEventListener("click", async () => {