274 lines
7.3 KiB
Go
274 lines
7.3 KiB
Go
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"
|
|
|
|
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)
|
|
}
|
|
|
|
// UpdateTitle updates a collection's title.
|
|
func (s *CollectionService) UpdateTitle(ctx context.Context, id string, title string) (*Response, error) {
|
|
path := "api/v1/collections/update_collection_title"
|
|
|
|
form := url.Values{}
|
|
form.Set("collection_id", id)
|
|
form.Set("title", title)
|
|
|
|
req, err := s.client.NewRequestWithForm(http.MethodPost, path, form)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return s.client.Do(ctx, req, nil)
|
|
}
|
|
|
|
// UpdateDescription updates a collection's description.
|
|
func (s *CollectionService) UpdateDescription(ctx context.Context, id string, description string) (*Response, error) {
|
|
path := "api/v1/collections/update_collection_description"
|
|
|
|
form := url.Values{}
|
|
form.Set("collection_id", id)
|
|
form.Set("description", description)
|
|
|
|
req, err := s.client.NewRequestWithForm(http.MethodPost, path, form)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return s.client.Do(ctx, req, nil)
|
|
}
|
|
|
|
// UpdateLayout updates a collection's layout.
|
|
// layout is one of: TIMELINE, GALLERY.
|
|
func (s *CollectionService) UpdateLayout(ctx context.Context, id string, layout string) (*Response, error) {
|
|
// todo: should we validate layout?
|
|
path := "api/v1/collections/update_collection_display_layout"
|
|
|
|
form := url.Values{}
|
|
form.Set("collection_id", id)
|
|
form.Set("display_layout", layout)
|
|
|
|
req, err := s.client.NewRequestWithForm(http.MethodPost, path, form)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return s.client.Do(ctx, req, nil)
|
|
}
|
|
|
|
// Follow follows a collection.
|
|
func (s *CollectionService) Follow(ctx context.Context, id string) (*Response, error) {
|
|
path := "api/v1/collections/follow_collection"
|
|
|
|
form := url.Values{}
|
|
form.Set("collection_id", id)
|
|
form.Set("follow", "true")
|
|
|
|
req, err := s.client.NewRequestWithForm(http.MethodPost, path, form)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return s.client.Do(ctx, req, nil)
|
|
}
|
|
|
|
// Unfollow unfollows a collection.
|
|
func (s *CollectionService) Unfollow(ctx context.Context, id string) (*Response, error) {
|
|
path := "api/v1/collections/follow_collection"
|
|
|
|
form := url.Values{}
|
|
form.Set("collection_id", id)
|
|
form.Set("follow", "false")
|
|
|
|
req, err := s.client.NewRequestWithForm(http.MethodPost, path, form)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return s.client.Do(ctx, req, nil)
|
|
}
|