krz/devianter
A DeviantArt guest API library for Go.
clone: git clone https://gitbay.org/krz/devianter.git
v0.3.0: 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 Name string `json:"prettyName"`
62 Token []string
63 Types []struct {
64 T string
65 H, W int
66 }
67}
68
69type Text struct {
70 Excerpt string
71 Html struct {
72 Markup, Type string
73 }
74}
75
76// структура поста
77type Post struct {
78 Deviation Deviation
79 Comments struct {
80 Total int
81 Cursor string
82 }
83
84 ParsedComments []struct {
85 Author string
86 Posted timeStamp
87 Replies, Likes int
88 }
89
90 IMG, Description string
91}
92
93// преобразование урла в правильный
94func UrlFromMedia(m Media, thumb ...int) (urlParsed, wellFormattedFilename string) {
95 var url strings.Builder
96
97 subtractWidthHeight := func(to int, target ...*int) {
98 for i, l := 0, len(target); i < l; i++ {
99 for x := *target[i]; x > to; x -= to {
100 *target[i] = x
101 }
102 }
103 }
104
105 for _, t := range m.Types {
106 if t.T == "fullview" {
107 url.WriteString(m.BaseUri)
108 if l := len(m.BaseUri); l != 0 && (m.BaseUri[l-3:] != "gif" && t.W*t.H < 33177600) {
109 if len(thumb) != 0 {
110 subtractWidthHeight(thumb[0], &t.W, &t.H)
111 }
112 wellFormattedFilename = m.Name + m.BaseUri[l-4:]
113
114 url.WriteString("/v1/fit/w_")
115 url.WriteString(strconv.Itoa(t.W))
116 url.WriteString(",h_")
117 url.WriteString(strconv.Itoa(t.H))
118 url.WriteString("/")
119 url.WriteString(wellFormattedFilename)
120
121 }
122 if len(m.Token) > 0 {
123 url.WriteString("?token=")
124 url.WriteString(m.Token[0])
125 }
126 }
127 }
128
129 urlParsed = url.String()
130
131 return
132}
133
134// для работы функции нужно ID поста и имя пользователя.
135func GetDeviation(id string, user string) (st Post, err Error) {
136 err = ujson(
137 "dadeviation/init?deviationid="+id+"&username="+user+"&type=art&include_session=false&expand=deviation.related&preload=true",
138 &st,
139 )
140
141 st.IMG, _ = UrlFromMedia(st.Deviation.Media)
142
143 // базовая обработка описания
144 txt := st.Deviation.TextContent.Html.Markup
145 if len(txt) > 1 && txt[1] == '{' {
146 var description struct {
147 Blocks []struct {
148 Text string
149 }
150 }
151
152 json.Unmarshal([]byte(txt), &description)
153 for _, a := range description.Blocks {
154 txt = a.Text
155 }
156 }
157 st.Description = txt
158
159 return
160}