diff --git a/app/util.go b/app/util.go index e22e83b..eb1c7ce 100644 --- a/app/util.go +++ b/app/util.go @@ -14,6 +14,7 @@ import ( "time" "git.macaw.me/skunky/devianter" + "golang.org/x/net/html" ) // парсинг темплейтов @@ -95,18 +96,59 @@ func ParseDescription(dscr devianter.Text) string { description[dl-1] == '}' { var descr struct { Blocks []struct { - Key, Text, Type string + Text, Type string InlineStyleRanges []struct { Offset, Length int Style string } + EntityRanges []struct { + Offset, Length int + Key int + } + Data struct { + TextAlignment string + } + } + EntityMap map[string]struct { + Type string + Data struct { + Config struct { + Aligment string + Width int + } + Data devianter.Deviation + } } } e := json.Unmarshal([]byte(description), &descr) err(e) + entities := make(map[int]devianter.Deviation) + for n, x := range descr.EntityMap { + num, _ := strconv.Atoi(n) + entities[num] = x.Data.Data + } + for _, x := range descr.Blocks { ranges := make(map[int]text) + + if len(x.InlineStyleRanges) == 0 { + switch x.Type { + case "atomic": + d := entities[x.EntityRanges[0].Key] + parseddescription.WriteString(``) + case "unstyled": + parseddescription.WriteString(x.Text) + } + parseddescription.WriteString("
") + } + for i, rngs := range x.InlineStyleRanges { var tag string @@ -140,7 +182,66 @@ func ParseDescription(dscr devianter.Text) string { } } } else if dl != 0 { - parseddescription.WriteString(description) + tagval := func(t *html.Tokenizer) string { + for { + tt := t.Next() + switch tt { + case html.ErrorToken: + return "" + case html.TextToken: + return string(t.Text()) + } + } + } + + tt := html.NewTokenizer(strings.NewReader(dscr.Html.Markup)) + for { + t := tt.Next() + switch t { + case html.ErrorToken: + return parseddescription.String() + case html.StartTagToken, html.EndTagToken, html.SelfClosingTagToken: + token := tt.Token() + switch token.Data { + case "a": + for _, a := range token.Attr { + if a.Key == "href" { + url := strings.ReplaceAll(a.Val, "https://www.deviantart.com/users/outgoing?", "") + if strings.Contains(url, "deviantart") { + url = strings.ReplaceAll(url, "https://www.deviantart.com/", "") + url = strings.ReplaceAll(url, url[0:strings.Index(url, "/")+1], "") + } + parseddescription.WriteString("" + tagval(tt) + " ") + } + } + case "img": + var ( + uri, title string + ) + for b, a := range token.Attr { + switch a.Key { + case "src": + if len(a.Val) > 9 && a.Val[8:9] == "e" { + uri = UrlBuilder("media", "emojitar", a.Val[37:len(a.Val)-4], "?type=e") + } + case "title": + title = a.Val + } + if title != "" { + for x := -1; x < b; x++ { + parseddescription.WriteString("") + } + } + } + case "br", "li", "ul", "p", "b": + parseddescription.WriteString(token.String()) + case "div": + parseddescription.WriteString("

") + } + case html.TextToken: + parseddescription.Write(tt.Text()) + } + } } return parseddescription.String() @@ -234,7 +335,7 @@ func (s skunkyart) DeviationList(devs []devianter.Deviation, content ...dlist) s } for _, data := range devs { if !(data.NSFW && !CFG.Nsfw) { - url := s.ParseMedia(data.Media) + url := ParseMedia(data.Media) if s.Atom { id := strconv.Itoa(data.ID) list.WriteString(``) @@ -307,7 +408,6 @@ func (s skunkyart) DeviationList(devs []devianter.Deviation, content ...dlist) s return list.String() } -// FIXME: первый комментарий не отображается. func (s skunkyart) ParseComments(c devianter.Comments) string { var cmmts strings.Builder replied := make(map[int]string) @@ -354,7 +454,7 @@ func (s skunkyart) ParseComments(c devianter.Comments) string { cmmts.WriteString(x.Posted.UTC().String()) cmmts.WriteString("]

") - cmmts.WriteString(x.Comment) + cmmts.WriteString(ParseDescription(x.TextContent)) cmmts.WriteString("

👍: ") cmmts.WriteString(strconv.Itoa(x.Likes)) cmmts.WriteString(" ⏩: ") @@ -369,7 +469,7 @@ func (s skunkyart) ParseComments(c devianter.Comments) string { return cmmts.String() } -func (s skunkyart) ParseMedia(media devianter.Media) string { +func ParseMedia(media devianter.Media) string { url := devianter.UrlFromMedia(media) if len(url) != 0 { url = url[21:] diff --git a/app/wrapper.go b/app/wrapper.go index 0a3d0a7..0340aed 100644 --- a/app/wrapper.go +++ b/app/wrapper.go @@ -127,7 +127,7 @@ func (s skunkyart) GRUser() { case "cover_deviation": group.About.BGMeta = x.ModuleData.CoverDeviation.Deviation group.About.BGMeta.Url = s.ConvertDeviantArtUrlToSkunkyArt(group.About.BGMeta.Url) - group.About.BG = s.ParseMedia(group.About.BGMeta.Media) + group.About.BG = ParseMedia(group.About.BGMeta.Media) case "group_admins": var htm strings.Builder for _, z := range x.ModuleData.GroupAdmins.Results { @@ -165,7 +165,7 @@ func (s skunkyart) GRUser() { folders.WriteString(`
`) @@ -212,10 +212,14 @@ func (s skunkyart) Deviation(author, postname string) { id := id_search[len(id_search)-1] post.Post = devianter.DeviationFunc(id, author) - post.Post.Description = ParseDescription(post.Post.Deviation.TextContent) + if post.Post.Deviation.TextContent.Excerpt != "" { + post.Post.Description = ParseDescription(post.Post.Deviation.TextContent) + } else { + post.Post.Description = ParseDescription(post.Post.Deviation.Extended.DescriptionText) + } // время публикации post.StringTime = post.Post.Deviation.PublishedTime.UTC().String() - post.Post.IMG = s.ParseMedia(post.Post.Deviation.Media) + post.Post.IMG = ParseMedia(post.Post.Deviation.Media) for _, x := range post.Post.Deviation.Extended.RelatedContent { if len(x.Deviations) != 0 { post.Related = s.DeviationList(x.Deviations) diff --git a/css/skunky.css b/css/skunky.css index c299dab..eb9b350 100644 --- a/css/skunky.css +++ b/css/skunky.css @@ -60,6 +60,7 @@ form input, button, select { color: rgb(160, 0, 147); } .content { + align-items: center; border-radius: 3px; display: flex; flex-wrap: wrap; @@ -112,4 +113,31 @@ form input, button, select { word-break: break-all; text-align: center; width: 5%; +} + +@media screen and (orientation: portrait) { + header { + scale: 155%; + justify-content: center; + } + .content { + margin: auto; + display: inherit; + scale: 100%; + } + .block { + max-width: 60%; + } +} + +@media screen and (max-width: 1462px) { + .block { + max-width: 30%; + } +} + +@media screen and (min-width: 788px) and (max-width: 884px) { + .block { + max-width: 35%; + } } \ No newline at end of file diff --git a/go.mod b/go.mod index ac1e0d0..0202154 100644 --- a/go.mod +++ b/go.mod @@ -4,4 +4,7 @@ go 1.22.3 replace git.macaw.me/skunky/devianter v0.1.0 => /home/skunk/projects/devianter -require git.macaw.me/skunky/devianter v0.1.0 +require ( + git.macaw.me/skunky/devianter v0.1.0 + golang.org/x/net v0.27.0 +) diff --git a/go.sum b/go.sum index e69de29..7566714 100644 --- a/go.sum +++ b/go.sum @@ -0,0 +1,2 @@ +golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= +golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= diff --git a/instances.json b/instances.json new file mode 100644 index 0000000..2de7e85 --- /dev/null +++ b/instances.json @@ -0,0 +1,14 @@ +{ + "instances": [{ + "urls": [{ + "i2p": "http://skunky.i2p/art", + "tor": "http://skunky0wjkf8j8ajofgh98aOZjhu8f.onion/art", + "ygg": "http://[324:71e:281a:9ed3::fa11]/skunkyart", + "clearnet": "https://skunky.net/art" + }], + "settings": { + "nsfw": true, + "proxy": true + } + }] +} \ No newline at end of file