improved logging

This commit is contained in:
2025-11-20 23:16:16 +01:00
parent 0e47fb6983
commit 239373d5a3
3 changed files with 58 additions and 44 deletions

View File

@@ -1,7 +1,7 @@
package cmd package cmd
import ( import (
"log" "log/slog"
"os" "os"
"path/filepath" "path/filepath"
"runtime" "runtime"
@@ -17,13 +17,18 @@ type args struct {
DeviceID string `arg:"--device-id" default:"steam-immich" help:"Device ID of the uploads"` 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"` 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"` 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() { func Run() {
var args args var args args
arg.MustParse(&args) arg.MustParse(&args)
if args.Verbose {
slog.SetLogLoggerLevel(slog.LevelDebug)
}
var steamUserdataDir = "" var steamUserdataDir = ""
if args.UserdataDir != "" { if args.UserdataDir != "" {
@@ -33,12 +38,10 @@ func Run() {
} }
if steamUserdataDir == "" { 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{ config := steamimmich.Config{
APIKey: args.APIKey, APIKey: args.APIKey,
BaseURL: args.BaseURL, BaseURL: args.BaseURL,
@@ -49,9 +52,11 @@ func Run() {
} }
if args.Revalidate { if args.Revalidate {
steamimmich.Revalidate(config) statusCode := steamimmich.Revalidate(config)
os.Exit(statusCode)
} else { } else {
steamimmich.Run(config) statusCode := steamimmich.Run(config)
os.Exit(statusCode)
} }
} }

View File

@@ -4,7 +4,7 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"io" "io"
"log" "log/slog"
"net/http" "net/http"
) )
@@ -24,7 +24,7 @@ func getGameName(appID string, cache map[string]string) string {
name, err := fetchGameName(appID) name, err := fetchGameName(appID)
if err != nil { 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 cache[appID] = UNKOWN_GAME_GAME
return UNKOWN_GAME_GAME return UNKOWN_GAME_GAME
} }

View File

@@ -2,7 +2,7 @@ package steamimmich
import ( import (
"fmt" "fmt"
"log" "log/slog"
"slices" "slices"
"sort" "sort"
"strconv" "strconv"
@@ -17,24 +17,25 @@ type Config struct {
CacheFile string CacheFile string
} }
func Run(config Config) { func Run(config Config) int {
screenshotFiles, err := listScreenshots(config.UserdataDir) screenshotFiles, err := listScreenshots(config.UserdataDir)
if err != nil { if err != nil {
log.Fatalf("Failed to scan for screenshots: %s", err) slog.Error("Failed to scan for screenshots", "err", err)
return return 1
} }
if len(screenshotFiles) == 0 { if len(screenshotFiles) == 0 {
log.Println("No screenshots found.") slog.Info("No screenshots found")
return return 0
} }
immichClient := newImmichHttpClient(config.APIKey) immichClient := newImmichHttpClient(config.APIKey)
localState, err := loadLocalState(config.CacheFile) localState, err := loadLocalState(config.CacheFile)
if err != nil { 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 { 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 }) idx := slices.IndexFunc(localState.Assets, func(e assetState) bool { return e.FilePath == filepath })
if idx != -1 { if idx != -1 {
log.Printf("Asset already uploaded: %s", filepath) slog.Debug("Asset already uploaded", "path", filepath)
continue continue
} }
res, err := uploadToImmich(filepath, appid, config.BaseURL, config.DeiveID, &immichClient) res, err := uploadToImmich(filepath, appid, config.BaseURL, config.DeiveID, &immichClient)
if err != nil { if err != nil {
log.Fatalf("Failed to upload to immich: %s", err) slog.Error("Failed to upload to immich", "err", err)
return 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}) 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) err := setAssetMetadata(assetsInGame, fmt.Sprintf("Game: %s", gameName), config.BaseURL, immichClient)
if err != nil { if err != nil {
log.Fatalf("Failed to set asset metadata: %s", err) slog.Error("Failed to set assets metadata", "err", err)
return return 1
} }
if config.Album != "" { if config.Album != "" {
err = addAssetsToAlbum(assetsInGame, config.Album, config.BaseURL, immichClient) err = addAssetsToAlbum(assetsInGame, config.Album, config.BaseURL, immichClient)
if err != nil { if err != nil {
log.Fatalf("Failed to add assets to album: %s", err) slog.Error("Failed to add assets to album", "err", err)
return 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) err = saveLocalState(config.CacheFile, *localState)
if err != nil { if err != nil {
log.Fatalf("Failed to save local cache: %s", err) slog.Error("Failed to save local cache", "err", err)
return return 1
}
} }
func Revalidate(config Config) { return 0
}
func Revalidate(config Config) int {
immichClient := newImmichHttpClient(config.APIKey) immichClient := newImmichHttpClient(config.APIKey)
localState, err := loadLocalState(config.CacheFile) localState, err := loadLocalState(config.CacheFile)
if err != nil { if err != nil {
log.Fatalf("Failed to load local state: %s", err) slog.Error("Failed to load local cache", "err", err)
return
return 1
} }
hashes, err := hashFiles(localState.Assets) hashes, err := hashFiles(localState.Assets)
if err != nil { if err != nil {
log.Fatalf("Failed to generate hashes: %s", err) slog.Error("Failed to generate hashes", "err", err)
return return 1
} }
idxToRemoveFromCache := []int{} idxToRemoveFromCache := []int{}
@@ -125,20 +131,21 @@ func Revalidate(config Config) {
results, err := bulkCheckAssets(idsToCheck, config.BaseURL, immichClient) results, err := bulkCheckAssets(idsToCheck, config.BaseURL, immichClient)
if err != nil { 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 { for _, result := range results {
i, err := strconv.Atoi(result.Id) i, err := strconv.Atoi(result.Id)
if err != nil { if err != nil {
log.Fatalf("What ?: %s", err) slog.Error("What ? This should never happen", "err", err)
return return 1
} }
asset := localState.Assets[i] asset := localState.Assets[i]
if asset.ImmichID != result.AssetId { 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 localState.Assets[i].ImmichID = result.AssetId
updated += 1 updated += 1
} }
@@ -159,13 +166,15 @@ func Revalidate(config Config) {
saveLocalState(config.CacheFile, *localState) saveLocalState(config.CacheFile, *localState)
log.Printf("Revalidated %d assets", len(results)) slog.Info("Revalidated assets", "count", len(localState.Assets))
log.Printf("Assets present on Immich: %d", rejected) slog.Info("Assets present on immich", "count", rejected)
log.Printf("Wrong metadata on cache: %d", updated) slog.Info("Wrong metadata on cache", "count", updated)
log.Printf("Missing on Immich: %d", missingFromImmich) slog.Info("Missing on Immich", "count", missingFromImmich)
log.Printf("Missing on local storage: %d", missingFile) slog.Info("Missing on local storage", "count", missingFile)
if (updated + missingFromImmich + missingFromImmich) > 0 { 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
} }