Wires the sovereign docmark MCP server (git.d-ma.be/mathias/docmark) as the converter for formats ingestion previously couldn't handle at all -- DOCX, XLSX, PPTX, PNG/JPG. A single self-contained tools/call POST (docmark runs stateless_http, no session handshake needed) does the conversion. - internal/extract/docmark.go: extractViaDocmark(path) -- reads DOCMARK_URL + DOCMARK_BEARER_TOKEN from env, base64-encodes the file, calls docmark's convert_to_markdown tool, surfaces tool/HTTP errors with context. - internal/extract/extract.go: routes .docx/.xlsx/.pptx/.png/.jpg/.jpeg to it. - internal/api/handler.go: isSupportedExtension() replaces the static supportedExtensions map -- the new extensions are gated on DOCMARK_URL being set, checked per-request. When DOCMARK_URL is unset (e.g. this repo's current deployed state), behavior is byte-for-byte unchanged from today: same 400/silent-skip as before. Zero risk until the env var is actually wired in infra. TDD throughout: docmark.go tested via httptest mock (success, not-configured, tool-error, HTTP-error, all 6 new extensions route correctly); handler-level test proves the DOCMARK_URL gate (docx 400 when unset, 200 when a working mock is configured). Full task check green (fmt/vet/govulncheck/all tests). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
44 lines
1.0 KiB
Go
44 lines
1.0 KiB
Go
// ingestion/internal/extract/extract.go
|
|
package extract
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
)
|
|
|
|
// Text reads the file at path and returns its plain-text content.
|
|
// Supported extensions: .md, .txt (passthrough), .pdf (via pdftotext),
|
|
// .docx/.xlsx/.pptx/.png/.jpg/.jpeg (via docmark, ADR-0013 -- requires
|
|
// DOCMARK_URL to be set; see docmark.go).
|
|
func Text(path string) (string, error) {
|
|
ext := strings.ToLower(fileExt(path))
|
|
switch ext {
|
|
case ".md", ".txt":
|
|
b, err := os.ReadFile(path)
|
|
if err != nil {
|
|
return "", fmt.Errorf("read %s: %w", path, err)
|
|
}
|
|
return string(b), nil
|
|
case ".pdf":
|
|
return extractPDF(path)
|
|
case ".docx", ".xlsx", ".pptx", ".png", ".jpg", ".jpeg":
|
|
return extractViaDocmark(path)
|
|
default:
|
|
return "", fmt.Errorf("unsupported file extension: %s", ext)
|
|
}
|
|
}
|
|
|
|
// fileExt returns the file extension including the dot, lowercased.
|
|
func fileExt(path string) string {
|
|
for i := len(path) - 1; i >= 0; i-- {
|
|
if path[i] == '.' {
|
|
return path[i:]
|
|
}
|
|
if path[i] == '/' || path[i] == '\\' {
|
|
break
|
|
}
|
|
}
|
|
return ""
|
|
}
|