From 6da0ebb0634871879d0987288b84d64c65df378a Mon Sep 17 00:00:00 2001 From: bel Date: Thu, 5 Jun 2025 20:13:56 -0600 Subject: [PATCH] traversing --- main.go | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 99 insertions(+), 10 deletions(-) diff --git a/main.go b/main.go index d77b212..9788284 100644 --- a/main.go +++ b/main.go @@ -19,16 +19,35 @@ func main() { jellyFrom, err := NewJelly(ctx, "squeaky2x3", "aFJKcZ4fUuN9FZ", "5c1de748f61145a085f272aea527c759", "213abf9acbe84d9fb9c3b06bbe1eec3b") if err != nil { - panic(err) + log.Fatal(err) } log.Printf("from %+v", jellyFrom) jellyTo, err := NewJelly(ctx, "belly", "qBentOcpHMUjhD", "497b212a22e34b54be091055edbe264d", "b71b931108ba4323b75b675871a7738f") if err != nil { - panic(err) + log.Fatal(err) } log.Printf("to %+v", jellyTo) + folders, err := jellyFrom.VirtualFolders(ctx) + if err != nil { + log.Fatal(err) + } + for len(folders) > 0 { + folder := folders[0] + folders = folders[1:] + + items, err := jellyFrom.ListFolder(ctx, folder) + if err != nil { + log.Fatal(err) + } + + for _, item := range items { + b, _ := json.MarshalIndent(item, "", " ") + log.Fatalf("%s", b) + } + } + log.Fatalf("not impl: %+v => %+v", jellyFrom, jellyTo) } @@ -42,7 +61,7 @@ func NewJelly(ctx context.Context, u, p, apitoken, optAccessToken string) (Jelly jelly := Jelly{u: u, apitoken: apitoken, accesstoken: optAccessToken} if optAccessToken != "" { - } else if accessToken, err := jelly.login(ctx, p); err != nil { + } else if accessToken, err := jelly.Login(ctx, p); err != nil { return Jelly{}, err } else { jelly.accesstoken = accessToken @@ -51,7 +70,58 @@ func NewJelly(ctx context.Context, u, p, apitoken, optAccessToken string) (Jelly return jelly, nil } -func (jelly Jelly) login(ctx context.Context, p string) (string, error) { +type FolderItem struct { + Name string + Id string + IsFolder bool + Parent Folder +} + +func (jelly Jelly) ListFolder(ctx context.Context, folder Folder) ([]FolderItem, error) { + resp, err := jelly.do(ctx, http.MethodGet, fmt.Sprintf("/Items?parentId=%s", folder.Id), nil) + if err != nil { + return nil, err + } + a := resp.(map[string]any)["Items"].([]any) + result := make([]FolderItem, len(a)) + for i := range a { + m := a[i].(map[string]any) + result[i] = FolderItem{ + Name: m["Name"].(string), + Id: m["Id"].(string), + IsFolder: m["IsFolder"].(bool), + Parent: folder, + } + } + return result, nil +} + +// get+set item via /UserItems/{itemId}/UserData + +type Folder struct { + Name string + Id string +} + +func (jelly Jelly) VirtualFolders(ctx context.Context) ([]Folder, 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)) + for i, v := range a { + m := v.(map[string]any) + result[i] = Folder{ + Id: m["ItemId"].(string), + Name: m["Name"].(string), + } + } + return result, nil +} + +func (jelly Jelly) Login(ctx context.Context, p string) (string, error) { resp, err := jelly.post(ctx, "/Users/AuthenticateByName", map[string]string{ "Username": jelly.u, "Pw": p, @@ -60,14 +130,33 @@ func (jelly Jelly) login(ctx context.Context, p string) (string, error) { return "", err } - var AccessToken struct { - AccessToken string + m, _ := resp.(map[string]any) + if m == nil { + return "", fmt.Errorf("no map response") } - err = json.NewDecoder(resp.Body).Decode(&AccessToken) - return AccessToken.AccessToken, err + token, _ := m["AccessToken"] + if token == nil { + return "", fmt.Errorf("no .AccessToken response") + } + s, _ := token.(string) + return s, nil } -func (jelly Jelly) post(ctx context.Context, path string, body any, headers ...string) (*http.Response, error) { +func (jelly Jelly) post(ctx context.Context, path string, body any, headers ...string) (any, error) { + return jelly.do(ctx, http.MethodPost, path, body, headers...) +} + +func (jelly Jelly) do(ctx context.Context, method, path string, body any, headers ...string) (any, error) { + resp, err := jelly._do(ctx, method, path, body, headers...) + if err != nil { + return nil, err + } + var result any + err = json.NewDecoder(resp.Body).Decode(&result) + return result, err +} + +func (jelly Jelly) _do(ctx context.Context, method, path string, body any, headers ...string) (*http.Response, error) { t := http.Transport{ DisableKeepAlives: true, } @@ -77,7 +166,7 @@ func (jelly Jelly) post(ctx context.Context, path string, body any, headers ...s } b, _ := json.Marshal(body) - req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("https://jellyfin.home.blapointe.com%s", path), bytes.NewReader(b)) + req, err := http.NewRequest(method, fmt.Sprintf("https://jellyfin.home.blapointe.com%s", path), bytes.NewReader(b)) if err != nil { return nil, err }