From 10214b7eb64561216dc35d4078d3e77d861b9982 Mon Sep 17 00:00:00 2001 From: Vartan Benohanian Date: Sat, 27 Jun 2020 00:24:12 -0400 Subject: [PATCH] Get/update settings Signed-off-by: Vartan Benohanian --- account.go | 249 +++++++++++++++++++++++---------- account_test.go | 110 +++++++++++++++ testdata/account/settings.json | 4 +- 3 files changed, 286 insertions(+), 77 deletions(-) diff --git a/account.go b/account.go index eb3ce26..56d22bd 100644 --- a/account.go +++ b/account.go @@ -2,7 +2,6 @@ package geddit import ( "context" - "fmt" "net/http" ) @@ -10,6 +9,8 @@ import ( // related methods of the Reddit API. type AccountService interface { Karma(ctx context.Context) ([]SubredditKarma, *Response, error) + Settings(ctx context.Context) (*Settings, *Response, error) + UpdateSettings(ctx context.Context, settings *Settings) (*Settings, *Response, error) } // AccountServiceOp implements the AccountService interface. @@ -36,106 +37,183 @@ type SubredditKarma struct { // https://praw.readthedocs.io/en/latest/code_overview/other/preferences.html#praw.models.Preferences.update // todo: these should probably be pointers with omitempty type Settings struct { - AcceptPrivateMessages bool `json:"accept_pms"` + // Control whose private messages you see: "everyone" or "whitelisted". + AcceptPrivateMessages *string `json:"accept_pms,omitempty"` // Allow Reddit to use your activity on Reddit to show you more relevant advertisements. - ActivityRelevantAds bool `json:"activity_relevant_ads"` + ActivityRelevantAds *bool `json:"activity_relevant_ads,omitempty"` // Allow reddit to log my outbound clicks for personalization. - AllowClickTracking bool `json:"allow_clicktracking"` + AllowClickTracking *bool `json:"allow_clicktracking,omitempty"` - // I would like to beta test features for reddit. By enabling, you will join r/beta immediately. - Beta bool `json:"beta"` - ClickGadget bool `json:"clickgadget"` - CollapseReadMessages bool `json:"collapse_read_messages"` - Compress bool `json:"compress"` - CredditAutorenew bool `json:"creddit_autorenew"` - DefaultCommentSort string `json:"default_comment_sort"` - ShowDomainDetails bool `json:"domain_details"` - SendEmailDigests bool `json:"email_digests"` - SendMessagesAsEmails bool `json:"email_messages"` - UnsubscribeFromAllEmails bool `json:"email_unsubscribe_all"` - DisableCustomThemes bool `json:"enable_default_themes"` - Location string `json:"g"` - HideAds bool `json:"hide_ads"` + // Beta test features for reddit. By enabling, you will join r/beta immediately. + Beta *bool `json:"beta,omitempty"` + // Show me links I've recently viewed. + ShowRecentlyViewedPosts *bool `json:"clickgadget,omitempty"` + + CollapseReadMessages *bool `json:"collapse_read_messages,omitempty"` + + // Compress the post display (make them look more compact). + Compress *bool `json:"compress,omitempty"` + + CredditAutorenew *bool `json:"creddit_autorenew,omitempty"` + + // One of "confidence", "top", "new", "controversial", "old", "random", "qa", "live". + DefaultCommentSort *string `json:"default_comment_sort,omitempty"` + + // Show additional details in the domain text when available, + // such as the source subreddit or the content author’s url/name. + ShowDomainDetails *bool `json:"domain_details,omitempty"` + + SendEmailDigests *bool `json:"email_digests,omitempty"` + SendMessagesAsEmails *bool `json:"email_messages,omitempty"` + UnsubscribeFromAllEmails *bool `json:"email_unsubscribe_all,omitempty"` + + // Disable subreddits from displaying their custom themes. + DisableCustomThemes *bool `json:"enable_default_themes,omitempty"` + + // One of "GLOBAL", "AR", "AU", "BG", "CA", "CL", "CO", "CZ", "FI", "GB", "GR", "HR", "HU", + // "IE", "IN", "IS", "JP", "MX", "MY", "NZ", "PH", "PL", "PR", "PT", "RO", "RS", "SE", "SG", + // "TH", "TR", "TW", "US", "US_AK", "US_AL", "US_AR", "US_AZ", "US_CA", "US_CO", "US_CT", + // "US_DC", "US_DE", "US_FL", "US_GA", "US_HI", "US_IA", "US_ID", "US_IL", "US_IN", "US_KS", + // "US_KY", "US_LA", "US_MA", "US_MD", "US_ME", "US_MI", "US_MN", "US_MO", "US_MS", "US_MT", + // "US_NC", "US_ND", "US_NE", "US_NH", "US_NJ", "US_NM", "US_NV", "US_NY", "US_OH", "US_OK", + // "US_OR", "US_PA", "US_RI", "US_SC", "US_SD", "US_TN", "US_TX", "US_UT", "US_VA", "US_VT", + // "US_WA", "US_WI", "US_WV", "US_WY". + Location *string `json:"geopopular,omitempty"` + + HideAds *bool `json:"hide_ads,omitempty"` // Don't allow search engines to index my user profile. - HideFromSearchEngines bool `json:"hide_from_robots"` + HideFromSearchEngines *bool `json:"hide_from_robots,omitempty"` - HideUpvotedPosts bool `json:"hide_ups"` - HideDownvotedPosts bool `json:"hide_downs"` + // Don’t show me posts after I’ve upvoted them, except my own. + HideUpvotedPosts *bool `json:"hide_ups,omitempty"` + // Don’t show me posts after I’ve downvoted them, except my own. + HideDownvotedPosts *bool `json:"hide_downs,omitempty"` + + // Show a dagger (†) on comments voted controversial (one that's been + // upvoted and downvoted significantly). + HighlightControversialComments *bool `json:"highlight_controversial,omitempty"` + HighlightNewComments *bool `json:"highlight_new_comments,omitempty"` + + // Ignore suggested sorts for specific threads/subreddits, like Q&As. + IgnoreSuggestedSorts *bool `json:"ignore_suggested_sort,omitempty"` - HighlightControversialComments bool `json:"highlight_controversial"` - HighlightNewComments bool `json:"highlight_new_comments"` - IgnoreSuggestedSorts bool `json:"ignore_suggested_sort"` // Use new Reddit as my default experience. - UseNewReddit bool `json:"in_redesign_beta"` - LabelNSFW bool `json:"label_nsfw"` - Language string `json:"lang"` - ShowOldSearchPage bool `json:"legacy_search"` - EnableNotifications bool `json:"live_orangereds"` - MarkMessagesAsRead bool `json:"mark_messages_read"` + // Use this to SET the setting. + UseNewReddit *bool `json:"in_redesign_beta,omitempty"` + + // Use new Reddit as my default experience. + // Use this to GET the setting. + UsesNewReddit *bool `json:"design_beta,omitempty"` + + // Label posts that are not safe for work (NSFW). + LabelNSFW *bool `json:"label_nsfw,omitempty"` + + // A valid IETF language tag (underscore separated). + Language *string `json:"lang,omitempty"` + + ShowOldSearchPage *bool `json:"legacy_search,omitempty"` + + // Send message notifications in my browser. + EnableNotifications *bool `json:"live_orangereds,omitempty"` + + MarkMessagesAsRead *bool `json:"mark_messages_read,omitempty"` // Determine whether to show thumbnails next to posts in subreddits. // - "on": show thumbnails next to posts // - "off": do not show thumbnails next to posts // - "subreddit": show thumbnails next to posts based on the subreddit's preferences - ShowThumbnails string `json:"media"` + ShowThumbnails *string `json:"media,omitempty"` // Determine whether to auto-expand media in subreddits. // - "on": auto-expand media previews // - "off": do not auto-expand media previews // - "subreddit": auto-expand media previews based on the subreddit's preferences - AutoExpandMedia string `json:"media_preview"` - MinimumCommentScore *int `json:"min_comment_score"` - MinimumPostScore *int `json:"min_link_score"` - EnableMentionNotifications bool `json:"monitor_mentions"` - OpenLinksInNewWindow bool `json:"newwindow"` - // todo: test this - DarkMode bool `json:"nightmode"` - DisableProfanity bool `json:"no_profanity"` - NumComments int `json:"num_comments,omitempty"` - NumPosts int `json:"numsites,omitempty"` - ShowSpotlightBox bool `json:"organic"` - // todo: test this - SubredditTheme string `json:"other_theme"` - ShowNSFW bool `json:"over_18"` - EnablePrivateRSSFeeds bool `json:"private_feeds"` - ProfileOptOut bool `json:"profile_opt_out"` + AutoExpandMedia *string `json:"media_preview,omitempty"` + + // Don't show me comments with a score less than this number. + // Must be between -100 and 100 (inclusive). + MinimumCommentScore *int `json:"min_comment_score,omitempty"` + + // Don't show me posts with a score less than this number. + // Must be between -100 and 100 (inclusive). + MinimumPostScore *int `json:"min_link_score,omitempty"` + + // Notify me when people say my username. + EnableMentionNotifications *bool `json:"monitor_mentions,omitempty"` + + // Opens link in a new window/tab. + OpenLinksInNewWindow *bool `json:"newwindow,omitempty"` + + DarkMode *bool `json:"nightmode,omitempty"` + DisableProfanity *bool `json:"no_profanity,omitempty"` + + // Display this many comments by default. + // Must be between 1 and 500 (inclusive). + NumberOfComments *int `json:"num_comments,omitempty,omitempty"` + + // Display this many posts by default. + // Must be between 1 and 100 (inclusive). + NumberOfPosts *int `json:"numsites,omitempty,omitempty"` + + // Show the spotlight box on the home feed. + // Not sure what this is though... + ShowSpotlightBox *bool `json:"organic,omitempty"` + + SubredditTheme *string `json:"other_theme,omitempty"` + + // Show content that is labeled not safe for work (NSFW). + ShowNSFW *bool `json:"over_18,omitempty"` + + EnablePrivateRSSFeeds *bool `json:"private_feeds,omitempty"` + + // View user profiles on desktop using legacy mode. + ProfileOptOut *bool `json:"profile_opt_out,omitempty"` // Make my upvotes and downvotes public. - PublicizeVotes bool `json:"public_votes"` + PublicizeVotes *bool `json:"public_votes,omitempty"` // Allow my data to be used for research purposes. - AllowResearch bool `json:"research"` - IncludeNSFWSearchResults bool `json:"search_include_over_18"` - ReceiveCrosspostMessages bool `json:"send_crosspost_messages"` - ReceiveWelcomeMessages bool `json:"send_welcome_messages"` + AllowResearch *bool `json:"research,omitempty"` + + IncludeNSFWSearchResults *bool `json:"search_include_over_18,omitempty"` + + // Receive a message when my post gets cross-posted. + ReceiveCrosspostMessages *bool `json:"send_crosspost_messages,omitempty"` + // Receive welcome messages from moderators when I join a community. + ReceiveWelcomeMessages *bool `json:"send_welcome_messages,omitempty"` // Show a user's flair (next to their name on a post or comment). - ShowUserFlair bool `json:"show_flair"` + ShowUserFlair *bool `json:"show_flair,omitempty"` // Show a post's flair. - ShowPostFlair bool `json:"show_link_flair"` + ShowPostFlair *bool `json:"show_link_flair,omitempty"` - ShowGoldExpiration bool `json:"show_gold_expiration"` - ShowLocationBasedRecommendations bool `json:"show_location_based_recommendations"` - ShowPromote bool `json:"show_promote"` - ShowCustomSubredditThemes bool `json:"show_stylesheets"` - ShowTrendingSubreddits bool `json:"show_trending"` - ShowTwitter bool `json:"show_twitter"` - StoreVisits bool `json:"store_visits"` - ThemeSelector string `json:"theme_selector"` + // Show how much gold you have remaining on your profile. + ShowGoldExpiration *bool `json:"show_gold_expiration,omitempty"` + ShowLocationBasedRecommendations *bool `json:"show_location_based_recommendations,omitempty"` + ShowPromote *bool `json:"show_promote,omitempty"` + ShowCustomSubredditThemes *bool `json:"show_stylesheets,omitempty"` + + // Show trending subreddits on the home feed. + ShowTrendingSubreddits *bool `json:"show_trending,omitempty"` + ShowTwitter *bool `json:"show_twitter,omitempty"` + StoreVisits *bool `json:"store_visits,omitempty"` + ThemeSelector *string `json:"theme_selector,omitempty"` // Allow Reddit to use data provided by third-parties to show you more relevant advertisements on Reddit.i - AllowThirdPartyDataAdPersonalization bool `json:"third_party_data_personalized_ads"` + AllowThirdPartyDataAdPersonalization *bool `json:"third_party_data_personalized_ads,omitempty"` // Allow personalization of advertisements using data from third-party websites. - AllowThirdPartySiteDataAdPersonalization bool `json:"third_party_site_data_personalized_ads"` + AllowThirdPartySiteDataAdPersonalization *bool `json:"third_party_site_data_personalized_ads,omitempty"` // Allow personalization of content using data from third-party websites. - AllowThirdPartySiteDataContentPersonalization bool `json:"third_party_site_data_personalized_content"` + AllowThirdPartySiteDataContentPersonalization *bool `json:"third_party_site_data_personalized_content,omitempty"` - EnableThreadedMessages bool `json:"threaded_messages"` - EnableThreadedModmail bool `json:"threaded_modmail"` - TopKarmaSubreddits bool `json:"top_karma_subreddits"` - UseGlobalDefaults bool `json:"use_global_defaults"` - // todo: test this, no_video_autoplay - EnableVideoAutoplay bool `json:"video_autoplay"` + EnableThreadedMessages *bool `json:"threaded_messages,omitempty"` + EnableThreadedModmail *bool `json:"threaded_modmail,omitempty"` + + // Show the communities you are active in on your profile (mobile only). + TopKarmaSubreddits *bool `json:"top_karma_subreddits,omitempty"` + + UseGlobalDefaults *bool `json:"use_global_defaults,omitempty"` + EnableVideoAutoplay *bool `json:"video_autoplay,omitempty"` } // Karma returns a breakdown of your karma per subreddit. @@ -157,16 +235,37 @@ func (s *AccountServiceOp) Karma(ctx context.Context) ([]SubredditKarma, *Respon } // Settings returns your account settings. -func (s *AccountServiceOp) Settings(ctx context.Context) { +func (s *AccountServiceOp) Settings(ctx context.Context) (*Settings, *Response, error) { path := "api/v1/me/prefs" req, err := s.client.NewRequest(http.MethodGet, path, nil) if err != nil { - return + return nil, nil, err } - fmt.Println(req) + root := new(Settings) + resp, err := s.client.Do(ctx, req, root) + if err != nil { + return nil, resp, err + } + + return root, resp, nil +} + +// UpdateSettings updates your account settings and returns the modified version. +func (s *AccountServiceOp) UpdateSettings(ctx context.Context, settings *Settings) (*Settings, *Response, error) { + path := "api/v1/me/prefs" + + req, err := s.client.NewRequest(http.MethodPatch, path, settings) + if err != nil { + return nil, nil, err + } root := new(Settings) - fmt.Println(root.ShowThumbnails) + resp, err := s.client.Do(ctx, req, root) + if err != nil { + return nil, resp, err + } + + return root, resp, nil } diff --git a/account_test.go b/account_test.go index 99212d1..a1da580 100644 --- a/account_test.go +++ b/account_test.go @@ -1,6 +1,7 @@ package geddit import ( + "encoding/json" "fmt" "net/http" "testing" @@ -15,6 +16,76 @@ var expectedKarma = []SubredditKarma{ {Subreddit: "golang", PostKarma: 1, CommentKarma: 0}, } +var expectedSettings = &Settings{ + AcceptPrivateMessages: String("everyone"), + ActivityRelevantAds: Bool(false), + AllowClickTracking: Bool(false), + Beta: Bool(false), + ShowRecentlyViewedPosts: Bool(true), + CollapseReadMessages: Bool(false), + Compress: Bool(false), + CredditAutorenew: nil, + DefaultCommentSort: String("top"), + ShowDomainDetails: Bool(false), + SendEmailDigests: Bool(false), + SendMessagesAsEmails: Bool(false), + UnsubscribeFromAllEmails: Bool(true), + DisableCustomThemes: Bool(false), + Location: String("GLOBAL"), + HideAds: Bool(false), + HideFromSearchEngines: Bool(false), + HideUpvotedPosts: Bool(false), + HideDownvotedPosts: Bool(false), + HighlightControversialComments: Bool(true), + HighlightNewComments: Bool(true), + IgnoreSuggestedSorts: Bool(true), + UseNewReddit: nil, + UsesNewReddit: Bool(false), + LabelNSFW: Bool(true), + Language: String("en-ca"), + ShowOldSearchPage: Bool(false), + EnableNotifications: Bool(true), + MarkMessagesAsRead: Bool(true), + ShowThumbnails: String("subreddit"), + AutoExpandMedia: String("off"), + MinimumCommentScore: nil, + MinimumPostScore: nil, + EnableMentionNotifications: Bool(true), + OpenLinksInNewWindow: Bool(true), + DarkMode: Bool(true), + DisableProfanity: Bool(false), + NumberOfComments: Int(200), + NumberOfPosts: Int(25), + ShowSpotlightBox: nil, + SubredditTheme: nil, + ShowNSFW: Bool(true), + EnablePrivateRSSFeeds: Bool(true), + ProfileOptOut: Bool(false), + PublicizeVotes: Bool(false), + AllowResearch: Bool(false), + IncludeNSFWSearchResults: Bool(true), + ReceiveCrosspostMessages: Bool(false), + ReceiveWelcomeMessages: Bool(true), + ShowUserFlair: Bool(true), + ShowPostFlair: Bool(true), + ShowGoldExpiration: Bool(false), + ShowLocationBasedRecommendations: Bool(false), + ShowPromote: nil, + ShowCustomSubredditThemes: Bool(true), + ShowTrendingSubreddits: Bool(true), + ShowTwitter: Bool(false), + StoreVisits: Bool(false), + ThemeSelector: nil, + AllowThirdPartyDataAdPersonalization: Bool(false), + AllowThirdPartySiteDataAdPersonalization: Bool(false), + AllowThirdPartySiteDataContentPersonalization: Bool(false), + EnableThreadedMessages: Bool(true), + EnableThreadedModmail: Bool(false), + TopKarmaSubreddits: Bool(false), + UseGlobalDefaults: Bool(false), + EnableVideoAutoplay: Bool(true), +} + func TestAccountServiceOp_Karma(t *testing.T) { setup() defer teardown() @@ -30,3 +101,42 @@ func TestAccountServiceOp_Karma(t *testing.T) { assert.NoError(t, err) assert.Equal(t, expectedKarma, karma) } + +func TestAccountServiceOp_Settings(t *testing.T) { + setup() + defer teardown() + + blob := readFileContents(t, "testdata/account/settings.json") + + mux.HandleFunc("/api/v1/me/prefs", func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, http.MethodGet, r.Method) + fmt.Fprint(w, blob) + }) + + settings, _, err := client.Account.Settings(ctx) + assert.NoError(t, err) + assert.Equal(t, expectedSettings, settings) +} + +func TestAccountServiceOp_UpdateSettings(t *testing.T) { + setup() + defer teardown() + + blob := readFileContents(t, "testdata/account/settings.json") + expectedSettingsBody := &Settings{NumberOfPosts: Int(10), MinimumCommentScore: Int(5), Compress: Bool(true)} + + mux.HandleFunc("/api/v1/me/prefs", func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, http.MethodPatch, r.Method) + + settingsBody := new(Settings) + err := json.NewDecoder(r.Body).Decode(settingsBody) + assert.NoError(t, err) + assert.Equal(t, expectedSettingsBody, settingsBody) + + fmt.Fprint(w, blob) + }) + + settings, _, err := client.Account.UpdateSettings(ctx, expectedSettingsBody) + assert.NoError(t, err) + assert.Equal(t, expectedSettings, settings) +} diff --git a/testdata/account/settings.json b/testdata/account/settings.json index fedf5a9..2d52bdf 100644 --- a/testdata/account/settings.json +++ b/testdata/account/settings.json @@ -42,7 +42,7 @@ "min_link_score": null, "media_preview": "off", "show_location_based_recommendations": false, - "nightmode": false, + "nightmode": true, "highlight_controversial": true, "geopopular": "GLOBAL", "third_party_site_data_personalized_ads": false, @@ -63,7 +63,7 @@ "send_welcome_messages": true, "show_gold_expiration": false, "highlight_new_comments": true, - "email_unsubscribe_all": false, + "email_unsubscribe_all": true, "default_comment_sort": "top", "accept_pms": "everyone" }