Groups implementation (alpha)
This commit is contained in:
parent
ab662f414c
commit
28d8653464
8
main.go
8
main.go
|
@ -36,6 +36,7 @@ func main() {
|
|||
e, p := endpoint(r.URL.Path)
|
||||
c := make(chan string, 100)
|
||||
|
||||
// some args
|
||||
page, _ := strconv.ParseInt(r.URL.Query().Get("p"), 10, 32)
|
||||
q := url.QueryEscape(r.URL.Query().Get("q"))
|
||||
|
||||
|
@ -43,6 +44,9 @@ func main() {
|
|||
w.Header().Set("Content-Location", util.Conf.Base_uri)
|
||||
}
|
||||
|
||||
action := r.URL.Query().Get("a")
|
||||
|
||||
// uri
|
||||
switch e {
|
||||
case "image":
|
||||
fmt.Fprintln(w, misc.Getimage(p, url.QueryEscape(r.URL.Query().Get("t"))))
|
||||
|
@ -59,10 +63,10 @@ func main() {
|
|||
fmt.Fprintln(w, misc.Misc(strings.ToLower(p), true))
|
||||
|
||||
case "group":
|
||||
fmt.Fprintln(w, "Groups is not implemented yet :(")
|
||||
fmt.Fprintln(w, misc.GetGroup(action, r.URL.Query().Get("folder"), p, int(page)))
|
||||
|
||||
case "user":
|
||||
fmt.Fprintln(w, user.Get(p, r.URL.Query().Get("a"), q, int(page)))
|
||||
fmt.Fprintln(w, user.Get(p, action, q, int(page)))
|
||||
|
||||
case "post":
|
||||
go post.Get(p, int(page)+1, c)
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
package misc
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"skunkyart/post"
|
||||
"skunkyart/user"
|
||||
"skunkyart/util"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func GetGroup(action, folderid, name string, page int) string {
|
||||
switch action {
|
||||
case "":
|
||||
return about(name, page)
|
||||
case "gallery":
|
||||
f := getfolders(&name)
|
||||
if folderid != "" {
|
||||
var j struct {
|
||||
Results []util.Deviation
|
||||
}
|
||||
rjs := util.Puppy("dashared/gallection/contents?username=" + name + "&type=gallery&offset=" + strconv.Itoa(50*page) + "&limit=50&folderid=" + folderid)
|
||||
json.Unmarshal([]byte(rjs), &j)
|
||||
|
||||
return util.BaseList("templates/search.htm", "&a=gallery&folder="+folderid, "group/"+name, j.Results, page, f)
|
||||
} else {
|
||||
var c = make(chan string, 10)
|
||||
if page < 1 {
|
||||
page++
|
||||
}
|
||||
go user.Gallery(&name, c, strconv.Itoa(page), f)
|
||||
return <-c
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func getfolders(name *string) string {
|
||||
var j util.AB
|
||||
rjs := util.Puppy("dauserprofile/init/gallery?username=" + *name + "&deviations_limit=0&with_subfolders=true")
|
||||
json.Unmarshal([]byte(rjs), &j)
|
||||
|
||||
var folders string
|
||||
for _, a := range j.Gruser.Page.Modules {
|
||||
for _, a := range a.ModuleData.Folders.Results {
|
||||
folders += "<a href=\"" + util.Conf.Base_uri + "group/" + *name + "?a=gallery&folder=" + strconv.Itoa(a.FolderId) + "\">" + a.Name + "</a> "
|
||||
}
|
||||
}
|
||||
return folders
|
||||
}
|
||||
|
||||
func about(name string, page int) string {
|
||||
var tmp struct {
|
||||
Name, Description, Foundation, Status, Comments, Bg, Bgname string
|
||||
V, P int
|
||||
}
|
||||
var j util.AB
|
||||
rjs := util.Puppy("dauserprofile/init/about?username=" + name)
|
||||
json.Unmarshal([]byte(rjs), &j)
|
||||
|
||||
tmp.Name = j.Owner.Username
|
||||
tmp.Status = j.PageExtraData.GruserTagline
|
||||
uid := make([]string, 1)
|
||||
uid[0] = strconv.Itoa(j.Gruser.GruserId)
|
||||
tmp.Comments = *post.GetComments(util.Conf.Base_uri+"group/"+tmp.Name, "", page+1, 4, uid)
|
||||
for _, a := range j.Gruser.Page.Modules {
|
||||
if a.ModuleData.GroupAbout.FoundationTs.Unix() > 0 {
|
||||
tmp.Foundation = a.ModuleData.GroupAbout.FoundationTs.UTC().String()
|
||||
}
|
||||
if a.ModuleData.GroupAbout.Description.Html.Markup != "" {
|
||||
tmp.Description += util.ParseDescription(a.ModuleData.GroupAbout.Description)
|
||||
}
|
||||
|
||||
tmp.Bg = util.Images(a.ModuleData.CoverDeviation.CoverDeviation, a.ModuleData.CoverDeviation.CoverDeviation.Media, true)
|
||||
tmp.Bgname = a.ModuleData.CoverDeviation.CoverDeviation.Title
|
||||
}
|
||||
|
||||
tmp.V = j.PageExtraData.Stats.Watchers
|
||||
tmp.P = j.PageExtraData.Stats.Pageviews
|
||||
|
||||
return util.TmpExec("templates/group.htm", &tmp)
|
||||
}
|
|
@ -59,5 +59,5 @@ func Search(q, p, scope string, output chan string) {
|
|||
} else {
|
||||
output <- "Missing query."
|
||||
}
|
||||
output <- util.TmpExec("templates/search/search.htm", &tmp)
|
||||
output <- util.TmpExec("templates/search.htm", &tmp)
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ func js(c string, cc int, id []string, t int) (*string, bool, bool) {
|
|||
for x := 0; x < cc; x++ {
|
||||
/*
|
||||
1: comments of the post;
|
||||
4: comments on userpage
|
||||
4: comments on userpage or group
|
||||
*/
|
||||
|
||||
p := "dashared/comments/thread?typeid=" + strconv.Itoa(t) + "&itemid=" + id[len(id)-1] + "&maxdepth=1000&order=newest"
|
||||
|
@ -121,16 +121,15 @@ func GetComments(uri, cursor string, page, typ int, id []string) *string {
|
|||
|
||||
// если комментариев больше, чем 0, то отображаем их, иначе пишем, что комментов нет.
|
||||
if comments.Total > 0 {
|
||||
htm = "<h2 id=\"comments\">Comments (" + strconv.Itoa(comments.Total) + ")</h2>" + htm
|
||||
uri = uri[strings.LastIndex(uri, "/")+1:]
|
||||
htm = "<details><summary><b>Comments (" + strconv.Itoa(comments.Total) + ")</b></summary>" + htm
|
||||
// uri = uri[strings.LastIndex(uri, "/")+1:]
|
||||
if prev {
|
||||
htm += "<a href=\"" + uri + "?p=" + strconv.Itoa(page-2) + "#comments\"><-- Back</a> "
|
||||
}
|
||||
if next {
|
||||
htm += "<a href=\"" + uri + "?p=" + strconv.Itoa(page) + "#comments\">Next --></a>"
|
||||
}
|
||||
} else {
|
||||
htm = "<p>There is no comments.</p>"
|
||||
htm += "</details>"
|
||||
}
|
||||
|
||||
return &htm
|
||||
|
|
34
post/main.go
34
post/main.go
|
@ -46,38 +46,16 @@ func _post(id []string, author string, url string, page int) string {
|
|||
|
||||
tmp.Img = util.Images(j.Deviation, j.Deviation.Media, true)
|
||||
|
||||
if j.Deviation.Extended.DescriptionText.Html.Markup != "" {
|
||||
tmp.Description = util.ParseDescription(j.Deviation.Extended.DescriptionText)
|
||||
} else {
|
||||
tmp.Description = util.ParseDescription(j.Deviation.TextContent)
|
||||
}
|
||||
|
||||
tmp.Time = j.Deviation.PublishedTime.UTC().String()
|
||||
tmp.Views = j.Deviation.Stats.Views
|
||||
tmp.FavsCount = j.Deviation.Stats.Favourites
|
||||
|
||||
if j.Deviation.Extended.DescriptionText.Html.Markup != "" {
|
||||
tmp.Description = j.Deviation.Extended.DescriptionText.Html.Markup
|
||||
} else {
|
||||
tmp.Description = j.Deviation.TextContent.Html.Markup
|
||||
}
|
||||
|
||||
if len(tmp.Description) > 0 {
|
||||
if tmp.Description[0:1] == "{" {
|
||||
var j2 struct {
|
||||
Blocks []struct {
|
||||
Text string
|
||||
}
|
||||
}
|
||||
|
||||
json.Unmarshal([]byte(tmp.Description), &j2)
|
||||
|
||||
tmp.Description = ""
|
||||
for _, a := range j2.Blocks {
|
||||
if j.Deviation.TextContent.Html.Type == "draft" || j.Deviation.Extended.DescriptionText.Html.Type == "draft" {
|
||||
tmp.Description += a.Text + "<br>"
|
||||
} else {
|
||||
tmp.Description = a.Text
|
||||
}
|
||||
}
|
||||
}
|
||||
tmp.Description = util.Parse(tmp.Description)
|
||||
}
|
||||
|
||||
tmp.Downloads = j.Deviation.Stats.Downloads
|
||||
tmp.Ai = j.Deviation.IsAiGenerated
|
||||
tmp.License = j.Deviation.License
|
||||
|
|
|
@ -7,6 +7,10 @@ a {
|
|||
text-decoration: none;
|
||||
color: cadetblue;
|
||||
}
|
||||
a:hover {
|
||||
color: red;
|
||||
transition: 400ms;
|
||||
}
|
||||
form input, button, select {
|
||||
background-color: #134134;
|
||||
padding: 5px;
|
||||
|
@ -38,7 +42,6 @@ form input, button, select {
|
|||
color: rgb(160, 0, 147);
|
||||
}
|
||||
.content {
|
||||
background-color: #001624;
|
||||
border-radius: 3px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
!BAZE!
|
||||
<title>{{.Name}} | SkunkyArt</title>
|
||||
<link rel="stylesheet" href="static/base.css">
|
||||
</head>
|
||||
<body>
|
||||
{{if (ne .Bg "no")}}
|
||||
<img src="{{.Bg}}" width="30%" title="{{.Bgname}}">
|
||||
{{end}}
|
||||
|
||||
<h1><img src="avatar/{{.Name}}" width="60px">{{.Name}}</h1>
|
||||
<h2><a href="group/{{.Name}}?a=gallery">Gallery</a></h2>
|
||||
|
||||
<p>Watchers: {{.V}}; Pageviews: {{.P}}</p>
|
||||
<p>Group has been foundated in {{.Foundation}}</p>
|
||||
|
||||
<p><i title="Group caption">{{.Status}}</i></p>
|
||||
<h2>About the group</h2>
|
||||
<p>{{.Description}}</p>
|
||||
{{.Comments}}
|
||||
</body>
|
||||
</html>
|
|
@ -20,7 +20,7 @@
|
|||
<span><strong><a href="user/{{.Author}}">{{.Author}}</a></strong> — {{if (.DD)}}
|
||||
<span class="dd" title="Daily Deviation!"><b>{{.Postname}}</b></span>
|
||||
{{else}}{{.Postname}}{{end}}
|
||||
{{if (ne .License "none")}}({{.License}}){{end}} {{if (.Ai)}}[🤖]{{end}}
|
||||
{{if (ne .License "none")}}<mark title="License">{{.License}}</mark>{{end}} {{if (.Ai)}}[🤖]{{end}}
|
||||
{{if (.Nsfw)}}[<span class="nsfw">NSFW</span>]{{end}}
|
||||
</span>
|
||||
<br>
|
||||
|
@ -39,10 +39,13 @@
|
|||
<figcaption>{{.Description}}</figcaption>
|
||||
{{end}}
|
||||
{{if (ne .Recomendations "")}}
|
||||
<h2>See also:</h2>
|
||||
<div class="content">
|
||||
{{.Recomendations}}
|
||||
</div>
|
||||
<br>
|
||||
<details>
|
||||
<summary><b>See also</b></summary>
|
||||
<div class="content">
|
||||
{{.Recomendations}}
|
||||
</div>
|
||||
</details>
|
||||
{{end}}
|
||||
{{.Comments}}
|
||||
</figure>
|
||||
|
|
|
@ -13,6 +13,10 @@
|
|||
<button type="submit">Search!</button>
|
||||
</form> <a href="user/{{.Name}}">Home</a>
|
||||
</h2>
|
||||
|
||||
{{if (ne .Folders "")}}
|
||||
<p>Folders: {{.Folders}}</p>
|
||||
{{end}}
|
||||
|
||||
<div class="content">
|
||||
{{.Posts}}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
Нужно сделать:
|
||||
- рефакторинг
|
||||
- провести оптимизацию кода
|
||||
- кеширование жсона
|
||||
- ~~реализовать работу на определённом пути (https://example.com/skunkyart)~~
|
|
@ -19,7 +19,7 @@ func about(name *string, page int, output chan string) {
|
|||
|
||||
{
|
||||
var tmp Tmp
|
||||
var j ab
|
||||
var j util.AB
|
||||
|
||||
// парсинг
|
||||
rawjson := util.Puppy("dauserprofile/init/about?username=" + *name)
|
||||
|
@ -105,6 +105,6 @@ func about(name *string, page int, output chan string) {
|
|||
tmp.Comments = *post.GetComments("user/"+tmp.Name, "", page+1, 4, uid)
|
||||
}
|
||||
|
||||
output <- util.TmpExec("templates/user/info.htm", tmp)
|
||||
output <- util.TmpExec("templates/user/info.htm", &tmp)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,11 +6,11 @@ import (
|
|||
"strconv"
|
||||
)
|
||||
|
||||
func gallery(name *string, output chan string, page string) {
|
||||
func Gallery(name *string, output chan string, page string, folders ...string) {
|
||||
{
|
||||
var tmp struct {
|
||||
Posts, Name, Nav string
|
||||
TP int
|
||||
Posts, Name, Nav, Folders string
|
||||
TP int
|
||||
}
|
||||
var j struct {
|
||||
Gruser struct {
|
||||
|
@ -27,6 +27,9 @@ func gallery(name *string, output chan string, page string) {
|
|||
}
|
||||
}
|
||||
}
|
||||
Owner struct {
|
||||
IsGroup bool
|
||||
}
|
||||
}
|
||||
|
||||
rawjson := util.Puppy("dauserprofile/init/gallery?username=" + *name + "&page=" + page + "&deviations_limit=50&with_subfolders=false")
|
||||
|
@ -51,8 +54,16 @@ func gallery(name *string, output chan string, page string) {
|
|||
}
|
||||
|
||||
tmp.Nav = ""
|
||||
path := "user/"
|
||||
if j.Owner.IsGroup {
|
||||
path = "group/"
|
||||
}
|
||||
for x := 0; x < tmp.TP; x++ {
|
||||
tmp.Nav += "<a href=\"" + util.Conf.Base_uri + "user/" + tmp.Name + "?a=gallery&p=" + strconv.Itoa(x+1) + "\">" + strconv.Itoa(x+1) + "</a> "
|
||||
tmp.Nav += "<a href=\"" + util.Conf.Base_uri + path + tmp.Name + "?a=gallery&p=" + strconv.Itoa(x+1) + "\">" + strconv.Itoa(x+1) + "</a> "
|
||||
}
|
||||
|
||||
for _, a := range folders {
|
||||
tmp.Folders = a
|
||||
}
|
||||
}
|
||||
output <- util.TmpExec("templates/user/gallery.htm", &tmp)
|
||||
|
|
31
user/main.go
31
user/main.go
|
@ -1,6 +1,9 @@
|
|||
package user
|
||||
|
||||
import "strconv"
|
||||
import (
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func Get(name, action, query string, page int) string {
|
||||
c := make(chan string, 100)
|
||||
|
@ -13,9 +16,33 @@ func Get(name, action, query string, page int) string {
|
|||
page = 1
|
||||
}
|
||||
|
||||
go gallery(&name, c, strconv.Itoa(page))
|
||||
go Gallery(&name, c, strconv.Itoa(page))
|
||||
case "search":
|
||||
go search(&name, &query, page, c)
|
||||
}
|
||||
return <-c
|
||||
}
|
||||
|
||||
func rerror(err *string) string {
|
||||
if len(*err) < 100 {
|
||||
var j struct {
|
||||
ErrorDescription string
|
||||
}
|
||||
|
||||
json.Unmarshal([]byte(*err), &j)
|
||||
|
||||
switch j.ErrorDescription {
|
||||
case "User deactivated.":
|
||||
return "User deactivated their account or has been banned."
|
||||
case "user_not_found.":
|
||||
return "Not exists user."
|
||||
default:
|
||||
if *err == "Something went wrong. Status: 403" {
|
||||
return "Rate limit from CloudFront."
|
||||
} else {
|
||||
return "Something went wrong."
|
||||
}
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
|
72
user/misc.go
72
user/misc.go
|
@ -1,72 +0,0 @@
|
|||
package user
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"skunkyart/util"
|
||||
)
|
||||
|
||||
type ab struct {
|
||||
ErrorDescription string
|
||||
Owner struct {
|
||||
Username string
|
||||
}
|
||||
Gruser struct {
|
||||
GruserId int
|
||||
Page struct {
|
||||
Modules []struct {
|
||||
Name string
|
||||
ModuleData struct {
|
||||
About struct {
|
||||
Country, Website, WebsiteLabel, Gender, Tagline string
|
||||
DeviantFor int64
|
||||
SocialLinks []struct {
|
||||
Value string
|
||||
}
|
||||
TextContent struct {
|
||||
Excerpt string
|
||||
Html struct {
|
||||
Markup string
|
||||
}
|
||||
}
|
||||
Interests []struct {
|
||||
Label, Value string
|
||||
}
|
||||
}
|
||||
CoverDeviation struct {
|
||||
CoverDeviation util.Deviation
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
PageExtraData struct {
|
||||
GruserTagline string
|
||||
Stats struct {
|
||||
Deviations, Watchers, Watching, Pageviews, CommentsReceivedProfile, CommentsMade, Favourites, Friends int
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func rerror(err *string) string {
|
||||
if len(*err) < 100 {
|
||||
var j struct {
|
||||
ErrorDescription string
|
||||
}
|
||||
|
||||
json.Unmarshal([]byte(*err), &j)
|
||||
|
||||
switch j.ErrorDescription {
|
||||
case "User deactivated.":
|
||||
return "User deactivated their account or has been banned."
|
||||
case "user_not_found.":
|
||||
return "Not exists user."
|
||||
default:
|
||||
if *err == "Something went wrong. Status: 403" {
|
||||
return "Rate limit from CloudFront."
|
||||
} else {
|
||||
return "Something went wrong."
|
||||
}
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package util
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
@ -21,16 +22,16 @@ type Deviation struct {
|
|||
Tags []struct {
|
||||
Name string
|
||||
}
|
||||
DescriptionText struct {
|
||||
Html HTML
|
||||
}
|
||||
RelatedContent []struct {
|
||||
DescriptionText tx
|
||||
RelatedContent []struct {
|
||||
Deviations []Deviation
|
||||
}
|
||||
}
|
||||
TextContent struct {
|
||||
Html HTML
|
||||
}
|
||||
TextContent tx
|
||||
}
|
||||
|
||||
type tx struct {
|
||||
Html HTML
|
||||
}
|
||||
|
||||
type Media struct {
|
||||
|
@ -103,16 +104,72 @@ func Images(deviation Deviation, media Media, nfmt bool) string {
|
|||
}
|
||||
|
||||
switch {
|
||||
case deviation.IsAiGenerated:
|
||||
deviation.Title += " [🤖]"
|
||||
case deviation.IsDailyDeviation:
|
||||
deviation.Title += " [<span class=\"dd\">DD</span>]"
|
||||
case deviation.IsMature:
|
||||
if !Conf.Nsfw {
|
||||
return ""
|
||||
}
|
||||
deviation.Title += " [<span class=\"nsfw\">NSFW</span>]"
|
||||
case deviation.IsAiGenerated:
|
||||
deviation.Title += " [🤖]"
|
||||
case deviation.IsDailyDeviation:
|
||||
deviation.Title += " [<span class=\"dd\">DD</span>]"
|
||||
}
|
||||
|
||||
return "<div class=\"block\">" + image + "<br><a href=\"" + Conf.Base_uri + "post" + link + "\">" + deviation.Author.Username + deviation.Title + "</a></div>"
|
||||
}
|
||||
|
||||
func ParseDescription(tx tx) string {
|
||||
var description string
|
||||
ds := tx.Html.Markup
|
||||
|
||||
if len(ds) > 0 {
|
||||
if ds[0:1] == "{" {
|
||||
var j2 struct {
|
||||
Blocks []struct {
|
||||
Text string
|
||||
}
|
||||
}
|
||||
|
||||
json.Unmarshal([]byte(ds), &j2)
|
||||
|
||||
for _, a := range j2.Blocks {
|
||||
if ds == "draft" {
|
||||
ds += a.Text + "<br>"
|
||||
} else {
|
||||
ds = a.Text
|
||||
}
|
||||
}
|
||||
}
|
||||
description = Parse(ds)
|
||||
|
||||
if len(description) > 1000 {
|
||||
tds := description[:1000]
|
||||
description = "<details><summary>" + tds + "</summary>" + tds[1000:] + "</details>"
|
||||
}
|
||||
|
||||
return description
|
||||
}
|
||||
return "No description."
|
||||
}
|
||||
|
||||
func BaseList(template, args, uri string, results []Deviation, page int, folders ...string) string {
|
||||
var tmp struct {
|
||||
Results, Pages, Folders string
|
||||
Total int
|
||||
}
|
||||
|
||||
for _, a := range folders {
|
||||
tmp.Folders = a
|
||||
}
|
||||
|
||||
for _, a := range results {
|
||||
tmp.Results += Images(a, a.Media, false)
|
||||
}
|
||||
|
||||
if page > 0 {
|
||||
tmp.Pages += "<a href=\"" + Conf.Base_uri + uri + "?p=" + strconv.Itoa(page-1) + args + "\"><-- Back</a> "
|
||||
}
|
||||
tmp.Pages += "<a href=\"" + Conf.Base_uri + uri + "?p=" + strconv.Itoa(page+1) + args + "\">Next --></a>"
|
||||
|
||||
return TmpExec(template, &tmp)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
package util
|
||||
|
||||
type AB struct {
|
||||
ErrorDescription string
|
||||
Owner struct {
|
||||
Username string
|
||||
}
|
||||
Gruser struct {
|
||||
GruserId int
|
||||
Page struct {
|
||||
Modules []struct {
|
||||
Name string
|
||||
ModuleData struct {
|
||||
About struct {
|
||||
Country, Website, WebsiteLabel, Gender, Tagline string
|
||||
DeviantFor int64
|
||||
SocialLinks []struct {
|
||||
Value string
|
||||
}
|
||||
TextContent Description
|
||||
Interests []struct {
|
||||
Label, Value string
|
||||
}
|
||||
}
|
||||
CoverDeviation struct {
|
||||
CoverDeviation Deviation
|
||||
}
|
||||
|
||||
// группы
|
||||
GroupAbout struct {
|
||||
Tagline string
|
||||
FoundationTs Time
|
||||
Description struct {
|
||||
Html HTML
|
||||
}
|
||||
}
|
||||
GroupAdmins struct {
|
||||
Results []struct {
|
||||
Username string
|
||||
}
|
||||
}
|
||||
Folders struct {
|
||||
Results []struct {
|
||||
FolderId int
|
||||
Name string
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
PageExtraData struct {
|
||||
GruserTagline string
|
||||
Stats struct {
|
||||
Deviations, Watchers, Watching, Pageviews, CommentsReceivedProfile, CommentsMade, Favourites, Friends int
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type Description struct {
|
||||
Excerpt string
|
||||
Html struct {
|
||||
Markup string
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue