Create WikiService
Signed-off-by: Vartan Benohanian <vartanbeno@gmail.com>
This commit is contained in:
@@ -81,16 +81,8 @@ type inboxThings struct {
|
|||||||
Messages []*Message
|
Messages []*Message
|
||||||
}
|
}
|
||||||
|
|
||||||
// init initializes or clears the listing.
|
|
||||||
func (t *inboxThings) init() {
|
|
||||||
t.Comments = make([]*Message, 0)
|
|
||||||
t.Messages = make([]*Message, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmarshalJSON implements the json.Unmarshaler interface.
|
// UnmarshalJSON implements the json.Unmarshaler interface.
|
||||||
func (t *inboxThings) UnmarshalJSON(b []byte) error {
|
func (t *inboxThings) UnmarshalJSON(b []byte) error {
|
||||||
t.init()
|
|
||||||
|
|
||||||
var things []inboxThing
|
var things []inboxThing
|
||||||
if err := json.Unmarshal(b, &things); err != nil {
|
if err := json.Unmarshal(b, &things); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ type Client struct {
|
|||||||
Stream *StreamService
|
Stream *StreamService
|
||||||
Subreddit *SubredditService
|
Subreddit *SubredditService
|
||||||
User *UserService
|
User *UserService
|
||||||
|
Wiki *WikiService
|
||||||
|
|
||||||
oauth2Transport *oauth2.Transport
|
oauth2Transport *oauth2.Transport
|
||||||
|
|
||||||
@@ -107,6 +108,7 @@ func newClient() *Client {
|
|||||||
client.Stream = &StreamService{client: client}
|
client.Stream = &StreamService{client: client}
|
||||||
client.Subreddit = &SubredditService{client: client}
|
client.Subreddit = &SubredditService{client: client}
|
||||||
client.User = &UserService{client: client}
|
client.User = &UserService{client: client}
|
||||||
|
client.Wiki = &WikiService{client: client}
|
||||||
|
|
||||||
postAndCommentService := &postAndCommentService{client: client}
|
postAndCommentService := &postAndCommentService{client: client}
|
||||||
client.Comment = &CommentService{client: client, postAndCommentService: postAndCommentService}
|
client.Comment = &CommentService{client: client, postAndCommentService: postAndCommentService}
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ func testClientServices(t *testing.T, c *Client) {
|
|||||||
"Stream",
|
"Stream",
|
||||||
"Subreddit",
|
"Subreddit",
|
||||||
"User",
|
"User",
|
||||||
|
"Wiki",
|
||||||
}
|
}
|
||||||
|
|
||||||
cp := reflect.ValueOf(c)
|
cp := reflect.ValueOf(c)
|
||||||
|
|||||||
+32
-26
@@ -6,19 +6,21 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
kindComment = "t1"
|
kindComment = "t1"
|
||||||
kindUser = "t2"
|
kindUser = "t2"
|
||||||
kindPost = "t3"
|
kindPost = "t3"
|
||||||
kindMessage = "t4"
|
kindMessage = "t4"
|
||||||
kindSubreddit = "t5"
|
kindSubreddit = "t5"
|
||||||
kindTrophy = "t6"
|
kindTrophy = "t6"
|
||||||
kindListing = "Listing"
|
kindListing = "Listing"
|
||||||
kindKarmaList = "KarmaList"
|
kindKarmaList = "KarmaList"
|
||||||
kindTrophyList = "TrophyList"
|
kindTrophyList = "TrophyList"
|
||||||
kindUserList = "UserList"
|
kindUserList = "UserList"
|
||||||
kindMore = "more"
|
kindMore = "more"
|
||||||
kindModAction = "modaction"
|
kindModAction = "modaction"
|
||||||
kindMulti = "LabeledMulti"
|
kindMulti = "LabeledMulti"
|
||||||
|
kindWikiPageListing = "wikipagelisting"
|
||||||
|
kindWikiPageSettings = "wikipagesettings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type anchor interface {
|
type anchor interface {
|
||||||
@@ -94,6 +96,10 @@ func (t *thing) UnmarshalJSON(b []byte) error {
|
|||||||
v = new(trophyList)
|
v = new(trophyList)
|
||||||
case kindKarmaList:
|
case kindKarmaList:
|
||||||
v = new([]*SubredditKarma)
|
v = new([]*SubredditKarma)
|
||||||
|
case kindWikiPageListing:
|
||||||
|
v = new([]string)
|
||||||
|
case kindWikiPageSettings:
|
||||||
|
v = new(WikiPageSettings)
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("unrecognized kind: %q", t.Kind)
|
return fmt.Errorf("unrecognized kind: %q", t.Kind)
|
||||||
}
|
}
|
||||||
@@ -168,6 +174,19 @@ func (t *thing) Karma() ([]*SubredditKarma, bool) {
|
|||||||
return *v, ok
|
return *v, ok
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *thing) WikiPages() ([]string, bool) {
|
||||||
|
v, ok := t.Data.(*[]string)
|
||||||
|
if !ok {
|
||||||
|
return nil, ok
|
||||||
|
}
|
||||||
|
return *v, ok
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *thing) WikiPageSettings() (v *WikiPageSettings, ok bool) {
|
||||||
|
v, ok = t.Data.(*WikiPageSettings)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// listing is a list of things coming from the Reddit API.
|
// listing is a list of things coming from the Reddit API.
|
||||||
// It also contains the after/before anchors useful for subsequent requests.
|
// It also contains the after/before anchors useful for subsequent requests.
|
||||||
type listing struct {
|
type listing struct {
|
||||||
@@ -263,21 +282,8 @@ type things struct {
|
|||||||
Multis []*Multi
|
Multis []*Multi
|
||||||
}
|
}
|
||||||
|
|
||||||
// init initializes or clears the listing.
|
|
||||||
func (t *things) init() {
|
|
||||||
t.Comments = make([]*Comment, 0)
|
|
||||||
t.Mores = make([]*More, 0)
|
|
||||||
t.Users = make([]*User, 0)
|
|
||||||
t.Posts = make([]*Post, 0)
|
|
||||||
t.Subreddits = make([]*Subreddit, 0)
|
|
||||||
t.ModActions = make([]*ModAction, 0)
|
|
||||||
t.Multis = make([]*Multi, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmarshalJSON implements the json.Unmarshaler interface.
|
// UnmarshalJSON implements the json.Unmarshaler interface.
|
||||||
func (t *things) UnmarshalJSON(b []byte) error {
|
func (t *things) UnmarshalJSON(b []byte) error {
|
||||||
t.init()
|
|
||||||
|
|
||||||
var things []thing
|
var things []thing
|
||||||
if err := json.Unmarshal(b, &things); err != nil {
|
if err := json.Unmarshal(b, &things); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
+170
@@ -0,0 +1,170 @@
|
|||||||
|
package reddit
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
|
||||||
|
"github.com/google/go-querystring/query"
|
||||||
|
)
|
||||||
|
|
||||||
|
// WikiService handles communication with the wiki
|
||||||
|
// related methods of the Reddit API.
|
||||||
|
//
|
||||||
|
// Reddit API docs: https://www.reddit.com/dev/api/#section_wiki
|
||||||
|
type WikiService struct {
|
||||||
|
client *Client
|
||||||
|
}
|
||||||
|
|
||||||
|
// WikiPagePermissionLevel defines who can edit a specific wiki page in a subreddit.
|
||||||
|
type WikiPagePermissionLevel int
|
||||||
|
|
||||||
|
const (
|
||||||
|
// PermissionSubredditWikiPermissions uses subreddit wiki permissions.
|
||||||
|
PermissionSubredditWikiPermissions WikiPagePermissionLevel = iota
|
||||||
|
// PermissionApprovedContributorsOnly is only for approved wiki contributors.
|
||||||
|
PermissionApprovedContributorsOnly
|
||||||
|
// PermissionModeratorsOnly is only for moderators.
|
||||||
|
PermissionModeratorsOnly
|
||||||
|
)
|
||||||
|
|
||||||
|
// WikiPageSettings holds the settings for a specific wiki page.
|
||||||
|
type WikiPageSettings struct {
|
||||||
|
PermissionLevel WikiPagePermissionLevel `json:"permlevel"`
|
||||||
|
Listed bool `json:"listed"`
|
||||||
|
Editors []*User `json:"editors"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// WikiPageSettingsUpdateRequest represents a request to update the visibility and
|
||||||
|
// permissions of a wiki page.
|
||||||
|
type WikiPageSettingsUpdateRequest struct {
|
||||||
|
// This HAS to be provided no matter what, or else we get a 500 response.
|
||||||
|
PermissionLevel WikiPagePermissionLevel `url:"permlevel"`
|
||||||
|
Listed *bool `url:"listed,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements the json.Unmarshaler interface.
|
||||||
|
func (s *WikiPageSettings) UnmarshalJSON(b []byte) error {
|
||||||
|
root := new(struct {
|
||||||
|
PermissionLevel WikiPagePermissionLevel `json:"permlevel"`
|
||||||
|
Listed bool `json:"listed"`
|
||||||
|
Things []thing `json:"editors"`
|
||||||
|
})
|
||||||
|
|
||||||
|
err := json.Unmarshal(b, root)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
s.PermissionLevel = root.PermissionLevel
|
||||||
|
s.Listed = root.Listed
|
||||||
|
|
||||||
|
for _, thing := range root.Things {
|
||||||
|
if user, ok := thing.User(); ok {
|
||||||
|
s.Editors = append(s.Editors, user)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pages retrieves a list of wiki pages in the subreddit.
|
||||||
|
// Returns 403 Forbidden if the wiki is disabled.
|
||||||
|
func (s *WikiService) Pages(ctx context.Context, subreddit string) ([]string, *Response, error) {
|
||||||
|
path := fmt.Sprintf("r/%s/wiki/pages", subreddit)
|
||||||
|
|
||||||
|
req, err := s.client.NewRequest(http.MethodGet, path, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
root := new(thing)
|
||||||
|
resp, err := s.client.Do(ctx, req, root)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
pages, _ := root.WikiPages()
|
||||||
|
return pages, resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Settings gets the subreddit's wiki page's settings.
|
||||||
|
func (s *WikiService) Settings(ctx context.Context, subreddit, page string) (*WikiPageSettings, *Response, error) {
|
||||||
|
path := fmt.Sprintf("r/%s/wiki/settings/%s", subreddit, page)
|
||||||
|
|
||||||
|
req, err := s.client.NewRequest(http.MethodGet, path, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
root := new(thing)
|
||||||
|
resp, err := s.client.Do(ctx, req, root)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
settings, _ := root.WikiPageSettings()
|
||||||
|
return settings, resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateSettings updates the subreddit's wiki page's settings.
|
||||||
|
func (s *WikiService) UpdateSettings(ctx context.Context, subreddit, page string, updateRequest *WikiPageSettingsUpdateRequest) (*WikiPageSettings, *Response, error) {
|
||||||
|
if updateRequest == nil {
|
||||||
|
return nil, nil, errors.New("updateRequest: cannot be nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
form, err := query.Values(updateRequest)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
path := fmt.Sprintf("r/%s/wiki/settings/%s", subreddit, page)
|
||||||
|
req, err := s.client.NewRequestWithForm(http.MethodPost, path, form)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
root := new(thing)
|
||||||
|
resp, err := s.client.Do(ctx, req, root)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
settings, _ := root.WikiPageSettings()
|
||||||
|
return settings, resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allow the user to edit the specified wiki page in the subreddit.
|
||||||
|
func (s *WikiService) Allow(ctx context.Context, subreddit, page, username string) (*Response, error) {
|
||||||
|
path := fmt.Sprintf("r/%s/api/wiki/alloweditor/add", subreddit)
|
||||||
|
|
||||||
|
form := url.Values{}
|
||||||
|
form.Set("page", page)
|
||||||
|
form.Set("username", username)
|
||||||
|
|
||||||
|
req, err := s.client.NewRequestWithForm(http.MethodPost, path, form)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.client.Do(ctx, req, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deny the user the ability to edit the specified wiki page in the subreddit.
|
||||||
|
func (s *WikiService) Deny(ctx context.Context, subreddit, page, username string) (*Response, error) {
|
||||||
|
path := fmt.Sprintf("r/%s/api/wiki/alloweditor/del", subreddit)
|
||||||
|
|
||||||
|
form := url.Values{}
|
||||||
|
form.Set("page", page)
|
||||||
|
form.Set("username", username)
|
||||||
|
|
||||||
|
req, err := s.client.NewRequestWithForm(http.MethodPost, path, form)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.client.Do(ctx, req, nil)
|
||||||
|
}
|
||||||
@@ -0,0 +1,138 @@
|
|||||||
|
package reddit
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
var expectedWikiPageSettings = &WikiPageSettings{
|
||||||
|
PermissionLevel: PermissionSubredditWikiPermissions,
|
||||||
|
Listed: true,
|
||||||
|
Editors: []*User{
|
||||||
|
{
|
||||||
|
ID: "164ab8",
|
||||||
|
Name: "v_95",
|
||||||
|
Created: &Timestamp{time.Date(2017, 3, 12, 4, 56, 47, 0, time.UTC)},
|
||||||
|
|
||||||
|
PostKarma: 691,
|
||||||
|
CommentKarma: 22235,
|
||||||
|
|
||||||
|
HasVerifiedEmail: true,
|
||||||
|
NSFW: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWikiService_Pages(t *testing.T) {
|
||||||
|
client, mux, teardown := setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/r/testsubreddit/wiki/pages", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
require.Equal(t, http.MethodGet, r.Method)
|
||||||
|
fmt.Fprint(w, `{
|
||||||
|
"kind": "wikipagelisting",
|
||||||
|
"data": [
|
||||||
|
"faq",
|
||||||
|
"index"
|
||||||
|
]
|
||||||
|
}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
pages, _, err := client.Wiki.Pages(ctx, "testsubreddit")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, []string{"faq", "index"}, pages)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWikiService_Settings(t *testing.T) {
|
||||||
|
client, mux, teardown := setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
blob, err := readFileContents("../testdata/wiki/page-settings.json")
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
mux.HandleFunc("/r/testsubreddit/wiki/settings/testpage", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
require.Equal(t, http.MethodGet, r.Method)
|
||||||
|
fmt.Fprint(w, blob)
|
||||||
|
})
|
||||||
|
|
||||||
|
settings, _, err := client.Wiki.Settings(ctx, "testsubreddit", "testpage")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, expectedWikiPageSettings, settings)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWikiService_UpdateSettings(t *testing.T) {
|
||||||
|
client, mux, teardown := setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
blob, err := readFileContents("../testdata/wiki/page-settings.json")
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
mux.HandleFunc("/r/testsubreddit/wiki/settings/testpage", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
require.Equal(t, http.MethodPost, r.Method)
|
||||||
|
|
||||||
|
form := url.Values{}
|
||||||
|
form.Set("permlevel", "1")
|
||||||
|
form.Set("listed", "false")
|
||||||
|
|
||||||
|
err := r.ParseForm()
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, form, r.PostForm)
|
||||||
|
|
||||||
|
fmt.Fprint(w, blob)
|
||||||
|
})
|
||||||
|
|
||||||
|
_, _, err = client.Wiki.UpdateSettings(ctx, "testsubreddit", "testpage", nil)
|
||||||
|
require.EqualError(t, err, "updateRequest: cannot be nil")
|
||||||
|
|
||||||
|
settings, _, err := client.Wiki.UpdateSettings(ctx, "testsubreddit", "testpage", &WikiPageSettingsUpdateRequest{
|
||||||
|
Listed: Bool(false),
|
||||||
|
PermissionLevel: PermissionApprovedContributorsOnly,
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, expectedWikiPageSettings, settings)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWikiService_Allow(t *testing.T) {
|
||||||
|
client, mux, teardown := setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/r/testsubreddit/api/wiki/alloweditor/add", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
require.Equal(t, http.MethodPost, r.Method)
|
||||||
|
|
||||||
|
form := url.Values{}
|
||||||
|
form.Set("page", "testpage")
|
||||||
|
form.Set("username", "testusername")
|
||||||
|
|
||||||
|
err := r.ParseForm()
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, form, r.PostForm)
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := client.Wiki.Allow(ctx, "testsubreddit", "testpage", "testusername")
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWikiService_Deny(t *testing.T) {
|
||||||
|
client, mux, teardown := setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/r/testsubreddit/api/wiki/alloweditor/del", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
require.Equal(t, http.MethodPost, r.Method)
|
||||||
|
|
||||||
|
form := url.Values{}
|
||||||
|
form.Set("page", "testpage")
|
||||||
|
form.Set("username", "testusername")
|
||||||
|
|
||||||
|
err := r.ParseForm()
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, form, r.PostForm)
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := client.Wiki.Deny(ctx, "testsubreddit", "testpage", "testusername")
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
||||||
Vendored
+180
@@ -0,0 +1,180 @@
|
|||||||
|
{
|
||||||
|
"kind": "wikipagesettings",
|
||||||
|
"data": {
|
||||||
|
"permlevel": 0,
|
||||||
|
"editors": [
|
||||||
|
{
|
||||||
|
"kind": "t2",
|
||||||
|
"data": {
|
||||||
|
"is_employee": false,
|
||||||
|
"has_visited_new_profile": false,
|
||||||
|
"is_friend": false,
|
||||||
|
"pref_no_profanity": false,
|
||||||
|
"has_external_account": false,
|
||||||
|
"pref_geopopular": "GLOBAL",
|
||||||
|
"pref_show_trending": true,
|
||||||
|
"subreddit": {
|
||||||
|
"default_set": true,
|
||||||
|
"user_is_contributor": false,
|
||||||
|
"banner_img": "",
|
||||||
|
"restrict_posting": true,
|
||||||
|
"user_is_banned": false,
|
||||||
|
"free_form_reports": true,
|
||||||
|
"community_icon": null,
|
||||||
|
"show_media": true,
|
||||||
|
"icon_color": "#94E044",
|
||||||
|
"user_is_muted": false,
|
||||||
|
"display_name": "u_v_95",
|
||||||
|
"header_img": null,
|
||||||
|
"title": "",
|
||||||
|
"coins": 0,
|
||||||
|
"previous_names": [],
|
||||||
|
"over_18": false,
|
||||||
|
"icon_size": [256, 256],
|
||||||
|
"primary_color": "",
|
||||||
|
"icon_img": "https://www.redditstatic.com/avatars/avatar_default_01_94E044.png",
|
||||||
|
"description": "",
|
||||||
|
"submit_link_label": "",
|
||||||
|
"header_size": null,
|
||||||
|
"restrict_commenting": false,
|
||||||
|
"subscribers": 1,
|
||||||
|
"submit_text_label": "",
|
||||||
|
"is_default_icon": true,
|
||||||
|
"link_flair_position": "",
|
||||||
|
"display_name_prefixed": "u/v_95",
|
||||||
|
"key_color": "",
|
||||||
|
"name": "t5_17a8op",
|
||||||
|
"is_default_banner": true,
|
||||||
|
"url": "/user/v_95/",
|
||||||
|
"quarantine": false,
|
||||||
|
"banner_size": null,
|
||||||
|
"user_is_moderator": true,
|
||||||
|
"public_description": "",
|
||||||
|
"link_flair_enabled": false,
|
||||||
|
"disable_contributor_requests": false,
|
||||||
|
"subreddit_type": "user",
|
||||||
|
"user_is_subscriber": false
|
||||||
|
},
|
||||||
|
"is_sponsor": false,
|
||||||
|
"gold_expiration": null,
|
||||||
|
"has_gold_subscription": false,
|
||||||
|
"num_friends": 29,
|
||||||
|
"features": {
|
||||||
|
"mod_service_mute_writes": true,
|
||||||
|
"promoted_trend_blanks": true,
|
||||||
|
"show_amp_link": true,
|
||||||
|
"report_service_handles_report_writes_to_db_for_helpdesk_reports": true,
|
||||||
|
"report_service_handles_self_harm_reports": true,
|
||||||
|
"report_service_handles_report_writes_to_db_for_modmail_reports": true,
|
||||||
|
"chat": true,
|
||||||
|
"mweb_link_tab": {
|
||||||
|
"owner": "growth",
|
||||||
|
"variant": "treatment_1",
|
||||||
|
"experiment_id": 404
|
||||||
|
},
|
||||||
|
"reports_double_write_to_report_service_for_spam": true,
|
||||||
|
"is_email_permission_required": true,
|
||||||
|
"reports_double_write_to_report_service_for_modmail_reports": true,
|
||||||
|
"mod_awards": true,
|
||||||
|
"econ_wallet_service": true,
|
||||||
|
"mweb_xpromo_revamp_v2": {
|
||||||
|
"owner": "growth",
|
||||||
|
"variant": "treatment_6",
|
||||||
|
"experiment_id": 457
|
||||||
|
},
|
||||||
|
"awards_on_streams": true,
|
||||||
|
"report_service_handles_accept_report": true,
|
||||||
|
"mweb_xpromo_modal_listing_click_daily_dismissible_ios": true,
|
||||||
|
"reports_double_write_to_report_service_for_som": true,
|
||||||
|
"chat_subreddit": true,
|
||||||
|
"reports_double_write_to_report_service_for_users": true,
|
||||||
|
"modlog_copyright_removal": true,
|
||||||
|
"report_service_handles_report_writes_to_db_for_users": true,
|
||||||
|
"do_not_track": true,
|
||||||
|
"reports_double_write_to_report_service_for_helpdesk_reports": true,
|
||||||
|
"report_service_handles_report_writes_to_db_for_spam": true,
|
||||||
|
"reports_double_write_to_report_service_for_sendbird_chats": true,
|
||||||
|
"mod_service_mute_reads": true,
|
||||||
|
"mweb_xpromo_interstitial_comments_ios": true,
|
||||||
|
"mweb_xpromo_modal_listing_click_daily_dismissible_android": true,
|
||||||
|
"chat_user_settings": true,
|
||||||
|
"premium_subscriptions_table": true,
|
||||||
|
"reports_double_write_to_report_service": true,
|
||||||
|
"mweb_xpromo_interstitial_comments_android": true,
|
||||||
|
"report_service_handles_report_writes_to_db_for_awards": true,
|
||||||
|
"mweb_nsfw_xpromo": {
|
||||||
|
"owner": "growth",
|
||||||
|
"variant": "control_2",
|
||||||
|
"experiment_id": 361
|
||||||
|
},
|
||||||
|
"noreferrer_to_noopener": true,
|
||||||
|
"reports_double_write_to_report_service_for_awards": true,
|
||||||
|
"mweb_sharing_web_share_api": {
|
||||||
|
"owner": "growth",
|
||||||
|
"variant": "control_1",
|
||||||
|
"experiment_id": 314
|
||||||
|
},
|
||||||
|
"mweb_xpromo_revamp_v3": {
|
||||||
|
"owner": "growth",
|
||||||
|
"variant": "treatment_2",
|
||||||
|
"experiment_id": 480
|
||||||
|
},
|
||||||
|
"chat_group_rollout": true,
|
||||||
|
"resized_styles_images": true,
|
||||||
|
"spez_modal": true,
|
||||||
|
"mweb_sharing_clipboard": {
|
||||||
|
"owner": "growth",
|
||||||
|
"variant": "control_2",
|
||||||
|
"experiment_id": 315
|
||||||
|
},
|
||||||
|
"expensive_coins_package": true,
|
||||||
|
"report_service_handles_report_writes_to_db_for_som": true
|
||||||
|
},
|
||||||
|
"can_edit_name": false,
|
||||||
|
"verified": true,
|
||||||
|
"new_modmail_exists": true,
|
||||||
|
"pref_autoplay": true,
|
||||||
|
"coins": 0,
|
||||||
|
"has_paypal_subscription": false,
|
||||||
|
"has_subscribed_to_premium": false,
|
||||||
|
"id": "164ab8",
|
||||||
|
"has_stripe_subscription": false,
|
||||||
|
"can_create_subreddit": true,
|
||||||
|
"over_18": true,
|
||||||
|
"is_gold": false,
|
||||||
|
"is_mod": true,
|
||||||
|
"suspension_expiration_utc": null,
|
||||||
|
"has_verified_email": true,
|
||||||
|
"is_suspended": false,
|
||||||
|
"pref_video_autoplay": true,
|
||||||
|
"in_chat": true,
|
||||||
|
"has_android_subscription": false,
|
||||||
|
"in_redesign_beta": false,
|
||||||
|
"icon_img": "https://www.redditstatic.com/avatars/avatar_default_01_94E044.png",
|
||||||
|
"has_mod_mail": false,
|
||||||
|
"pref_nightmode": true,
|
||||||
|
"hide_from_robots": false,
|
||||||
|
"password_set": true,
|
||||||
|
"modhash": null,
|
||||||
|
"link_karma": 691,
|
||||||
|
"force_password_reset": false,
|
||||||
|
"inbox_count": 0,
|
||||||
|
"pref_top_karma_subreddits": false,
|
||||||
|
"has_mail": false,
|
||||||
|
"pref_show_snoovatar": false,
|
||||||
|
"name": "v_95",
|
||||||
|
"pref_clickgadget": 5,
|
||||||
|
"created": 1489323407.0,
|
||||||
|
"gold_creddits": 0,
|
||||||
|
"created_utc": 1489294607.0,
|
||||||
|
"has_ios_subscription": false,
|
||||||
|
"pref_show_twitter": false,
|
||||||
|
"in_beta": false,
|
||||||
|
"comment_karma": 22235,
|
||||||
|
"has_subscribed": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"listed": true
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user