Compare commits

...

1 Commits

Author SHA1 Message Date
root
1a2bf580cd v2.6.51: fix PDF import — raise UI body limit, wire real analyze
All checks were successful
Release / Test backend (push) Successful in 38s
Release / Check ui (push) Successful in 1m49s
Release / Docker (push) Successful in 6m4s
Release / Gitea Release (push) Successful in 40s
- docker-compose.yml: BODY_SIZE_LIMIT=52428800 (50MB) on UI service
  — adapter-node was rejecting PDFs >512KB with 'Content-length exceeds limit'
- storage/import.go: add AnalyzeFile() public function using real PDF/EPUB parsers
- handlers_import.go: analyzeImportFile() now calls storage.AnalyzeFile() instead
  of the file-size stub, so chapter count is accurate in the preview
2026-04-09 15:55:06 +05:00
3 changed files with 46 additions and 9 deletions

View File

@@ -127,16 +127,17 @@ func (s *Server) handleAdminImport(w http.ResponseWriter, r *http.Request) {
})
}
// analyzeImportFile does a quick scan of the file to count chapters.
// This is a placeholder - real implementation would parse PDF/EPUB properly.
// analyzeImportFile parses the file to count chapters and extract preview lines.
func analyzeImportFile(data []byte, fileType string) *importPreview {
// TODO: Implement actual PDF/EPUB parsing to count chapters
// For now, estimate based on file size
preview := &importPreview{
Chapters: estimateChapters(data, fileType),
FirstLines: []string{},
count, firstLines, err := storage.AnalyzeFile(data, fileType)
if err != nil || count == 0 {
// Fall back to rough size estimate so the UI still shows something
count = estimateChapters(data, fileType)
}
return &importPreview{
Chapters: count,
FirstLines: firstLines,
}
return preview
}
func estimateChapters(data []byte, fileType string) int {

View File

@@ -54,7 +54,41 @@ func (i *importer) Import(ctx context.Context, objectKey, fileType string) ([]bo
return parseEPUB(data)
}
// ── PDF parsing ───────────────────────────────────────────────────────────────
// AnalyzeFile parses the given PDF or EPUB data and returns the detected
// chapter count and up to 3 preview lines (first non-empty line of each of
// the first 3 chapters). It is used by the analyze-only endpoint so users
// can preview chapter count before committing the import.
func AnalyzeFile(data []byte, fileType string) (chapterCount int, firstLines []string, err error) {
var chapters []bookstore.Chapter
switch fileType {
case "pdf":
chapters, err = parsePDF(data)
case "epub":
chapters, err = parseEPUB(data)
default:
return 0, nil, fmt.Errorf("unsupported file type: %s", fileType)
}
if err != nil {
return 0, nil, err
}
chapterCount = len(chapters)
for i, ch := range chapters {
if i >= 3 {
break
}
line := strings.TrimSpace(ch.Content)
if nl := strings.Index(line, "\n"); nl > 0 {
line = line[:nl]
}
if len(line) > 120 {
line = line[:120] + "…"
}
firstLines = append(firstLines, line)
}
return chapterCount, firstLines, nil
}
func parsePDF(data []byte) ([]bookstore.Chapter, error) {
r, err := pdf.NewReader(bytes.NewReader(data), int64(len(data)))

View File

@@ -307,6 +307,8 @@ services:
# OpenTelemetry tracing
OTEL_EXPORTER_OTLP_ENDPOINT: "${OTEL_EXPORTER_OTLP_ENDPOINT}"
OTEL_SERVICE_NAME: "ui"
# Allow large PDF/EPUB uploads (adapter-node default is 512KB)
BODY_SIZE_LIMIT: "52428800"
# OAuth2 providers
GOOGLE_CLIENT_ID: "${GOOGLE_CLIENT_ID}"
GOOGLE_CLIENT_SECRET: "${GOOGLE_CLIENT_SECRET}"