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 } }