commit 3035f1740e0c871f69032fd48aa8427079e225d8 from: Oliver Lowe date: Tue Oct 24 01:33:18 2023 UTC lemmy: start decoding users in API responses This commit adds tests too as it's starting to get a bit trickier. commit - 99ed05e33dafeb84968e397f636c0090d85f691d commit + 3035f1740e0c871f69032fd48aa8427079e225d8 blob - f5681458c0573b29ade3aa333a2202deb850ffb0 blob + c8087b3a191946d99eda401cd408e29da0810beb --- client.go +++ client.go @@ -180,17 +180,8 @@ func (c *Client) LookupPost(id int) (Post, error) { } else if resp.StatusCode != http.StatusOK { return Post{}, fmt.Errorf("remote status %s: %w", resp.Status, decodeError(resp.Body)) } - - type jresponse struct { - PostView struct { - Post Post - } `json:"post_view"` - } - var jresp jresponse - if err := json.NewDecoder(resp.Body).Decode(&jresp); err != nil { - return Post{}, fmt.Errorf("decode post: %w", err) - } - return jresp.PostView.Post, nil + post, _, _, err := decodePostResponse(resp.Body) + return post, err } func (c *Client) Comments(post int, mode ListMode) ([]Comment, error) { blob - /dev/null blob + 023adbc6b2985e9e542b3452e9af34072dc71850 (mode 644) --- /dev/null +++ decode.go @@ -0,0 +1,38 @@ +package lemmy + +import ( + "encoding/json" + "fmt" + "io" +) + +func decodePosts(r io.Reader) ([]Post, error) { + var jresponse struct { + Posts []struct { + Post Post + } + } + if err := json.NewDecoder(r).Decode(&jresponse); err != nil { + return nil, fmt.Errorf("decode posts response: %w", err) + } + var posts []Post + for _, post := range jresponse.Posts { + posts = append(posts, post.Post) + } + return posts, nil +} + +func decodePostResponse(r io.Reader) (Post, Person, Community, error) { + type jresponse struct { + PostView struct { + Post Post + Creator Person + Community Community + } `json:"post_view"` + } + var jresp jresponse + if err := json.NewDecoder(r).Decode(&jresp); err != nil { + return Post{}, Person{}, Community{}, fmt.Errorf("decode post: %w", err) + } + return jresp.PostView.Post, jresp.PostView.Creator, jresp.PostView.Community, nil +} blob - /dev/null blob + 5f624e673cafb2eeb02f2b9476a9d2ce5e86231d (mode 644) --- /dev/null +++ decode_test.go @@ -0,0 +1,25 @@ +package lemmy + +import ( + "os" + "testing" +) + +func TestPost(t *testing.T) { + f, err := os.Open("testdata/post.json") + if err != nil { + t.Fatal(err) + } + defer f.Close() + post, creator, _, err := decodePostResponse(f) + if err != nil { + t.Fatal(err) + } + t.Log(post.ID) + if creator.ID != 2 { + t.Errorf("check creator ID: want %d, got %d", 2, creator.ID) + } + if creator.String() != "TheAnonymouseJoker@lemmy.ml" { + t.Errorf("creator username: want %s, got %s", "TheAnonymouseJoker@lemmy.ml", creator.String()) + } +} blob - 5576477559ec98812d2c2a8539b45bf133252331 blob + f3ed6a3ebdfe703816ef494d354abc7a233d715a --- lemmy.go +++ lemmy.go @@ -95,7 +95,18 @@ func parseCommentPath(s string) ([]int, error) { return refs, nil } -type Creator struct { - ID int - Username string `json:"name"` +type Person struct { + ID int `json:"id"` + Name string `json:"name"` + ActorID string `json:"actor_id"` + Local bool `json:"local"` } + +func (p Person) String() string { + if p.Local { + return p.Name + } + noscheme := strings.TrimPrefix(p.ActorID, "https://") + instance, _, _ := strings.Cut(noscheme, "/") + return fmt.Sprintf("%s@%s", p.Name, instance) +} blob - /dev/null blob + 49517a363daef5b71884f9a0cf7f88346e8408d4 (mode 644) --- /dev/null +++ testdata/post.json @@ -0,0 +1,287 @@ +{ + "post_view": { + "post": { + "id": 4986856, + "name": "Please DM before self promoting a blog or website or product, otherwise it is subject to removal. Repeated or serious offenders may face the music.", + "creator_id": 2, + "community_id": 65, + "removed": false, + "locked": true, + "published": "2023-10-02T12:27:13.123925", + "deleted": false, + "nsfw": false, + "ap_id": "https://lemmy.ml/post/5883569", + "local": false, + "language_id": 37, + "featured_community": true, + "featured_local": false + }, + "creator": { + "id": 2, + "name": "TheAnonymouseJoker", + "avatar": "https://lemmy.ml/pictrs/image/8fd70139-4603-4fb7-8f16-d78f43790c1f.jpeg", + "banned": false, + "published": "2020-06-07T12:34:31.646688", + "updated": "2022-06-17T08:27:41.447164", + "actor_id": "https://lemmy.ml/u/TheAnonymouseJoker", + "local": false, + "deleted": false, + "admin": false, + "bot_account": false, + "instance_id": 2 + }, + "community": { + "id": 65, + "name": "privacy", + "title": "Privacy", + "description": "# A place to discuss privacy and freedom in the digital world.\n\nPrivacy has become a very important issue in modern society, with companies and governments constantly abusing their power, more and more people are waking up to the importance of digital privacy. \n\nIn this community everyone is welcome to post links and discuss topics related to privacy.\n\n### Some Rules\n\n \n - Posting a link to a website containing tracking isn't great, if contents of the website are behind a paywall maybe copy them into the post\n - Don't promote proprietary software\n - Try to keep things on topic\n - If you have a question, please try searching for previous discussions, maybe it has already been answered\n - Reposts are fine, but should have at least a couple of weeks in between so that the post can reach a new audience\n - Be nice :)\n\n### Related communities\n\n- [Lemmy.ml libre_culture](https://lemmy.ml/c/libre_culture)\n- [Lemmy.ml privatelife](https://lemmy.ml/c/privatelife)\n- [Lemmy.ml DeGoogle](https://lemmy.ml/c/degoogle)\n- [Lemmy.ca privacy](https://lemmy.ca/c/privacy)\n\n### Chat rooms\n\n- [Matrix/Element]Dead\n\n- [Discord](https://discord.gg/8xfrVjvngh)\n\nmuch thanks to @gary_host_laptop for the logo design :)", + "removed": false, + "published": "2019-11-15T23:50:53.712299", + "updated": "2023-07-21T19:06:26.177465", + "deleted": false, + "nsfw": false, + "actor_id": "https://lemmy.ml/c/privacy", + "local": false, + "icon": "https://lemmy.ml/pictrs/image/h1ChnLuBHr.png", + "banner": "https://lemmy.ml/pictrs/image/DBjcqOW9ds.png", + "hidden": false, + "posting_restricted_to_mods": false, + "instance_id": 2 + }, + "creator_banned_from_community": false, + "counts": { + "id": 609626, + "post_id": 4986856, + "comments": 0, + "score": 64, + "upvotes": 73, + "downvotes": 9, + "published": "2023-10-02T12:27:13.123925", + "newest_comment_time_necro": "2023-10-02T12:27:13.123925", + "newest_comment_time": "2023-10-02T12:27:13.123925", + "featured_community": true, + "featured_local": false, + "hot_rank": 0, + "hot_rank_active": 0, + "community_id": 65, + "creator_id": 2 + }, + "subscribed": "NotSubscribed", + "saved": false, + "read": false, + "creator_blocked": false, + "unread_comments": 0 + }, + "community_view": { + "community": { + "id": 65, + "name": "privacy", + "title": "Privacy", + "description": "# A place to discuss privacy and freedom in the digital world.\n\nPrivacy has become a very important issue in modern society, with companies and governments constantly abusing their power, more and more people are waking up to the importance of digital privacy. \n\nIn this community everyone is welcome to post links and discuss topics related to privacy.\n\n### Some Rules\n\n \n - Posting a link to a website containing tracking isn't great, if contents of the website are behind a paywall maybe copy them into the post\n - Don't promote proprietary software\n - Try to keep things on topic\n - If you have a question, please try searching for previous discussions, maybe it has already been answered\n - Reposts are fine, but should have at least a couple of weeks in between so that the post can reach a new audience\n - Be nice :)\n\n### Related communities\n\n- [Lemmy.ml libre_culture](https://lemmy.ml/c/libre_culture)\n- [Lemmy.ml privatelife](https://lemmy.ml/c/privatelife)\n- [Lemmy.ml DeGoogle](https://lemmy.ml/c/degoogle)\n- [Lemmy.ca privacy](https://lemmy.ca/c/privacy)\n\n### Chat rooms\n\n- [Matrix/Element]Dead\n\n- [Discord](https://discord.gg/8xfrVjvngh)\n\nmuch thanks to @gary_host_laptop for the logo design :)", + "removed": false, + "published": "2019-11-15T23:50:53.712299", + "updated": "2023-07-21T19:06:26.177465", + "deleted": false, + "nsfw": false, + "actor_id": "https://lemmy.ml/c/privacy", + "local": false, + "icon": "https://lemmy.ml/pictrs/image/h1ChnLuBHr.png", + "banner": "https://lemmy.ml/pictrs/image/DBjcqOW9ds.png", + "hidden": false, + "posting_restricted_to_mods": false, + "instance_id": 2 + }, + "subscribed": "NotSubscribed", + "blocked": false, + "counts": { + "id": 46, + "community_id": 65, + "subscribers": 277, + "posts": 1149, + "comments": 26900, + "published": "2019-11-15T23:50:53.712299", + "users_active_day": 147, + "users_active_week": 671, + "users_active_month": 2450, + "users_active_half_year": 7408, + "hot_rank": 0 + } + }, + "moderators": [ + { + "community": { + "id": 65, + "name": "privacy", + "title": "Privacy", + "description": "# A place to discuss privacy and freedom in the digital world.\n\nPrivacy has become a very important issue in modern society, with companies and governments constantly abusing their power, more and more people are waking up to the importance of digital privacy. \n\nIn this community everyone is welcome to post links and discuss topics related to privacy.\n\n### Some Rules\n\n \n - Posting a link to a website containing tracking isn't great, if contents of the website are behind a paywall maybe copy them into the post\n - Don't promote proprietary software\n - Try to keep things on topic\n - If you have a question, please try searching for previous discussions, maybe it has already been answered\n - Reposts are fine, but should have at least a couple of weeks in between so that the post can reach a new audience\n - Be nice :)\n\n### Related communities\n\n- [Lemmy.ml libre_culture](https://lemmy.ml/c/libre_culture)\n- [Lemmy.ml privatelife](https://lemmy.ml/c/privatelife)\n- [Lemmy.ml DeGoogle](https://lemmy.ml/c/degoogle)\n- [Lemmy.ca privacy](https://lemmy.ca/c/privacy)\n\n### Chat rooms\n\n- [Matrix/Element]Dead\n\n- [Discord](https://discord.gg/8xfrVjvngh)\n\nmuch thanks to @gary_host_laptop for the logo design :)", + "removed": false, + "published": "2019-11-15T23:50:53.712299", + "updated": "2023-07-21T19:06:26.177465", + "deleted": false, + "nsfw": false, + "actor_id": "https://lemmy.ml/c/privacy", + "local": false, + "icon": "https://lemmy.ml/pictrs/image/h1ChnLuBHr.png", + "banner": "https://lemmy.ml/pictrs/image/DBjcqOW9ds.png", + "hidden": false, + "posting_restricted_to_mods": false, + "instance_id": 2 + }, + "moderator": { + "id": 83, + "name": "k_o_t", + "avatar": "https://lemmy.ml/pictrs/image/992c7275-dd2a-4fa3-aace-6819e72995fb.png", + "banned": false, + "published": "2019-12-29T11:51:05.628232", + "updated": "2022-01-13T15:18:29.470615", + "actor_id": "https://lemmy.ml/u/k_o_t", + "local": false, + "deleted": false, + "matrix_user_id": "@brokoli:matrix.org", + "admin": false, + "bot_account": false, + "instance_id": 2 + } + }, + { + "community": { + "id": 65, + "name": "privacy", + "title": "Privacy", + "description": "# A place to discuss privacy and freedom in the digital world.\n\nPrivacy has become a very important issue in modern society, with companies and governments constantly abusing their power, more and more people are waking up to the importance of digital privacy. \n\nIn this community everyone is welcome to post links and discuss topics related to privacy.\n\n### Some Rules\n\n \n - Posting a link to a website containing tracking isn't great, if contents of the website are behind a paywall maybe copy them into the post\n - Don't promote proprietary software\n - Try to keep things on topic\n - If you have a question, please try searching for previous discussions, maybe it has already been answered\n - Reposts are fine, but should have at least a couple of weeks in between so that the post can reach a new audience\n - Be nice :)\n\n### Related communities\n\n- [Lemmy.ml libre_culture](https://lemmy.ml/c/libre_culture)\n- [Lemmy.ml privatelife](https://lemmy.ml/c/privatelife)\n- [Lemmy.ml DeGoogle](https://lemmy.ml/c/degoogle)\n- [Lemmy.ca privacy](https://lemmy.ca/c/privacy)\n\n### Chat rooms\n\n- [Matrix/Element]Dead\n\n- [Discord](https://discord.gg/8xfrVjvngh)\n\nmuch thanks to @gary_host_laptop for the logo design :)", + "removed": false, + "published": "2019-11-15T23:50:53.712299", + "updated": "2023-07-21T19:06:26.177465", + "deleted": false, + "nsfw": false, + "actor_id": "https://lemmy.ml/c/privacy", + "local": false, + "icon": "https://lemmy.ml/pictrs/image/h1ChnLuBHr.png", + "banner": "https://lemmy.ml/pictrs/image/DBjcqOW9ds.png", + "hidden": false, + "posting_restricted_to_mods": false, + "instance_id": 2 + }, + "moderator": { + "id": 805, + "name": "tmpod", + "display_name": "Tmpod", + "avatar": "https://lemmy.pt/pictrs/image/gIPQUt3mxw.png", + "banned": false, + "published": "2021-09-10T19:37:20.367073", + "updated": "2022-08-04T16:23:06.747838", + "actor_id": "https://lemmy.pt/u/tmpod", + "bio": "Estudante de Engenharia Inform\u00e1tica apaixonado pela \u00e1rea; algures em Portugal.\n\nAdministrador da inst\u00e2ncia lemmy.pt.\n\n---\n\nComputer Science student, passionate about the field; somewhere in Portugal.\n\nlemmy.pt instance administrator.\n\n---\n\nhttps://tmpod.dev", + "local": false, + "banner": "https://lemmy.pt/pictrs/image/iLIlqIIuaW.jpg", + "deleted": false, + "matrix_user_id": "@tmpod:matrix.org", + "admin": false, + "bot_account": false, + "instance_id": 69 + } + }, + { + "community": { + "id": 65, + "name": "privacy", + "title": "Privacy", + "description": "# A place to discuss privacy and freedom in the digital world.\n\nPrivacy has become a very important issue in modern society, with companies and governments constantly abusing their power, more and more people are waking up to the importance of digital privacy. \n\nIn this community everyone is welcome to post links and discuss topics related to privacy.\n\n### Some Rules\n\n \n - Posting a link to a website containing tracking isn't great, if contents of the website are behind a paywall maybe copy them into the post\n - Don't promote proprietary software\n - Try to keep things on topic\n - If you have a question, please try searching for previous discussions, maybe it has already been answered\n - Reposts are fine, but should have at least a couple of weeks in between so that the post can reach a new audience\n - Be nice :)\n\n### Related communities\n\n- [Lemmy.ml libre_culture](https://lemmy.ml/c/libre_culture)\n- [Lemmy.ml privatelife](https://lemmy.ml/c/privatelife)\n- [Lemmy.ml DeGoogle](https://lemmy.ml/c/degoogle)\n- [Lemmy.ca privacy](https://lemmy.ca/c/privacy)\n\n### Chat rooms\n\n- [Matrix/Element]Dead\n\n- [Discord](https://discord.gg/8xfrVjvngh)\n\nmuch thanks to @gary_host_laptop for the logo design :)", + "removed": false, + "published": "2019-11-15T23:50:53.712299", + "updated": "2023-07-21T19:06:26.177465", + "deleted": false, + "nsfw": false, + "actor_id": "https://lemmy.ml/c/privacy", + "local": false, + "icon": "https://lemmy.ml/pictrs/image/h1ChnLuBHr.png", + "banner": "https://lemmy.ml/pictrs/image/DBjcqOW9ds.png", + "hidden": false, + "posting_restricted_to_mods": false, + "instance_id": 2 + }, + "moderator": { + "id": 2, + "name": "TheAnonymouseJoker", + "avatar": "https://lemmy.ml/pictrs/image/8fd70139-4603-4fb7-8f16-d78f43790c1f.jpeg", + "banned": false, + "published": "2020-06-07T12:34:31.646688", + "updated": "2022-06-17T08:27:41.447164", + "actor_id": "https://lemmy.ml/u/TheAnonymouseJoker", + "local": false, + "deleted": false, + "admin": false, + "bot_account": false, + "instance_id": 2 + } + }, + { + "community": { + "id": 65, + "name": "privacy", + "title": "Privacy", + "description": "# A place to discuss privacy and freedom in the digital world.\n\nPrivacy has become a very important issue in modern society, with companies and governments constantly abusing their power, more and more people are waking up to the importance of digital privacy. \n\nIn this community everyone is welcome to post links and discuss topics related to privacy.\n\n### Some Rules\n\n \n - Posting a link to a website containing tracking isn't great, if contents of the website are behind a paywall maybe copy them into the post\n - Don't promote proprietary software\n - Try to keep things on topic\n - If you have a question, please try searching for previous discussions, maybe it has already been answered\n - Reposts are fine, but should have at least a couple of weeks in between so that the post can reach a new audience\n - Be nice :)\n\n### Related communities\n\n- [Lemmy.ml libre_culture](https://lemmy.ml/c/libre_culture)\n- [Lemmy.ml privatelife](https://lemmy.ml/c/privatelife)\n- [Lemmy.ml DeGoogle](https://lemmy.ml/c/degoogle)\n- [Lemmy.ca privacy](https://lemmy.ca/c/privacy)\n\n### Chat rooms\n\n- [Matrix/Element]Dead\n\n- [Discord](https://discord.gg/8xfrVjvngh)\n\nmuch thanks to @gary_host_laptop for the logo design :)", + "removed": false, + "published": "2019-11-15T23:50:53.712299", + "updated": "2023-07-21T19:06:26.177465", + "deleted": false, + "nsfw": false, + "actor_id": "https://lemmy.ml/c/privacy", + "local": false, + "icon": "https://lemmy.ml/pictrs/image/h1ChnLuBHr.png", + "banner": "https://lemmy.ml/pictrs/image/DBjcqOW9ds.png", + "hidden": false, + "posting_restricted_to_mods": false, + "instance_id": 2 + }, + "moderator": { + "id": 4651, + "name": "Yayannick", + "avatar": "https://lemmy.ml/pictrs/image/99671f4f-dc19-437d-9f91-18a17e3e07ef.png", + "banned": false, + "published": "2021-12-10T08:12:33.393328", + "updated": "2023-01-27T14:20:11.869598", + "actor_id": "https://lemmy.ml/u/Yayannick", + "bio": "The last man on Earth hears a knock on the door.", + "local": false, + "deleted": false, + "admin": false, + "bot_account": false, + "instance_id": 2 + } + }, + { + "community": { + "id": 65, + "name": "privacy", + "title": "Privacy", + "description": "# A place to discuss privacy and freedom in the digital world.\n\nPrivacy has become a very important issue in modern society, with companies and governments constantly abusing their power, more and more people are waking up to the importance of digital privacy. \n\nIn this community everyone is welcome to post links and discuss topics related to privacy.\n\n### Some Rules\n\n \n - Posting a link to a website containing tracking isn't great, if contents of the website are behind a paywall maybe copy them into the post\n - Don't promote proprietary software\n - Try to keep things on topic\n - If you have a question, please try searching for previous discussions, maybe it has already been answered\n - Reposts are fine, but should have at least a couple of weeks in between so that the post can reach a new audience\n - Be nice :)\n\n### Related communities\n\n- [Lemmy.ml libre_culture](https://lemmy.ml/c/libre_culture)\n- [Lemmy.ml privatelife](https://lemmy.ml/c/privatelife)\n- [Lemmy.ml DeGoogle](https://lemmy.ml/c/degoogle)\n- [Lemmy.ca privacy](https://lemmy.ca/c/privacy)\n\n### Chat rooms\n\n- [Matrix/Element]Dead\n\n- [Discord](https://discord.gg/8xfrVjvngh)\n\nmuch thanks to @gary_host_laptop for the logo design :)", + "removed": false, + "published": "2019-11-15T23:50:53.712299", + "updated": "2023-07-21T19:06:26.177465", + "deleted": false, + "nsfw": false, + "actor_id": "https://lemmy.ml/c/privacy", + "local": false, + "icon": "https://lemmy.ml/pictrs/image/h1ChnLuBHr.png", + "banner": "https://lemmy.ml/pictrs/image/DBjcqOW9ds.png", + "hidden": false, + "posting_restricted_to_mods": false, + "instance_id": 2 + }, + "moderator": { + "id": 3061, + "name": "ranok", + "banned": false, + "published": "2023-06-01T12:58:56.504051", + "actor_id": "https://sopuli.xyz/u/ranok", + "local": false, + "deleted": false, + "admin": false, + "bot_account": false, + "instance_id": 11 + } + } + ], + "cross_posts": [] +}