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}) }