From ed031b353078d0b58a67981de4d463c8563a20d7 Mon Sep 17 00:00:00 2001 From: lost+skunk Date: Sun, 30 Jun 2024 14:40:27 +0300 Subject: попытка реализовать галерею. так сыро потому что мне скоро уезжать MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/router.go | 4 +- app/util.go | 198 +++++++++++++++++++++++++++++++ app/wraper.go | 368 ++++++++++++++++------------------------------------------ 3 files changed, 303 insertions(+), 267 deletions(-) (limited to 'app') diff --git a/app/router.go b/app/router.go index 9e51fd9..d98e2a9 100644 --- a/app/router.go +++ b/app/router.go @@ -52,7 +52,7 @@ func Router() { // пути switch e { default: - skunky.httperr(404) + skunky.ReturnHTTPError(404) case "/", "": open_n_send("html/index.htm") case "post": @@ -62,7 +62,7 @@ func Router() { skunky.Search() case "dd": skunky.DD() - case "group": + case "group_user": skunky.GRUser() case "media": diff --git a/app/util.go b/app/util.go index 7c4d104..e4a1de2 100644 --- a/app/util.go +++ b/app/util.go @@ -2,11 +2,38 @@ package app import ( "encoding/json" + "net/http" + "strconv" "strings" + "text/template" "git.macaw.me/skunky/devianter" ) +// парсинг темплейтов +func (s skunkyart) ExecuteTemplate(file string, data any) { + var buf strings.Builder + tmp, e := template.ParseFiles(file) + err(e) + err(tmp.Execute(&buf, &data)) + wr(s.Writer, buf.String()) +} + +func (s skunkyart) ReturnHTTPError(status int) { + s.Writer.WriteHeader(status) + + // пострйока с помощью strings.Builder, потому что такой метод быстрее обычного сложения + var msg strings.Builder + msg.WriteString(``) + msg.WriteString("

") + msg.WriteString(strconv.Itoa(status)) + msg.WriteString(" - ") + msg.WriteString(http.StatusText(status)) + msg.WriteString("

") + + wr(s.Writer, msg.String()) +} + type text struct { TXT string from int @@ -87,3 +114,174 @@ func ParseDescription(dscr devianter.Text) string { return parseddescription.String() } + +// навигация по страницам +type dlist struct { + Pages int + More bool +} + +// FIXME: на некоротрых артах первая страница может вызывать полное отсутствие панели навигации. +func (s skunkyart) NavBase(c dlist) string { + // TODO: сделать понятнее + // навигация по страницам + var list strings.Builder + list.WriteString("
") + p := s.Page + + // функция для генерации ссылок + prevrev := func(msg string, page int, onpage bool) { + if !onpage { + list.WriteString(``) + list.WriteString(msg) + list.WriteString(" ") + } else { + list.WriteString(strconv.Itoa(page)) + list.WriteString(" ") + } + } + + // вперёд-назад + if p > 1 { + prevrev("<= Prev |", p-1, false) + } else { + p = 1 + } + + if c.Pages > 0 { + // назад + for x := p - 6; x < p && x > 0; x++ { + prevrev(strconv.Itoa(x), x, false) + } + + // вперёд + for x := p; x <= p+6; x++ { + if x == p { + prevrev("", x, true) + x++ + } + + if x > p { + prevrev(strconv.Itoa(x), x, false) + } + } + } + + // вперёд-назад + if c.More { + prevrev("| Next =>", p+1, false) + } + + return list.String() +} + +func (s skunkyart) DeviationList(devs []devianter.Deviation, content ...dlist) string { + var list strings.Builder + list.WriteString(`
`) + for _, data := range devs { + url := devianter.UrlFromMedia(data.Media) + + list.WriteString(`") + } + list.WriteString("
") + list.WriteString(s.NavBase(content[0])) + + return list.String() +} + +// FIXME: первый комментарий не отображается. +func (s skunkyart) ParseComments(c devianter.Comments) string { + var cmmts strings.Builder + replied := make(map[int]string) + + cmmts.WriteString("
Comments: ") + cmmts.WriteString(strconv.Itoa(c.Total)) + cmmts.WriteString("") + for _, x := range c.Thread { + replied[x.ID] = x.User.Username + cmmts.WriteString(`

`) + cmmts.WriteString(x.User.Username) + cmmts.WriteString(" ") + + if x.Parent > 0 { + cmmts.WriteString(` In reply to `) + if replied[x.Parent] == "" { + cmmts.WriteString("???") + } else { + cmmts.WriteString(replied[x.Parent]) + } + cmmts.WriteString("") + } + cmmts.WriteString(" [") + cmmts.WriteString(x.Posted.UTC().String()) + cmmts.WriteString("]

") + + cmmts.WriteString(x.Comment) + cmmts.WriteString("

👍: ") + cmmts.WriteString(strconv.Itoa(x.Likes)) + cmmts.WriteString(" ⏩: ") + cmmts.WriteString(strconv.Itoa(x.Replies)) + cmmts.WriteString("

\n") + } + cmmts.WriteString(s.NavBase(dlist{ + Pages: 0, + More: c.HasMore, + })) + cmmts.WriteString("
") + return cmmts.String() +} diff --git a/app/wraper.go b/app/wraper.go index ccaccee..2b733fd 100644 --- a/app/wraper.go +++ b/app/wraper.go @@ -1,14 +1,13 @@ package app import ( - "bytes" + "fmt" "io" "net/http" "net/url" "regexp" "strconv" "strings" - "text/template" "time" "git.macaw.me/skunky/devianter" @@ -17,206 +16,108 @@ import ( var wr = io.WriteString type skunkyart struct { - Writer http.ResponseWriter - Args url.Values - Type rune - Query string - Page int -} - -// парсинг темплейтов -func (s skunkyart) exe(file string, data any) { - var buf bytes.Buffer - tmp, e := template.ParseFiles(file) - err(e) - tmp.Execute(&buf, &data) - wr(s.Writer, buf.String()) -} - -func (s skunkyart) httperr(status int) { - s.Writer.WriteHeader(status) - - // пострйока с помощью strings.Builder, потому что такой метод быстрее обычного сложения - var msg strings.Builder - msg.WriteString(``) - msg.WriteString("

") - msg.WriteString(strconv.Itoa(status)) - msg.WriteString(" - ") - msg.WriteString(http.StatusText(status)) - msg.WriteString("

") - - wr(s.Writer, msg.String()) -} - -// навигация по страницам -type dlist struct { - Pages int - More bool -} - -// FIXME: на некоротрых артах первая страница может вызывать полное отсутствие панели навигации. -func (s skunkyart) NavBase(c dlist) string { - // TODO: сделать понятнее - // навигация по страницам - var list strings.Builder - list.WriteString("
") - p := s.Page - - // функция для генерации ссылок - prevrev := func(msg string, page int, onpage bool) { - if !onpage { - list.WriteString(``) - list.WriteString(msg) - list.WriteString(" ") - } else { - list.WriteString(strconv.Itoa(page)) - list.WriteString(" ") - } - } - - // вперёд-назад - if p > 1 { - prevrev("<= Prev |", p-1, false) - } else { - p = 1 - } - - if c.Pages > 0 { - // назад - for x := p - 6; x < p && x > 0; x++ { - prevrev(strconv.Itoa(x), x, false) - } - - // вперёд - for x := p; x <= p+6; x++ { - if x == p { - prevrev("", x, true) - x++ + Writer http.ResponseWriter + Args url.Values + Type rune + Query string + Page int + Templates struct { + GroupUser struct { + GR devianter.GRuser + CreationDate string + + About struct { + A devianter.About + + DescriptionFormatted string + Interests, Social string + Comments string + BG string + BGMeta devianter.Deviation } - if x > p { - prevrev(strconv.Itoa(x), x, false) + Gallery struct { + Pages int + List string } } + Search struct { + Content devianter.Search + List string + } } - - // вперёд-назад - if c.More { - prevrev("| Next =>", p+1, false) - } - - return list.String() } func (s skunkyart) GRUser() { - var group struct { - GR devianter.GRuser - CreationDate string - - About struct { - A devianter.About - - DescriptionFormatted string - Interests string - Social string - BG devianter.Deviation - } - } - if len(s.Query) < 1 { - s.httperr(400) + s.ReturnHTTPError(400) return } var g devianter.Group g.Name = s.Query - group.GR = g.GroupFunc() - - if g := group.GR; !g.Owner.Group { - for _, x := range g.Gruser.Page.Modules { - var about = group.About.A - if x.ModuleData.About.RegDate != 0 { - about = x.ModuleData.About - } - group.About.DescriptionFormatted = ParseDescription(about.Description) + s.Templates.GroupUser.GR = g.GroupFunc() + group := &s.Templates.GroupUser - for _, val := range x.ModuleData.About.Interests { - var interest strings.Builder - interest.WriteString(val.Label) - interest.WriteString(": ") - interest.WriteString(val.Value) - interest.WriteString("
") - group.About.Interests += interest.String() - } - - for _, val := range x.ModuleData.About.SocialLinks { - var social strings.Builder - social.WriteString(``) - social.WriteString(val.Value) - social.WriteString("
") - group.About.Social += social.String() - } - - if rd := x.ModuleData.About.RegDate; rd != 0 { - group.CreationDate = time.Unix(time.Now().Unix()-rd, 0).UTC().String() + switch s.Type { + case 'a': + if g := group.GR; !g.Owner.Group { + for _, x := range g.Gruser.Page.Modules { + switch x.Name { + case "about": + group.About.A = x.ModuleData.About + var about = group.About.A + group.About.DescriptionFormatted = ParseDescription(about.Description) + group.About.Comments = s.ParseComments(devianter.CommentsFunc( + strconv.Itoa(group.GR.Gruser.ID), + "", + s.Page, + 4, + )) + + for _, val := range x.ModuleData.About.SocialLinks { + var social strings.Builder + social.WriteString(``) + social.WriteString(val.Value) + social.WriteString("
") + group.About.Social += social.String() + } + + for _, val := range x.ModuleData.About.Interests { + var interest strings.Builder + interest.WriteString(val.Label) + interest.WriteString(": ") + interest.WriteString(val.Value) + interest.WriteString("
") + group.About.Interests += interest.String() + } + + if rd := x.ModuleData.About.RegDate; rd != 0 { + group.CreationDate = time.Unix(time.Now().Unix()-rd, 0).UTC().String() + } + case "cover_deviation": + group.About.BGMeta = x.ModuleData.CoverDeviation.Deviation + group.About.BG = devianter.UrlFromMedia(group.About.BGMeta.Media) + } } - } - } else { - - } - - s.exe("html/gruser.htm", &group) -} - -func (s skunkyart) DeviationList(devs []devianter.Deviation, content ...dlist) string { - var list strings.Builder - list.WriteString(`
`) - for _, data := range devs { - url := devianter.UrlFromMedia(data.Media) - - list.WriteString(`") + default: + s.ReturnHTTPError(400) } - list.WriteString("
") - list.WriteString(s.NavBase(content[0])) - return list.String() + s.ExecuteTemplate("html/gruser.htm", &s) } // посты @@ -250,115 +151,52 @@ func (s skunkyart) Deviation(author, postname string) { post.Tags += tag.String() } - // FIXME: первый комментарий не отображается. - // генерация комментов - var cmmts strings.Builder - replied := make(map[int]string) - c := devianter.CommentsFunc(id, post.Post.Comments.Cursor, s.Page, 1) - - cmmts.WriteString("
Comments: ") - cmmts.WriteString(strconv.Itoa(c.Total)) - cmmts.WriteString("") - for _, x := range c.Thread { - replied[x.ID] = x.User.Username - cmmts.WriteString(`

`) - cmmts.WriteString(x.User.Username) - cmmts.WriteString(" ") + post.Comments = s.ParseComments(devianter.CommentsFunc(id, post.Post.Comments.Cursor, s.Page, 1)) - if x.Parent > 0 { - cmmts.WriteString(` In reply to `) - if replied[x.Parent] == "" { - cmmts.WriteString("???") - } else { - cmmts.WriteString(replied[x.Parent]) - } - cmmts.WriteString("") - } - cmmts.WriteString(" [") - cmmts.WriteString(x.Posted.UTC().String()) - cmmts.WriteString("]

") - - cmmts.WriteString(x.Comment) - cmmts.WriteString("

👍: ") - cmmts.WriteString(strconv.Itoa(x.Likes)) - cmmts.WriteString(" ⏩: ") - cmmts.WriteString(strconv.Itoa(x.Replies)) - cmmts.WriteString("

\n") - } - cmmts.WriteString(s.NavBase(dlist{ - Pages: 0, - More: c.HasMore, - })) - cmmts.WriteString("
") - - post.Comments = cmmts.String() - - s.exe("html/deviantion.htm", &post) + s.ExecuteTemplate("html/deviantion.htm", &post) } else { - s.httperr(400) + s.ReturnHTTPError(400) } } func (s skunkyart) DD() { dd := devianter.DailyDeviationsFunc(s.Page) - s.exe("html/list.htm", s.DeviationList(dd.Deviations, dlist{ + s.ExecuteTemplate("html/list.htm", s.DeviationList(dd.Deviations, dlist{ Pages: 0, More: dd.HasMore, })) } func (s skunkyart) Search() { - // тут всё и так понятно + var e error + ss := &s.Templates.Search switch s.Type { - case 'a', 't', 'g': - var srch struct { - Search devianter.Search - List string - } - - var e error - srch.Search, e = devianter.SearchFunc(s.Query, s.Page, s.Type) - err(e) - srch.List = s.DeviationList(srch.Search.Results, dlist{ - Pages: srch.Search.Pages, - More: srch.Search.HasMore, - }) - - s.exe("html/search.htm", &srch) + case 'a', 't': + ss.Content, e = devianter.SearchFunc(s.Query, s.Page, s.Type) + case 'g': + ss.Content, e = devianter.SearchFunc(s.Query, s.Page, s.Type, s.Args.Get("usr")) default: - s.httperr(400) + s.ReturnHTTPError(400) } + err(e) + + ss.List = s.DeviationList(ss.Content.Results, dlist{ + Pages: ss.Content.Pages, + More: ss.Content.HasMore, + }) + + s.ExecuteTemplate("html/search.htm", &s) } func (s skunkyart) Emojitar(name string) { if name != "" && (s.Type == 'a' || s.Type == 'e') { ae, e := devianter.AEmedia(name, s.Type) if e != nil { - s.httperr(404) + s.ReturnHTTPError(404) println(e.Error()) } wr(s.Writer, ae) } else { - s.httperr(400) + s.ReturnHTTPError(400) } } -- cgit v1.2.3