diff --git a/cmd/steamimmich.go b/cmd/steamimmich.go index 1af698b..a438aa3 100644 --- a/cmd/steamimmich.go +++ b/cmd/steamimmich.go @@ -1,7 +1,7 @@ package cmd import ( - "log" + "log/slog" "os" "path/filepath" "runtime" @@ -17,13 +17,18 @@ type args struct { DeviceID string `arg:"--device-id" default:"steam-immich" help:"Device ID of the uploads"` Album string `arg:"--album" help:"UUID of a album to upload to"` CacheFile string `arg:"--cache" default:"$XDG_CACHE_HOME/steam-immich.json" help:"Location of the cache file"` - Revalidate bool `args:"--revalidate" default:"false" help:"Only revalidate and fix the cache"` + Revalidate bool `arg:"--revalidate" help:"Only revalidate and fix the cache"` + Verbose bool `arg:"-v,--verbose" help:"Toggle verbose logging"` } func Run() { var args args arg.MustParse(&args) + if args.Verbose { + slog.SetLogLoggerLevel(slog.LevelDebug) + } + var steamUserdataDir = "" if args.UserdataDir != "" { @@ -33,12 +38,10 @@ func Run() { } if steamUserdataDir == "" { - log.Fatal("Can not find steam userdata dir. Please set with --steam-userdata-dir") + slog.Error("Can not find steam userdata dir. Please set with --steam-userdata-dir") + os.Exit(1) } - // Disable timestamp in log - log.SetFlags(0) - config := steamimmich.Config{ APIKey: args.APIKey, BaseURL: args.BaseURL, @@ -49,9 +52,11 @@ func Run() { } if args.Revalidate { - steamimmich.Revalidate(config) + statusCode := steamimmich.Revalidate(config) + os.Exit(statusCode) } else { - steamimmich.Run(config) + statusCode := steamimmich.Run(config) + os.Exit(statusCode) } } diff --git a/internal/steam.go b/internal/steam.go index 4d36197..0433135 100644 --- a/internal/steam.go +++ b/internal/steam.go @@ -4,7 +4,7 @@ import ( "encoding/json" "fmt" "io" - "log" + "log/slog" "net/http" ) @@ -24,7 +24,7 @@ func getGameName(appID string, cache map[string]string) string { name, err := fetchGameName(appID) if err != nil { - log.Printf("failed to fetch name for AppID: %s. Setting to Unknown", appID) + slog.Warn("Failed to fetch name for AppID. Setting to Unknown", "appid", appID) cache[appID] = UNKOWN_GAME_GAME return UNKOWN_GAME_GAME } diff --git a/internal/steamimmich.go b/internal/steamimmich.go index 2caf86f..37f35a5 100644 --- a/internal/steamimmich.go +++ b/internal/steamimmich.go @@ -2,7 +2,7 @@ package steamimmich import ( "fmt" - "log" + "log/slog" "slices" "sort" "strconv" @@ -17,24 +17,25 @@ type Config struct { CacheFile string } -func Run(config Config) { +func Run(config Config) int { screenshotFiles, err := listScreenshots(config.UserdataDir) if err != nil { - log.Fatalf("Failed to scan for screenshots: %s", err) - return + slog.Error("Failed to scan for screenshots", "err", err) + return 1 } if len(screenshotFiles) == 0 { - log.Println("No screenshots found.") - return + slog.Info("No screenshots found") + return 0 } immichClient := newImmichHttpClient(config.APIKey) localState, err := loadLocalState(config.CacheFile) if err != nil { - log.Fatalf("Failed to load local state: %s", err) + slog.Error("Failed to load local cache", "err", err) + return 1 } for appid, files := range screenshotFiles { @@ -46,18 +47,18 @@ func Run(config Config) { idx := slices.IndexFunc(localState.Assets, func(e assetState) bool { return e.FilePath == filepath }) if idx != -1 { - log.Printf("Asset already uploaded: %s", filepath) + slog.Debug("Asset already uploaded", "path", filepath) continue } res, err := uploadToImmich(filepath, appid, config.BaseURL, config.DeiveID, &immichClient) if err != nil { - log.Fatalf("Failed to upload to immich: %s", err) - return + slog.Error("Failed to upload to immich", "err", err) + return 1 } - log.Printf("Assest uploaded: %s (%s) %s with ID: %s", gameName, appid, filepath, res.ID) + slog.Info("Assets uploaded", "path", filepath, "id", res.ID) localState.Assets = append(localState.Assets, assetState{FilePath: filepath, ImmichID: res.ID}) @@ -66,42 +67,47 @@ func Run(config Config) { err := setAssetMetadata(assetsInGame, fmt.Sprintf("Game: %s", gameName), config.BaseURL, immichClient) if err != nil { - log.Fatalf("Failed to set asset metadata: %s", err) - return + slog.Error("Failed to set assets metadata", "err", err) + return 1 } if config.Album != "" { err = addAssetsToAlbum(assetsInGame, config.Album, config.BaseURL, immichClient) if err != nil { - log.Fatalf("Failed to add assets to album: %s", err) - return + slog.Error("Failed to add assets to album", "err", err) + return 1 } - log.Printf("Added %d assets to album %s", len(assetsInGame), config.Album) + if len(assetsInGame) > 0 { + slog.Info("Added assets to album", "count", len(assetsInGame)) + } } } - log.Println("Finished uploading screenshots") + slog.Info("Finished uploading screenshots") err = saveLocalState(config.CacheFile, *localState) if err != nil { - log.Fatalf("Failed to save local cache: %s", err) - return + slog.Error("Failed to save local cache", "err", err) + return 1 } + + return 0 } -func Revalidate(config Config) { +func Revalidate(config Config) int { immichClient := newImmichHttpClient(config.APIKey) localState, err := loadLocalState(config.CacheFile) if err != nil { - log.Fatalf("Failed to load local state: %s", err) - return + slog.Error("Failed to load local cache", "err", err) + + return 1 } hashes, err := hashFiles(localState.Assets) if err != nil { - log.Fatalf("Failed to generate hashes: %s", err) - return + slog.Error("Failed to generate hashes", "err", err) + return 1 } idxToRemoveFromCache := []int{} @@ -125,20 +131,21 @@ func Revalidate(config Config) { results, err := bulkCheckAssets(idsToCheck, config.BaseURL, immichClient) if err != nil { - log.Fatalf("Failed to bulk check hashes: %s", err) + slog.Error("Failed to bulk check hashes", "err", err) + return 1 } for _, result := range results { i, err := strconv.Atoi(result.Id) if err != nil { - log.Fatalf("What ?: %s", err) - return + slog.Error("What ? This should never happen", "err", err) + return 1 } asset := localState.Assets[i] if asset.ImmichID != result.AssetId { - log.Printf("Asset %s had the wrong Immich ID. New %s", asset.FilePath, result.AssetId) + slog.Info("Asset has the wrong Immich ID", "path", asset.FilePath, "id", result.AssetId) localState.Assets[i].ImmichID = result.AssetId updated += 1 } @@ -159,13 +166,15 @@ func Revalidate(config Config) { saveLocalState(config.CacheFile, *localState) - log.Printf("Revalidated %d assets", len(results)) - log.Printf("Assets present on Immich: %d", rejected) - log.Printf("Wrong metadata on cache: %d", updated) - log.Printf("Missing on Immich: %d", missingFromImmich) - log.Printf("Missing on local storage: %d", missingFile) + slog.Info("Revalidated assets", "count", len(localState.Assets)) + slog.Info("Assets present on immich", "count", rejected) + slog.Info("Wrong metadata on cache", "count", updated) + slog.Info("Missing on Immich", "count", missingFromImmich) + slog.Info("Missing on local storage", "count", missingFile) if (updated + missingFromImmich + missingFromImmich) > 0 { - log.Printf("Fixed cache. Run the normal upload command again. If error persists try removing cache file at: %s", config.CacheFile) + slog.Info("Fixed cache. Run the normal upload command again. If error persists try removing cache file", "path", config.CacheFile) } + + return 0 }