7b83e8366a
Signed-off-by: Vartan Benohanian <vartanbeno@gmail.com>
135 lines
3.1 KiB
Go
135 lines
3.1 KiB
Go
package geddit
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
)
|
|
|
|
// todo: query parameter "show" = "all"
|
|
|
|
// Searcher defines some parameters common to all requests
|
|
// used to conduct searches against the Reddit API.
|
|
type Searcher interface {
|
|
setAfter(string)
|
|
setBefore(string)
|
|
setLimit(int)
|
|
setSort(Sort)
|
|
setTimespan(Timespan)
|
|
}
|
|
|
|
// Contains all options used for searching.
|
|
// Not all are used for every search endpoint.
|
|
// For example, for getting a user's posts, "q" is not used.
|
|
// After/Before are used as the anchor points for subsequent searches.
|
|
// Limit is the maximum number of items to be returned (default: 25, max: 100).
|
|
// Sort: hot, new, top, controversial, etc.
|
|
// Timespan: hour, day, week, month, year, all.
|
|
type searchOpts struct {
|
|
Query string `url:"q,omitempty"`
|
|
Type string `url:"type,omitempty"`
|
|
After string `url:"after,omitempty"`
|
|
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"`
|
|
}
|
|
|
|
type clientSearcher struct {
|
|
client *Client
|
|
opts searchOpts
|
|
}
|
|
|
|
var _ Searcher = &clientSearcher{}
|
|
|
|
func (s *clientSearcher) setAfter(v string) {
|
|
s.opts.After = v
|
|
}
|
|
|
|
func (s *clientSearcher) setBefore(v string) {
|
|
s.opts.Before = v
|
|
}
|
|
|
|
func (s *clientSearcher) setLimit(v int) {
|
|
s.opts.Limit = v
|
|
}
|
|
|
|
func (s *clientSearcher) setSort(v Sort) {
|
|
s.opts.Sort = v.String()
|
|
}
|
|
|
|
func (s *clientSearcher) setTimespan(v Timespan) {
|
|
s.opts.Timespan = v.String()
|
|
}
|
|
|
|
func (s *clientSearcher) Do(ctx context.Context, path string) (*rootListing, *Response, error) {
|
|
path, err := addOptions(path, s.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
|
|
}
|
|
|
|
return root, resp, nil
|
|
}
|
|
|
|
// SearchOpt sets search options.
|
|
type SearchOpt func(s Searcher)
|
|
|
|
// SetAfter sets the after option.
|
|
func SetAfter(v string) SearchOpt {
|
|
return func(s Searcher) {
|
|
s.setAfter(v)
|
|
}
|
|
}
|
|
|
|
// SetBefore sets the before option.
|
|
func SetBefore(v string) SearchOpt {
|
|
return func(s Searcher) {
|
|
s.setBefore(v)
|
|
}
|
|
}
|
|
|
|
// SetLimit sets the limit option.
|
|
func SetLimit(v int) SearchOpt {
|
|
return func(s Searcher) {
|
|
s.setLimit(v)
|
|
}
|
|
}
|
|
|
|
// SetSort sets the sort option.
|
|
func SetSort(v Sort) SearchOpt {
|
|
return func(s Searcher) {
|
|
s.setSort(v)
|
|
}
|
|
}
|
|
|
|
// SetTimespan sets the timespan option.
|
|
func SetTimespan(v Timespan) SearchOpt {
|
|
return func(s Searcher) {
|
|
s.setTimespan(v)
|
|
}
|
|
}
|
|
|
|
// FromSubreddits is an option that restricts the
|
|
// search to happen in the specified subreddits.
|
|
// If none are specified, it's like searching r/all.
|
|
// This option is only applicable to the PostSearcher.
|
|
func FromSubreddits(subreddits ...string) SearchOpt {
|
|
return func(s Searcher) {
|
|
if ps, ok := s.(*PostSearcher); ok {
|
|
ps.subreddits = subreddits
|
|
ps.opts.RestrictSubreddits = len(subreddits) > 0
|
|
}
|
|
}
|
|
}
|