diff --git a/main.go b/main.go index 9788284..0ac464e 100644 --- a/main.go +++ b/main.go @@ -8,6 +8,7 @@ import ( "io" "log" "net/http" + "os" "os/signal" "syscall" "time" @@ -43,8 +44,16 @@ func main() { } for _, item := range items { - b, _ := json.MarshalIndent(item, "", " ") - log.Fatalf("%s", b) + if item.IsFolder { + folders = append([]FolderItem{item}, folders...) + } else if userData, err := jellyFrom.UserDataOf(ctx, item); err != nil { + log.Fatal(err) + } else if userData.PlayCount == 0 && userData.PlaybackPositionTicks == 0 { + } else if userDataB, err := jellyTo.UserDataOf(ctx, item); err != nil { + log.Fatal(err) + } else if err := jellyTo.SetUserData(ctx, userData.Plus(userDataB)); err != nil { + log.Fatalf("failed to set user data of %+v: %v", userData, err) + } } } @@ -74,10 +83,10 @@ type FolderItem struct { Name string Id string IsFolder bool - Parent Folder + Parent *FolderItem } -func (jelly Jelly) ListFolder(ctx context.Context, folder Folder) ([]FolderItem, error) { +func (jelly Jelly) ListFolder(ctx context.Context, folder FolderItem) ([]FolderItem, error) { resp, err := jelly.do(ctx, http.MethodGet, fmt.Sprintf("/Items?parentId=%s", folder.Id), nil) if err != nil { return nil, err @@ -90,7 +99,7 @@ func (jelly Jelly) ListFolder(ctx context.Context, folder Folder) ([]FolderItem, Name: m["Name"].(string), Id: m["Id"].(string), IsFolder: m["IsFolder"].(bool), - Parent: folder, + Parent: &folder, } } return result, nil @@ -98,24 +107,72 @@ func (jelly Jelly) ListFolder(ctx context.Context, folder Folder) ([]FolderItem, // get+set item via /UserItems/{itemId}/UserData -type Folder struct { - Name string - Id string +type UserData struct { + IsFavorite bool + ItemId string + Key string + PlayCount float64 + PlaybackPositionTicks float64 + Played bool + FolderItem FolderItem `json:",omitempty"` } -func (jelly Jelly) VirtualFolders(ctx context.Context) ([]Folder, error) { +func (this UserData) Plus(that UserData) UserData { + this.IsFavorite = this.IsFavorite || that.IsFavorite + //this.ItemId + //this.Key + if this.PlayCount < that.PlayCount { + this.PlayCount = that.PlayCount + } + if this.PlaybackPositionTicks < that.PlaybackPositionTicks { + this.PlaybackPositionTicks = that.PlaybackPositionTicks + } + this.Played = this.Played || that.Played + return this +} + +func (jelly Jelly) SetUserData(ctx context.Context, userData UserData) error { + fi := userData.FolderItem + if os.Getenv("DRY_RUN") != "false" { + b, _ := json.Marshal(userData) + log.Printf("SET %s", b) + return nil + } + userData.FolderItem = FolderItem{} + _, err := jelly.do(ctx, http.MethodPost, "/UserItems/"+fi.Id+"/UserData", userData) + return err +} + +func (jelly Jelly) UserDataOf(ctx context.Context, folderItem FolderItem) (UserData, error) { + resp, err := jelly.do(ctx, http.MethodGet, "/UserItems/"+folderItem.Id+"/UserData", nil) + if err != nil { + return UserData{}, err + } + return UserData{ + IsFavorite: resp.(map[string]any)["IsFavorite"].(bool), + ItemId: resp.(map[string]any)["ItemId"].(string), + Key: resp.(map[string]any)["Key"].(string), + PlayCount: resp.(map[string]any)["PlayCount"].(float64), + PlaybackPositionTicks: resp.(map[string]any)["PlaybackPositionTicks"].(float64), + Played: resp.(map[string]any)["Played"].(bool), + FolderItem: folderItem, + }, nil +} + +func (jelly Jelly) VirtualFolders(ctx context.Context) ([]FolderItem, error) { resp, err := jelly.do(ctx, http.MethodGet, "/Library/VirtualFolders", nil) if err != nil { return nil, err } a := resp.([]any) - result := make([]Folder, len(a)) + result := make([]FolderItem, len(a)) for i, v := range a { m := v.(map[string]any) - result[i] = Folder{ - Id: m["ItemId"].(string), - Name: m["Name"].(string), + result[i] = FolderItem{ + Id: m["ItemId"].(string), + Name: m["Name"].(string), + IsFolder: true, } } return result, nil