Add method chaining for getting posts from subreddits
Signed-off-by: Vartan Benohanian <vartanbeno@gmail.com>
This commit is contained in:
parent
eda947f6b5
commit
01fad4ece5
2 changed files with 102 additions and 86 deletions
14
search.go
14
search.go
|
@ -36,9 +36,7 @@ func (s *SearchServiceOp) Posts(query string) *PostSearchBuilder {
|
||||||
b.client = s.client
|
b.client = s.client
|
||||||
b.opts.Query = query
|
b.opts.Query = query
|
||||||
b.opts.Type = "link"
|
b.opts.Type = "link"
|
||||||
b.opts.Sort = SortRelevance.String()
|
return b.Sort(SortRelevance).Timespan(TimespanAll)
|
||||||
b.opts.Timespan = TimespanAll.String()
|
|
||||||
return b
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Subreddits searches for subreddits.
|
// Subreddits searches for subreddits.
|
||||||
|
@ -95,14 +93,18 @@ func (b *PostSearchBuilder) Limit(limit int) *PostSearchBuilder {
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
// InSubreddits restricts the search to happen in the specified subreddits only.
|
// FromSubreddits restricts the search to happen in the specified subreddits only.
|
||||||
// If none are set, the search is run against r/all.
|
func (b *PostSearchBuilder) FromSubreddits(subreddits ...string) *PostSearchBuilder {
|
||||||
func (b *PostSearchBuilder) InSubreddits(subreddits ...string) *PostSearchBuilder {
|
|
||||||
b.subreddits = subreddits
|
b.subreddits = subreddits
|
||||||
b.opts.RestrictSubreddits = len(subreddits) > 0
|
b.opts.RestrictSubreddits = len(subreddits) > 0
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FromAll runs the search against r/all.
|
||||||
|
func (b *PostSearchBuilder) FromAll() *PostSearchBuilder {
|
||||||
|
return b.FromSubreddits()
|
||||||
|
}
|
||||||
|
|
||||||
// Sort sets the sort option.
|
// Sort sets the sort option.
|
||||||
func (b *PostSearchBuilder) Sort(sort Sort) *PostSearchBuilder {
|
func (b *PostSearchBuilder) Sort(sort Sort) *PostSearchBuilder {
|
||||||
b.opts.Sort = sort.String()
|
b.opts.Sort = sort.String()
|
||||||
|
|
174
subreddit.go
174
subreddit.go
|
@ -12,6 +12,8 @@ import (
|
||||||
// SubredditService handles communication with the subreddit
|
// SubredditService handles communication with the subreddit
|
||||||
// related methods of the Reddit API
|
// related methods of the Reddit API
|
||||||
type SubredditService interface {
|
type SubredditService interface {
|
||||||
|
GetPosts() *PostFinder
|
||||||
|
|
||||||
GetByName(ctx context.Context, subreddit string) (*Subreddit, *Response, error)
|
GetByName(ctx context.Context, subreddit string) (*Subreddit, *Response, error)
|
||||||
|
|
||||||
GetPopular(ctx context.Context, opts *ListOptions) (*Subreddits, *Response, error)
|
GetPopular(ctx context.Context, opts *ListOptions) (*Subreddits, *Response, error)
|
||||||
|
@ -24,13 +26,6 @@ type SubredditService interface {
|
||||||
GetMineWhereModerator(ctx context.Context, opts *ListOptions) (*Subreddits, *Response, error)
|
GetMineWhereModerator(ctx context.Context, opts *ListOptions) (*Subreddits, *Response, error)
|
||||||
GetMineWhereStreams(ctx context.Context, opts *ListOptions) (*Subreddits, *Response, error)
|
GetMineWhereStreams(ctx context.Context, opts *ListOptions) (*Subreddits, *Response, error)
|
||||||
|
|
||||||
GetHotLinks(ctx context.Context, opts *ListOptions, subreddits ...string) (*Links, *Response, error)
|
|
||||||
GetBestLinks(ctx context.Context, opts *ListOptions, subreddits ...string) (*Links, *Response, error)
|
|
||||||
GetNewLinks(ctx context.Context, opts *ListOptions, subreddits ...string) (*Links, *Response, error)
|
|
||||||
GetRisingLinks(ctx context.Context, opts *ListOptions, subreddits ...string) (*Links, *Response, error)
|
|
||||||
GetControversialLinks(ctx context.Context, opts *ListOptions, subreddits ...string) (*Links, *Response, error)
|
|
||||||
GetTopLinks(ctx context.Context, opts *ListOptions, subreddits ...string) (*Links, *Response, error)
|
|
||||||
|
|
||||||
GetSticky1(ctx context.Context, subreddit string) (*LinkAndComments, *Response, error)
|
GetSticky1(ctx context.Context, subreddit string) (*LinkAndComments, *Response, error)
|
||||||
GetSticky2(ctx context.Context, subreddit string) (*LinkAndComments, *Response, error)
|
GetSticky2(ctx context.Context, subreddit string) (*LinkAndComments, *Response, error)
|
||||||
|
|
||||||
|
@ -65,6 +60,16 @@ type SubredditShort struct {
|
||||||
ActiveUsers int `json:"active_user_count"`
|
ActiveUsers int `json:"active_user_count"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetPosts returns posts.
|
||||||
|
// By default, it'll look for the hottest posts from r/all.
|
||||||
|
// Note: when looking for hot posts in a subreddit, it will include the
|
||||||
|
// sticked posts (if any) PLUS posts from the limit parameter (25 by default).
|
||||||
|
func (s *SubredditServiceOp) GetPosts() *PostFinder {
|
||||||
|
f := new(PostFinder)
|
||||||
|
f.client = s.client
|
||||||
|
return f.Sort(SortHot).FromAll()
|
||||||
|
}
|
||||||
|
|
||||||
// GetByName gets a subreddit by name
|
// GetByName gets a subreddit by name
|
||||||
func (s *SubredditServiceOp) GetByName(ctx context.Context, subreddit string) (*Subreddit, *Response, error) {
|
func (s *SubredditServiceOp) GetByName(ctx context.Context, subreddit string) (*Subreddit, *Response, error) {
|
||||||
if subreddit == "" {
|
if subreddit == "" {
|
||||||
|
@ -126,46 +131,6 @@ func (s *SubredditServiceOp) GetMineWhereStreams(ctx context.Context, opts *List
|
||||||
return s.getSubreddits(ctx, "subreddits/mine/contributor", opts)
|
return s.getSubreddits(ctx, "subreddits/mine/contributor", opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetHotLinks returns the hot links
|
|
||||||
// If no subreddit are provided, then it runs the search against all those the client is subscribed to
|
|
||||||
// IMPORTANT: for subreddits, this will include the stickied posts (if any)
|
|
||||||
// PLUS the number of posts from the limit parameter (which is 25 by default)
|
|
||||||
func (s *SubredditServiceOp) GetHotLinks(ctx context.Context, opts *ListOptions, subreddits ...string) (*Links, *Response, error) {
|
|
||||||
return s.getLinks(ctx, SortHot, opts, subreddits...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetBestLinks returns the best links
|
|
||||||
// If no subreddit are provided, then it runs the search against all those the client is subscribed to
|
|
||||||
// IMPORTANT: for subreddits, this will include the stickied posts (if any)
|
|
||||||
// PLUS the number of posts from the limit parameter (which is 25 by default)
|
|
||||||
func (s *SubredditServiceOp) GetBestLinks(ctx context.Context, opts *ListOptions, subreddits ...string) (*Links, *Response, error) {
|
|
||||||
return s.getLinks(ctx, SortBest, opts, subreddits...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetNewLinks returns the new links
|
|
||||||
// If no subreddit are provided, then it runs the search against all those the client is subscribed to
|
|
||||||
func (s *SubredditServiceOp) GetNewLinks(ctx context.Context, opts *ListOptions, subreddits ...string) (*Links, *Response, error) {
|
|
||||||
return s.getLinks(ctx, SortNew, opts, subreddits...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetRisingLinks returns the rising links
|
|
||||||
// If no subreddit are provided, then it runs the search against all those the client is subscribed to
|
|
||||||
func (s *SubredditServiceOp) GetRisingLinks(ctx context.Context, opts *ListOptions, subreddits ...string) (*Links, *Response, error) {
|
|
||||||
return s.getLinks(ctx, SortRising, opts, subreddits...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetControversialLinks returns the controversial links
|
|
||||||
// If no subreddit are provided, then it runs the search against all those the client is subscribed to
|
|
||||||
func (s *SubredditServiceOp) GetControversialLinks(ctx context.Context, opts *ListOptions, subreddits ...string) (*Links, *Response, error) {
|
|
||||||
return s.getLinks(ctx, SortControversial, opts, subreddits...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetTopLinks returns the top links
|
|
||||||
// If no subreddit are provided, then it runs the search against all those the client is subscribed to
|
|
||||||
func (s *SubredditServiceOp) GetTopLinks(ctx context.Context, opts *ListOptions, subreddits ...string) (*Links, *Response, error) {
|
|
||||||
return s.getLinks(ctx, SortTop, opts, subreddits...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetSticky1 returns the first stickied post on a subreddit (if it exists)
|
// GetSticky1 returns the first stickied post on a subreddit (if it exists)
|
||||||
func (s *SubredditServiceOp) GetSticky1(ctx context.Context, name string) (*LinkAndComments, *Response, error) {
|
func (s *SubredditServiceOp) GetSticky1(ctx context.Context, name string) (*LinkAndComments, *Response, error) {
|
||||||
return s.getSticky(ctx, name, sticky1)
|
return s.getSticky(ctx, name, sticky1)
|
||||||
|
@ -292,39 +257,6 @@ func (s *SubredditServiceOp) getSubreddits(ctx context.Context, path string, opt
|
||||||
return l, resp, nil
|
return l, resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SubredditServiceOp) getLinks(ctx context.Context, sort Sort, opts *ListOptions, subreddits ...string) (*Links, *Response, error) {
|
|
||||||
path := sorts[sort]
|
|
||||||
if len(subreddits) > 0 {
|
|
||||||
path = fmt.Sprintf("r/%s/%s", strings.Join(subreddits, "+"), sort)
|
|
||||||
}
|
|
||||||
|
|
||||||
path, err := addOptions(path, opts)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
req, err := s.client.NewRequest(http.MethodGet, path, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
root := new(rootListing)
|
|
||||||
resp, err := s.client.Do(ctx, req, root)
|
|
||||||
if err != nil {
|
|
||||||
return nil, resp, err
|
|
||||||
}
|
|
||||||
|
|
||||||
l := new(Links)
|
|
||||||
|
|
||||||
if root.Data != nil {
|
|
||||||
l.Links = root.Data.Things.Links
|
|
||||||
l.After = root.Data.After
|
|
||||||
l.Before = root.Data.Before
|
|
||||||
}
|
|
||||||
|
|
||||||
return l, resp, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// getSticky returns one of the 2 stickied posts of the subreddit (if they exist)
|
// getSticky returns one of the 2 stickied posts of the subreddit (if they exist)
|
||||||
// Num should be equal to 1 or 2, depending on which one you want
|
// Num should be equal to 1 or 2, depending on which one you want
|
||||||
// If it's <= 1, it's 1
|
// If it's <= 1, it's 1
|
||||||
|
@ -353,3 +285,85 @@ func (s *SubredditServiceOp) getSticky(ctx context.Context, subreddit string, nu
|
||||||
|
|
||||||
return root, resp, nil
|
return root, resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PostFinder finds posts from the specified subreddits.
|
||||||
|
// If no subreddits are specified, it finds posts from the ones the client is subscribed to.
|
||||||
|
type PostFinder struct {
|
||||||
|
client *Client
|
||||||
|
subreddits []string
|
||||||
|
sort string
|
||||||
|
opts struct {
|
||||||
|
After string `url:"after,omitempty"`
|
||||||
|
Before string `url:"before,omitempty"`
|
||||||
|
Limit int `url:"limit,omitempty"`
|
||||||
|
Timespan string `url:"t,omitempty"`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// After sets the after option.
|
||||||
|
func (f *PostFinder) After(after string) *PostFinder {
|
||||||
|
f.opts.After = after
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
|
||||||
|
// Before sets the before option.
|
||||||
|
func (f *PostFinder) Before(before string) *PostFinder {
|
||||||
|
f.opts.Before = before
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
|
||||||
|
// Limit sets the limit option.
|
||||||
|
func (f *PostFinder) Limit(limit int) *PostFinder {
|
||||||
|
f.opts.Limit = limit
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromSubreddits restricts the search to the subreddits.
|
||||||
|
func (f *PostFinder) FromSubreddits(subreddits ...string) *PostFinder {
|
||||||
|
f.subreddits = subreddits
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromAll allows the finder to find posts from r/all.
|
||||||
|
func (f *PostFinder) FromAll() *PostFinder {
|
||||||
|
f.subreddits = []string{"all"}
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort sets the sort option.
|
||||||
|
func (f *PostFinder) Sort(sort Sort) *PostFinder {
|
||||||
|
f.sort = sort.String()
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
|
||||||
|
// Timespan sets the timespan option.
|
||||||
|
func (f *PostFinder) Timespan(timespan Timespan) *PostFinder {
|
||||||
|
f.opts.Timespan = timespan.String()
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do conducts the search.
|
||||||
|
func (f *PostFinder) Do(ctx context.Context) (*Links, *Response, error) {
|
||||||
|
path := f.sort
|
||||||
|
if len(f.subreddits) > 0 {
|
||||||
|
path = fmt.Sprintf("r/%s/%s", strings.Join(f.subreddits, "+"), f.sort)
|
||||||
|
}
|
||||||
|
|
||||||
|
path, err := addOptions(path, f.opts)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := f.client.NewRequest(http.MethodGet, path, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
root := new(rootListing)
|
||||||
|
resp, err := f.client.Do(ctx, req, root)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return root.getLinks(), resp, nil
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue