Compare commits
4 Commits
c0eae078fa
...
06996a35d5
| Author | SHA1 | Date | |
|---|---|---|---|
|
06996a35d5
|
|||
|
510daabd8a
|
|||
|
004ffe70ea
|
|||
|
2ae7caf4eb
|
@@ -34,6 +34,9 @@ func main() {
|
|||||||
log.Fatal("Can not find steam userdata dir. Please set with --steam-userdata-dir")
|
log.Fatal("Can not find steam userdata dir. Please set with --steam-userdata-dir")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Disable timestamp in log
|
||||||
|
log.SetFlags(0)
|
||||||
|
|
||||||
steamimmich.Run(steamimmich.Config{
|
steamimmich.Run(steamimmich.Config{
|
||||||
APIKey: args.APIKey,
|
APIKey: args.APIKey,
|
||||||
BaseURL: args.BaseURL,
|
BaseURL: args.BaseURL,
|
||||||
|
|||||||
@@ -40,11 +40,9 @@ func uploadToImmich(filePath, appID, baseURL, apiKey, deviceID string) (*uploadR
|
|||||||
return nil, fmt.Errorf("stat file: %w", err)
|
return nil, fmt.Errorf("stat file: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create multipart form
|
|
||||||
var body bytes.Buffer
|
var body bytes.Buffer
|
||||||
writer := multipart.NewWriter(&body)
|
writer := multipart.NewWriter(&body)
|
||||||
|
|
||||||
// Attach the image file
|
|
||||||
part, err := writer.CreateFormFile("assetData", filepath.Base(filePath))
|
part, err := writer.CreateFormFile("assetData", filepath.Base(filePath))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("create form file: %w", err)
|
return nil, fmt.Errorf("create form file: %w", err)
|
||||||
@@ -54,9 +52,8 @@ func uploadToImmich(filePath, appID, baseURL, apiKey, deviceID string) (*uploadR
|
|||||||
}
|
}
|
||||||
|
|
||||||
modTime := fileInfo.ModTime().UTC().Format(time.RFC3339)
|
modTime := fileInfo.ModTime().UTC().Format(time.RFC3339)
|
||||||
createTime := modTime // If you don't have a separate created time
|
createTime := modTime
|
||||||
|
|
||||||
// Required metadata fields
|
|
||||||
writer.WriteField("deviceAssetId", fmt.Sprintf("%s-%s", appID, filepath.Base(filePath)))
|
writer.WriteField("deviceAssetId", fmt.Sprintf("%s-%s", appID, filepath.Base(filePath)))
|
||||||
writer.WriteField("deviceId", deviceID)
|
writer.WriteField("deviceId", deviceID)
|
||||||
writer.WriteField("fileCreatedAt", createTime)
|
writer.WriteField("fileCreatedAt", createTime)
|
||||||
@@ -65,7 +62,6 @@ func uploadToImmich(filePath, appID, baseURL, apiKey, deviceID string) (*uploadR
|
|||||||
|
|
||||||
writer.Close()
|
writer.Close()
|
||||||
|
|
||||||
// Build request
|
|
||||||
req, err := http.NewRequest("POST", fmt.Sprintf("%s/api/assets", baseURL), &body)
|
req, err := http.NewRequest("POST", fmt.Sprintf("%s/api/assets", baseURL), &body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("create request: %w", err)
|
return nil, fmt.Errorf("create request: %w", err)
|
||||||
@@ -88,7 +84,7 @@ func uploadToImmich(filePath, appID, baseURL, apiKey, deviceID string) (*uploadR
|
|||||||
|
|
||||||
var result uploadResponse
|
var result uploadResponse
|
||||||
if err := json.Unmarshal(respBody, &result); err != nil {
|
if err := json.Unmarshal(respBody, &result); err != nil {
|
||||||
return nil, fmt.Errorf("Failed to parse immich response: %s", err)
|
return nil, fmt.Errorf("parse immich response: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &result, nil
|
return &result, nil
|
||||||
@@ -139,13 +135,13 @@ func addAssetsToAlbum(assets []string, album, baseURL, apiKey string) error {
|
|||||||
defer res.Body.Close()
|
defer res.Body.Close()
|
||||||
|
|
||||||
respBody, _ := io.ReadAll(res.Body)
|
respBody, _ := io.ReadAll(res.Body)
|
||||||
if res.StatusCode >= 300 {
|
if res.StatusCode != 200 {
|
||||||
return fmt.Errorf("Failed to add assets to album (%d): %s", res.StatusCode, string(respBody))
|
return fmt.Errorf("add assets to album (%d): %s", res.StatusCode, string(respBody))
|
||||||
}
|
}
|
||||||
|
|
||||||
var result []bulkIdResponseDto
|
var result []bulkIdResponseDto
|
||||||
if err := json.Unmarshal(respBody, &result); err != nil {
|
if err := json.Unmarshal(respBody, &result); err != nil {
|
||||||
return fmt.Errorf("Failed to parse immich response: %s", err)
|
return fmt.Errorf("parse immich response: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -16,40 +17,45 @@ type SteamAPIResponse struct {
|
|||||||
} `json:"data"`
|
} `json:"data"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func getGameName(appid string, cache map[string]string) string {
|
func getGameName(appID string, cache map[string]string) string {
|
||||||
if name, ok := cache[appid]; ok {
|
if name, ok := cache[appID]; ok {
|
||||||
return name
|
return name
|
||||||
}
|
}
|
||||||
|
|
||||||
url := fmt.Sprintf("https://store.steampowered.com/api/appdetails?appids=%s", appid)
|
name, err := fetchGameName(appID)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("failed to fetch name for AppID: %s. Setting to Unknown", appID)
|
||||||
|
cache[appID] = UNKOWN_GAME_GAME
|
||||||
|
return UNKOWN_GAME_GAME
|
||||||
|
}
|
||||||
|
|
||||||
|
cache[appID] = name
|
||||||
|
return name
|
||||||
|
}
|
||||||
|
|
||||||
|
func fetchGameName(appID string) (string, error) {
|
||||||
|
url := fmt.Sprintf("https://store.steampowered.com/api/appdetails?appids=%s", appID)
|
||||||
resp, err := http.Get(url)
|
resp, err := http.Get(url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Error fetching app name for %s: %v\n", appid, err)
|
return "", fmt.Errorf("fetching game name for %s: %s", appID, err)
|
||||||
cache[appid] = UNKOWN_GAME_GAME
|
|
||||||
return cache[appid]
|
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
body, err := io.ReadAll(resp.Body)
|
body, err := io.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Error reading response for %s: %v\n", appid, err)
|
return "", fmt.Errorf("reading response for %s: %s", appID, err)
|
||||||
cache[appid] = UNKOWN_GAME_GAME
|
|
||||||
return cache[appid]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var result map[string]SteamAPIResponse
|
var result map[string]SteamAPIResponse
|
||||||
if err := json.Unmarshal(body, &result); err != nil {
|
if err := json.Unmarshal(body, &result); err != nil {
|
||||||
fmt.Printf("Error parsing JSON for %s: %v\n", appid, err)
|
return "", fmt.Errorf("parsing response for %s: %s", appID, err)
|
||||||
cache[appid] = UNKOWN_GAME_GAME
|
|
||||||
return cache[appid]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if entry, ok := result[appid]; ok && entry.Success {
|
entry, ok := result[appID]
|
||||||
name := entry.Data.Name
|
|
||||||
cache[appid] = name
|
if !ok || !entry.Success {
|
||||||
return name
|
return "", fmt.Errorf("game not found in response for %s", appID)
|
||||||
}
|
}
|
||||||
|
|
||||||
cache[appid] = UNKOWN_GAME_GAME
|
return entry.Data.Name, nil
|
||||||
return cache[appid]
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package steamimmich
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"log"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
@@ -10,18 +10,19 @@ type Config struct {
|
|||||||
APIKey string
|
APIKey string
|
||||||
UserdataDir string
|
UserdataDir string
|
||||||
DeiveID string
|
DeiveID string
|
||||||
|
Album string
|
||||||
}
|
}
|
||||||
|
|
||||||
func Run(config Config) {
|
func Run(config Config) {
|
||||||
screenshotFiles, err := listScreenshots(config.UserdataDir)
|
screenshotFiles, err := listScreenshots(config.UserdataDir)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Failed to scan for screenshots")
|
log.Fatalf("Failed to scan for screenshots: %s", err)
|
||||||
os.Exit(1)
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(screenshotFiles) == 0 {
|
if len(screenshotFiles) == 0 {
|
||||||
fmt.Println("No screenshots found.")
|
log.Println("No screenshots found.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,38 +30,37 @@ func Run(config Config) {
|
|||||||
|
|
||||||
for appid, files := range screenshotFiles {
|
for appid, files := range screenshotFiles {
|
||||||
gameName := getGameName(appid, gameNameCache)
|
gameName := getGameName(appid, gameNameCache)
|
||||||
fmt.Printf("AppID: %s → %s\n", appid, gameName)
|
|
||||||
|
|
||||||
assetsInGame := make([]string, 0)
|
assetsInGame := make([]string, 0)
|
||||||
|
|
||||||
for _, f := range files {
|
for _, filepath := range files {
|
||||||
fmt.Printf(" %s\n", f)
|
res, err := uploadToImmich(filepath, appid, config.BaseURL, config.APIKey, config.DeiveID)
|
||||||
|
|
||||||
res, err := uploadToImmich(f, appid, config.BaseURL, config.APIKey, config.DeiveID)
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Failed to upload to immich: %s", err)
|
log.Fatalf("Failed to upload to immich: %s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("Done. ID: %s", res.ID)
|
log.Printf("Assest uploaded: %s (%s) %s with ID: %s", gameName, appid, filepath, res.ID)
|
||||||
|
|
||||||
assetsInGame = append(assetsInGame, res.ID)
|
assetsInGame = append(assetsInGame, res.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
err := setAssetMetadata(assetsInGame, fmt.Sprintf("Game: %s", gameName), config.BaseURL, config.APIKey)
|
err := setAssetMetadata(assetsInGame, fmt.Sprintf("Game: %s", gameName), config.BaseURL, config.APIKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Stopped: %s", err)
|
log.Fatalf("Failed to set asset metadata: %s", err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.Album != "" {
|
if config.Album != "" {
|
||||||
err = addAssetsToAlbum(assetsInGame, config.Album, config.BaseURL, config.APIKey)
|
err = addAssetsToAlbum(assetsInGame, config.Album, config.BaseURL, config.APIKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Stopped: %s", err)
|
log.Fatalf("Failed to add assets to album: %s", err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println()
|
log.Printf("Added %d assets to album %s", len(assetsInGame), config.Album)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Println("Finished uploading screenshots")
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user