Commit ed98913

bryfry <bryon@fryer.io>
2025-01-19 20:11:24
add golang capture and findbadjpeg
1 parent adcaa1f
capture.go
@@ -0,0 +1,69 @@
+package main
+
+import (
+	"fmt"
+	"io"
+	"log/slog"
+	"net/http"
+	"net/url"
+	"os"
+	"time"
+)
+
+func main() {
+	snapshotURL := "http://USERNAME:PASSWORD@192.168.58.58/snapshot.JPG"
+	client := &http.Client{
+		Timeout: 1700 * time.Millisecond,
+	}
+
+	for {
+		startTime := time.Now()
+
+		outputFile := fmt.Sprintf("%x.jpg", startTime.Unix())
+
+		resp, err := client.Get(snapshotURL)
+		if err != nil {
+			if urlError, ok := err.(*url.Error); ok && urlError.Timeout() {
+				elapsed := time.Since(startTime)
+				slog.Warn("timed out",
+					slog.String("elapsed", elapsed.String()))
+				continue
+			} else {
+				slog.Error("failed to fetch URL",
+					slog.String("err", err.Error()))
+				continue
+			}
+		}
+		defer resp.Body.Close()
+
+		if resp.StatusCode != http.StatusOK {
+			slog.Error("bad response status",
+				slog.String("status", resp.Status))
+		}
+
+		out, err := os.Create(outputFile)
+		if err != nil {
+			slog.Error("failed to create file",
+				slog.String("err", err.Error()),
+				slog.String("file", outputFile))
+		}
+		defer out.Close()
+
+		_, err = io.Copy(out, resp.Body)
+		if err != nil {
+			slog.Error("failed to save image",
+				slog.String("err", err.Error()))
+			continue
+		}
+
+		elapsed := time.Since(startTime)
+		sleepTime := time.Second - elapsed
+		if sleepTime < 0 {
+			slog.Warn("late, no sleep",
+				slog.String("elapsed", elapsed.String()))
+		}
+		if sleepTime > 0 {
+			time.Sleep(sleepTime)
+		}
+	}
+}
findbadjpeg.go
@@ -0,0 +1,80 @@
+package main
+
+import (
+	"fmt"
+	"image"
+	_ "image/jpeg"
+	"io/fs"
+	"log"
+	"os"
+	"path/filepath"
+	"sync"
+)
+
+// WorkerPool size
+const workerCount = 16
+const srcDir = "./all/"
+const badDir = "./bad/"
+
+func main() {
+	filesChan := make(chan string, 100)
+	var wg sync.WaitGroup
+
+	for i := 0; i < workerCount; i++ {
+		wg.Add(1)
+		go worker(filesChan, &wg)
+	}
+
+	// Scan directory for files
+	go func() {
+		filepath.Walk(srcDir, func(path string, info fs.FileInfo, err error) error {
+			if err != nil {
+				return err
+			}
+			if !info.IsDir() {
+				// Only process files
+				filesChan <- path
+			}
+			return nil
+		})
+		fmt.Println("walk complete closing channel")
+		close(filesChan)
+	}()
+
+	wg.Wait()
+	fmt.Println("All files processed.")
+}
+
+// worker processes files received from the channel.
+func worker(filesChan chan string, wg *sync.WaitGroup) {
+	defer wg.Done()
+	for file := range filesChan {
+		err := processFile(file)
+		if err != nil {
+			log.Printf("Error processing file %s: %v\n", file, err)
+		}
+	}
+}
+
+func processFile(filePath string) error {
+
+	// Open the file
+	file, err := os.Open(filePath)
+	if err != nil {
+		return fmt.Errorf("failed to open file: %w", err)
+	}
+	defer file.Close()
+
+	// Decode the image to check for issues
+	_, _, err = image.Decode(file)
+	if err != nil {
+
+		file.Close()
+		moveDest := filepath.Join(badDir, filepath.Base(filePath))
+		os.Rename(filePath, moveDest)
+		log.Printf("moving bad file %s: %v\n", filePath, err)
+		return nil
+	}
+
+	return nil
+}
go.mod
@@ -0,0 +1,3 @@
+module christmas-cam
+
+go 1.22.0