-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathcomment.go
More file actions
95 lines (89 loc) · 3.01 KB
/
Copy pathcomment.go
File metadata and controls
95 lines (89 loc) · 3.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package ig
import (
"fmt"
"net/url"
"strconv"
"strings"
)
func (c *Client) resolveMediaRESTID(mediaID string) (string, error) {
s := strings.TrimSpace(mediaID)
if s == "" {
return "", fmt.Errorf("ig: empty media id")
}
if strings.Contains(s, "_") {
return s, nil
}
pk, err := strconv.ParseInt(s, 10, 64)
if err != nil {
return "", fmt.Errorf("ig: media id: %w", err)
}
m, err := c.MediaInfoV1(pk)
if err != nil {
return "", err
}
if m.User.PK == 0 {
return "", fmt.Errorf("ig: could not resolve media owner for comments")
}
return fmt.Sprintf("%d_%d", m.PK, m.User.PK), nil
}
func parseMediaCommentsResponse(res map[string]any) MediaCommentsPage {
page := MediaCommentsPage{}
if arr, ok := res["comments"].([]any); ok {
for _, x := range arr {
if m, ok := x.(map[string]any); ok {
page.Comments = append(page.Comments, extractComment(m))
}
}
}
page.NextMaxID = toString(res["next_max_id"])
page.NextMinID = toString(res["next_min_id"])
page.CommentCount = int(toInt64(res["comment_count"]))
moreMax := toBool(res["has_more_comments"]) && page.NextMaxID != ""
moreMin := toBool(res["has_more_headload_comments"]) && page.NextMinID != ""
page.HasMore = moreMax || moreMin
return page
}
// MediaCommentsFirstPage loads the first page of comments for a media item. mediaID may be "mediaPk_userPk" or numeric media PK only (one extra info/ call to resolve owner).
func (c *Client) MediaCommentsFirstPage(mediaID string) (MediaCommentsPage, error) {
return c.MediaCommentsFetch(mediaID, "", "")
}
// MediaCommentsFetch loads one comments page. For the first page pass empty maxID and minID. For pagination pass either next_max_id or next_min_id from the previous MediaCommentsPage (not both).
func (c *Client) MediaCommentsFetch(mediaID string, maxID, minID string) (MediaCommentsPage, error) {
if maxID != "" && minID != "" {
return MediaCommentsPage{}, fmt.Errorf("ig: pass at most one of maxID or minID")
}
rest, err := c.resolveMediaRESTID(mediaID)
if err != nil {
return MediaCommentsPage{}, err
}
params := url.Values{}
params.Set("can_support_threading", "true")
if maxID != "" {
params.Set("max_id", maxID)
}
if minID != "" {
params.Set("min_id", minID)
}
res, err := c.PrivateRequest(PrivateRequestOpts{
Endpoint: fmt.Sprintf("media/%s/comments/", rest),
Params: params,
WithSignature: false,
})
if err != nil {
return MediaCommentsPage{}, err
}
return parseMediaCommentsResponse(res), nil
}
// MediaCommentsNext fetches the next page using cursors from a previous page. Returns an error if HasMore is false or cursors are missing.
func (c *Client) MediaCommentsNext(mediaID string, prev MediaCommentsPage) (MediaCommentsPage, error) {
if !prev.HasMore {
return MediaCommentsPage{}, fmt.Errorf("ig: no more comments")
}
if prev.NextMaxID != "" {
return c.MediaCommentsFetch(mediaID, prev.NextMaxID, "")
}
if prev.NextMinID != "" {
return c.MediaCommentsFetch(mediaID, "", prev.NextMinID)
}
return MediaCommentsPage{}, fmt.Errorf("ig: missing comment cursor")
}