From 667de65e2fda7cb30ec886ccf6619a4178d5488b Mon Sep 17 00:00:00 2001 From: lost+skunk Date: Sat, 13 Jul 2024 21:32:04 +0300 Subject: v1.3 --- app/parsers.go | 367 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 367 insertions(+) create mode 100644 app/parsers.go (limited to 'app/parsers.go') diff --git a/app/parsers.go b/app/parsers.go new file mode 100644 index 0000000..0665476 --- /dev/null +++ b/app/parsers.go @@ -0,0 +1,367 @@ +package app + +import ( + "encoding/json" + "strconv" + "strings" + + "git.macaw.me/skunky/devianter" + "golang.org/x/net/html" +) + +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(ParseDescription(x.TextContent)) + cmmts.WriteString("

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

\n") + } + cmmts.WriteString(s.NavBase(DeviationList{ + Pages: 0, + More: c.HasMore, + })) + cmmts.WriteString("
") + return cmmts.String() +} + +func (s skunkyart) DeviationList(devs []devianter.Deviation, content ...DeviationList) string { + var list strings.Builder + if s.Atom && s.Page > 1 { + s.ReturnHTTPError(400) + return "" + } else if s.Atom { + list.WriteString(``) + list.WriteString(``) + if s.Type == 0 { + list.WriteString("Daily Deviations") + } else if len(devs) != 0 { + list.WriteString(devs[0].Author.Username) + } else { + list.WriteString("SkunkyArt") + } + list.WriteString(``) + + list.WriteString(``) + } else { + list.WriteString(`
`) + } + for _, data := range devs { + if !(data.NSFW && !CFG.Nsfw) { + url := ParseMedia(data.Media) + if s.Atom { + id := strconv.Itoa(data.ID) + list.WriteString(``) + list.WriteString(data.Author.Username) + list.WriteString(``) + list.WriteString(data.Title) + list.WriteString(``) + list.WriteString(id) + list.WriteString(``) + list.WriteString(data.PublishedTime.UTC().Format("Mon, 02 Jan 2006 15:04:05 -0700")) + list.WriteString(``) + list.WriteString(``) + list.WriteString(data.Title) + list.WriteString(`

`) + list.WriteString(ParseDescription(data.TextContent)) + list.WriteString(`

`) + } else { + list.WriteString(`") + } + } + } + + if s.Atom { + list.WriteString("") + s.Writer.Write([]byte(list.String())) + return "" + } else { + list.WriteString("
") + if content != nil { + list.WriteString(s.NavBase(content[0])) + } + } + + return list.String() +} + +/* DESCRIPTION/COMMENT PARSER */ +type text struct { + TXT string + TXT_RAW string + From int + To int +} + +func ParseDescription(dscr devianter.Text) string { + var parseddescription strings.Builder + TagBuilder := func(content string, tags ...string) string { + l := len(tags) + for x := 0; x < l; x++ { + var htm strings.Builder + htm.WriteString("<") + htm.WriteString(tags[x]) + htm.WriteString(">") + + htm.WriteString(content) + + htm.WriteString("") + content = htm.String() + } + return content + } + DeleteTrackingFromUrl := func(url string) string { + if len(url) > 42 && url[:42] == "https://www.deviantart.com/users/outgoing?" { + url = url[42:] + } + return url + } + + if description, dl := dscr.Html.Markup, len(dscr.Html.Markup); dl != 0 && + description[0] == '{' && + description[dl-1] == '}' { + var descr struct { + Blocks []struct { + 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 { + Url string + Config struct { + Aligment string + Width int + } + Data devianter.Deviation + } + } + } + e := json.Unmarshal([]byte(description), &descr) + try(e) + + entities := make(map[int]devianter.Deviation) + urls := make(map[int]string) + for n, x := range descr.EntityMap { + num, _ := strconv.Atoi(n) + if x.Data.Url != "" { + urls[num] = DeleteTrackingFromUrl(x.Data.Url) + } + entities[num] = x.Data.Data + } + + for _, x := range descr.Blocks { + Styles := make([]text, len(x.InlineStyleRanges)) + + if len(x.InlineStyleRanges) != 0 { + var tags = make(map[int][]string) + for n, rngs := range x.InlineStyleRanges { + Styles := &Styles[n] + switch rngs.Style { + case "BOLD": + rngs.Style = "b" + case "UNDERLINE": + rngs.Style = "u" + case "ITALIC": + rngs.Style = "i" + } + Styles.From = rngs.Offset + Styles.To = rngs.Offset + rngs.Length + FT := Styles.From * Styles.To + tags[FT] = append(tags[FT], rngs.Style) + } + for n := 0; n < len(Styles); n++ { + Styles := &Styles[n] + Styles.TXT_RAW = x.Text[Styles.From:Styles.To] + Styles.TXT = TagBuilder(Styles.TXT_RAW, tags[Styles.From*Styles.To]...) + } + } + + switch x.Type { + case "atomic": + d := entities[x.EntityRanges[0].Key] + parseddescription.WriteString(``) + case "unstyled": + if l := len(Styles); l != 0 { + for n, r := range Styles { + var tag string + if x.Type == "header-two" { + tag = "h2" + } + + parseddescription.WriteString(x.Text[:r.From]) + if len(urls) != 0 && len(x.EntityRanges) != 0 { + ra := &x.EntityRanges[0] + + parseddescription.WriteString(``) + parseddescription.WriteString(r.TXT) + parseddescription.WriteString(``) + } else if l > n+1 { + parseddescription.WriteString(r.TXT) + } + parseddescription.WriteString(TagBuilder(tag, x.Text[r.To:])) + } + } else { + parseddescription.WriteString(x.Text) + } + } + parseddescription.WriteString("
") + } + } else if dl != 0 { + for tt := html.NewTokenizer(strings.NewReader(dscr.Html.Markup)); ; { + switch tt.Next() { + 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 := DeleteTrackingFromUrl(a.Val) + parseddescription.WriteString(``) + parseddescription.WriteString(GetValueOfTag(tt)) + parseddescription.WriteString(" ") + } + } + 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() +} -- cgit v1.2.3