krz/devianter

A DeviantArt guest API library for Go.

clone: git clone https://gitbay.org/krz/devianter.git

v0.3.1: 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		if err := json.Unmarshal([]byte(txt), &description); err != nil {
153			// Handle error appropriately
154			try(err) // or log/return the error
155		}
156		for _, a := range description.Blocks {
157			txt = a.Text
158		}
159	}
160	st.Description = txt
161
162	return
163}