Commit 8391cc34a9

8391cc34a95a82cf025b96e4352246a245d06d61

parent: 0f528ee9fa

Unsigned

lost+skunk <skunky@ebloid.ru> · 2024-07-09 14:24 UTC

Улучшение парсинга описания/комментариев в формате JSON

Layout: unified · split

app/util.go +60 −38
@@ -113,6 +113,12 @@ func ParseDescription(dscr devianter.Text) string {
113 } 113 }
114 return content 114 return content
115 } 115 }
116 DeleteSpywareFromUrl := func(url string) string {
117 if len(url) > 42 && url[:42] == "https://www.deviantart.com/users/outgoing?" {
118 url = url[42:]
119 }
120 return url
121 }
116 122
117 if description, dl := dscr.Html.Markup, len(dscr.Html.Markup); dl != 0 && 123 if description, dl := dscr.Html.Markup, len(dscr.Html.Markup); dl != 0 &&
118 description[0] == '{' && 124 description[0] == '{' &&
@@ -135,6 +141,7 @@ func ParseDescription(dscr devianter.Text) string {
135 EntityMap map[string]struct { 141 EntityMap map[string]struct {
136 Type string 142 Type string
137 Data struct { 143 Data struct {
144 Url string
138 Config struct { 145 Config struct {
139 Aligment string 146 Aligment string
140 Width int 147 Width int
@@ -147,31 +154,18 @@ func ParseDescription(dscr devianter.Text) string {
147 err(e) 154 err(e)
148 155
149 entities := make(map[int]devianter.Deviation) 156 entities := make(map[int]devianter.Deviation)
157 urls := make(map[int]string)
150 for n, x := range descr.EntityMap { 158 for n, x := range descr.EntityMap {
151 num, _ := strconv.Atoi(n) 159 num, _ := strconv.Atoi(n)
160 if x.Data.Url != "" {
161 urls[num] = DeleteSpywareFromUrl(x.Data.Url)
162 }
152 entities[num] = x.Data.Data 163 entities[num] = x.Data.Data
153 } 164 }
154 165
155 for _, x := range descr.Blocks { 166 for _, x := range descr.Blocks {
156 ranges := make(map[int]text) 167 ranges := make(map[int]text)
157 168
158 if len(x.InlineStyleRanges) == 0 {
159 switch x.Type {
160 case "atomic":
161 d := entities[x.EntityRanges[0].Key]
162 parseddescription.WriteString(`<img width="50%" src="`)
163 parseddescription.WriteString(ParseMedia(d.Media))
164 parseddescription.WriteString(`" title="`)
165 parseddescription.WriteString(d.Author.Username)
166 parseddescription.WriteString(" - ")
167 parseddescription.WriteString(d.Title)
168 parseddescription.WriteString(`">`)
169 case "unstyled":
170 parseddescription.WriteString(x.Text)
171 }
172 parseddescription.WriteString("<br>")
173 }
174
175 for i, rngs := range x.InlineStyleRanges { 169 for i, rngs := range x.InlineStyleRanges {
176 var tag string 170 var tag string
177 171
@@ -192,22 +186,48 @@ func ParseDescription(dscr devianter.Text) string {
192 } 186 }
193 } 187 }
194 188
195 for _, r := range ranges { 189 switch x.Type {
196 var tag string 190 case "atomic":
197 switch x.Type { 191 d := entities[x.EntityRanges[0].Key]
198 case "header-two": 192 parseddescription.WriteString(`<img width="50%" src="`)
199 tag = "h2" 193 parseddescription.WriteString(ParseMedia(d.Media))
200 case "unstyled": 194 parseddescription.WriteString(`" title="`)
201 tag = "p" 195 parseddescription.WriteString(d.Author.Username)
196 parseddescription.WriteString(" - ")
197 parseddescription.WriteString(d.Title)
198 parseddescription.WriteString(`">`)
199 case "unstyled":
200 if len(ranges) != 0 {
201 for _, r := range ranges {
202 var tag string
203 switch x.Type {
204 case "header-two":
205 tag = "h2"
206 }
207
208 parseddescription.WriteString(x.Text[:r.from])
209 if len(urls) != 0 && len(x.EntityRanges) != 0 {
210 ra := &x.EntityRanges[0]
211
212 parseddescription.WriteString(`<a target="_blank" href="`)
213 parseddescription.WriteString(urls[ra.Key])
214 parseddescription.WriteString(`">`)
215 parseddescription.WriteString(r.TXT)
216 parseddescription.WriteString(`</a>`)
217 } else {
218 parseddescription.WriteString(r.TXT)
219 }
220 parseddescription.WriteString(TagBuilder(tag, x.Text[r.to:]))
221 }
222 } else {
223 parseddescription.WriteString(x.Text)
202 } 224 }
203 parseddescription.WriteString(r.TXT)
204 parseddescription.WriteString(TagBuilder(tag, x.Text[r.to:]))
205 } 225 }
226 parseddescription.WriteString("<br>")
206 } 227 }
207 } else if dl != 0 { 228 } else if dl != 0 {
208 for tt := html.NewTokenizer(strings.NewReader(dscr.Html.Markup)); ; { 229 for tt := html.NewTokenizer(strings.NewReader(dscr.Html.Markup)); ; {
209 t := tt.Next() 230 switch tt.Next() {
210 switch t {
211 case html.ErrorToken: 231 case html.ErrorToken:
212 return parseddescription.String() 232 return parseddescription.String()
213 case html.StartTagToken, html.EndTagToken, html.SelfClosingTagToken: 233 case html.StartTagToken, html.EndTagToken, html.SelfClosingTagToken:
@@ -216,18 +236,16 @@ func ParseDescription(dscr devianter.Text) string {
216 case "a": 236 case "a":
217 for _, a := range token.Attr { 237 for _, a := range token.Attr {
218 if a.Key == "href" { 238 if a.Key == "href" {
219 url := strings.ReplaceAll(a.Val, "https://www.deviantart.com/users/outgoing?", "") 239 url := DeleteSpywareFromUrl(a.Val)
220 if strings.Contains(url, "deviantart") { 240 parseddescription.WriteString(`<a target="_blank" href="`)
221 url = strings.ReplaceAll(url, "https://www.deviantart.com/", "") 241 parseddescription.WriteString(url)
222 url = strings.ReplaceAll(url, url[0:strings.Index(url, "/")+1], "") 242 parseddescription.WriteString(`">`)
223 } 243 parseddescription.WriteString(tagval(tt))
224 parseddescription.WriteString("<a target=\"_blank\" href=\"" + url + "\">" + tagval(tt) + "</a> ") 244 parseddescription.WriteString("</a> ")
225 } 245 }
226 } 246 }
227 case "img": 247 case "img":
228 var ( 248 var uri, title string
229 uri, title string
230 )
231 for b, a := range token.Attr { 249 for b, a := range token.Attr {
232 switch a.Key { 250 switch a.Key {
233 case "src": 251 case "src":
@@ -239,7 +257,11 @@ func ParseDescription(dscr devianter.Text) string {
239 } 257 }
240 if title != "" { 258 if title != "" {
241 for x := -1; x < b; x++ { 259 for x := -1; x < b; x++ {
242 parseddescription.WriteString("<img src=\"" + uri + "\" title=\"" + title + "\">") 260 parseddescription.WriteString(`<img src="`)
261 parseddescription.WriteString(uri)
262 parseddescription.WriteString(`" title="`)
263 parseddescription.WriteString(title)
264 parseddescription.WriteString(`">`)
243 } 265 }
244 } 266 }
245 } 267 }
gowna added
html/deviantion.htm +8 −2
@@ -3,6 +3,7 @@
3 <head> 3 <head>
4 <title>SkunkyArt | {{.Templates.Deviation.Post.Deviation.Author.Username}} - {{.Templates.Deviation.Post.Deviation.Title}}</title> 4 <title>SkunkyArt | {{.Templates.Deviation.Post.Deviation.Author.Username}} - {{.Templates.Deviation.Post.Deviation.Title}}</title>
5 <link rel="stylesheet" href="{{.BasePath}}gui/css/skunky.css"> 5 <link rel="stylesheet" href="{{.BasePath}}gui/css/skunky.css">
6 <meta name="referrer" content="no-referrer" />
6 </head> 7 </head>
7 <main> 8 <main>
8 <header> 9 <header>
@@ -33,10 +34,15 @@
33 {{if (ne .Templates.Deviation.Tags "")}} 34 {{if (ne .Templates.Deviation.Tags "")}}
34 {{.Templates.Deviation.Tags}}<br> 35 {{.Templates.Deviation.Tags}}<br>
35 {{end}} 36 {{end}}
36 <span>Published: <strong>{{.Templates.Deviation.StringTime}}</strong>; Views: <strong>{{.Templates.Deviation.Post.Deviation.Stats.Views}}</strong>; Favourites: <strong>{{.Templates.Deviation.Post.Deviation.Stats.Favourites}}</strong>; Downloads: <strong>{{.Templates.Deviation.Post.Deviation.Stats.Downloads}}</strong></span> 37 <span>Published: <strong>{{.Templates.Deviation.StringTime}}</strong>; Views: <strong>{{.Templates.Deviation.Post.Deviation.Stats.Views}}</strong>; Favourites: <strong>{{.Templates.Deviation.Post.Deviation.Stats.Favourites}}</strong>; Downloads: <strong>{{.Templates.Deviation.Post.Deviation.Stats.Downloads}}</strong><span>
38 <br><a target="_blank" href="https://www.deviantart.com/{{.Templates.Deviation.Post.Deviation.Author.Username}}/art/art-{{.Templates.Deviation.Post.Deviation.ID}}">Redirect to original</a>
39 </span>
37 {{if (ne .Templates.Deviation.Post.Description "")}} 40 {{if (ne .Templates.Deviation.Post.Description "")}}
38 <figcaption> 41 <figcaption>
39 {{.Templates.Deviation.Post.Description}} 42 <details>
43 <summary>Description</summary>
44 {{.Templates.Deviation.Post.Description}}
45 </details>
40 </figcaption> 46 </figcaption>
41 {{end}} 47 {{end}}
42 {{if ne .Templates.Deviation.Related ""}} 48 {{if ne .Templates.Deviation.Related ""}}