Rename structs, move them to a separate file

Signed-off-by: Vartan Benohanian <vartanbeno@gmail.com>
This commit is contained in:
Vartan Benohanian 2020-05-03 19:17:39 -04:00
parent 9e7cb10526
commit c897c14b23
6 changed files with 343 additions and 362 deletions

View File

@ -25,15 +25,6 @@ type CommentServiceOp struct {
var _ CommentService = &CommentServiceOp{}
// CommentList holds information about a list of comments
// The after and before fields help decide the anchor point for a subsequent
// call that returns a list
type CommentList struct {
Comments []Comment `json:"comments,omitempty"`
After string `json:"after,omitempty"`
Before string `json:"before,omitempty"`
}
func (s *CommentServiceOp) isCommentID(id string) bool {
return strings.HasPrefix(id, kindComment+"_")
}

230
geddit.go
View File

@ -380,233 +380,3 @@ func addOptions(s string, opt interface{}) (string, error) {
origURL.RawQuery = origValues.Encode()
return origURL.String(), nil
}
type root struct {
Kind string `json:"kind,omitempty"`
Data interface{} `json:"data,omitempty"`
}
type rootListing struct {
Kind string `json:"kind,omitempty"`
Data *Listing `json:"data"`
}
// Listing holds things coming from the Reddit API
// It also contains the after/before anchors useful for subsequent requests
type Listing struct {
Things Things `json:"children"`
After string `json:"after"`
Before string `json:"before"`
}
// Things are stuff!
type Things struct {
Comments []Comment `json:"comments,omitempty"`
Links []Link `json:"links,omitempty"`
Subreddits []Subreddit `json:"subreddits,omitempty"`
// todo: add the other kinds of things
}
// UnmarshalJSON implements the json.Unmarshaler interface.
func (l *Things) UnmarshalJSON(b []byte) error {
var children []map[string]interface{}
if err := json.Unmarshal(b, &children); err != nil {
return err
}
for _, child := range children {
byteValue, _ := json.Marshal(child)
switch child["kind"] {
case kindComment:
root := new(commentRoot)
if err := json.Unmarshal(byteValue, root); err == nil && root.Data != nil {
l.Comments = append(l.Comments, *root.Data)
}
case kindAccount:
case kindLink:
root := new(linkRoot)
if err := json.Unmarshal(byteValue, root); err == nil && root.Data != nil {
l.Links = append(l.Links, *root.Data)
}
case kindMessage:
case kindSubreddit:
root := new(subredditRoot)
if err := json.Unmarshal(byteValue, root); err == nil && root.Data != nil {
l.Subreddits = append(l.Subreddits, *root.Data)
}
case kindAward:
}
}
return nil
}
const (
kindListing string = "Listing"
kindComment string = "t1"
kindAccount string = "t2"
kindLink string = "t3"
kindMessage string = "t4"
kindSubreddit string = "t5"
kindAward string = "t6"
)
type commentRoot struct {
Kind string `json:"kind,omitempty"`
Data *Comment `json:"data,omitempty"`
}
type linkRoot struct {
Kind string `json:"kind,omitempty"`
Data *Link `json:"data,omitempty"`
}
type subredditRoot struct {
Kind string `json:"kind,omitempty"`
Data *Subreddit `json:"data,omitempty"`
}
// Comment is a comment posted by a user
type Comment struct {
ID string `json:"id,omitempty"`
FullID string `json:"name,omitempty"`
ParentID string `json:"parent_id,omitempty"`
Permalink string `json:"permalink,omitempty"`
Body string `json:"body,omitempty"`
Author string `json:"author,omitempty"`
AuthorID string `json:"author_fullname,omitempty"`
AuthorFlairText string `json:"author_flair_text,omitempty"`
AuthorFlairID string `json:"author_flair_template_id,omitempty"`
Subreddit string `json:"subreddit,omitempty"`
SubredditNamePrefixed string `json:"subreddit_name_prefixed,omitempty"`
SubredditID string `json:"subreddit_id,omitempty"`
Score int `json:"score"`
Controversiality int `json:"controversiality"`
Created *Timestamp `json:"created_utc,omitempty"`
Edited *Timestamp `json:"edited,omitempty"`
LinkID string `json:"link_id,omitempty"`
// These don't appear when submitting a comment
LinkTitle string `json:"link_title,omitempty"`
LinkPermalink string `json:"link_permalink,omitempty"`
LinkAuthor string `json:"link_author,omitempty"`
LinkNumComments int `json:"num_comments"`
IsSubmitter bool `json:"is_submitter"`
ScoreHidden bool `json:"score_hidden"`
Saved bool `json:"saved"`
Stickied bool `json:"stickied"`
Locked bool `json:"locked"`
CanGild bool `json:"can_gild"`
NSFW bool `json:"over_18"`
// If a comment has no replies, its "replies" value is "",
// which the unmarshaler doesn't like
// So we capture this varying field in RepliesRaw, and then
// fill it in Replies
RepliesRaw json.RawMessage `json:"replies,omitempty"`
Replies []commentRoot `json:"-"`
}
// Link is a submitted post on Reddit
type Link struct {
ID string `json:"id,omitempty"`
FullID string `json:"name,omitempty"`
Created *Timestamp `json:"created_utc,omitempty"`
Edited *Timestamp `json:"edited,omitempty"`
Permalink string `json:"permalink,omitempty"`
URL string `json:"url,omitempty"`
Title string `json:"title,omitempty"`
Body string `json:"selftext,omitempty"`
Score int `json:"score"`
NumberOfComments int `json:"num_comments"`
SubredditID string `json:"subreddit_id,omitempty"`
SubredditName string `json:"subreddit,omitempty"`
SubredditNamePrefixed string `json:"subreddit_name_prefixed,omitempty"`
AuthorID string `json:"author_fullname,omitempty"`
AuthorName string `json:"author,omitempty"`
Spoiler bool `json:"spoiler"`
Locked bool `json:"locked"`
NSFW bool `json:"over_18"`
IsSelfPost bool `json:"is_self"`
Saved bool `json:"saved"`
Stickied bool `json:"stickied"`
}
// Subreddit holds information about a subreddit
type Subreddit struct {
ID string `json:"id,omitempty"`
FullID string `json:"name,omitempty"`
Created *Timestamp `json:"created_utc,omitempty"`
URL string `json:"url,omitempty"`
Name string `json:"display_name,omitempty"`
NamePrefixed string `json:"display_name_prefixed,omitempty"`
Title string `json:"title,omitempty"`
PublicDescription string `json:"public_description,omitempty"`
Type string `json:"subreddit_type,omitempty"`
SuggestedCommentSort string `json:"suggested_comment_sort,omitempty"`
Subscribers int `json:"subscribers"`
ActiveUserCount *int `json:"active_user_count,omitempty"`
NSFW bool `json:"over18"`
UserIsMod bool `json:"user_is_moderator"`
}
func (rl *rootListing) getAfter() string {
if rl == nil || rl.Data == nil {
return ""
}
return rl.Data.After
}
func (rl *rootListing) getBefore() string {
if rl == nil || rl.Data == nil {
return ""
}
return rl.Data.Before
}
func (rl *rootListing) getComments() *CommentList {
if rl == nil || rl.Data == nil {
return nil
}
return &CommentList{
Comments: rl.Data.Things.Comments,
After: rl.Data.After,
Before: rl.Data.Before,
}
}
func (rl *rootListing) getLinks() *LinkList {
if rl == nil || rl.Data == nil {
return nil
}
return &LinkList{
Links: rl.Data.Things.Links,
After: rl.Data.After,
Before: rl.Data.Before,
}
}
func (rl *rootListing) getSubreddits() *SubredditList {
if rl == nil || rl.Data == nil {
return nil
}
return &SubredditList{
Subreddits: rl.Data.Things.Subreddits,
After: rl.Data.After,
Before: rl.Data.Before,
}
}

View File

@ -18,30 +18,6 @@ type ListingsServiceOp struct {
var _ ListingsService = &ListingsServiceOp{}
type listingRoot struct {
Kind string `json:"kind,omitempty"`
Data *struct {
Dist int `json:"dist"`
Children []map[string]interface{} `json:"children,omitempty"`
After string `json:"after,omitempty"`
Before string `json:"before,omitempty"`
} `json:"data,omitempty"`
}
// Listing holds various types of things that all come from the Reddit API
// type Listing struct {
// Links []*Submission `json:"links,omitempty"`
// Comments []*Comment `json:"comments,omitempty"`
// Subreddits []*Subreddit `json:"subreddits,omitempty"`
// }
// CommentsLinksSubreddits holds comments, links, and subreddits
type CommentsLinksSubreddits struct {
Comments []Comment `json:"comments,omitempty"`
Links []Link `json:"links,omitempty"`
Subreddits []Subreddit `json:"subreddits,omitempty"`
}
// Get gets a list of things based on their IDs
// Only links, comments, and subreddits are allowed
func (s *ListingsServiceOp) Get(ctx context.Context, ids ...string) (*CommentsLinksSubreddits, *Response, error) {

View File

@ -15,22 +15,22 @@ import (
type SubredditService interface {
GetByName(ctx context.Context, name string) (*Subreddit, *Response, error)
GetPopular(ctx context.Context, opts *ListOptions) (*SubredditList, *Response, error)
GetNew(ctx context.Context, opts *ListOptions) (*SubredditList, *Response, error)
GetGold(ctx context.Context, opts *ListOptions) (*SubredditList, *Response, error)
GetDefault(ctx context.Context, opts *ListOptions) (*SubredditList, *Response, error)
GetPopular(ctx context.Context, opts *ListOptions) (*Subreddits, *Response, error)
GetNew(ctx context.Context, opts *ListOptions) (*Subreddits, *Response, error)
GetGold(ctx context.Context, opts *ListOptions) (*Subreddits, *Response, error)
GetDefault(ctx context.Context, opts *ListOptions) (*Subreddits, *Response, error)
GetMineWhereSubscriber(ctx context.Context, opts *ListOptions) (*SubredditList, *Response, error)
GetMineWhereContributor(ctx context.Context, opts *ListOptions) (*SubredditList, *Response, error)
GetMineWhereModerator(ctx context.Context, opts *ListOptions) (*SubredditList, *Response, error)
GetMineWhereStreams(ctx context.Context, opts *ListOptions) (*SubredditList, *Response, error)
GetMineWhereSubscriber(ctx context.Context, opts *ListOptions) (*Subreddits, *Response, error)
GetMineWhereContributor(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)
GetHotLinks(ctx context.Context, opts *ListOptions, names ...string) (*LinkList, *Response, error)
GetBestLinks(ctx context.Context, opts *ListOptions, names ...string) (*LinkList, *Response, error)
GetNewLinks(ctx context.Context, opts *ListOptions, names ...string) (*LinkList, *Response, error)
GetRisingLinks(ctx context.Context, opts *ListOptions, names ...string) (*LinkList, *Response, error)
GetControversialLinks(ctx context.Context, opts *ListOptions, names ...string) (*LinkList, *Response, error)
GetTopLinks(ctx context.Context, opts *ListOptions, names ...string) (*LinkList, *Response, error)
GetHotLinks(ctx context.Context, opts *ListOptions, names ...string) (*Links, *Response, error)
GetBestLinks(ctx context.Context, opts *ListOptions, names ...string) (*Links, *Response, error)
GetNewLinks(ctx context.Context, opts *ListOptions, names ...string) (*Links, *Response, error)
GetRisingLinks(ctx context.Context, opts *ListOptions, names ...string) (*Links, *Response, error)
GetControversialLinks(ctx context.Context, opts *ListOptions, names ...string) (*Links, *Response, error)
GetTopLinks(ctx context.Context, opts *ListOptions, names ...string) (*Links, *Response, error)
// GetSticky1(ctx context.Context, name string) (interface{}, *Response, error)
// GetSticky2(ctx context.Context, name string) (interface{}, *Response, error)
@ -50,25 +50,6 @@ type SubredditServiceOp struct {
var _ SubredditService = &SubredditServiceOp{}
// SubredditList holds information about a list of subreddits
// The after and before fields help decide the anchor point for a subsequent
// call that returns a list
type SubredditList struct {
Subreddits []Subreddit `json:"subreddits,omitempty"`
After string `json:"after,omitempty"`
Before string `json:"before,omitempty"`
}
// LinkList holds information about a list of links
// The after and before fields help decide the anchor point for a subsequent
// call that returns a list
// Note: not to be confused with linked lists
type LinkList struct {
Links []Link `json:"submissions,omitempty"`
After string `json:"after,omitempty"`
Before string `json:"before,omitempty"`
}
// GetByName gets a subreddit by name
func (s *SubredditServiceOp) GetByName(ctx context.Context, name string) (*Subreddit, *Response, error) {
if name == "" {
@ -91,42 +72,42 @@ func (s *SubredditServiceOp) GetByName(ctx context.Context, name string) (*Subre
}
// GetPopular returns popular subreddits
func (s *SubredditServiceOp) GetPopular(ctx context.Context, opts *ListOptions) (*SubredditList, *Response, error) {
func (s *SubredditServiceOp) GetPopular(ctx context.Context, opts *ListOptions) (*Subreddits, *Response, error) {
return s.getSubreddits(ctx, "subreddits/popular", opts)
}
// GetNew returns new subreddits
func (s *SubredditServiceOp) GetNew(ctx context.Context, opts *ListOptions) (*SubredditList, *Response, error) {
func (s *SubredditServiceOp) GetNew(ctx context.Context, opts *ListOptions) (*Subreddits, *Response, error) {
return s.getSubreddits(ctx, "subreddits/new", opts)
}
// GetGold returns gold subreddits
func (s *SubredditServiceOp) GetGold(ctx context.Context, opts *ListOptions) (*SubredditList, *Response, error) {
func (s *SubredditServiceOp) GetGold(ctx context.Context, opts *ListOptions) (*Subreddits, *Response, error) {
return s.getSubreddits(ctx, "subreddits/gold", opts)
}
// GetDefault returns default subreddits
func (s *SubredditServiceOp) GetDefault(ctx context.Context, opts *ListOptions) (*SubredditList, *Response, error) {
func (s *SubredditServiceOp) GetDefault(ctx context.Context, opts *ListOptions) (*Subreddits, *Response, error) {
return s.getSubreddits(ctx, "subreddits/default", opts)
}
// GetMineWhereSubscriber returns the list of subreddits the client is subscribed to
func (s *SubredditServiceOp) GetMineWhereSubscriber(ctx context.Context, opts *ListOptions) (*SubredditList, *Response, error) {
func (s *SubredditServiceOp) GetMineWhereSubscriber(ctx context.Context, opts *ListOptions) (*Subreddits, *Response, error) {
return s.getSubreddits(ctx, "subreddits/mine/subscriber", opts)
}
// GetMineWhereContributor returns the list of subreddits the client is a contributor to
func (s *SubredditServiceOp) GetMineWhereContributor(ctx context.Context, opts *ListOptions) (*SubredditList, *Response, error) {
func (s *SubredditServiceOp) GetMineWhereContributor(ctx context.Context, opts *ListOptions) (*Subreddits, *Response, error) {
return s.getSubreddits(ctx, "subreddits/mine/contributor", opts)
}
// GetMineWhereModerator returns the list of subreddits the client is a moderator in
func (s *SubredditServiceOp) GetMineWhereModerator(ctx context.Context, opts *ListOptions) (*SubredditList, *Response, error) {
func (s *SubredditServiceOp) GetMineWhereModerator(ctx context.Context, opts *ListOptions) (*Subreddits, *Response, error) {
return s.getSubreddits(ctx, "subreddits/mine/contributor", opts)
}
// GetMineWhereStreams returns the list of subreddits the client is subscribed to and has hosted videos in
func (s *SubredditServiceOp) GetMineWhereStreams(ctx context.Context, opts *ListOptions) (*SubredditList, *Response, error) {
func (s *SubredditServiceOp) GetMineWhereStreams(ctx context.Context, opts *ListOptions) (*Subreddits, *Response, error) {
return s.getSubreddits(ctx, "subreddits/mine/contributor", opts)
}
@ -154,7 +135,7 @@ var sorts = [...]string{
// If no subreddit names 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, names ...string) (*LinkList, *Response, error) {
func (s *SubredditServiceOp) GetHotLinks(ctx context.Context, opts *ListOptions, names ...string) (*Links, *Response, error) {
return s.getLinks(ctx, sortHot, opts, names...)
}
@ -162,31 +143,31 @@ func (s *SubredditServiceOp) GetHotLinks(ctx context.Context, opts *ListOptions,
// If no subreddit names 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, names ...string) (*LinkList, *Response, error) {
func (s *SubredditServiceOp) GetBestLinks(ctx context.Context, opts *ListOptions, names ...string) (*Links, *Response, error) {
return s.getLinks(ctx, sortBest, opts, names...)
}
// GetNewLinks returns the new links
// If no subreddit names are provided, then it runs the search against all those the client is subscribed to
func (s *SubredditServiceOp) GetNewLinks(ctx context.Context, opts *ListOptions, names ...string) (*LinkList, *Response, error) {
func (s *SubredditServiceOp) GetNewLinks(ctx context.Context, opts *ListOptions, names ...string) (*Links, *Response, error) {
return s.getLinks(ctx, sortNew, opts, names...)
}
// GetRisingLinks returns the rising links
// If no subreddit names are provided, then it runs the search against all those the client is subscribed to
func (s *SubredditServiceOp) GetRisingLinks(ctx context.Context, opts *ListOptions, names ...string) (*LinkList, *Response, error) {
func (s *SubredditServiceOp) GetRisingLinks(ctx context.Context, opts *ListOptions, names ...string) (*Links, *Response, error) {
return s.getLinks(ctx, sortRising, opts, names...)
}
// GetControversialLinks returns the controversial links
// If no subreddit names are provided, then it runs the search against all those the client is subscribed to
func (s *SubredditServiceOp) GetControversialLinks(ctx context.Context, opts *ListOptions, names ...string) (*LinkList, *Response, error) {
func (s *SubredditServiceOp) GetControversialLinks(ctx context.Context, opts *ListOptions, names ...string) (*Links, *Response, error) {
return s.getLinks(ctx, sortControversial, opts, names...)
}
// GetTopLinks returns the top links
// If no subreddit names are provided, then it runs the search against all those the client is subscribed to
func (s *SubredditServiceOp) GetTopLinks(ctx context.Context, opts *ListOptions, names ...string) (*LinkList, *Response, error) {
func (s *SubredditServiceOp) GetTopLinks(ctx context.Context, opts *ListOptions, names ...string) (*Links, *Response, error) {
return s.getLinks(ctx, sortTop, opts, names...)
}
@ -258,7 +239,7 @@ func (s *SubredditServiceOp) handleSubscription(ctx context.Context, form url.Va
return resp, nil
}
func (s *SubredditServiceOp) getSubreddits(ctx context.Context, path string, opts *ListOptions) (*SubredditList, *Response, error) {
func (s *SubredditServiceOp) getSubreddits(ctx context.Context, path string, opts *ListOptions) (*Subreddits, *Response, error) {
path, err := addOptions(path, opts)
if err != nil {
return nil, nil, err
@ -275,7 +256,7 @@ func (s *SubredditServiceOp) getSubreddits(ctx context.Context, path string, opt
return nil, resp, err
}
l := new(SubredditList)
l := new(Subreddits)
if root.Data != nil {
l.Subreddits = root.Data.Things.Subreddits
@ -286,7 +267,7 @@ func (s *SubredditServiceOp) getSubreddits(ctx context.Context, path string, opt
return l, resp, nil
}
func (s *SubredditServiceOp) getLinks(ctx context.Context, sort sort, opts *ListOptions, names ...string) (*LinkList, *Response, error) {
func (s *SubredditServiceOp) getLinks(ctx context.Context, sort sort, opts *ListOptions, names ...string) (*Links, *Response, error) {
path := sorts[sort]
if len(names) > 0 {
path = fmt.Sprintf("r/%s/%s", strings.Join(names, "+"), sorts[sort])
@ -308,7 +289,7 @@ func (s *SubredditServiceOp) getLinks(ctx context.Context, sort sort, opts *List
return nil, resp, err
}
l := new(LinkList)
l := new(Links)
if root.Data != nil {
l.Links = root.Data.Things.Links

271
things.go Normal file
View File

@ -0,0 +1,271 @@
package geddit
import "encoding/json"
const (
kindComment = "t1"
kindAccount = "t2"
kindLink = "t3"
kindMessage = "t4"
kindSubreddit = "t5"
kindAward = "t6"
kindListing = "Listing"
kindUserList = "UserList"
kindMode = "more"
)
type root struct {
Kind string `json:"kind,omitempty"`
Data interface{} `json:"data,omitempty"`
}
type rootListing struct {
Kind string `json:"kind,omitempty"`
Data *Listing `json:"data"`
}
// Listing holds things coming from the Reddit API
// It also contains the after/before anchors useful for subsequent requests
type Listing struct {
Things Things `json:"children"`
After string `json:"after"`
Before string `json:"before"`
}
// Things are stuff!
type Things struct {
Comments []Comment `json:"comments,omitempty"`
Links []Link `json:"links,omitempty"`
Subreddits []Subreddit `json:"subreddits,omitempty"`
// todo: add the other kinds of things
}
type commentRoot struct {
Kind string `json:"kind,omitempty"`
Data *Comment `json:"data,omitempty"`
}
type linkRoot struct {
Kind string `json:"kind,omitempty"`
Data *Link `json:"data,omitempty"`
}
type subredditRoot struct {
Kind string `json:"kind,omitempty"`
Data *Subreddit `json:"data,omitempty"`
}
// UnmarshalJSON implements the json.Unmarshaler interface.
func (l *Things) UnmarshalJSON(b []byte) error {
var children []map[string]interface{}
if err := json.Unmarshal(b, &children); err != nil {
return err
}
for _, child := range children {
byteValue, _ := json.Marshal(child)
switch child["kind"] {
case kindComment:
root := new(commentRoot)
if err := json.Unmarshal(byteValue, root); err == nil && root.Data != nil {
l.Comments = append(l.Comments, *root.Data)
}
case kindAccount:
case kindLink:
root := new(linkRoot)
if err := json.Unmarshal(byteValue, root); err == nil && root.Data != nil {
l.Links = append(l.Links, *root.Data)
}
case kindMessage:
case kindSubreddit:
root := new(subredditRoot)
if err := json.Unmarshal(byteValue, root); err == nil && root.Data != nil {
l.Subreddits = append(l.Subreddits, *root.Data)
}
case kindAward:
}
}
return nil
}
// Comment is a comment posted by a user
type Comment struct {
ID string `json:"id,omitempty"`
FullID string `json:"name,omitempty"`
ParentID string `json:"parent_id,omitempty"`
Permalink string `json:"permalink,omitempty"`
Body string `json:"body,omitempty"`
Author string `json:"author,omitempty"`
AuthorID string `json:"author_fullname,omitempty"`
AuthorFlairText string `json:"author_flair_text,omitempty"`
AuthorFlairID string `json:"author_flair_template_id,omitempty"`
Subreddit string `json:"subreddit,omitempty"`
SubredditNamePrefixed string `json:"subreddit_name_prefixed,omitempty"`
SubredditID string `json:"subreddit_id,omitempty"`
Score int `json:"score"`
Controversiality int `json:"controversiality"`
Created *Timestamp `json:"created_utc,omitempty"`
Edited *Timestamp `json:"edited,omitempty"`
LinkID string `json:"link_id,omitempty"`
// These don't appear when submitting a comment
LinkTitle string `json:"link_title,omitempty"`
LinkPermalink string `json:"link_permalink,omitempty"`
LinkAuthor string `json:"link_author,omitempty"`
LinkNumComments int `json:"num_comments"`
IsSubmitter bool `json:"is_submitter"`
ScoreHidden bool `json:"score_hidden"`
Saved bool `json:"saved"`
Stickied bool `json:"stickied"`
Locked bool `json:"locked"`
CanGild bool `json:"can_gild"`
NSFW bool `json:"over_18"`
// If a comment has no replies, its "replies" value is "",
// which the unmarshaler doesn't like
// So we capture this varying field in RepliesRaw, and then
// fill it in Replies
RepliesRaw json.RawMessage `json:"replies,omitempty"`
Replies []commentRoot `json:"-"`
}
// Link is a submitted post on Reddit
type Link struct {
ID string `json:"id,omitempty"`
FullID string `json:"name,omitempty"`
Created *Timestamp `json:"created_utc,omitempty"`
Edited *Timestamp `json:"edited,omitempty"`
Permalink string `json:"permalink,omitempty"`
URL string `json:"url,omitempty"`
Title string `json:"title,omitempty"`
Body string `json:"selftext,omitempty"`
Score int `json:"score"`
NumberOfComments int `json:"num_comments"`
SubredditID string `json:"subreddit_id,omitempty"`
SubredditName string `json:"subreddit,omitempty"`
SubredditNamePrefixed string `json:"subreddit_name_prefixed,omitempty"`
AuthorID string `json:"author_fullname,omitempty"`
AuthorName string `json:"author,omitempty"`
Spoiler bool `json:"spoiler"`
Locked bool `json:"locked"`
NSFW bool `json:"over_18"`
IsSelfPost bool `json:"is_self"`
Saved bool `json:"saved"`
Stickied bool `json:"stickied"`
}
// Subreddit holds information about a subreddit
type Subreddit struct {
ID string `json:"id,omitempty"`
FullID string `json:"name,omitempty"`
Created *Timestamp `json:"created_utc,omitempty"`
URL string `json:"url,omitempty"`
Name string `json:"display_name,omitempty"`
NamePrefixed string `json:"display_name_prefixed,omitempty"`
Title string `json:"title,omitempty"`
PublicDescription string `json:"public_description,omitempty"`
Type string `json:"subreddit_type,omitempty"`
SuggestedCommentSort string `json:"suggested_comment_sort,omitempty"`
Subscribers int `json:"subscribers"`
ActiveUserCount *int `json:"active_user_count,omitempty"`
NSFW bool `json:"over18"`
UserIsMod bool `json:"user_is_moderator"`
}
func (rl *rootListing) getAfter() string {
if rl == nil || rl.Data == nil {
return ""
}
return rl.Data.After
}
func (rl *rootListing) getBefore() string {
if rl == nil || rl.Data == nil {
return ""
}
return rl.Data.Before
}
func (rl *rootListing) getComments() *Comments {
if rl == nil || rl.Data == nil {
return nil
}
return &Comments{
Comments: rl.Data.Things.Comments,
After: rl.Data.After,
Before: rl.Data.Before,
}
}
func (rl *rootListing) getLinks() *Links {
if rl == nil || rl.Data == nil {
return nil
}
return &Links{
Links: rl.Data.Things.Links,
After: rl.Data.After,
Before: rl.Data.Before,
}
}
func (rl *rootListing) getSubreddits() *Subreddits {
if rl == nil || rl.Data == nil {
return nil
}
return &Subreddits{
Subreddits: rl.Data.Things.Subreddits,
After: rl.Data.After,
Before: rl.Data.Before,
}
}
// Comments is a list of comments
type Comments struct {
Comments []Comment `json:"comments,omitempty"`
After string `json:"after"`
Before string `json:"before"`
}
// Subreddits is a list of subreddits
type Subreddits struct {
Subreddits []Subreddit `json:"subreddits,omitempty"`
After string `json:"after"`
Before string `json:"before"`
}
// Links is a list of links
type Links struct {
Links []Link `json:"submissions,omitempty"`
After string `json:"after"`
Before string `json:"before"`
}
// CommentsLinks is a list of comments and links
type CommentsLinks struct {
Comments []Comment `json:"comments,omitempty"`
Links []Link `json:"links,omitempty"`
After string `json:"after"`
Before string `json:"before"`
}
// CommentsLinksSubreddits is a list of comments, links, and subreddits
type CommentsLinksSubreddits struct {
Comments []Comment `json:"comments,omitempty"`
Links []Link `json:"links,omitempty"`
Subreddits []Subreddit `json:"subreddits,omitempty"`
}

88
user.go
View File

@ -17,34 +17,34 @@ type UserService interface {
Overview(ctx context.Context, opts *ListOptions) (*CommentsLinks, *Response, error)
// returns the client's links
GetHotLinks(ctx context.Context, opts *ListOptions) (*LinkList, *Response, error)
GetNewLinks(ctx context.Context, opts *ListOptions) (*LinkList, *Response, error)
GetTopLinks(ctx context.Context, opts *ListOptions) (*LinkList, *Response, error)
GetControversialLinks(ctx context.Context, opts *ListOptions) (*LinkList, *Response, error)
GetHotLinks(ctx context.Context, opts *ListOptions) (*Links, *Response, error)
GetNewLinks(ctx context.Context, opts *ListOptions) (*Links, *Response, error)
GetTopLinks(ctx context.Context, opts *ListOptions) (*Links, *Response, error)
GetControversialLinks(ctx context.Context, opts *ListOptions) (*Links, *Response, error)
// returns the links of the user with the username
GetHotLinksOf(ctx context.Context, username string, opts *ListOptions) (*LinkList, *Response, error)
GetNewLinksOf(ctx context.Context, username string, opts *ListOptions) (*LinkList, *Response, error)
GetTopLinksOf(ctx context.Context, username string, opts *ListOptions) (*LinkList, *Response, error)
GetControversialLinksOf(ctx context.Context, username string, opts *ListOptions) (*LinkList, *Response, error)
GetHotLinksOf(ctx context.Context, username string, opts *ListOptions) (*Links, *Response, error)
GetNewLinksOf(ctx context.Context, username string, opts *ListOptions) (*Links, *Response, error)
GetTopLinksOf(ctx context.Context, username string, opts *ListOptions) (*Links, *Response, error)
GetControversialLinksOf(ctx context.Context, username string, opts *ListOptions) (*Links, *Response, error)
GetUpvoted(ctx context.Context, opts *ListOptions) (*LinkList, *Response, error)
GetDownvoted(ctx context.Context, opts *ListOptions) (*LinkList, *Response, error)
GetHidden(ctx context.Context, opts *ListOptions) (*LinkList, *Response, error)
GetUpvoted(ctx context.Context, opts *ListOptions) (*Links, *Response, error)
GetDownvoted(ctx context.Context, opts *ListOptions) (*Links, *Response, error)
GetHidden(ctx context.Context, opts *ListOptions) (*Links, *Response, error)
GetSaved(ctx context.Context, opts *ListOptions) (*CommentsLinks, *Response, error)
GetGilded(ctx context.Context, opts *ListOptions) (*CommentsLinks, *Response, error)
// returns the client's comments
GetHotComments(ctx context.Context, opts *ListOptions) (*CommentList, *Response, error)
GetNewComments(ctx context.Context, opts *ListOptions) (*CommentList, *Response, error)
GetTopComments(ctx context.Context, opts *ListOptions) (*CommentList, *Response, error)
GetControversialComments(ctx context.Context, opts *ListOptions) (*CommentList, *Response, error)
GetHotComments(ctx context.Context, opts *ListOptions) (*Comments, *Response, error)
GetNewComments(ctx context.Context, opts *ListOptions) (*Comments, *Response, error)
GetTopComments(ctx context.Context, opts *ListOptions) (*Comments, *Response, error)
GetControversialComments(ctx context.Context, opts *ListOptions) (*Comments, *Response, error)
// returns the comments of the user with the username
GetHotCommentsOf(ctx context.Context, username string, opts *ListOptions) (*CommentList, *Response, error)
GetNewCommentsOf(ctx context.Context, username string, opts *ListOptions) (*CommentList, *Response, error)
GetTopCommentsOf(ctx context.Context, username string, opts *ListOptions) (*CommentList, *Response, error)
GetControversialCommentsOf(ctx context.Context, username string, opts *ListOptions) (*CommentList, *Response, error)
GetHotCommentsOf(ctx context.Context, username string, opts *ListOptions) (*Comments, *Response, error)
GetNewCommentsOf(ctx context.Context, username string, opts *ListOptions) (*Comments, *Response, error)
GetTopCommentsOf(ctx context.Context, username string, opts *ListOptions) (*Comments, *Response, error)
GetControversialCommentsOf(ctx context.Context, username string, opts *ListOptions) (*Comments, *Response, error)
Friend(ctx context.Context, username string, note string) (interface{}, *Response, error)
Unblock(ctx context.Context, username string) (*Response, error)
@ -91,14 +91,6 @@ type UserShort struct {
NSFW bool `json:"profile_over_18"`
}
// CommentsLinks holds comments and links
type CommentsLinks struct {
Comments []Comment `json:"comments,omitempty"`
Links []Link `json:"links,omitempty"`
After string `json:"after"`
Before string `json:"before"`
}
// Get returns information about the user
func (s *UserServiceOp) Get(ctx context.Context, username string) (*User, *Response, error) {
path := fmt.Sprintf("user/%s/about", username)
@ -177,67 +169,67 @@ func (s *UserServiceOp) Overview(ctx context.Context, opts *ListOptions) (*Comme
}
// GetHotLinks returns a list of the client's hottest submissions
func (s *UserServiceOp) GetHotLinks(ctx context.Context, opts *ListOptions) (*LinkList, *Response, error) {
func (s *UserServiceOp) GetHotLinks(ctx context.Context, opts *ListOptions) (*Links, *Response, error) {
path := fmt.Sprintf("user/%s/submitted?sort=%s", s.client.Username, sorts[sortHot])
return s.getLinks(ctx, path, opts)
}
// GetNewLinks returns a list of the client's newest submissions
func (s *UserServiceOp) GetNewLinks(ctx context.Context, opts *ListOptions) (*LinkList, *Response, error) {
func (s *UserServiceOp) GetNewLinks(ctx context.Context, opts *ListOptions) (*Links, *Response, error) {
path := fmt.Sprintf("user/%s/submitted?sort=%s", s.client.Username, sorts[sortNew])
return s.getLinks(ctx, path, opts)
}
// GetTopLinks returns a list of the client's top submissions
func (s *UserServiceOp) GetTopLinks(ctx context.Context, opts *ListOptions) (*LinkList, *Response, error) {
func (s *UserServiceOp) GetTopLinks(ctx context.Context, opts *ListOptions) (*Links, *Response, error) {
path := fmt.Sprintf("user/%s/submitted?sort=%s", s.client.Username, sorts[sortTop])
return s.getLinks(ctx, path, opts)
}
// GetControversialLinks returns a list of the client's most controversial submissions
func (s *UserServiceOp) GetControversialLinks(ctx context.Context, opts *ListOptions) (*LinkList, *Response, error) {
func (s *UserServiceOp) GetControversialLinks(ctx context.Context, opts *ListOptions) (*Links, *Response, error) {
path := fmt.Sprintf("user/%s/submitted?sort=%s", s.client.Username, sorts[sortControversial])
return s.getLinks(ctx, path, opts)
}
// GetHotLinksOf returns a list of the user's hottest submissions
func (s *UserServiceOp) GetHotLinksOf(ctx context.Context, username string, opts *ListOptions) (*LinkList, *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])
return s.getLinks(ctx, path, opts)
}
// GetNewLinksOf returns a list of the user's newest submissions
func (s *UserServiceOp) GetNewLinksOf(ctx context.Context, username string, opts *ListOptions) (*LinkList, *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])
return s.getLinks(ctx, path, opts)
}
// GetTopLinksOf returns a list of the user's top submissions
func (s *UserServiceOp) GetTopLinksOf(ctx context.Context, username string, opts *ListOptions) (*LinkList, *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])
return s.getLinks(ctx, path, opts)
}
// GetControversialLinksOf returns a list of the user's most controversial submissions
func (s *UserServiceOp) GetControversialLinksOf(ctx context.Context, username string, opts *ListOptions) (*LinkList, *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])
return s.getLinks(ctx, path, opts)
}
// GetUpvoted returns a list of the client's upvoted submissions
func (s *UserServiceOp) GetUpvoted(ctx context.Context, opts *ListOptions) (*LinkList, *Response, error) {
func (s *UserServiceOp) GetUpvoted(ctx context.Context, opts *ListOptions) (*Links, *Response, error) {
path := fmt.Sprintf("user/%s/upvoted", s.client.Username)
return s.getLinks(ctx, path, opts)
}
// GetDownvoted returns a list of the client's downvoted submissions
func (s *UserServiceOp) GetDownvoted(ctx context.Context, opts *ListOptions) (*LinkList, *Response, error) {
func (s *UserServiceOp) GetDownvoted(ctx context.Context, opts *ListOptions) (*Links, *Response, error) {
path := fmt.Sprintf("user/%s/downvoted", s.client.Username)
return s.getLinks(ctx, path, opts)
}
// GetHidden returns a list of the client's hidden submissions
func (s *UserServiceOp) GetHidden(ctx context.Context, opts *ListOptions) (*LinkList, *Response, error) {
func (s *UserServiceOp) GetHidden(ctx context.Context, opts *ListOptions) (*Links, *Response, error) {
path := fmt.Sprintf("user/%s/hidden", s.client.Username)
return s.getLinks(ctx, path, opts)
}
@ -255,42 +247,42 @@ func (s *UserServiceOp) GetGilded(ctx context.Context, opts *ListOptions) (*Comm
}
// GetHotComments returns a list of the client's hottest comments
func (s *UserServiceOp) GetHotComments(ctx context.Context, opts *ListOptions) (*CommentList, *Response, error) {
func (s *UserServiceOp) GetHotComments(ctx context.Context, opts *ListOptions) (*Comments, *Response, error) {
return s.getComments(ctx, s.client.Username, sortHot, opts)
}
// GetNewComments returns a list of the client's newest comments
func (s *UserServiceOp) GetNewComments(ctx context.Context, opts *ListOptions) (*CommentList, *Response, error) {
func (s *UserServiceOp) GetNewComments(ctx context.Context, opts *ListOptions) (*Comments, *Response, error) {
return s.getComments(ctx, s.client.Username, sortNew, opts)
}
// GetTopComments returns a list of the client's top comments
func (s *UserServiceOp) GetTopComments(ctx context.Context, opts *ListOptions) (*CommentList, *Response, error) {
func (s *UserServiceOp) GetTopComments(ctx context.Context, opts *ListOptions) (*Comments, *Response, error) {
return s.getComments(ctx, s.client.Username, sortTop, opts)
}
// GetControversialComments returns a list of the client's most controversial comments
func (s *UserServiceOp) GetControversialComments(ctx context.Context, opts *ListOptions) (*CommentList, *Response, error) {
func (s *UserServiceOp) GetControversialComments(ctx context.Context, opts *ListOptions) (*Comments, *Response, error) {
return s.getComments(ctx, s.client.Username, sortControversial, opts)
}
// GetHotCommentsOf returns a list of the user's hottest comments
func (s *UserServiceOp) GetHotCommentsOf(ctx context.Context, username string, opts *ListOptions) (*CommentList, *Response, error) {
func (s *UserServiceOp) GetHotCommentsOf(ctx context.Context, username string, opts *ListOptions) (*Comments, *Response, error) {
return s.getComments(ctx, username, sortHot, opts)
}
// GetNewCommentsOf returns a list of the user's newest comments
func (s *UserServiceOp) GetNewCommentsOf(ctx context.Context, username string, opts *ListOptions) (*CommentList, *Response, error) {
func (s *UserServiceOp) GetNewCommentsOf(ctx context.Context, username string, opts *ListOptions) (*Comments, *Response, error) {
return s.getComments(ctx, username, sortNew, opts)
}
// GetTopCommentsOf returns a list of the user's top comments
func (s *UserServiceOp) GetTopCommentsOf(ctx context.Context, username string, opts *ListOptions) (*CommentList, *Response, error) {
func (s *UserServiceOp) GetTopCommentsOf(ctx context.Context, username string, opts *ListOptions) (*Comments, *Response, error) {
return s.getComments(ctx, username, sortTop, opts)
}
// GetControversialCommentsOf returns a list of the user's most controversial comments
func (s *UserServiceOp) GetControversialCommentsOf(ctx context.Context, username string, opts *ListOptions) (*CommentList, *Response, error) {
func (s *UserServiceOp) GetControversialCommentsOf(ctx context.Context, username string, opts *ListOptions) (*Comments, *Response, error) {
return s.getComments(ctx, username, sortControversial, opts)
}
@ -344,7 +336,7 @@ func (s *UserServiceOp) Unfriend(ctx context.Context, username string) (*Respons
return s.client.Do(ctx, req, nil)
}
func (s *UserServiceOp) getLinks(ctx context.Context, path string, opts *ListOptions) (*LinkList, *Response, error) {
func (s *UserServiceOp) getLinks(ctx context.Context, path string, opts *ListOptions) (*Links, *Response, error) {
path, err := addOptions(path, opts)
if err != nil {
return nil, nil, err
@ -364,7 +356,7 @@ func (s *UserServiceOp) getLinks(ctx context.Context, path string, opts *ListOpt
return root.getLinks(), resp, nil
}
func (s *UserServiceOp) getComments(ctx context.Context, username string, sort sort, opts *ListOptions) (*CommentList, *Response, error) {
func (s *UserServiceOp) getComments(ctx context.Context, username string, sort sort, opts *ListOptions) (*Comments, *Response, error) {
path := fmt.Sprintf("user/%s/comments?sort=%s", username, sorts[sort])
path, err := addOptions(path, opts)
if err != nil {