Scanyonero/server.go
David Vogel 853a1bb58d Rework into FTP scanning server
- Rename to Scanyonero
- Add FTP server that ingests TIFF, PNG, JPEG or PDF files
- Add web interface to check and modify ingested files
- Rework how ocrmypdf is invoked

Basics are working, but the program is not in a usable state.
2025-05-14 12:08:38 +02:00

152 lines
3.7 KiB
Go

package main
import (
"fmt"
"image/jpeg"
"log"
"net/http"
"strconv"
"github.com/nfnt/resize"
)
type Server struct {
http.ServeMux
Documents Queue
}
func NewServer() *Server {
s := &Server{}
s.Handle("/", http.FileServer(http.Dir("./static")))
s.HandleFunc("GET /api/queue-entry-page/{id}/image", s.handleGetQueueEntryImage)
s.HandleFunc("GET /api/queue-entry-page/{id}/preview", s.handleGetQueueEntryPreview)
//s.HandleFunc("PUT /documents/{id}", addItem)
//s.HandleFunc("DELETE /documents/{id}", s.handleRemoveDocument)
s.HandleFunc("/ws", s.handleWebSocket)
return s
}
func (s *Server) handleGetQueueEntryImage(w http.ResponseWriter, r *http.Request) {
var id QueueEntryID
if i, err := strconv.ParseInt(r.PathValue("id"), 10, 0); err != nil {
w.WriteHeader(http.StatusBadRequest)
msg := fmt.Sprintf("Failed to parse document id: %v.", err)
w.Write([]byte(msg))
log.Print(msg)
return
} else {
id = QueueEntryID(i)
}
s.Documents.Lock()
defer s.Documents.Unlock()
entry := s.Documents.QueueEntryByID(id)
if entry == nil {
w.WriteHeader(http.StatusNotFound)
msg := fmt.Sprintf("Failed to find %T with ID %v.", entry, id)
w.Write([]byte(msg))
log.Print(msg)
return
}
page, ok := entry.QueueEntryData.(QueueEntryDataPage)
if !ok {
w.WriteHeader(http.StatusInternalServerError)
msg := fmt.Sprintf("Entry %d isn't a page.", entry.ID)
w.Write([]byte(msg))
log.Print(msg)
return
}
if page.Page == nil {
w.WriteHeader(http.StatusInternalServerError)
msg := fmt.Sprintf("Entry %d doesn't contain any page data.", entry.ID)
w.Write([]byte(msg))
log.Print(msg)
return
}
if page.Page.Image == nil {
w.WriteHeader(http.StatusInternalServerError)
msg := fmt.Sprintf("Page %d doesn't contain any image.", entry.ID)
w.Write([]byte(msg))
log.Print(msg)
return
}
w.Header().Set("Content-Type", "image/jpeg")
if err := jpeg.Encode(w, page.Page.Image, nil); err != nil {
w.WriteHeader(http.StatusInternalServerError)
msg := fmt.Sprintf("Failed to encode JPEG: %v.", err)
w.Write([]byte(msg))
log.Print(msg)
return
}
}
func (s *Server) handleGetQueueEntryPreview(w http.ResponseWriter, r *http.Request) {
var id QueueEntryID
if i, err := strconv.ParseInt(r.PathValue("id"), 10, 0); err != nil {
w.WriteHeader(http.StatusBadRequest)
msg := fmt.Sprintf("Failed to parse document id: %v.", err)
w.Write([]byte(msg))
log.Print(msg)
return
} else {
id = QueueEntryID(i)
}
s.Documents.Lock()
defer s.Documents.Unlock()
entry := s.Documents.QueueEntryByID(id)
if entry == nil {
w.WriteHeader(http.StatusNotFound)
msg := fmt.Sprintf("Failed to find %T with ID %v.", entry, id)
w.Write([]byte(msg))
log.Print(msg)
return
}
page, ok := entry.QueueEntryData.(QueueEntryDataPage)
if !ok {
w.WriteHeader(http.StatusInternalServerError)
msg := fmt.Sprintf("Entry %d isn't a page.", entry.ID)
w.Write([]byte(msg))
log.Print(msg)
return
}
if page.Page == nil {
w.WriteHeader(http.StatusInternalServerError)
msg := fmt.Sprintf("Entry %d doesn't contain any page data.", entry.ID)
w.Write([]byte(msg))
log.Print(msg)
return
}
if page.Page.Image == nil {
w.WriteHeader(http.StatusInternalServerError)
msg := fmt.Sprintf("Page %d doesn't contain any image.", entry.ID)
w.Write([]byte(msg))
log.Print(msg)
return
}
// Resize image to a preview with a width of about 512 pixels.
img := resize.Resize(512, 0, page.Page.Image, resize.Lanczos2)
w.Header().Set("Content-Type", "image/jpeg")
if err := jpeg.Encode(w, img, nil); err != nil {
w.WriteHeader(http.StatusInternalServerError)
msg := fmt.Sprintf("Failed to encode JPEG: %v.", err)
w.Write([]byte(msg))
log.Print(msg)
return
}
}