screenshot-server/main.go

118 lines
2.6 KiB
Go

// screenshot-server: Serves the latest screenshot from ~/Desktop, then deletes it
// Run: go build -o screenshot-server && ./screenshot-server
// Fetch: curl http://mac-ip:9123/screenshot -o screenshot.png
package main
import (
"fmt"
"io"
"log"
"net/http"
"os"
"path/filepath"
"sort"
"strings"
)
const (
port = ":9123"
desktopDir = "" // Will be set to ~/Desktop
)
func getDesktopPath() string {
home, err := os.UserHomeDir()
if err != nil {
log.Fatal("Cannot find home directory:", err)
}
return filepath.Join(home, "Desktop")
}
func findLatestScreenshot(desktop string) (string, error) {
entries, err := os.ReadDir(desktop)
if err != nil {
return "", err
}
var screenshots []os.DirEntry
for _, e := range entries {
name := e.Name()
if strings.HasPrefix(name, "Screenshot") && strings.HasSuffix(name, ".png") {
screenshots = append(screenshots, e)
}
}
if len(screenshots) == 0 {
return "", fmt.Errorf("no screenshots found")
}
// Sort by modification time (newest first)
sort.Slice(screenshots, func(i, j int) bool {
infoI, _ := screenshots[i].Info()
infoJ, _ := screenshots[j].Info()
return infoI.ModTime().After(infoJ.ModTime())
})
return filepath.Join(desktop, screenshots[0].Name()), nil
}
func screenshotHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet {
http.Error(w, "GET only", http.StatusMethodNotAllowed)
return
}
desktop := getDesktopPath()
path, err := findLatestScreenshot(desktop)
if err != nil {
http.Error(w, err.Error(), http.StatusNotFound)
log.Println("No screenshot:", err)
return
}
// Open and serve
f, err := os.Open(path)
if err != nil {
http.Error(w, "Cannot open file", http.StatusInternalServerError)
return
}
defer f.Close()
filename := filepath.Base(path)
w.Header().Set("Content-Type", "image/png")
w.Header().Set("X-Screenshot-Name", filename)
_, err = io.Copy(w, f)
if err != nil {
log.Println("Error sending:", err)
return
}
// Delete after successful send
f.Close()
if err := os.Remove(path); err != nil {
log.Println("Warning: could not delete:", err)
} else {
log.Println("Served and deleted:", filename)
}
}
func healthHandler(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("ok"))
}
func main() {
http.HandleFunc("/screenshot", screenshotHandler)
http.HandleFunc("/health", healthHandler)
log.Printf("Screenshot server starting on %s", port)
log.Printf("Desktop: %s", getDesktopPath())
log.Printf("Endpoints:")
log.Printf(" GET /screenshot - fetch & delete latest screenshot")
log.Printf(" GET /health - health check")
if err := http.ListenAndServe(port, nil); err != nil {
log.Fatal(err)
}
}