Go-Backend (chi, pgx, golang-migrate) + React/TS-Frontend als PWA. Enthalten: Auth inkl. OIDC, Dateien mit Versionen und Papierkorb, Freigaben (Links + intern), WebDAV, Gruppenordner, Admin/Theming, Volltextsuche mit OCR, eigener PDF-Betrachter und WOPI-Office (Collabora/OnlyOffice). Nicht im Repo: deploy/.env (Sitzungsschlüssel, DB- und Admin-Passwort) sowie alle Daten- und Build-Verzeichnisse – siehe .gitignore. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
51 lines
1.8 KiB
Go
51 lines
1.8 KiB
Go
package files
|
||
|
||
import (
|
||
"net/http"
|
||
|
||
"aether/pkg/response"
|
||
)
|
||
|
||
// TextPages beantwortet GET /api/v1/files/{id}/text.
|
||
//
|
||
// **Wofür das da ist:** Der PDF-Betrachter im Browser sucht im Dokument – aber
|
||
// bei einem *Scan* steht im PDF kein einziges Wort, nur ein Bild. Der erkannte
|
||
// Text liegt daneben in der Datenbank. Ohne diesen Endpunkt fände die Suche im
|
||
// Dokument ausgerechnet bei dem Dateityp nichts, für den die Texterkennung
|
||
// überhaupt gebaut wurde.
|
||
//
|
||
// Geliefert wird der Text **in Seiten zerlegt**. Mehr geht nicht: Wo genau auf
|
||
// dem Bild ein Wort steht, weiß nur die Erkennung selbst, und wir bewahren
|
||
// ihre Koordinaten nicht auf. Die Seite ist aber der Sprung, auf den es
|
||
// ankommt – bei einem zwölfseitigen Beleg ist das der Unterschied zwischen
|
||
// „gefunden" und „such weiter".
|
||
//
|
||
// Die Prüfung ist dieselbe wie beim Herunterladen: Wer die Datei nicht lesen
|
||
// darf, bekommt hier auch ihren Text nicht. Das ist keine Kleinigkeit – der
|
||
// Text *ist* der Inhalt der Rechnung.
|
||
func (h *Handler) TextPages(w http.ResponseWriter, r *http.Request) {
|
||
id, err := parseID(r, "id")
|
||
if err != nil {
|
||
response.Error(w, http.StatusBadRequest, "invalid file id")
|
||
return
|
||
}
|
||
if _, ok := h.resolveFile(w, r, id, false); !ok {
|
||
return
|
||
}
|
||
// Ohne Texterkennung gibt es keinen Text – das ist eine Auskunft, kein
|
||
// Fehler. Der Betrachter zeigt dann schlicht keine Fundstellen an.
|
||
if h.docs == nil {
|
||
response.JSON(w, http.StatusOK, map[string]any{"pages": []string{}, "source": ""})
|
||
return
|
||
}
|
||
pages, source, err := h.docs.TextPages(r.Context(), id)
|
||
if err != nil {
|
||
response.Error(w, http.StatusInternalServerError, "database error")
|
||
return
|
||
}
|
||
if pages == nil {
|
||
pages = []string{}
|
||
}
|
||
response.JSON(w, http.StatusOK, map[string]any{"pages": pages, "source": source})
|
||
}
|