package app import ( "bytes" "io" "net/http" "net/url" "regexp" "strconv" "strings" "text/template" "git.macaw.me/skunky/devianter" ) 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()) } func (s skunkyart) DeviationList(devs []devianter.Deviation) string { var list strings.Builder list.WriteString(`
`) for _, data := range devs { url := devianter.UrlFromMedia(data.Media) list.WriteString(`

`) list.WriteString(data.Author.Username) list.WriteString(" - ") list.WriteString(data.Title) // шильдики нсфв, аи и ежедневного поста if data.NSFW { list.WriteString(` [NSFW]`) } if data.AI { list.WriteString(" [🤖]") } if data.DD { list.WriteString(` [DD]`) } list.WriteString("
") } list.WriteString("
") return list.String() } // посты func (s skunkyart) Deviation(author, postname string) { // поиск ID re := regexp.MustCompile("[0-9]+").FindAllString(postname, -1) if len(re) >= 1 { var post struct { Post devianter.Post StringTime string Tags string Comments string } id := re[len(re)-1] post.Post = devianter.DeviationFunc(id, author) // время публикации post.StringTime = post.Post.Deviation.PublishedTime.UTC().String() println(post.Post.Description) // хештэги for _, x := range post.Post.Deviation.Extended.Tags { var tag strings.Builder tag.WriteString(` #`) tag.WriteString(x.Name) tag.WriteString("") post.Tags += tag.String() } // генерация комментов var cmmts strings.Builder var replied map[int]string _ = replied 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 { cmmts.WriteString(`

") cmmts.WriteString(x.User.Username) 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("
") post.Comments = cmmts.String() s.exe("html/deviantion.htm", &post) } else { s.httperr(400) } } func (s skunkyart) Search() { // тут всё и так понятно if s.Type == 'a' || s.Type == 't' || s.Type == '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) s.exe("html/search.htm", &srch) } else { s.httperr(400) } } 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) println(e.Error()) } wr(s.Writer, ae) } else { s.httperr(400) } }