mirror of
https://github.com/hanzoai/extract-svc.git
synced 2026-10-30 18:36:53 +00:00
Document text extraction service. Drop-in replacement for Huly's rekoni — listens on :4004 and serves /v1/extract, /v1/extract/url, /v1/health. - Pure Go, no CGo, no shelled binaries - Format detection by magic bytes (filename ignored) - PDF via ledongthuc/pdf; DOCX/XLSX/PPTX via native ZIP+XML walk; HTML via x/net/html with script/style strip; RTF via small native parser; plain text and markdown pass-through - Bearer JWT auth against IAM JWKS (RS256/RS512), 10m cache - 25 MB streaming upload cap, distroless static runtime - Tests for every format (real fixtures in testdata/) Image OCR is out of scope for v0.1 and returns HTTP 415.
39 lines
921 B
Go
39 lines
921 B
Go
// PDF text extraction via github.com/ledongthuc/pdf — MIT-licensed,
|
|
// pure Go, no LGPL transitive deps. We use GetPlainText (visible-page
|
|
// text walker) rather than Reader.Rows so we get a single concatenated
|
|
// stream that matches what rekoni emitted.
|
|
package extract
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"io"
|
|
|
|
"github.com/ledongthuc/pdf"
|
|
)
|
|
|
|
type pdfExtractor struct{}
|
|
|
|
func init() { register(FormatPDF, pdfExtractor{}) }
|
|
|
|
func (pdfExtractor) Extract(data []byte) (Result, error) {
|
|
r, err := pdf.NewReader(bytes.NewReader(data), int64(len(data)))
|
|
if err != nil {
|
|
return Result{}, fmt.Errorf("pdf parse: %w", err)
|
|
}
|
|
tr, err := r.GetPlainText()
|
|
if err != nil {
|
|
return Result{}, fmt.Errorf("pdf text: %w", err)
|
|
}
|
|
out, err := io.ReadAll(tr)
|
|
if err != nil {
|
|
return Result{}, fmt.Errorf("pdf read: %w", err)
|
|
}
|
|
return Result{
|
|
Text: string(out),
|
|
Metadata: map[string]any{
|
|
"pages": r.NumPage(),
|
|
},
|
|
}, nil
|
|
}
|