diff options
Diffstat (limited to 'user-group.go')
| -rw-r--r-- | user-group.go | 83 |
1 files changed, 72 insertions, 11 deletions
diff --git a/user-group.go b/user-group.go index dba8a91..d7c9358 100644 --- a/user-group.go +++ b/user-group.go @@ -6,7 +6,14 @@ import ( "strings" ) -// структура группы или пользователя +// GRuser is a profile — a user's or a group's, as DeviantArt models both the +// same way. Owner.Group distinguishes them, and determines which of the +// ModuleData fields are populated: GroupAbout and GroupAdmins for a group, the +// embedded users for a person. +// +// The Page.Modules slice mirrors the site's own profile layout, so a caller +// looking for one piece of information has to search the slice for the module +// that carries it rather than reading a field directly. type GRuser struct { ErrorDescription string Owner struct { @@ -35,6 +42,12 @@ type GRuser struct { } `json:"pageExtraData"` } +// Gallery is a listing of deviations from a profile, returned by +// [Group.Gallery] and [Group.Favourites]. +// +// Where the deviations land depends on the call. Results is the flat listing; +// folder-scoped requests instead nest them inside the Modules slice, under +// Folder for a gallery or Folders for the folder index itself. type Gallery struct { Gruser struct { ID int `json:"gruserId"` @@ -42,7 +55,8 @@ type Gallery struct { Modules []struct { Name string ModuleData struct { - // группы + // Folders is the index of a profile's folders, each with a + // representative thumbnail. Folders struct { HasMore bool Results []struct { @@ -54,7 +68,7 @@ type Gallery struct { } } - // галерея + // Folder is the contents of one folder. Folder struct { HasMore bool Username string @@ -69,12 +83,23 @@ type Gallery struct { Results []Deviation } +// Group is the entry point for everything scoped to one profile. Despite the +// name it addresses users as well as groups, since DeviantArt treats the two +// alike. +// +// Name is the profile's username and must be set; the methods return an error +// otherwise. Construct it directly: +// +// g := devianter.Group{Name: "someuser"} +// profile, apiErr, err := g.Get() type Group struct { - Name string // обязательно заполнить + Name string // required Content Gallery } -// подходит как группа, так и пользователь +// Get retrieves the profile itself — its about page, statistics, and, for a +// group, its admins. It works for both users and groups; inspect +// Owner.Group on the result to tell which was returned. func (s Group) Get() (g GRuser, daError Error, err error) { if s.Name == "" { return g, daError, errors.New("missing Name field") @@ -84,10 +109,24 @@ func (s Group) Get() (g GRuser, daError Error, err error) { return } +// Favourites retrieves a page of the profile's favourites (its collections), 50 +// at a time, zero-based. +// +// Set all to gather every folder's contents into one listing. Otherwise pass a +// positive folderid to read a single folder, or 0 for the profile's default +// favourites listing. +// +// folderid is optional; omitting it is the same as passing 0. Only the first +// value is used. func (s Group) Favourites(page int, all bool, folderid ...int) (g Group, err Error) { var url strings.Builder - if fid := folderid[0]; fid > 0 || all { + fid := 0 + if len(folderid) > 0 { + fid = folderid[0] + } + + if fid > 0 || all { url.WriteString("dashared/gallection/contents") if all { url.WriteString("?all_folder=true") @@ -109,19 +148,31 @@ func (s Group) Favourites(page int, all bool, folderid ...int) (g Group, err Err return } -// гарелея пользователя или группы +// Gallery retrieves a page of the profile's gallery, 50 deviations at a time. +// Pass a positive folderid to read one folder, or 0 for the whole gallery. +// +// folderid is optional; omitting it is the same as passing 0. Only the first +// value is used. +// +// Note that page is interpreted differently by the two paths this takes: the +// whole-gallery listing is zero-based, while a folder listing is one-based. func (s Group) Gallery(page int, folderid ...int) (g Group, daError Error, err error) { if s.Name == "" { return g, daError, errors.New("missing Name field") } + fid := 0 + if len(folderid) > 0 { + fid = folderid[0] + } + var url strings.Builder - if folderid[0] > 0 { + if fid > 0 { page-- url.WriteString("dashared/gallection/contents?username=") url.WriteString(s.Name) url.WriteString("&folderid=") - url.WriteString(strconv.Itoa(folderid[0])) + url.WriteString(strconv.Itoa(fid)) url.WriteString("&offset=") url.WriteString(strconv.Itoa(page * 50)) url.WriteString("&type=gallery&") @@ -139,10 +190,14 @@ func (s Group) Gallery(page int, folderid ...int) (g Group, daError Error, err e return } +// GroupAbout is a group's about page: when it was founded and its description. type GroupAbout struct { FoundatedAt timeStamp `json:"foundationTs"` Description Text } + +// GroupAdmins lists a group's staff. TypeId encodes each member's role +// (founder, co-founder, contributor). type GroupAdmins struct { Results []struct { TypeId int @@ -152,10 +207,14 @@ type GroupAdmins struct { } } +// About is a person's profile information, all of it self-reported and any of +// it possibly empty. type About struct { Country, Website, WebsiteLabel, Gender string - RegDate int64 `json:"deviantFor"` - Description Text `json:"textContent"` + // RegDate is how long the account has existed, in seconds — an age, not a + // registration date, despite the name. + RegDate int64 `json:"deviantFor"` + Description Text `json:"textContent"` SocialLinks []struct { Value string @@ -165,6 +224,8 @@ type About struct { } } +// users is the person-specific half of a profile's module data, embedded into +// [GRuser] so its fields surface inline. type users struct { About About CoverDeviation struct { |
