krz/devianter
A DeviantArt guest API library for Go.
clone: git clone https://gitbay.org/krz/devianter.git
v0.2.5: deviantion.go · raw
1package devianter
2
3import (
4 "encoding/json"
5 "strconv"
6 "strings"
7 "time"
8)
9
10// хрень для парсинга времени публикации
11type timeStamp struct {
12 time.Time
13}
14
15func (t *timeStamp) UnmarshalJSON(b []byte) (err error) {
16 if b[0] == '"' && b[len(b)-1] == '"' {
17 b = b[1 : len(b)-1]
18 }
19 t.Time, err = time.Parse("2006-01-02T15:04:05-0700", string(b))
20 return
21}
22
23// самая главная структура для поста
24type Deviation struct {
25 Title, Url, License string
26 PublishedTime timeStamp
27 ID int `json:"deviationId"`
28
29 NSFW bool `json:"isMature"`
30 AI bool `json:"isAiGenerated"`
31 DD bool `json:"isDailyDeviation"`
32
33 Author struct {
34 Username string
35 }
36 Stats struct {
37 Favourites, Views, Downloads int
38 }
39 Media Media
40 Extended struct {
41 Tags []struct {
42 Name string
43 }
44 OriginalFile struct {
45 Type string
46 Width int
47 Height int
48 Filesize int
49 }
50 DescriptionText Text
51 RelatedContent []struct {
52 Deviations []Deviation
53 }
54 }
55 TextContent Text
56}
57
58// её выпердыши
59type Media struct {
60 BaseUri string
61 Token []string
62 Types []struct {
63 T string
64 H, W int
65 }
66}
67
68type Text struct {
69 Excerpt string
70 Html struct {
71 Markup, Type string
72 }
73}
74
75// структура поста
76type Post struct {
77 Deviation Deviation
78 Comments struct {
79 Total int
80 Cursor string
81 }
82
83 ParsedComments []struct {
84 Author string
85 Posted timeStamp
86 Replies, Likes int
87 }
88
89 IMG, Description string
90}
91
92// преобразование урла в правильный
93func UrlFromMedia(m Media, thumb ...int) string {
94 var url strings.Builder
95
96 subtractWidthHeight := func(to int, target ...*int) {
97 for i, l := 0, len(target); i < l; i++ {
98 for x := *target[i]; x > to; x -= to {
99 *target[i] = x
100 }
101 }
102 }
103
104 for _, t := range m.Types {
105 if t.T == "fullview" {
106 url.WriteString(m.BaseUri)
107 if m.BaseUri[len(m.BaseUri)-3:] != "gif" && t.W*t.H < 33177600 {
108 if len(thumb) != 0 {
109 subtractWidthHeight(thumb[0], &t.W, &t.H)
110 }
111
112 url.WriteString("/v1/fit/w_")
113 url.WriteString(strconv.Itoa(t.W))
114 url.WriteString(",h_")
115 url.WriteString(strconv.Itoa(t.H))
116 url.WriteString("/")
117 url.WriteString("image")
118 url.WriteString(".gif")
119 }
120 if len(m.Token) > 0 {
121 url.WriteString("?token=")
122 url.WriteString(m.Token[0])
123 }
124 }
125 }
126
127 return url.String()
128}
129
130// для работы функции нужно ID поста и имя пользователя.
131func GetDeviation(id string, user string) Post {
132 var st Post
133 ujson(
134 "dadeviation/init?deviationid="+id+"&username="+user+"&type=art&include_session=false&expand=deviation.related&preload=true",
135 &st,
136 )
137
138 st.IMG = UrlFromMedia(st.Deviation.Media)
139
140 // базовая обработка описания
141 txt := st.Deviation.TextContent.Html.Markup
142 if len(txt) > 0 && txt[1] == '{' {
143 var description struct {
144 Blocks []struct {
145 Text string
146 }
147 }
148
149 json.Unmarshal([]byte(txt), &description)
150 for _, a := range description.Blocks {
151 txt = a.Text
152 }
153 }
154
155 st.Description = txt
156
157 return st
158}