Commit a8633b828f

a8633b828f3e4e2d232e2194d9f2b85cdcd9e8db

parent: aec0bfc438

Unsigned

lost+skunk <skunky@ebloid.ru> · 2024-06-27 11:51 UTC

крымские наработки

Layout: unified · split

app/router.go +3
@@ -62,6 +62,9 @@ func Router() {
6262 skunky.Search()
6363 case "dd":
6464 skunky.DD()
65 case "group":
66 skunky.GRUser()
67
6568 case "media":
6669 skunky.Emojitar(url)
6770 case "about":
app/util.go added +89
@@ -0,0 +1,89 @@
1package app
2
3import (
4 "encoding/json"
5 "strings"
6
7 "git.macaw.me/skunky/devianter"
8)
9
10type text struct {
11 TXT string
12 from int
13 to int
14}
15
16func ParseDescription(dscr devianter.Text) string {
17 var parseddescription strings.Builder
18 TagBuilder := func(tag string, content string) string {
19 if tag != "" {
20 var htm strings.Builder
21 htm.WriteString("<")
22 htm.WriteString(tag)
23 htm.WriteString(">")
24
25 htm.WriteString(content)
26
27 htm.WriteString("</")
28 htm.WriteString(tag)
29 htm.WriteString(">")
30 return htm.String()
31 }
32 return content
33 }
34
35 if description, dl := dscr.Html.Markup, len(dscr.Html.Markup); dl != 0 &&
36 description[0] == '{' &&
37 description[dl-1] == '}' {
38 var descr struct {
39 Blocks []struct {
40 Key, Text, Type string
41 InlineStyleRanges []struct {
42 Offset, Length int
43 Style string
44 }
45 }
46 }
47 e := json.Unmarshal([]byte(description), &descr)
48 err(e)
49
50 for _, x := range descr.Blocks {
51 ranges := make(map[int]text)
52 for i, rngs := range x.InlineStyleRanges {
53 var tag string
54
55 switch rngs.Style {
56 case "BOLD":
57 tag = "b"
58 case "UNDERLINE":
59 tag = "u"
60 case "ITALIC":
61 tag = "i"
62 }
63
64 fromto := rngs.Offset + rngs.Length
65 ranges[i] = text{
66 TXT: TagBuilder(tag, x.Text[rngs.Offset:fromto]),
67 from: rngs.Offset,
68 to: fromto,
69 }
70 }
71
72 for _, r := range ranges {
73 var tag string
74 switch x.Type {
75 case "header-two":
76 tag = "h2"
77 case "unstyled":
78 tag = "p"
79 }
80 parseddescription.WriteString(r.TXT)
81 parseddescription.WriteString(TagBuilder(tag, x.Text[r.to:]))
82 }
83 }
84 } else if dl != 0 {
85 parseddescription.WriteString(description)
86 }
87
88 return parseddescription.String()
89}
app/wraper.go +69 −2
@@ -9,6 +9,7 @@ import (
99 "strconv"
1010 "strings"
1111 "text/template"
12 "time"
1213
1314 "git.macaw.me/skunky/devianter"
1415)
@@ -117,6 +118,68 @@ func (s skunkyart) NavBase(c dlist) string {
117118 return list.String()
118119}
119120
121func (s skunkyart) GRUser() {
122 var group struct {
123 GR devianter.GRuser
124 CreationDate string
125
126 About struct {
127 A devianter.About
128
129 DescriptionFormatted string
130 Interests string
131 Social string
132 BG devianter.Deviation
133 }
134 }
135
136 if len(s.Query) < 1 {
137 s.httperr(400)
138 return
139 }
140
141 var g devianter.Group
142 g.Name = s.Query
143 group.GR = g.GroupFunc()
144
145 if g := group.GR; !g.Owner.Group {
146 for _, x := range g.Gruser.Page.Modules {
147 var about = group.About.A
148 if x.ModuleData.About.RegDate != 0 {
149 about = x.ModuleData.About
150 }
151 group.About.DescriptionFormatted = ParseDescription(about.Description)
152
153 for _, val := range x.ModuleData.About.Interests {
154 var interest strings.Builder
155 interest.WriteString(val.Label)
156 interest.WriteString(": <b>")
157 interest.WriteString(val.Value)
158 interest.WriteString("</b><br>")
159 group.About.Interests += interest.String()
160 }
161
162 for _, val := range x.ModuleData.About.SocialLinks {
163 var social strings.Builder
164 social.WriteString(`<a target="_blank" href="`)
165 social.WriteString(val.Value)
166 social.WriteString(`">`)
167 social.WriteString(val.Value)
168 social.WriteString("</a><br>")
169 group.About.Social += social.String()
170 }
171
172 if rd := x.ModuleData.About.RegDate; rd != 0 {
173 group.CreationDate = time.Unix(time.Now().Unix()-rd, 0).UTC().String()
174 }
175 }
176 } else {
177
178 }
179
180 s.exe("html/gruser.htm", &group)
181}
182
120183func (s skunkyart) DeviationList(devs []devianter.Deviation, content ...dlist) string {
121184 var list strings.Builder
122185 list.WriteString(`<div class="content">`)
@@ -171,6 +234,7 @@ func (s skunkyart) Deviation(author, postname string) {
171234 id := re[len(re)-1]
172235 post.Post = devianter.DeviationFunc(id, author)
173236
237 post.Post.Description = ParseDescription(post.Post.Deviation.TextContent)
174238 // время публикации
175239 post.StringTime = post.Post.Deviation.PublishedTime.UTC().String()
176240
@@ -218,6 +282,7 @@ func (s skunkyart) Deviation(author, postname string) {
218282 cmmts.WriteString(`">`)
219283 cmmts.WriteString(x.User.Username)
220284 cmmts.WriteString("</b></a> ")
285
221286 if x.Parent > 0 {
222287 cmmts.WriteString(` In reply to <a href="#`)
223288 cmmts.WriteString(strconv.Itoa(x.Parent))
@@ -232,6 +297,7 @@ func (s skunkyart) Deviation(author, postname string) {
232297 cmmts.WriteString(" [")
233298 cmmts.WriteString(x.Posted.UTC().String())
234299 cmmts.WriteString("]<p>")
300
235301 cmmts.WriteString(x.Comment)
236302 cmmts.WriteString("<p>👍: ")
237303 cmmts.WriteString(strconv.Itoa(x.Likes))
@@ -263,7 +329,8 @@ func (s skunkyart) DD() {
263329
264330func (s skunkyart) Search() {
265331 // тут всё и так понятно
266 if s.Type == 'a' || s.Type == 't' || s.Type == 'g' {
332 switch s.Type {
333 case 'a', 't', 'g':
267334 var srch struct {
268335 Search devianter.Search
269336 List string
@@ -278,7 +345,7 @@ func (s skunkyart) Search() {
278345 })
279346
280347 s.exe("html/search.htm", &srch)
281 } else {
348 default:
282349 s.httperr(400)
283350 }
284351}
css/skunky.css +1 −1
@@ -8,7 +8,7 @@ a {
88 color: cadetblue;
99}
1010a:hover {
11 color: red;
11 color: yellow;
1212 transition: 400ms;
1313}
1414header h1 {
html/deviantion.htm +2
@@ -34,7 +34,9 @@
3434 {{end}}
3535 <span>Published: <strong>{{.StringTime}}</strong>; Views: <strong>{{.Post.Deviation.Stats.Views}}</strong>; Favourites: <strong>{{.Post.Deviation.Stats.Favourites}}</strong>; Downloads: <strong>{{.Post.Deviation.Stats.Downloads}}</strong></span>
3636 {{if (ne .Post.Description "")}}
37 <figcaption>
3738 {{.Post.Description}}
39 </figcaption>
3840 {{end}}
3941 {{if (ne .Comments "")}}
4042 {{.Comments}}
html/gruser.htm added +43
@@ -0,0 +1,43 @@
1<!DOCTYPE html>
2<html>
3 <head>
4 <title>SkunkyArt | {{.GR.Owner.Username}}</title>
5 <link rel="stylesheet" href="/gui/css/skunky.css">
6 </head>
7 <main>
8 <header>
9 <h1><a href="/">HOME</a> | <a href="/dd">DD</a></h1>
10 <form method="get" action="/search">
11 <input type="text" name="q" placeholder="Search for ..." autocomplete="off" autocapitalize="none" spellcheck="false">
12 <select name="type">
13 <option value="all">All</option>
14 <option value="tag">Tag</option>
15 </select>
16 <button type="submit">Search!</button>
17 </form>
18 </header>
19 <img src="/media/{{.GR.Owner.Username}}?type=a" width="30px" height="30px"> <b>{{.GR.Owner.Username}}</b>
20 {{if (eq .About.A.Gender "male")}}
21 ♂️
22 {{end}}
23 {{if (eq .About.A.Gender "female")}}
24 ♀️
25 {{end}}
26 [<span title="UID">{{.GR.Gruser.ID}}</span>]
27 [<span title="Registration date">{{.CreationDate}}</span>]
28 <i title="User's Tag">"{{.GR.Extra.Tag}}"</i>
29
30 <h3 id="stats"><a href="#stats">#</a> Statistics</h3>
31 <p>Favourites: <b>{{.GR.Extra.Stats.Favourites}}</b>; Deviations: <b>{{.GR.Extra.Stats.Deviations}}</b>; Watchers: <b>{{.GR.Extra.Stats.Watchers}}</b>
32 <p>Watching: <b>{{.GR.Extra.Stats.Watching}}</b>; Pageviews: <b>{{.GR.Extra.Stats.Pageviews}}</b>; Comments Made: <b>{{.GR.Extra.Stats.CommentsMade}}</b>; Friends: <b>{{.GR.Extra.Stats.Friends}}</b></p>
33
34 <h3 id="interests"><a href="#interests">#</a> Interests</h3>
35 {{.About.Interests}}
36
37 <h3 id="social"><a href="#social">#</a> Social Links</h3>
38 {{.About.Social}}
39
40 <h3 id="about"><a href="#about">#</a> About me</h3>
41 {{.About.DescriptionFormatted}}
42 </main>
43</html>
\ No newline at end of file
main.go +4 −1
@@ -7,7 +7,10 @@ import (
77)
88
99func main() {
10 devianter.UpdateCSRF()
10 err := devianter.UpdateCSRF()
11 if err != nil {
12 println(err.Error())
13 }
1114
1215 app.Router()
1316}