Fix PDF thumbnails (ghostscript), 3MF viewer (official loader), PDF viewer (blob fetch)
All checks were successful
Automated Container Build / build-and-push (push) Successful in 1m9s

This commit is contained in:
Elijah 2026-05-31 21:52:32 -07:00
parent facb1c6f8b
commit c239fbb296
5 changed files with 218 additions and 51 deletions

View file

@ -148,7 +148,9 @@ func (m *ThumbnailManager) worker(id int) {
err = generateVideoThumbnail(fullSourcePath, destPath)
} else if strings.HasPrefix(job.MimeType, "audio/") {
err = generateAudioThumbnail(fullSourcePath, destPath)
} else if strings.HasSuffix(job.FilePath, ".docx") || strings.HasSuffix(job.FilePath, ".pptx") || strings.HasSuffix(job.FilePath, ".xlsx") || strings.HasSuffix(strings.ToLower(job.FilePath), ".pdf") {
} else if strings.HasSuffix(strings.ToLower(job.FilePath), ".pdf") {
err = generatePdfThumbnail(fullSourcePath, destPath)
} else if strings.HasSuffix(job.FilePath, ".docx") || strings.HasSuffix(job.FilePath, ".pptx") || strings.HasSuffix(job.FilePath, ".xlsx") {
err = generateOfficeThumbnail(job.FilePath, destPath, m.Config)
} else {
continue
@ -211,6 +213,39 @@ func generateAudioThumbnail(src, dest string) error {
return nil
}
func generatePdfThumbnail(src, dest string) error {
// Use Ghostscript to render the first page of the PDF as a JPEG
tmpFile := dest + ".tmp.jpg"
cmd := exec.Command("gs",
"-dNOPAUSE", "-dBATCH", "-dSAFER", "-dQUIET",
"-sDEVICE=jpeg",
"-dFirstPage=1", "-dLastPage=1",
"-r72", // 72 DPI is enough for a thumbnail
"-dJPEGQ=85",
fmt.Sprintf("-sOutputFile=%s", tmpFile),
src,
)
timer := time.AfterFunc(30*time.Second, func() {
if cmd.Process != nil {
cmd.Process.Kill()
}
})
err := cmd.Run()
timer.Stop()
if err != nil {
os.Remove(tmpFile)
return fmt.Errorf("ghostscript failed: %w", err)
}
// Resize the rendered page to standard thumbnail size
err = generateImageThumbnail(tmpFile, dest)
os.Remove(tmpFile)
return err
}
func generateOfficeThumbnail(filePath, destPath string, cfg *config.Config) error {
// Generate a download token for the Conversion API to fetch the file from our backend
token, err := middleware.GenerateDownloadToken(0, "system_worker", cfg.JWTSecret, filePath)