17 Q string |
16 Q string |
18 Limit int |
17 Limit int |
19 } |
18 } |
20 |
19 |
21 // getSingleAccount returns an account entity |
20 // getSingleAccount returns an account entity |
22 // The target can be "account", "verify_credentials", "follow", "unfollow", |
21 // The operation 'op' can be "account", "verify_credentials", "follow", |
23 // "block", "unblock", "mute", "unmute", "follow_requests/authorize" or |
22 // "unfollow", "block", "unblock", "mute", "unmute", |
24 // "follow_requests/reject". |
23 // "follow_requests/authorize" or // "follow_requests/reject". |
25 // The id is optional and depends on the target. |
24 // The id is optional and depends on the operation. |
26 func (g *Client) getSingleAccount(target string, id int) (*Account, error) { |
25 func (g *Client) getSingleAccount(op string, id int) (*Account, error) { |
27 var endPoint string |
26 var endPoint string |
28 method := rest.Get |
27 method := rest.Get |
29 strID := strconv.Itoa(id) |
28 strID := strconv.Itoa(id) |
30 |
29 |
31 switch target { |
30 switch op { |
32 case "account": |
31 case "account": |
33 endPoint = "accounts/" + strID |
32 endPoint = "accounts/" + strID |
34 case "verify_credentials": |
33 case "verify_credentials": |
35 endPoint = "accounts/verify_credentials" |
34 endPoint = "accounts/verify_credentials" |
36 case "follow", "unfollow", "block", "unblock", "mute", "unmute": |
35 case "follow", "unfollow", "block", "unblock", "mute", "unmute": |
37 endPoint = "accounts/" + strID + "/" + target |
36 endPoint = "accounts/" + strID + "/" + op |
38 method = rest.Post |
37 method = rest.Post |
39 case "follow_requests/authorize", "follow_requests/reject": |
38 case "follow_requests/authorize", "follow_requests/reject": |
40 // The documentation is incorrect, the endpoint actually |
39 // The documentation is incorrect, the endpoint actually |
41 // is "follow_requests/:id/{authorize|reject}" |
40 // is "follow_requests/:id/{authorize|reject}" |
42 endPoint = target[:16] + strID + "/" + target[16:] |
41 endPoint = op[:16] + strID + "/" + op[16:] |
43 method = rest.Post |
42 method = rest.Post |
44 default: |
43 default: |
45 return nil, ErrInvalidParameter |
44 return nil, ErrInvalidParameter |
46 } |
45 } |
47 |
46 |
48 req := g.prepareRequest(endPoint) |
|
49 req.Method = method |
|
50 |
|
51 r, err := rest.API(req) |
|
52 if err != nil { |
|
53 return nil, fmt.Errorf("getAccount (%s): %s", target, err.Error()) |
|
54 } |
|
55 |
|
56 // Check for error reply |
|
57 var errorResult Error |
|
58 if err := json.Unmarshal([]byte(r.Body), &errorResult); err == nil { |
|
59 // The empty object is not an error |
|
60 if errorResult.Text != "" { |
|
61 return nil, fmt.Errorf("%s", errorResult.Text) |
|
62 } |
|
63 } |
|
64 |
|
65 // Not an error reply; let's unmarshal the data |
|
66 var account Account |
47 var account Account |
67 err = json.Unmarshal([]byte(r.Body), &account) |
48 if err := g.apiCall(endPoint, method, nil, &account); err != nil { |
68 if err != nil { |
49 return nil, err |
69 return nil, fmt.Errorf("getAccount (%s) API: %s", target, err.Error()) |
|
70 } |
50 } |
71 return &account, nil |
51 return &account, nil |
72 } |
52 } |
73 |
53 |
74 // getMultipleAccounts returns a list of account entities |
54 // getMultipleAccounts returns a list of account entities |
75 // The target can be "followers", "following", "search", "blocks", "mutes", |
55 // The operation 'op' can be "followers", "following", "search", "blocks", |
76 // "follow_requests". |
56 // "mutes", "follow_requests". |
77 // The id is optional and depends on the target. |
57 // The id is optional and depends on the operation. |
78 func (g *Client) getMultipleAccounts(target string, opts *getAccountsOptions) ([]Account, error) { |
58 func (g *Client) getMultipleAccounts(op string, opts *getAccountsOptions) ([]Account, error) { |
79 var endPoint string |
59 var endPoint string |
80 switch target { |
60 |
|
61 switch op { |
81 case "followers", "following": |
62 case "followers", "following": |
82 if opts == nil || opts.ID < 1 { |
63 if opts == nil || opts.ID < 1 { |
83 return []Account{}, ErrInvalidID |
64 return []Account{}, ErrInvalidID |
84 } |
65 } |
85 endPoint = "accounts/" + strconv.Itoa(opts.ID) + "/" + target |
66 endPoint = "accounts/" + strconv.Itoa(opts.ID) + "/" + op |
86 case "follow_requests", "blocks", "mutes": |
67 case "follow_requests", "blocks", "mutes": |
87 endPoint = target |
68 endPoint = op |
88 case "search": |
69 case "search": |
89 if opts == nil || opts.Q == "" { |
70 if opts == nil || opts.Q == "" { |
90 return []Account{}, ErrInvalidParameter |
71 return []Account{}, ErrInvalidParameter |
91 } |
72 } |
92 endPoint = "accounts/" + target |
73 endPoint = "accounts/" + op |
93 default: |
74 default: |
94 return nil, ErrInvalidParameter |
75 return nil, ErrInvalidParameter |
95 } |
76 } |
96 |
77 |
97 req := g.prepareRequest(endPoint) |
|
98 |
|
99 // Handle target-specific query parameters |
78 // Handle target-specific query parameters |
100 if target == "search" { |
79 params := make(apiCallParams) |
101 req.QueryParams["q"] = opts.Q |
80 if op == "search" { |
|
81 params["q"] = opts.Q |
102 if opts.Limit > 0 { |
82 if opts.Limit > 0 { |
103 req.QueryParams["limit"] = strconv.Itoa(opts.Limit) |
83 params["limit"] = strconv.Itoa(opts.Limit) |
104 } |
84 } |
105 } |
85 } |
106 |
86 |
107 r, err := rest.API(req) |
|
108 if err != nil { |
|
109 return nil, fmt.Errorf("getAccount (%s): %s", target, err.Error()) |
|
110 } |
|
111 |
|
112 // Check for error reply |
|
113 var errorResult Error |
|
114 if err := json.Unmarshal([]byte(r.Body), &errorResult); err == nil { |
|
115 // The empty object is not an error |
|
116 if errorResult.Text != "" { |
|
117 return nil, fmt.Errorf("%s", errorResult.Text) |
|
118 } |
|
119 } |
|
120 |
|
121 // Not an error reply; let's unmarshal the data |
|
122 var accounts []Account |
87 var accounts []Account |
123 err = json.Unmarshal([]byte(r.Body), &accounts) |
88 if err := g.apiCall(endPoint, rest.Get, params, &accounts); err != nil { |
124 if err != nil { |
89 return nil, err |
125 return nil, fmt.Errorf("getAccount (%s) API: %s", target, err.Error()) |
|
126 } |
90 } |
127 return accounts, nil |
91 return accounts, nil |
128 } |
92 } |
129 |
93 |
130 // GetAccount returns an account entity |
94 // GetAccount returns an account entity |
188 } |
152 } |
189 return nil |
153 return nil |
190 } |
154 } |
191 |
155 |
192 // FollowRemoteAccount follows a remote account |
156 // FollowRemoteAccount follows a remote account |
193 // The parameter 'id' is a URI (username@domain). |
157 // The parameter 'uri' is a URI (e.g. "username@domain"). |
194 func (g *Client) FollowRemoteAccount(id string) (*Account, error) { |
158 func (g *Client) FollowRemoteAccount(uri string) (*Account, error) { |
195 if id == "" { |
159 if uri == "" { |
196 return nil, ErrInvalidID |
160 return nil, ErrInvalidID |
197 } |
161 } |
198 |
162 |
199 req := g.prepareRequest("follows") |
163 params := make(apiCallParams) |
200 req.Method = rest.Post |
164 params["uri"] = uri |
201 req.QueryParams["uri"] = id |
165 |
202 r, err := rest.API(req) |
|
203 if err != nil { |
|
204 return nil, fmt.Errorf("FollowRemoteAccount: %s", err.Error()) |
|
205 } |
|
206 |
|
207 // Check for error reply |
|
208 var errorResult Error |
|
209 if err := json.Unmarshal([]byte(r.Body), &errorResult); err == nil { |
|
210 // The empty object is not an error |
|
211 if errorResult.Text != "" { |
|
212 return nil, fmt.Errorf("%s", errorResult.Text) |
|
213 } |
|
214 } |
|
215 |
|
216 // Not an error reply; let's unmarshal the data |
|
217 var account Account |
166 var account Account |
218 err = json.Unmarshal([]byte(r.Body), &account) |
167 if err := g.apiCall("follows", rest.Post, params, &account); err != nil { |
219 if err != nil { |
168 return nil, err |
220 return nil, fmt.Errorf("FollowRemoteAccount API: %s", err.Error()) |
|
221 } |
169 } |
222 if account.ID == 0 { |
170 if account.ID == 0 { |
223 return nil, ErrEntityNotFound |
171 return nil, ErrEntityNotFound |
224 } |
172 } |
225 return &account, nil |
173 return &account, nil |
300 func (g *Client) GetAccountRelationships(accountIDs []int) ([]Relationship, error) { |
248 func (g *Client) GetAccountRelationships(accountIDs []int) ([]Relationship, error) { |
301 if len(accountIDs) < 1 { |
249 if len(accountIDs) < 1 { |
302 return nil, ErrInvalidID |
250 return nil, ErrInvalidID |
303 } |
251 } |
304 |
252 |
305 req := g.prepareRequest("accounts/relationships") |
|
306 |
|
307 if len(accountIDs) > 1 { // XXX |
253 if len(accountIDs) > 1 { // XXX |
308 return nil, fmt.Errorf("accounts/relationships currently does not work with more than 1 ID") |
254 return nil, fmt.Errorf("accounts/relationships currently does not work with more than 1 ID") |
309 } |
255 } |
310 req.QueryParams["id"] = strconv.Itoa(accountIDs[0]) |
256 |
|
257 params := make(apiCallParams) |
|
258 params["id"] = strconv.Itoa(accountIDs[0]) |
311 /* |
259 /* |
312 for i, id := range accountIDList { |
260 for i, id := range accountIDList { |
313 qID := fmt.Sprintf("id[%d]", i+1) |
261 qID := fmt.Sprintf("id[%d]", i+1) |
314 req.QueryParams[qID] = strconv.Itoa(id) |
262 params[qID] = strconv.Itoa(id) |
315 } |
263 } |
316 */ |
264 */ |
317 |
265 |
318 r, err := rest.API(req) |
|
319 if err != nil { |
|
320 return nil, fmt.Errorf("GetAccountRelationships: %s", err.Error()) |
|
321 } |
|
322 |
|
323 // Check for error reply |
|
324 var errorResult Error |
|
325 if err := json.Unmarshal([]byte(r.Body), &errorResult); err == nil { |
|
326 // The empty object is not an error |
|
327 if errorResult.Text != "" { |
|
328 return nil, fmt.Errorf("%s", errorResult.Text) |
|
329 } |
|
330 } |
|
331 |
|
332 // Not an error reply; let's unmarshal the data |
|
333 var rl []Relationship |
266 var rl []Relationship |
334 err = json.Unmarshal([]byte(r.Body), &rl) |
267 if err := g.apiCall("accounts/relationships", rest.Get, params, &rl); err != nil { |
335 if err != nil { |
268 return nil, err |
336 return nil, fmt.Errorf("accounts/relationships API: %s", err.Error()) |
|
337 } |
269 } |
338 return rl, nil |
270 return rl, nil |
339 } |
271 } |
340 |
272 |
341 // GetAccountStatuses returns a list of status entities for the given account |
273 // GetAccountStatuses returns a list of status entities for the given account |
345 if accountID < 1 { |
277 if accountID < 1 { |
346 return nil, ErrInvalidID |
278 return nil, ErrInvalidID |
347 } |
279 } |
348 |
280 |
349 endPoint := "accounts/" + strconv.Itoa(accountID) + "/" + "statuses" |
281 endPoint := "accounts/" + strconv.Itoa(accountID) + "/" + "statuses" |
350 req := g.prepareRequest(endPoint) |
282 params := make(apiCallParams) |
351 |
|
352 if onlyMedia { |
283 if onlyMedia { |
353 req.QueryParams["only_media"] = "true" |
284 params["only_media"] = "true" |
354 } |
285 } |
355 if excludeReplies { |
286 if excludeReplies { |
356 req.QueryParams["exclude_replies"] = "true" |
287 params["exclude_replies"] = "true" |
357 } |
288 } |
358 |
289 |
359 r, err := rest.API(req) |
|
360 if err != nil { |
|
361 return nil, fmt.Errorf("GetAccountStatuses: %s", err.Error()) |
|
362 } |
|
363 |
|
364 // Check for error reply |
|
365 var errorResult Error |
|
366 if err := json.Unmarshal([]byte(r.Body), &errorResult); err == nil { |
|
367 // The empty object is not an error |
|
368 if errorResult.Text != "" { |
|
369 return nil, fmt.Errorf("%s", errorResult.Text) |
|
370 } |
|
371 } |
|
372 |
|
373 // Not an error reply; let's unmarshal the data |
|
374 var sl []Status |
290 var sl []Status |
375 err = json.Unmarshal([]byte(r.Body), &sl) |
291 if err := g.apiCall(endPoint, rest.Get, params, &sl); err != nil { |
376 if err != nil { |
292 return nil, err |
377 return nil, fmt.Errorf("accounts/statuses API: %s", err.Error()) |
|
378 } |
293 } |
379 return sl, nil |
294 return sl, nil |
380 } |
295 } |
381 |
296 |
382 // FollowRequestAuthorize authorizes or rejects an account follow-request |
297 // FollowRequestAuthorize authorizes or rejects an account follow-request |