main
bel 2025-06-05 21:06:24 -06:00
parent 6da0ebb063
commit 06fefaca60
1 changed files with 70 additions and 13 deletions

83
main.go
View File

@ -8,6 +8,7 @@ import (
"io" "io"
"log" "log"
"net/http" "net/http"
"os"
"os/signal" "os/signal"
"syscall" "syscall"
"time" "time"
@ -43,8 +44,16 @@ func main() {
} }
for _, item := range items { for _, item := range items {
b, _ := json.MarshalIndent(item, "", " ") if item.IsFolder {
log.Fatalf("%s", b) 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 Name string
Id string Id string
IsFolder bool 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) resp, err := jelly.do(ctx, http.MethodGet, fmt.Sprintf("/Items?parentId=%s", folder.Id), nil)
if err != nil { if err != nil {
return nil, err return nil, err
@ -90,7 +99,7 @@ func (jelly Jelly) ListFolder(ctx context.Context, folder Folder) ([]FolderItem,
Name: m["Name"].(string), Name: m["Name"].(string),
Id: m["Id"].(string), Id: m["Id"].(string),
IsFolder: m["IsFolder"].(bool), IsFolder: m["IsFolder"].(bool),
Parent: folder, Parent: &folder,
} }
} }
return result, nil return result, nil
@ -98,24 +107,72 @@ func (jelly Jelly) ListFolder(ctx context.Context, folder Folder) ([]FolderItem,
// get+set item via /UserItems/{itemId}/UserData // get+set item via /UserItems/{itemId}/UserData
type Folder struct { type UserData struct {
Name string IsFavorite bool
Id string 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) resp, err := jelly.do(ctx, http.MethodGet, "/Library/VirtualFolders", nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
a := resp.([]any) a := resp.([]any)
result := make([]Folder, len(a)) result := make([]FolderItem, len(a))
for i, v := range a { for i, v := range a {
m := v.(map[string]any) m := v.(map[string]any)
result[i] = Folder{ result[i] = FolderItem{
Id: m["ItemId"].(string), Id: m["ItemId"].(string),
Name: m["Name"].(string), Name: m["Name"].(string),
IsFolder: true,
} }
} }
return result, nil return result, nil