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}