Add CollectionService
Signed-off-by: Vartan Benohanian <vartanbeno@gmail.com>
This commit is contained in:
+193
@@ -0,0 +1,193 @@
|
|||||||
|
package reddit
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/google/go-querystring/query"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CollectionService handles communication with the collection
|
||||||
|
// related methods of the Reddit API.
|
||||||
|
//
|
||||||
|
// Reddit API docs: https://www.reddit.com/dev/api/#section_collections
|
||||||
|
type CollectionService struct {
|
||||||
|
client *Client
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collection is a mod curated group of posts within a subreddit.
|
||||||
|
type Collection struct {
|
||||||
|
ID string `json:"collection_id,omitempty"`
|
||||||
|
Created *Timestamp `json:"created_at_utc,omitempty"`
|
||||||
|
Updated *Timestamp `json:"last_update_utc,omitempty"`
|
||||||
|
|
||||||
|
Title string `json:"title,omitempty"`
|
||||||
|
Description string `json:"description,omitempty"`
|
||||||
|
Permalink string `json:"permalink,omitempty"`
|
||||||
|
Layout string `json:"display_layout,omitempty"`
|
||||||
|
|
||||||
|
SubredditID string `json:"subreddit_id,omitempty"`
|
||||||
|
Author string `json:"author_name,omitempty"`
|
||||||
|
AuthorID string `json:"author_id,omitempty"`
|
||||||
|
|
||||||
|
// Post at the top of the collection.
|
||||||
|
// This does not appear when getting a list of collections.
|
||||||
|
PrimaryPostID string `json:"primary_link_id,omitempty"`
|
||||||
|
PostIDs []string `json:"link_ids,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// CollectionCreateRequest represents a request to create a collection.
|
||||||
|
type CollectionCreateRequest struct {
|
||||||
|
Title string `url:"title"`
|
||||||
|
Description string `url:"description,omitempty"`
|
||||||
|
SubredditID string `url:"sr_fullname"`
|
||||||
|
// One of: TIMELINE, GALLERY.
|
||||||
|
Layout string `url:"display_layout,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get gets a collection by its ID.
|
||||||
|
func (s *CollectionService) Get(ctx context.Context, id string) (*Collection, *Response, error) {
|
||||||
|
path := "api/v1/collections/collection"
|
||||||
|
|
||||||
|
type params struct {
|
||||||
|
ID string `url:"collection_id"`
|
||||||
|
IncludePosts bool `url:"include_links"`
|
||||||
|
}
|
||||||
|
path, err := addOptions(path, params{id, false})
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := s.client.NewRequest(http.MethodGet, path, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
collection := new(Collection)
|
||||||
|
resp, err := s.client.Do(ctx, req, collection)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return collection, resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromSubreddit gets all collections in the subreddit.
|
||||||
|
func (s *CollectionService) FromSubreddit(ctx context.Context, id string) ([]*Collection, *Response, error) {
|
||||||
|
path := "api/v1/collections/subreddit_collections"
|
||||||
|
|
||||||
|
type params struct {
|
||||||
|
SubredditID string `url:"sr_fullname"`
|
||||||
|
}
|
||||||
|
path, err := addOptions(path, params{id})
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := s.client.NewRequest(http.MethodGet, path, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var collections []*Collection
|
||||||
|
resp, err := s.client.Do(ctx, req, &collections)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return collections, resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create creates a collection.
|
||||||
|
func (s *CollectionService) Create(ctx context.Context, createRequest *CollectionCreateRequest) (*Collection, *Response, error) {
|
||||||
|
if createRequest == nil {
|
||||||
|
return nil, nil, errors.New("createRequest: cannot be nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
path := "api/v1/collections/create_collection"
|
||||||
|
|
||||||
|
// todo: do this for multireddit stuff too
|
||||||
|
form, err := query.Values(createRequest)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := s.client.NewRequestWithForm(http.MethodPost, path, form)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
collection := new(Collection)
|
||||||
|
resp, err := s.client.Do(ctx, req, collection)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return collection, resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete deletes a collection via its id.
|
||||||
|
func (s *CollectionService) Delete(ctx context.Context, id string) (*Response, error) {
|
||||||
|
path := "api/v1/collections/delete_collection"
|
||||||
|
|
||||||
|
form := url.Values{}
|
||||||
|
form.Set("collection_id", id)
|
||||||
|
|
||||||
|
req, err := s.client.NewRequestWithForm(http.MethodPost, path, form)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.client.Do(ctx, req, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddPost adds a post (via its full ID) to a collection (via its id).
|
||||||
|
func (s *CollectionService) AddPost(ctx context.Context, postID, collectionID string) (*Response, error) {
|
||||||
|
path := "api/v1/collections/add_post_to_collection"
|
||||||
|
|
||||||
|
form := url.Values{}
|
||||||
|
form.Set("link_fullname", postID)
|
||||||
|
form.Set("collection_id", collectionID)
|
||||||
|
|
||||||
|
req, err := s.client.NewRequestWithForm(http.MethodPost, path, form)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.client.Do(ctx, req, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemovePost removes a post (via its full ID) from a collection (via its id).
|
||||||
|
func (s *CollectionService) RemovePost(ctx context.Context, postID, collectionID string) (*Response, error) {
|
||||||
|
path := "api/v1/collections/remove_post_in_collection"
|
||||||
|
|
||||||
|
form := url.Values{}
|
||||||
|
form.Set("link_fullname", postID)
|
||||||
|
form.Set("collection_id", collectionID)
|
||||||
|
|
||||||
|
req, err := s.client.NewRequestWithForm(http.MethodPost, path, form)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.client.Do(ctx, req, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReorderPosts reorders posts in a collection.
|
||||||
|
func (s *CollectionService) ReorderPosts(ctx context.Context, collectionID string, postIDs ...string) (*Response, error) {
|
||||||
|
path := "api/v1/collections/reorder_collection"
|
||||||
|
|
||||||
|
form := url.Values{}
|
||||||
|
form.Set("collection_id", collectionID)
|
||||||
|
form.Set("link_ids", strings.Join(postIDs, ","))
|
||||||
|
|
||||||
|
req, err := s.client.NewRequestWithForm(http.MethodPost, path, form)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.client.Do(ctx, req, nil)
|
||||||
|
}
|
||||||
@@ -92,6 +92,7 @@ type Client struct {
|
|||||||
redditID string
|
redditID string
|
||||||
|
|
||||||
Account *AccountService
|
Account *AccountService
|
||||||
|
Collection *CollectionService
|
||||||
Comment *CommentService
|
Comment *CommentService
|
||||||
Flair *FlairService
|
Flair *FlairService
|
||||||
Listings *ListingsService
|
Listings *ListingsService
|
||||||
@@ -139,6 +140,7 @@ func newClient(httpClient *http.Client) *Client {
|
|||||||
c := &Client{client: httpClient, BaseURL: baseURL, TokenURL: tokenURL}
|
c := &Client{client: httpClient, BaseURL: baseURL, TokenURL: tokenURL}
|
||||||
|
|
||||||
c.Account = &AccountService{client: c}
|
c.Account = &AccountService{client: c}
|
||||||
|
c.Collection = &CollectionService{client: c}
|
||||||
c.Flair = &FlairService{client: c}
|
c.Flair = &FlairService{client: c}
|
||||||
c.Listings = &ListingsService{client: c}
|
c.Listings = &ListingsService{client: c}
|
||||||
c.Moderation = &ModerationService{client: c}
|
c.Moderation = &ModerationService{client: c}
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ func readFileContents(path string) (string, error) {
|
|||||||
func testClientServices(t *testing.T, c *Client) {
|
func testClientServices(t *testing.T, c *Client) {
|
||||||
services := []string{
|
services := []string{
|
||||||
"Account",
|
"Account",
|
||||||
|
"Collection",
|
||||||
"Comment",
|
"Comment",
|
||||||
"Flair",
|
"Flair",
|
||||||
"Listings",
|
"Listings",
|
||||||
|
|||||||
Reference in New Issue
Block a user