diff --git a/README.md b/README.rst similarity index 100% rename from README.md rename to README.rst diff --git a/main.go b/main.go index da589ac..cb5603a 100644 --- a/main.go +++ b/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) diff --git a/misc/groups.go b/misc/groups.go new file mode 100644 index 0000000..993b3cd --- /dev/null +++ b/misc/groups.go @@ -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.Name + " " + } + } + 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) +} diff --git a/misc/search.go b/misc/search.go index 1d4a07a..77eecbb 100644 --- a/misc/search.go +++ b/misc/search.go @@ -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) } diff --git a/post/comments.go b/post/comments.go index 16ad927..d3824cf 100644 --- a/post/comments.go +++ b/post/comments.go @@ -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 = "

Comments (" + strconv.Itoa(comments.Total) + ")

" + htm - uri = uri[strings.LastIndex(uri, "/")+1:] + htm = "
Comments (" + strconv.Itoa(comments.Total) + ")" + htm + // uri = uri[strings.LastIndex(uri, "/")+1:] if prev { htm += "<-- Back " } if next { htm += "Next -->" } - } else { - htm = "

There is no comments.

" + htm += "
" } return &htm diff --git a/post/main.go b/post/main.go index 757dc98..26d7330 100644 --- a/post/main.go +++ b/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 + "
" - } 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 diff --git a/static/base.css b/static/base.css index 0b86ad1..4e5a4fe 100644 --- a/static/base.css +++ b/static/base.css @@ -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; diff --git a/templates/group.htm b/templates/group.htm new file mode 100644 index 0000000..8f90ce2 --- /dev/null +++ b/templates/group.htm @@ -0,0 +1,24 @@ + + + + !BAZE! + {{.Name}} | SkunkyArt + + + + {{if (ne .Bg "no")}} + + {{end}} + +

{{.Name}}

+

Gallery

+ +

Watchers: {{.V}}; Pageviews: {{.P}}

+

Group has been foundated in {{.Foundation}}

+ +

{{.Status}}

+

About the group

+

{{.Description}}

+ {{.Comments}} + + \ No newline at end of file diff --git a/templates/post.htm b/templates/post.htm index f950672..781f3bc 100644 --- a/templates/post.htm +++ b/templates/post.htm @@ -20,7 +20,7 @@ {{.Author}} — {{if (.DD)}} {{.Postname}} {{else}}{{.Postname}}{{end}} - {{if (ne .License "none")}}({{.License}}){{end}} {{if (.Ai)}}[🤖]{{end}} + {{if (ne .License "none")}}{{.License}}{{end}} {{if (.Ai)}}[🤖]{{end}} {{if (.Nsfw)}}[NSFW]{{end}}
@@ -39,10 +39,13 @@
{{.Description}}
{{end}} {{if (ne .Recomendations "")}} -

See also:

-
- {{.Recomendations}} -
+
+
+ See also +
+ {{.Recomendations}} +
+
{{end}} {{.Comments}} diff --git a/templates/search/search.htm b/templates/search.htm similarity index 100% rename from templates/search/search.htm rename to templates/search.htm diff --git a/templates/user/gallery.htm b/templates/user/gallery.htm index 6bb7f24..b0b7f5c 100644 --- a/templates/user/gallery.htm +++ b/templates/user/gallery.htm @@ -13,6 +13,10 @@ Home + + {{if (ne .Folders "")}} +

Folders: {{.Folders}}

+ {{end}}
{{.Posts}} diff --git a/todo.md b/todo.rst similarity index 97% rename from todo.md rename to todo.rst index a8c7526..f67500c 100644 --- a/todo.md +++ b/todo.rst @@ -1,4 +1,5 @@ Нужно сделать: +- рефакторинг - провести оптимизацию кода - кеширование жсона - ~~реализовать работу на определённом пути (https://example.com/skunkyart)~~ diff --git a/user/about.go b/user/about.go index 70577d6..1bc19a5 100644 --- a/user/about.go +++ b/user/about.go @@ -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) } } diff --git a/user/gallery.go b/user/gallery.go index df3389a..8912bfc 100644 --- a/user/gallery.go +++ b/user/gallery.go @@ -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 += "" + strconv.Itoa(x+1) + " " + tmp.Nav += "" + strconv.Itoa(x+1) + " " + } + + for _, a := range folders { + tmp.Folders = a } } output <- util.TmpExec("templates/user/gallery.htm", &tmp) diff --git a/user/main.go b/user/main.go index 4796a02..30d0dbe 100644 --- a/user/main.go +++ b/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 "" +} diff --git a/user/misc.go b/user/misc.go deleted file mode 100644 index ac8d4c9..0000000 --- a/user/misc.go +++ /dev/null @@ -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 "" -} diff --git a/util/dtype.go b/util/dtype.go index 806301b..11aa28a 100644 --- a/util/dtype.go +++ b/util/dtype.go @@ -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 += " [DD]" case deviation.IsMature: if !Conf.Nsfw { return "" } deviation.Title += " [NSFW]" + case deviation.IsAiGenerated: + deviation.Title += " [🤖]" + case deviation.IsDailyDeviation: + deviation.Title += " [DD]" } return "
" + image + "
" + deviation.Author.Username + deviation.Title + "
" } + +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 + "
" + } else { + ds = a.Text + } + } + } + description = Parse(ds) + + if len(description) > 1000 { + tds := description[:1000] + description = "
" + tds + "" + tds[1000:] + "
" + } + + 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 += "<-- Back " + } + tmp.Pages += "Next -->" + + return TmpExec(template, &tmp) +} diff --git a/util/grjunk.go b/util/grjunk.go new file mode 100644 index 0000000..9ef5b1d --- /dev/null +++ b/util/grjunk.go @@ -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 + } +}