Zum Inhalt springen

MediaWiki:Gadget-LabelScan.js: Unterschied zwischen den Versionen

Aus ADOS Wiki
Keine Bearbeitungszusammenfassung
Keine Bearbeitungszusammenfassung
Zeile 36: Zeile 36:
     await loadTesseract();
     await loadTesseract();


     return Tesseract.recognize(file, "eng", {
     return Tesseract.recognize(file, "deu+eng", {
      logger: m => { /* kein Fortschritt nötig */ }
    tessedit_char_whitelist: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 -'()",
    tessedit_pageseg_mode: 6,
    logger: m => { /* Fortschritt optional */ }
     }).then(r => r.data.text || "");
     }).then(r => r.data.text || "");
   }
   }


   // Sucht nach Destillerie & Alter
   // Sucht nach Destillerie & Alter
  function extractQuery(text) {
function extractQuery(text) {
    text = text.replace(/\s+/g, " ");
  text = text.replace(/\s+/g, " ");


    const dist = text.match(/\b([A-Z][a-z]{3,})\b/);
  const names = text.match(/\b([A-Z][a-z]{3,})\b/g) || [];
    const age = text.match(/\b([1-3]?\d)\s?(years?|yo|Jahre)\b/i);
  const ages = text.match(/\b([1-3]?\d)\s?(years?|yo|Jahre|Jahr)\b/gi) || [];
  const years = text.match(/\b(19|20)\d{2}\b/g) || [];


    let parts = [];
  const parts = [...names.slice(0, 2), ...ages.slice(0, 1), ...years.slice(0, 1)];
    if (dist) parts.push(dist[1]);
    if (age) parts.push(age[1]);


    return parts.join(" ");
  return parts.join(" ");
  }
}


   async function searchWiki(q) {
   async function searchWiki(q) {

Version vom 6. November 2025, 20:54 Uhr

/* Einfacher & stabiler Label-Scanner
   Kein Worker, keine WASM, läuft in allen Browsern */

(function () {

  const btn = document.getElementById("ados-scan-run");
  const fileInput = document.getElementById("ados-scan-file");
  const statusEl = document.getElementById("ados-scan-status");
  const resultsEl = document.getElementById("ados-scan-results");
  const previewEl = document.getElementById("ados-scan-preview");

  if (!btn || !fileInput) return;

  function setStatus(t) {
    statusEl.textContent = t || "";
  }

  function preview(file) {
    const url = URL.createObjectURL(file);
    previewEl.innerHTML = `<img src="${url}" style="max-width:100%; border-radius:6px;">`;
  }

  // Tesseract v4 → stabil, kein WASM nötig
  function loadTesseract() {
    return new Promise((resolve, reject) => {
      if (window.Tesseract) return resolve();
      const s = document.createElement("script");
      s.src = "https://cdn.jsdelivr.net/npm/tesseract.js@4/dist/tesseract.min.js";
      s.onload = resolve;
      s.onerror = reject;
      document.head.appendChild(s);
    });
  }

  async function runOCR(file) {
    await loadTesseract();

    return Tesseract.recognize(file, "deu+eng", {
    tessedit_char_whitelist: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 -'()",
    tessedit_pageseg_mode: 6,
    logger: m => { /* Fortschritt optional */ }
    }).then(r => r.data.text || "");
  }

  // Sucht nach Destillerie & Alter
function extractQuery(text) {
  text = text.replace(/\s+/g, " ");

  const names = text.match(/\b([A-Z][a-z]{3,})\b/g) || [];
  const ages = text.match(/\b([1-3]?\d)\s?(years?|yo|Jahre|Jahr)\b/gi) || [];
  const years = text.match(/\b(19|20)\d{2}\b/g) || [];

  const parts = [...names.slice(0, 2), ...ages.slice(0, 1), ...years.slice(0, 1)];

  return parts.join(" ");
}

  async function searchWiki(q) {
    await mw.loader.using("mediawiki.api");
    const api = new mw.Api();
    const r = await api.get({
      action: "query",
      list: "search",
      srsearch: q,
      formatversion: 2
    });
    return r.query.search || [];
  }

  function renderResults(list) {
    if (!list.length) {
      resultsEl.innerHTML = "<div style='opacity:0.6'>Keine Treffer gefunden</div>";
      return;
    }
    resultsEl.innerHTML = list.map(it =>
      `<div><a href="/wiki/${encodeURIComponent(it.title)}">${it.title}</a></div>`
    ).join("");
  }

  fileInput.addEventListener("change", () => {
    if (fileInput.files[0]) preview(fileInput.files[0]);
  });

  btn.addEventListener("click", async () => {
    if (!fileInput.files[0]) return alert("Bitte Bild wählen!");

    btn.disabled = true;
    setStatus("Erkenne Text …");

    try {
      const text = await runOCR(fileInput.files[0]);
      setStatus("Suche im Wiki …");

      const q = extractQuery(text);
      const hits = await searchWiki(q);

      renderResults(hits);
      setStatus("Fertig ✅");
    } catch (e) {
      console.error(e);
      setStatus("Fehler ❗");
    }

    btn.disabled = false;
  });

})();