Commit ed98913
Changed files (3)
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