2024-06-03 21:50:30 +00:00
|
|
|
package devianter
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"strconv"
|
2024-06-13 21:05:21 +00:00
|
|
|
"strings"
|
2024-07-29 22:20:00 +00:00
|
|
|
"time"
|
2024-06-03 21:50:30 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// хрень для парсинга времени публикации
|
2024-07-29 22:20:00 +00:00
|
|
|
type timeStamp struct {
|
|
|
|
time.Time
|
2024-06-03 21:50:30 +00:00
|
|
|
}
|
|
|
|
|
2024-07-29 22:20:00 +00:00
|
|
|
func (t *timeStamp) UnmarshalJSON(b []byte) (err error) {
|
2024-06-03 21:50:30 +00:00
|
|
|
if b[0] == '"' && b[len(b)-1] == '"' {
|
|
|
|
b = b[1 : len(b)-1]
|
|
|
|
}
|
2024-07-29 22:20:00 +00:00
|
|
|
t.Time, err = time.Parse("2006-01-02T15:04:05-0700", string(b))
|
2024-06-03 21:50:30 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// самая главная структура для поста
|
2024-06-13 21:05:21 +00:00
|
|
|
type Deviation struct {
|
2024-06-05 11:32:40 +00:00
|
|
|
Title, Url, License string
|
2024-07-29 22:20:00 +00:00
|
|
|
PublishedTime timeStamp
|
2024-07-13 18:40:17 +00:00
|
|
|
ID int `json:"deviationId"`
|
2024-06-05 11:32:40 +00:00
|
|
|
|
|
|
|
NSFW bool `json:"isMature"`
|
|
|
|
AI bool `json:"isAiGenerated"`
|
|
|
|
DD bool `json:"isDailyDeviation"`
|
|
|
|
|
|
|
|
Author struct {
|
2024-06-03 21:50:30 +00:00
|
|
|
Username string
|
|
|
|
}
|
|
|
|
Stats struct {
|
|
|
|
Favourites, Views, Downloads int
|
|
|
|
}
|
2024-06-27 11:52:33 +00:00
|
|
|
Media Media
|
2024-06-03 21:50:30 +00:00
|
|
|
Extended struct {
|
|
|
|
Tags []struct {
|
|
|
|
Name string
|
|
|
|
}
|
2024-07-13 18:40:17 +00:00
|
|
|
OriginalFile struct {
|
|
|
|
Type string
|
|
|
|
Width int
|
|
|
|
Height int
|
|
|
|
Filesize int
|
|
|
|
}
|
2024-06-27 11:52:33 +00:00
|
|
|
DescriptionText Text
|
2024-06-03 21:50:30 +00:00
|
|
|
RelatedContent []struct {
|
2024-06-13 21:05:21 +00:00
|
|
|
Deviations []Deviation
|
2024-06-03 21:50:30 +00:00
|
|
|
}
|
|
|
|
}
|
2024-06-27 11:52:33 +00:00
|
|
|
TextContent Text
|
2024-06-03 21:50:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// её выпердыши
|
2024-06-27 11:52:33 +00:00
|
|
|
type Media struct {
|
2024-06-03 21:50:30 +00:00
|
|
|
BaseUri string
|
2024-09-04 17:18:39 +00:00
|
|
|
Name string `json:"prettyName"`
|
2024-06-03 21:50:30 +00:00
|
|
|
Token []string
|
|
|
|
Types []struct {
|
|
|
|
T string
|
|
|
|
H, W int
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-06-27 11:52:33 +00:00
|
|
|
type Text struct {
|
2024-06-05 11:32:40 +00:00
|
|
|
Excerpt string
|
|
|
|
Html struct {
|
2024-06-03 21:50:30 +00:00
|
|
|
Markup, Type string
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-06-05 11:32:40 +00:00
|
|
|
// структура поста
|
2024-06-13 21:05:21 +00:00
|
|
|
type Post struct {
|
|
|
|
Deviation Deviation
|
2024-06-03 21:50:30 +00:00
|
|
|
Comments struct {
|
|
|
|
Total int
|
|
|
|
Cursor string
|
|
|
|
}
|
|
|
|
|
|
|
|
ParsedComments []struct {
|
|
|
|
Author string
|
2024-07-29 22:20:00 +00:00
|
|
|
Posted timeStamp
|
2024-06-03 21:50:30 +00:00
|
|
|
Replies, Likes int
|
|
|
|
}
|
|
|
|
|
2024-06-13 21:05:21 +00:00
|
|
|
IMG, Description string
|
|
|
|
}
|
|
|
|
|
|
|
|
// преобразование урла в правильный
|
2024-09-04 17:18:39 +00:00
|
|
|
func UrlFromMedia(m Media, thumb ...int) (urlParsed, wellFormattedFilename string) {
|
2024-06-13 21:05:21 +00:00
|
|
|
var url strings.Builder
|
2024-07-29 22:20:00 +00:00
|
|
|
|
|
|
|
subtractWidthHeight := func(to int, target ...*int) {
|
|
|
|
for i, l := 0, len(target); i < l; i++ {
|
|
|
|
for x := *target[i]; x > to; x -= to {
|
|
|
|
*target[i] = x
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-06-13 21:05:21 +00:00
|
|
|
for _, t := range m.Types {
|
|
|
|
if t.T == "fullview" {
|
|
|
|
url.WriteString(m.BaseUri)
|
2024-08-14 16:18:40 +00:00
|
|
|
if l := len(m.BaseUri); l != 0 && (m.BaseUri[l-3:] != "gif" && t.W*t.H < 33177600) {
|
2024-07-29 22:20:00 +00:00
|
|
|
if len(thumb) != 0 {
|
|
|
|
subtractWidthHeight(thumb[0], &t.W, &t.H)
|
|
|
|
}
|
2024-09-04 17:18:39 +00:00
|
|
|
wellFormattedFilename = m.Name + m.BaseUri[l-4:]
|
2024-07-29 22:20:00 +00:00
|
|
|
|
2024-07-13 18:40:17 +00:00
|
|
|
url.WriteString("/v1/fit/w_")
|
2024-06-13 21:05:21 +00:00
|
|
|
url.WriteString(strconv.Itoa(t.W))
|
|
|
|
url.WriteString(",h_")
|
|
|
|
url.WriteString(strconv.Itoa(t.H))
|
|
|
|
url.WriteString("/")
|
2024-09-04 17:18:39 +00:00
|
|
|
url.WriteString(wellFormattedFilename)
|
|
|
|
|
2024-06-13 21:05:21 +00:00
|
|
|
}
|
2024-06-14 17:05:21 +00:00
|
|
|
if len(m.Token) > 0 {
|
|
|
|
url.WriteString("?token=")
|
|
|
|
url.WriteString(m.Token[0])
|
|
|
|
}
|
2024-06-13 21:05:21 +00:00
|
|
|
}
|
|
|
|
}
|
2024-07-29 22:20:00 +00:00
|
|
|
|
2024-09-04 17:18:39 +00:00
|
|
|
urlParsed = url.String()
|
|
|
|
|
|
|
|
return
|
2024-06-03 21:50:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// для работы функции нужно ID поста и имя пользователя.
|
2024-09-04 17:18:39 +00:00
|
|
|
func GetDeviation(id string, user string) (st Post, err Error) {
|
|
|
|
err = ujson(
|
2024-06-03 21:50:30 +00:00
|
|
|
"dadeviation/init?deviationid="+id+"&username="+user+"&type=art&include_session=false&expand=deviation.related&preload=true",
|
|
|
|
&st,
|
|
|
|
)
|
|
|
|
|
2024-09-04 17:18:39 +00:00
|
|
|
st.IMG, _ = UrlFromMedia(st.Deviation.Media)
|
2024-06-03 21:50:30 +00:00
|
|
|
|
|
|
|
// базовая обработка описания
|
|
|
|
txt := st.Deviation.TextContent.Html.Markup
|
2024-06-13 21:05:21 +00:00
|
|
|
if len(txt) > 0 && txt[1] == '{' {
|
2024-06-03 21:50:30 +00:00
|
|
|
var description struct {
|
|
|
|
Blocks []struct {
|
|
|
|
Text string
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
json.Unmarshal([]byte(txt), &description)
|
|
|
|
for _, a := range description.Blocks {
|
|
|
|
txt = a.Text
|
|
|
|
}
|
|
|
|
}
|
2024-06-13 21:05:21 +00:00
|
|
|
st.Description = txt
|
2024-09-04 17:18:39 +00:00
|
|
|
|
|
|
|
return
|
2024-06-03 21:50:30 +00:00
|
|
|
}
|