Use method chaining for searches
Signed-off-by: Vartan Benohanian <vartanbeno@gmail.com>
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SearchService handles communication with the search
|
// SearchService handles communication with the search
|
||||||
@@ -12,20 +13,9 @@ import (
|
|||||||
// user must check the following in their preferences:
|
// user must check the following in their preferences:
|
||||||
// "include not safe for work (NSFW) search results in searches"
|
// "include not safe for work (NSFW) search results in searches"
|
||||||
type SearchService interface {
|
type SearchService interface {
|
||||||
Users(ctx context.Context, q string, opts *ListOptions) (*Users, *Response, error)
|
Posts(query string) *PostSearchBuilder
|
||||||
|
Subreddits(query string) *SubredditSearchBuilder
|
||||||
LinksByRelevance(ctx context.Context, q string, opts *ListOptions) (*Links, *Response, error)
|
Users(query string) *UserSearchBuilder
|
||||||
LinksByHottest(ctx context.Context, q string, opts *ListOptions) (*Links, *Response, error)
|
|
||||||
LinksByTop(ctx context.Context, q string, opts *ListOptions) (*Links, *Response, error)
|
|
||||||
LinksByComments(ctx context.Context, q string, opts *ListOptions) (*Links, *Response, error)
|
|
||||||
LinksByRelevanceInSubreddit(ctx context.Context, subreddit, q string, opts *ListOptions) (*Links, *Response, error)
|
|
||||||
LinksByHottestInSubreddit(ctx context.Context, subreddit, q string, opts *ListOptions) (*Links, *Response, error)
|
|
||||||
LinksByTopInSubreddit(ctx context.Context, subreddit, q string, opts *ListOptions) (*Links, *Response, error)
|
|
||||||
LinksByCommentsInSubreddit(ctx context.Context, subreddit, q string, opts *ListOptions) (*Links, *Response, error)
|
|
||||||
|
|
||||||
Subreddits(ctx context.Context, q string, opts *ListOptions) (*Subreddits, *Response, error)
|
|
||||||
SubredditNames(ctx context.Context, q string) ([]string, *Response, error)
|
|
||||||
SubredditInfo(ctx context.Context, q string) ([]SubredditShort, *Response, error)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SearchServiceOp implements the VoteService interface
|
// SearchServiceOp implements the VoteService interface
|
||||||
@@ -35,153 +25,161 @@ type SearchServiceOp struct {
|
|||||||
|
|
||||||
var _ SearchService = &SearchServiceOp{}
|
var _ SearchService = &SearchServiceOp{}
|
||||||
|
|
||||||
type searchQuery struct {
|
// Posts searches for posts.
|
||||||
ListOptions
|
// By default, it searches for the most relevant posts of all time.
|
||||||
Query string `url:"q,omitempty"`
|
// To change the sorting, use PostSearchBuilder.Sort().
|
||||||
Type string `url:"type,omitempty"`
|
// Possible sort options: relevance, hot, top, new, comments.
|
||||||
Sort string `url:"sort,omitempty"`
|
// To change the timespan, use PostSearchBuilder.Timespan().
|
||||||
|
// Possible timespan options: hour, day, week, month, year, all.
|
||||||
|
func (s *SearchServiceOp) Posts(query string) *PostSearchBuilder {
|
||||||
|
b := new(PostSearchBuilder)
|
||||||
|
b.client = s.client
|
||||||
|
b.opts.Query = query
|
||||||
|
b.opts.Type = "link"
|
||||||
|
b.opts.Sort = SortRelevance.String()
|
||||||
|
b.opts.Timespan = TimespanAll.String()
|
||||||
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
type subredditNamesRoot struct {
|
// Subreddits searches for subreddits.
|
||||||
Names []string `json:"names,omitempty"`
|
func (s *SearchServiceOp) Subreddits(query string) *SubredditSearchBuilder {
|
||||||
|
b := new(SubredditSearchBuilder)
|
||||||
|
b.client = s.client
|
||||||
|
b.opts.Query = query
|
||||||
|
b.opts.Type = "sr"
|
||||||
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
type subredditShortsRoot struct {
|
// Users searches for users.
|
||||||
Subreddits []SubredditShort `json:"subreddits,omitempty"`
|
func (s *SearchServiceOp) Users(query string) *UserSearchBuilder {
|
||||||
|
b := new(UserSearchBuilder)
|
||||||
|
b.client = s.client
|
||||||
|
b.opts.Query = query
|
||||||
|
b.opts.Type = "user"
|
||||||
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
// SubredditShort represents minimal information about a subreddit
|
type searchOpts struct {
|
||||||
type SubredditShort struct {
|
Query string `url:"q"`
|
||||||
Name string `json:"name,omitempty"`
|
Type string `url:"type,omitempty"`
|
||||||
Subscribers int `json:"subscriber_count"`
|
After string `url:"after,omitempty"`
|
||||||
ActiveUsers int `json:"active_user_count"`
|
Before string `url:"before,omitempty"`
|
||||||
|
Limit int `url:"limit,omitempty"`
|
||||||
|
RestrictSubreddits bool `url:"restrict_sr,omitempty"`
|
||||||
|
Sort string `url:"sort,omitempty"`
|
||||||
|
Timespan string `url:"t,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func newSearchQuery(query, _type, sort string, opts *ListOptions) *searchQuery {
|
// PostSearchBuilder helps conducts searches that return posts.
|
||||||
if opts == nil {
|
type PostSearchBuilder struct {
|
||||||
opts = &ListOptions{}
|
client *Client
|
||||||
|
subreddits []string
|
||||||
|
opts searchOpts
|
||||||
|
}
|
||||||
|
|
||||||
|
// After sets the after option.
|
||||||
|
func (b *PostSearchBuilder) After(after string) *PostSearchBuilder {
|
||||||
|
b.opts.After = after
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// Before sets the before option.
|
||||||
|
func (b *PostSearchBuilder) Before(before string) *PostSearchBuilder {
|
||||||
|
b.opts.Before = before
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// Limit sets the limit option.
|
||||||
|
func (b *PostSearchBuilder) Limit(limit int) *PostSearchBuilder {
|
||||||
|
b.opts.Limit = limit
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// InSubreddits restricts the search to happen in the specified subreddits only.
|
||||||
|
// If none are set, the search is run against r/all.
|
||||||
|
func (b *PostSearchBuilder) InSubreddits(subreddits ...string) *PostSearchBuilder {
|
||||||
|
b.subreddits = subreddits
|
||||||
|
b.opts.RestrictSubreddits = len(subreddits) > 0
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort sets the sort option.
|
||||||
|
func (b *PostSearchBuilder) Sort(sort Sort) *PostSearchBuilder {
|
||||||
|
b.opts.Sort = sort.String()
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// Timespan sets the timespan option.
|
||||||
|
func (b *PostSearchBuilder) Timespan(timespan Timespan) *PostSearchBuilder {
|
||||||
|
b.opts.Timespan = timespan.String()
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do conducts the search.
|
||||||
|
func (b *PostSearchBuilder) Do(ctx context.Context) (*Links, *Response, error) {
|
||||||
|
path := "search"
|
||||||
|
if len(b.subreddits) > 0 {
|
||||||
|
path = fmt.Sprintf("r/%s/search", strings.Join(b.subreddits, "+"))
|
||||||
}
|
}
|
||||||
return &searchQuery{
|
|
||||||
ListOptions: *opts,
|
|
||||||
Query: query,
|
|
||||||
Type: _type,
|
|
||||||
Sort: sort,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Users searches for users
|
path, err := addOptions(path, b.opts)
|
||||||
func (s *SearchServiceOp) Users(ctx context.Context, q string, opts *ListOptions) (*Users, *Response, error) {
|
|
||||||
query := newSearchQuery(q, "user", "", opts)
|
|
||||||
|
|
||||||
root, resp, err := s.search(ctx, "", query)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return root.getUsers(), resp, nil
|
req, err := b.client.NewRequest(http.MethodGet, path, nil)
|
||||||
}
|
|
||||||
|
|
||||||
// LinksByRelevance searches for links sorted by relevance to the search query in all of Reddit
|
|
||||||
func (s *SearchServiceOp) LinksByRelevance(ctx context.Context, q string, opts *ListOptions) (*Links, *Response, error) {
|
|
||||||
query := newSearchQuery(q, "link", sorts[sortRelevance], opts)
|
|
||||||
|
|
||||||
root, resp, err := s.search(ctx, "", query)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
root := new(rootListing)
|
||||||
|
resp, err := b.client.Do(ctx, req, root)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
return root.getLinks(), resp, nil
|
return root.getLinks(), resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// LinksByHottest searches for the hottest links in all of Reddit
|
// SubredditSearchBuilder helps conducts searches that return subreddits.
|
||||||
func (s *SearchServiceOp) LinksByHottest(ctx context.Context, q string, opts *ListOptions) (*Links, *Response, error) {
|
type SubredditSearchBuilder struct {
|
||||||
query := newSearchQuery(q, "link", sorts[sortHot], opts)
|
client *Client
|
||||||
|
opts searchOpts
|
||||||
|
}
|
||||||
|
|
||||||
root, resp, err := s.search(ctx, "", query)
|
// After sets the after option.
|
||||||
|
func (b *SubredditSearchBuilder) After(after string) *SubredditSearchBuilder {
|
||||||
|
b.opts.After = after
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// Before sets the before option.
|
||||||
|
func (b *SubredditSearchBuilder) Before(before string) *SubredditSearchBuilder {
|
||||||
|
b.opts.Before = before
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// Limit sets the limit option.
|
||||||
|
func (b *SubredditSearchBuilder) Limit(limit int) *SubredditSearchBuilder {
|
||||||
|
b.opts.Limit = limit
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do conducts the search.
|
||||||
|
func (b *SubredditSearchBuilder) Do(ctx context.Context) (*Subreddits, *Response, error) {
|
||||||
|
path := "search"
|
||||||
|
path, err := addOptions(path, b.opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return root.getLinks(), resp, nil
|
req, err := b.client.NewRequest(http.MethodGet, path, nil)
|
||||||
}
|
|
||||||
|
|
||||||
// LinksByTop searches for the top links in all of Reddit
|
|
||||||
func (s *SearchServiceOp) LinksByTop(ctx context.Context, q string, opts *ListOptions) (*Links, *Response, error) {
|
|
||||||
query := newSearchQuery(q, "link", sorts[sortTop], opts)
|
|
||||||
|
|
||||||
root, resp, err := s.search(ctx, "", query)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return root.getLinks(), resp, nil
|
root := new(rootListing)
|
||||||
}
|
resp, err := b.client.Do(ctx, req, root)
|
||||||
|
|
||||||
// LinksByComments searches for links with the highest number of comments in all of Reddit
|
|
||||||
func (s *SearchServiceOp) LinksByComments(ctx context.Context, q string, opts *ListOptions) (*Links, *Response, error) {
|
|
||||||
query := newSearchQuery(q, "link", sorts[sortComments], opts)
|
|
||||||
|
|
||||||
root, resp, err := s.search(ctx, "", query)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return root.getLinks(), resp, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// LinksByRelevanceInSubreddit searches for link sorted by relevance to the search query in the specified subreddit
|
|
||||||
func (s *SearchServiceOp) LinksByRelevanceInSubreddit(ctx context.Context, subreddit, q string, opts *ListOptions) (*Links, *Response, error) {
|
|
||||||
query := newSearchQuery(q, "link", sorts[sortRelevance], opts)
|
|
||||||
|
|
||||||
root, resp, err := s.search(ctx, subreddit, query)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return root.getLinks(), resp, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// LinksByHottestInSubreddit searches for the hottest links in the specified subreddit
|
|
||||||
func (s *SearchServiceOp) LinksByHottestInSubreddit(ctx context.Context, subreddit, q string, opts *ListOptions) (*Links, *Response, error) {
|
|
||||||
query := newSearchQuery(q, "link", sorts[sortHot], opts)
|
|
||||||
|
|
||||||
root, resp, err := s.search(ctx, subreddit, query)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return root.getLinks(), resp, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// LinksByTopInSubreddit searches for the top links in the specified subreddit
|
|
||||||
func (s *SearchServiceOp) LinksByTopInSubreddit(ctx context.Context, subreddit, q string, opts *ListOptions) (*Links, *Response, error) {
|
|
||||||
query := newSearchQuery(q, "link", sorts[sortTop], opts)
|
|
||||||
|
|
||||||
root, resp, err := s.search(ctx, subreddit, query)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return root.getLinks(), resp, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// LinksByCommentsInSubreddit searches for links with the highest number of comments in the specified subreddit
|
|
||||||
func (s *SearchServiceOp) LinksByCommentsInSubreddit(ctx context.Context, subreddit, q string, opts *ListOptions) (*Links, *Response, error) {
|
|
||||||
query := newSearchQuery(q, "link", sorts[sortComments], opts)
|
|
||||||
|
|
||||||
root, resp, err := s.search(ctx, subreddit, query)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return root.getLinks(), resp, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Subreddits searches for subreddits
|
|
||||||
func (s *SearchServiceOp) Subreddits(ctx context.Context, q string, opts *ListOptions) (*Subreddits, *Response, error) {
|
|
||||||
query := newSearchQuery(q, "sr", "", opts)
|
|
||||||
|
|
||||||
root, resp, err := s.search(ctx, "", query)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, resp, err
|
return nil, resp, err
|
||||||
}
|
}
|
||||||
@@ -189,64 +187,48 @@ func (s *SearchServiceOp) Subreddits(ctx context.Context, q string, opts *ListOp
|
|||||||
return root.getSubreddits(), resp, nil
|
return root.getSubreddits(), resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SubredditNames searches for subreddits with names beginning with the query provided
|
// UserSearchBuilder helps conducts searches that return posts.
|
||||||
func (s *SearchServiceOp) SubredditNames(ctx context.Context, q string) ([]string, *Response, error) {
|
type UserSearchBuilder struct {
|
||||||
path := fmt.Sprintf("api/search_reddit_names?query=%s", q)
|
client *Client
|
||||||
|
opts searchOpts
|
||||||
req, err := s.client.NewRequest(http.MethodGet, path, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
root := new(subredditNamesRoot)
|
|
||||||
resp, err := s.client.Do(ctx, req, root)
|
|
||||||
if err != nil {
|
|
||||||
return nil, resp, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return root.Names, resp, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SubredditInfo searches for subreddits with names beginning with the query provided
|
// After sets the after option.
|
||||||
// They hold a bit more info that just the name
|
func (b *UserSearchBuilder) After(after string) *UserSearchBuilder {
|
||||||
func (s *SearchServiceOp) SubredditInfo(ctx context.Context, q string) ([]SubredditShort, *Response, error) {
|
b.opts.After = after
|
||||||
path := fmt.Sprintf("api/search_subreddits?query=%s", q)
|
return b
|
||||||
|
|
||||||
req, err := s.client.NewRequest(http.MethodPost, path, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
root := new(subredditShortsRoot)
|
|
||||||
resp, err := s.client.Do(ctx, req, root)
|
|
||||||
if err != nil {
|
|
||||||
return nil, resp, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return root.Subreddits, resp, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SearchServiceOp) search(ctx context.Context, subreddit string, opts *searchQuery) (*rootListing, *Response, error) {
|
// Before sets the before option.
|
||||||
|
func (b *UserSearchBuilder) Before(before string) *UserSearchBuilder {
|
||||||
|
b.opts.Before = before
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// Limit sets the limit option.
|
||||||
|
func (b *UserSearchBuilder) Limit(limit int) *UserSearchBuilder {
|
||||||
|
b.opts.Limit = limit
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do conducts the search.
|
||||||
|
func (b *UserSearchBuilder) Do(ctx context.Context) (*Users, *Response, error) {
|
||||||
path := "search"
|
path := "search"
|
||||||
if subreddit != "" {
|
path, err := addOptions(path, b.opts)
|
||||||
path = fmt.Sprintf("r/%s/search?restrict_sr=true", subreddit)
|
|
||||||
}
|
|
||||||
|
|
||||||
path, err := addOptions(path, opts)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
req, err := s.client.NewRequest(http.MethodGet, path, nil)
|
req, err := b.client.NewRequest(http.MethodGet, path, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
root := new(rootListing)
|
root := new(rootListing)
|
||||||
resp, err := s.client.Do(ctx, req, root)
|
resp, err := b.client.Do(ctx, req, root)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, resp, err
|
return nil, resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return root, resp, nil
|
return root.getUsers(), resp, nil
|
||||||
}
|
}
|
||||||
|
|||||||
+63
-8
@@ -38,6 +38,9 @@ type SubredditService interface {
|
|||||||
SubscribeByID(ctx context.Context, ids ...string) (*Response, error)
|
SubscribeByID(ctx context.Context, ids ...string) (*Response, error)
|
||||||
Unsubscribe(ctx context.Context, subreddits ...string) (*Response, error)
|
Unsubscribe(ctx context.Context, subreddits ...string) (*Response, error)
|
||||||
UnsubscribeByID(ctx context.Context, ids ...string) (*Response, error)
|
UnsubscribeByID(ctx context.Context, ids ...string) (*Response, error)
|
||||||
|
|
||||||
|
SearchSubredditNames(ctx context.Context, query string) ([]string, *Response, error)
|
||||||
|
SearchSubredditInfo(ctx context.Context, query string) ([]SubredditShort, *Response, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SubredditServiceOp implements the SubredditService interface
|
// SubredditServiceOp implements the SubredditService interface
|
||||||
@@ -47,6 +50,21 @@ type SubredditServiceOp struct {
|
|||||||
|
|
||||||
var _ SubredditService = &SubredditServiceOp{}
|
var _ SubredditService = &SubredditServiceOp{}
|
||||||
|
|
||||||
|
type subredditNamesRoot struct {
|
||||||
|
Names []string `json:"names,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type subredditShortsRoot struct {
|
||||||
|
Subreddits []SubredditShort `json:"subreddits,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SubredditShort represents minimal information about a subreddit
|
||||||
|
type SubredditShort struct {
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
Subscribers int `json:"subscriber_count"`
|
||||||
|
ActiveUsers int `json:"active_user_count"`
|
||||||
|
}
|
||||||
|
|
||||||
// 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 == "" {
|
||||||
@@ -113,7 +131,7 @@ func (s *SubredditServiceOp) GetMineWhereStreams(ctx context.Context, opts *List
|
|||||||
// IMPORTANT: for subreddits, this will include the stickied posts (if any)
|
// 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)
|
// 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) {
|
func (s *SubredditServiceOp) GetHotLinks(ctx context.Context, opts *ListOptions, subreddits ...string) (*Links, *Response, error) {
|
||||||
return s.getLinks(ctx, sortHot, opts, subreddits...)
|
return s.getLinks(ctx, SortHot, opts, subreddits...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetBestLinks returns the best links
|
// GetBestLinks returns the best links
|
||||||
@@ -121,31 +139,31 @@ func (s *SubredditServiceOp) GetHotLinks(ctx context.Context, opts *ListOptions,
|
|||||||
// IMPORTANT: for subreddits, this will include the stickied posts (if any)
|
// 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)
|
// 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) {
|
func (s *SubredditServiceOp) GetBestLinks(ctx context.Context, opts *ListOptions, subreddits ...string) (*Links, *Response, error) {
|
||||||
return s.getLinks(ctx, sortBest, opts, subreddits...)
|
return s.getLinks(ctx, SortBest, opts, subreddits...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetNewLinks returns the new links
|
// GetNewLinks returns the new links
|
||||||
// If no subreddit are provided, then it runs the search against all those the client is subscribed to
|
// 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) {
|
func (s *SubredditServiceOp) GetNewLinks(ctx context.Context, opts *ListOptions, subreddits ...string) (*Links, *Response, error) {
|
||||||
return s.getLinks(ctx, sortNew, opts, subreddits...)
|
return s.getLinks(ctx, SortNew, opts, subreddits...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetRisingLinks returns the rising links
|
// GetRisingLinks returns the rising links
|
||||||
// If no subreddit are provided, then it runs the search against all those the client is subscribed to
|
// 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) {
|
func (s *SubredditServiceOp) GetRisingLinks(ctx context.Context, opts *ListOptions, subreddits ...string) (*Links, *Response, error) {
|
||||||
return s.getLinks(ctx, sortRising, opts, subreddits...)
|
return s.getLinks(ctx, SortRising, opts, subreddits...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetControversialLinks returns the controversial links
|
// GetControversialLinks returns the controversial links
|
||||||
// If no subreddit are provided, then it runs the search against all those the client is subscribed to
|
// 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) {
|
func (s *SubredditServiceOp) GetControversialLinks(ctx context.Context, opts *ListOptions, subreddits ...string) (*Links, *Response, error) {
|
||||||
return s.getLinks(ctx, sortControversial, opts, subreddits...)
|
return s.getLinks(ctx, SortControversial, opts, subreddits...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetTopLinks returns the top links
|
// GetTopLinks returns the top links
|
||||||
// If no subreddit are provided, then it runs the search against all those the client is subscribed to
|
// 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) {
|
func (s *SubredditServiceOp) GetTopLinks(ctx context.Context, opts *ListOptions, subreddits ...string) (*Links, *Response, error) {
|
||||||
return s.getLinks(ctx, sortTop, opts, subreddits...)
|
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)
|
||||||
@@ -194,6 +212,43 @@ func (s *SubredditServiceOp) UnsubscribeByID(ctx context.Context, ids ...string)
|
|||||||
return s.handleSubscription(ctx, form)
|
return s.handleSubscription(ctx, form)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SearchSubredditNames searches for subreddits with names beginning with the query provided
|
||||||
|
func (s *SubredditServiceOp) SearchSubredditNames(ctx context.Context, query string) ([]string, *Response, error) {
|
||||||
|
path := fmt.Sprintf("api/search_reddit_names?query=%s", query)
|
||||||
|
|
||||||
|
req, err := s.client.NewRequest(http.MethodGet, path, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
root := new(subredditNamesRoot)
|
||||||
|
resp, err := s.client.Do(ctx, req, root)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return root.Names, resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SearchSubredditInfo searches for subreddits with names beginning with the query provided.
|
||||||
|
// They hold a bit more info that just the name, but still not much.
|
||||||
|
func (s *SubredditServiceOp) SearchSubredditInfo(ctx context.Context, query string) ([]SubredditShort, *Response, error) {
|
||||||
|
path := fmt.Sprintf("api/search_subreddits?query=%s", query)
|
||||||
|
|
||||||
|
req, err := s.client.NewRequest(http.MethodPost, path, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
root := new(subredditShortsRoot)
|
||||||
|
resp, err := s.client.Do(ctx, req, root)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return root.Subreddits, resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s *SubredditServiceOp) handleSubscription(ctx context.Context, form url.Values) (*Response, error) {
|
func (s *SubredditServiceOp) handleSubscription(ctx context.Context, form url.Values) (*Response, error) {
|
||||||
path := "api/subscribe"
|
path := "api/subscribe"
|
||||||
req, err := s.client.NewPostForm(path, form)
|
req, err := s.client.NewPostForm(path, form)
|
||||||
@@ -237,10 +292,10 @@ 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) {
|
func (s *SubredditServiceOp) getLinks(ctx context.Context, sort Sort, opts *ListOptions, subreddits ...string) (*Links, *Response, error) {
|
||||||
path := sorts[sort]
|
path := sorts[sort]
|
||||||
if len(subreddits) > 0 {
|
if len(subreddits) > 0 {
|
||||||
path = fmt.Sprintf("r/%s/%s", strings.Join(subreddits, "+"), sorts[sort])
|
path = fmt.Sprintf("r/%s/%s", strings.Join(subreddits, "+"), sort)
|
||||||
}
|
}
|
||||||
|
|
||||||
path, err := addOptions(path, opts)
|
path, err := addOptions(path, opts)
|
||||||
|
|||||||
@@ -17,18 +17,8 @@ const (
|
|||||||
kindMode = "more"
|
kindMode = "more"
|
||||||
)
|
)
|
||||||
|
|
||||||
type sort int
|
// Sort is a sorting option.
|
||||||
|
type Sort int
|
||||||
const (
|
|
||||||
sortHot sort = iota
|
|
||||||
sortBest
|
|
||||||
sortNew
|
|
||||||
sortRising
|
|
||||||
sortControversial
|
|
||||||
sortTop
|
|
||||||
sortRelevance
|
|
||||||
sortComments
|
|
||||||
)
|
|
||||||
|
|
||||||
var sorts = [...]string{
|
var sorts = [...]string{
|
||||||
"hot",
|
"hot",
|
||||||
@@ -37,12 +27,60 @@ var sorts = [...]string{
|
|||||||
"rising",
|
"rising",
|
||||||
"controversial",
|
"controversial",
|
||||||
"top",
|
"top",
|
||||||
|
|
||||||
// for search queries
|
|
||||||
"relevance",
|
"relevance",
|
||||||
"comments",
|
"comments",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Different sorting options.
|
||||||
|
const (
|
||||||
|
SortHot Sort = iota
|
||||||
|
SortBest
|
||||||
|
SortNew
|
||||||
|
SortRising
|
||||||
|
SortControversial
|
||||||
|
SortTop
|
||||||
|
SortRelevance
|
||||||
|
SortComments
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s Sort) String() string {
|
||||||
|
if s < SortHot || s > SortComments {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return sorts[s]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Timespan is a timespan option.
|
||||||
|
// E.g. "hour" means in the last hour, "all" means all-time.
|
||||||
|
// It is used when conducting searches.
|
||||||
|
type Timespan int
|
||||||
|
|
||||||
|
var timespans = [...]string{
|
||||||
|
"hour",
|
||||||
|
"day",
|
||||||
|
"week",
|
||||||
|
"month",
|
||||||
|
"year",
|
||||||
|
"all",
|
||||||
|
}
|
||||||
|
|
||||||
|
// Different timespan options.
|
||||||
|
const (
|
||||||
|
TimespanHour Timespan = iota
|
||||||
|
TimespanDay
|
||||||
|
TimespanWeek
|
||||||
|
TimespanMonth
|
||||||
|
TimespanYear
|
||||||
|
TimespanAll
|
||||||
|
)
|
||||||
|
|
||||||
|
func (t Timespan) String() string {
|
||||||
|
if t < TimespanHour || t > TimespanAll {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return timespans[t]
|
||||||
|
}
|
||||||
|
|
||||||
type sticky int
|
type sticky int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|||||||
@@ -191,25 +191,25 @@ func (s *UserServiceOp) GetControversialLinks(ctx context.Context, opts *ListOpt
|
|||||||
|
|
||||||
// GetHotLinksOf returns a list of the user's hottest submissions
|
// GetHotLinksOf returns a list of the user's hottest submissions
|
||||||
func (s *UserServiceOp) GetHotLinksOf(ctx context.Context, username string, opts *ListOptions) (*Links, *Response, error) {
|
func (s *UserServiceOp) GetHotLinksOf(ctx context.Context, username string, opts *ListOptions) (*Links, *Response, error) {
|
||||||
path := fmt.Sprintf("user/%s/submitted?sort=%s", username, sorts[sortHot])
|
path := fmt.Sprintf("user/%s/submitted?sort=%s", username, SortHot)
|
||||||
return s.getLinks(ctx, path, opts)
|
return s.getLinks(ctx, path, opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetNewLinksOf returns a list of the user's newest submissions
|
// GetNewLinksOf returns a list of the user's newest submissions
|
||||||
func (s *UserServiceOp) GetNewLinksOf(ctx context.Context, username string, opts *ListOptions) (*Links, *Response, error) {
|
func (s *UserServiceOp) GetNewLinksOf(ctx context.Context, username string, opts *ListOptions) (*Links, *Response, error) {
|
||||||
path := fmt.Sprintf("user/%s/submitted?sort=%s", username, sorts[sortNew])
|
path := fmt.Sprintf("user/%s/submitted?sort=%s", username, SortNew)
|
||||||
return s.getLinks(ctx, path, opts)
|
return s.getLinks(ctx, path, opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetTopLinksOf returns a list of the user's top submissions
|
// GetTopLinksOf returns a list of the user's top submissions
|
||||||
func (s *UserServiceOp) GetTopLinksOf(ctx context.Context, username string, opts *ListOptions) (*Links, *Response, error) {
|
func (s *UserServiceOp) GetTopLinksOf(ctx context.Context, username string, opts *ListOptions) (*Links, *Response, error) {
|
||||||
path := fmt.Sprintf("user/%s/submitted?sort=%s", username, sorts[sortTop])
|
path := fmt.Sprintf("user/%s/submitted?sort=%s", username, SortTop)
|
||||||
return s.getLinks(ctx, path, opts)
|
return s.getLinks(ctx, path, opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetControversialLinksOf returns a list of the user's most controversial submissions
|
// GetControversialLinksOf returns a list of the user's most controversial submissions
|
||||||
func (s *UserServiceOp) GetControversialLinksOf(ctx context.Context, username string, opts *ListOptions) (*Links, *Response, error) {
|
func (s *UserServiceOp) GetControversialLinksOf(ctx context.Context, username string, opts *ListOptions) (*Links, *Response, error) {
|
||||||
path := fmt.Sprintf("user/%s/submitted?sort=%s", username, sorts[sortControversial])
|
path := fmt.Sprintf("user/%s/submitted?sort=%s", username, SortControversial)
|
||||||
return s.getLinks(ctx, path, opts)
|
return s.getLinks(ctx, path, opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -265,25 +265,25 @@ func (s *UserServiceOp) GetControversialComments(ctx context.Context, opts *List
|
|||||||
|
|
||||||
// GetHotCommentsOf returns a list of the user's hottest comments
|
// GetHotCommentsOf returns a list of the user's hottest comments
|
||||||
func (s *UserServiceOp) GetHotCommentsOf(ctx context.Context, username string, opts *ListOptions) (*Comments, *Response, error) {
|
func (s *UserServiceOp) GetHotCommentsOf(ctx context.Context, username string, opts *ListOptions) (*Comments, *Response, error) {
|
||||||
path := fmt.Sprintf("user/%s/comments?sort=%s", username, sorts[sortHot])
|
path := fmt.Sprintf("user/%s/comments?sort=%s", username, SortHot)
|
||||||
return s.getComments(ctx, path, opts)
|
return s.getComments(ctx, path, opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetNewCommentsOf returns a list of the user's newest comments
|
// GetNewCommentsOf returns a list of the user's newest comments
|
||||||
func (s *UserServiceOp) GetNewCommentsOf(ctx context.Context, username string, opts *ListOptions) (*Comments, *Response, error) {
|
func (s *UserServiceOp) GetNewCommentsOf(ctx context.Context, username string, opts *ListOptions) (*Comments, *Response, error) {
|
||||||
path := fmt.Sprintf("user/%s/comments?sort=%s", username, sorts[sortNew])
|
path := fmt.Sprintf("user/%s/comments?sort=%s", username, SortNew)
|
||||||
return s.getComments(ctx, path, opts)
|
return s.getComments(ctx, path, opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetTopCommentsOf returns a list of the user's top comments
|
// GetTopCommentsOf returns a list of the user's top comments
|
||||||
func (s *UserServiceOp) GetTopCommentsOf(ctx context.Context, username string, opts *ListOptions) (*Comments, *Response, error) {
|
func (s *UserServiceOp) GetTopCommentsOf(ctx context.Context, username string, opts *ListOptions) (*Comments, *Response, error) {
|
||||||
path := fmt.Sprintf("user/%s/comments?sort=%s", username, sorts[sortTop])
|
path := fmt.Sprintf("user/%s/comments?sort=%s", username, SortTop)
|
||||||
return s.getComments(ctx, path, opts)
|
return s.getComments(ctx, path, opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetControversialCommentsOf returns a list of the user's most controversial comments
|
// GetControversialCommentsOf returns a list of the user's most controversial comments
|
||||||
func (s *UserServiceOp) GetControversialCommentsOf(ctx context.Context, username string, opts *ListOptions) (*Comments, *Response, error) {
|
func (s *UserServiceOp) GetControversialCommentsOf(ctx context.Context, username string, opts *ListOptions) (*Comments, *Response, error) {
|
||||||
path := fmt.Sprintf("user/%s/comments?sort=%s", username, sorts[sortControversial])
|
path := fmt.Sprintf("user/%s/comments?sort=%s", username, SortControversial)
|
||||||
return s.getComments(ctx, path, opts)
|
return s.getComments(ctx, path, opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user