krz/devianter
A DeviantArt guest API library for Go.
clone: git clone https://gitbay.org/krz/devianter.git
v0.2.5: util.go · raw
1package devianter
2
3import (
4 "encoding/json"
5 "errors"
6 "io"
7 "net/http"
8 "strings"
9)
10
11// функция для высера ошибки в stderr
12func try(txt error) {
13 if txt != nil {
14 println(txt.Error())
15 }
16}
17
18// сокращение для вызова щенка и парсинга жсона
19func ujson(data string, output any) {
20 input, err := puppy(data)
21 try(err)
22 try(json.Unmarshal([]byte(input), output))
23}
24
25/* REQUEST SECTION */
26// структура для ответа сервера
27type reqrt struct {
28 Body string
29 Status int
30 Cookies []*http.Cookie
31 Headers http.Header
32}
33
34// функция для совершения запроса
35var UserAgent string
36
37func request(uri string, other ...string) reqrt {
38 var r reqrt
39
40 // создаём новый запрос
41 cli := &http.Client{}
42 req, e := http.NewRequest("GET", uri, nil)
43 try(e)
44
45 req.Header.Set("User-Agent", "Mozilla/5.0 (X11; Linux x86_64; rv:123.0) Gecko/20100101 Firefox/123.0.0")
46
47 // куки и UA-шник
48 if UserAgent != "" {
49 req.Header.Set("User-Agent", UserAgent)
50 }
51 if len(other) != 0 {
52 req.Header.Set("Cookie", other[0])
53 }
54
55 resp, e := cli.Do(req)
56 try(e)
57 defer resp.Body.Close()
58
59 body, e := io.ReadAll(resp.Body)
60 try(e)
61
62 // заполняем структуру
63 r.Body = string(body)
64 r.Cookies = resp.Cookies()
65 r.Headers = resp.Header
66 r.Status = resp.StatusCode
67
68 return r
69}
70
71/* PUPPY aka DeviantArt API */
72// получение или обновление токена
73var cookie string
74var token string
75
76func UpdateCSRF() error {
77 if cookie == "" {
78 req := request("https://www.deviantart.com/_puppy")
79
80 for _, content := range req.Cookies {
81 cookie = content.Raw
82 }
83 }
84
85 req := request("https://www.deviantart.com", cookie)
86 if req.Status != 200 {
87 return errors.New(req.Body)
88 }
89 token = req.Body[strings.Index(req.Body, "window.__CSRF_TOKEN__ = '")+25 : strings.Index(req.Body, "window.__XHR_LOCAL__")-3]
90
91 return nil
92}
93
94func puppy(data string) (string, error) {
95 var url strings.Builder
96 url.WriteString("https://www.deviantart.com/_puppy/")
97 url.WriteString(data)
98 url.WriteString("&csrf_token=")
99 url.WriteString(token)
100 url.WriteString("&da_minor_version=20230710")
101
102 body := request(url.String(), cookie)
103
104 // если код ответа не 200, возвращается ошибка
105 if body.Status != 200 {
106 return "", errors.New(body.Body)
107 }
108
109 return body.Body, nil
110}