anitrack/AniListFunctions.go

492 lines
9.1 KiB
Go
Raw Normal View History

package main
import (
"bytes"
"encoding/json"
"io"
"log"
"net/http"
)
2024-07-24 09:15:52 -04:00
func AniListQuery(body interface{}, login bool) (json.RawMessage, string) {
reader, _ := json.Marshal(body)
response, err := http.NewRequest("POST", "https://graphql.anilist.co", bytes.NewBuffer(reader))
if err != nil {
log.Printf("Failed at response, %s\n", err)
}
if login && (AniListJWT{}) != aniListJwt {
response.Header.Add("Authorization", "Bearer "+aniListJwt.AccessToken)
} else if login {
return nil, "Please login to anilist to make this request"
}
response.Header.Add("Content-Type", "application/json")
response.Header.Add("Accept", "application/json")
client := &http.Client{}
res, reserr := client.Do(response)
if reserr != nil {
log.Printf("Failed at res, %s\n", err)
}
defer res.Body.Close()
returnedBody, err := io.ReadAll(res.Body)
return returnedBody, res.Status
}
func (a *App) GetAniListItem(aniId int, login bool) AniListGetSingleAnime {
2024-07-30 20:41:18 -04:00
var user = a.GetAniListLoggedInUser()
var neededVariables interface{}
if login {
2024-07-29 16:54:05 -04:00
neededVariables = struct {
MediaId int `json:"mediaId"`
UserId int `json:"userId"`
ListType string `json:"listType"`
2024-07-29 16:54:05 -04:00
}{
MediaId: aniId,
UserId: user.Data.Viewer.ID,
ListType: "ANIME",
}
} else {
neededVariables = struct {
2024-07-29 16:54:05 -04:00
MediaId int `json:"mediaId"`
ListType string `json:"listType"`
2024-07-29 16:54:05 -04:00
}{
MediaId: aniId,
ListType: "ANIME",
}
}
body := struct {
2024-07-29 16:54:05 -04:00
Query string `json:"query"`
Variables interface{} `json:"variables"`
}{
Query: `
query($userId: Int, $mediaId: Int, $listType: MediaType) {
MediaList(mediaId: $mediaId, userId: $userId, type: $listType) {
id
mediaId
userId
media {
id
idMal
title {
romaji
english
native
}
description
coverImage {
large
}
season
seasonYear
status
episodes
nextAiringEpisode {
airingAt
timeUntilAiring
episode
}
tags{
id
name
description
rank
isMediaSpoiler
isAdult
}
isAdult
}
status
startedAt{
year
month
day
}
completedAt{
year
month
day
}
notes
progress
score
repeat
user {
id
name
avatar {
large
medium
}
statistics {
anime {
count
statuses {
status
count
}
}
}
}
}
}
`,
Variables: neededVariables,
}
returnedBody, status := AniListQuery(body, login)
var post AniListGetSingleAnime
if status == "404 Not Found" && login == false {
return post
}
if status == "404 Not Found" && login {
post = a.GetAniListItem(aniId, false)
}
2024-07-24 09:15:52 -04:00
err := json.Unmarshal(returnedBody, &post)
if err != nil {
log.Printf("Failed at unmarshal, %s\n", err)
}
if login == false {
post.Data.MediaList.UserID = user.Data.Viewer.ID
post.Data.MediaList.Status = ""
post.Data.MediaList.StartedAt.Year = 0
post.Data.MediaList.StartedAt.Month = 0
post.Data.MediaList.StartedAt.Day = 0
post.Data.MediaList.CompletedAt.Year = 0
post.Data.MediaList.CompletedAt.Month = 0
post.Data.MediaList.CompletedAt.Day = 0
post.Data.MediaList.Notes = ""
post.Data.MediaList.Progress = 0
post.Data.MediaList.Score = 0
post.Data.MediaList.Repeat = 0
post.Data.MediaList.User.ID = user.Data.Viewer.ID
post.Data.MediaList.User.Name = user.Data.Viewer.Name
post.Data.MediaList.User.Avatar.Large = user.Data.Viewer.Avatar.Large
post.Data.MediaList.User.Avatar.Medium = user.Data.Viewer.Avatar.Medium
post.Data.MediaList.User.Statistics.Anime.Count = 0
// This provides an empty array and frees up the memory from the garbage collector
post.Data.MediaList.User.Statistics.Anime.Statuses = nil
}
2024-07-24 09:15:52 -04:00
return post
}
func (a *App) AniListSearch(query string) any {
type Variables struct {
Search string `json:"search"`
ListType string `json:"listType"`
}
body := struct {
Query string `json:"query"`
Variables Variables `json:"variables"`
}{
Query: `
query ($search: String!, $listType: MediaType) {
Page (page: 1, perPage: 100) {
pageInfo {
total
currentPage
lastPage
hasNextPage
perPage
}
media (search: $search, type: $listType) {
id
idMal
title {
romaji
english
native
}
description
coverImage {
large
}
season
seasonYear
status
episodes
nextAiringEpisode{
airingAt
timeUntilAiring
episode
}
tags{
id
name
description
rank
isMediaSpoiler
isAdult
}
isAdult
}
}
}
`,
Variables: Variables{
Search: query,
ListType: "ANIME",
},
}
2024-07-24 09:15:52 -04:00
returnedBody, _ := AniListQuery(body, false)
var post interface{}
err := json.Unmarshal(returnedBody, &post)
if err != nil {
log.Printf("Failed at unmarshal, %s\n", err)
}
return post
}
func (a *App) GetAniListUserWatchingList(page int, perPage int, sort string) AniListCurrentUserWatchList {
2024-07-30 20:41:18 -04:00
var user = a.GetAniListLoggedInUser()
type Variables struct {
Page int `json:"page"`
PerPage int `json:"perPage"`
UserId int `json:"userId"`
ListType string `json:"listType"`
Status string `json:"status"`
Sort string `json:"sort"`
2024-07-24 09:15:52 -04:00
}
body := struct {
Query string `json:"query"`
Variables Variables `json:"variables"`
2024-07-24 09:15:52 -04:00
}{
Query: `
query(
$page: Int
$perPage: Int
$userId: Int
$listType: MediaType
$status: MediaListStatus
$sort:[MediaListSort]
) {
Page(page: $page, perPage: $perPage) {
pageInfo {
total
perPage
currentPage
lastPage
hasNextPage
}
mediaList(userId: $userId, type: $listType, status: $status, sort: $sort) {
id
mediaId
userId
media {
id
idMal
title {
romaji
english
native
}
description
coverImage {
large
}
season
seasonYear
status
episodes
nextAiringEpisode{
airingAt
timeUntilAiring
episode
}
tags{
id
name
description
rank
isMediaSpoiler
isAdult
}
isAdult
}
status
startedAt {
year
month
day
}
completedAt {
year
month
day
}
notes
progress
score
repeat
user {
id
name
avatar{
large
medium
}
statistics {
anime {
count
statuses {
status
count
}
}
}
}
}
}
}
2024-07-24 09:15:52 -04:00
`,
Variables: Variables{
Page: page,
PerPage: perPage,
UserId: user.Data.Viewer.ID,
ListType: "ANIME",
Status: "CURRENT",
Sort: sort,
},
2024-07-24 09:15:52 -04:00
}
returnedBody, _ := AniListQuery(body, true)
2024-07-24 09:15:52 -04:00
var post AniListCurrentUserWatchList
err := json.Unmarshal(returnedBody, &post)
2024-07-24 09:15:52 -04:00
if err != nil {
log.Printf("Failed at unmarshal, %s\n", err)
}
// Getting the real total, finding the real last page and storing that in the Page info
statuses := post.Data.Page.MediaList[0].User.Statistics.Anime.Statuses
var total int
for _, status := range statuses {
if status.Status == "CURRENT" {
total = status.Count
}
}
2024-07-24 09:15:52 -04:00
lastPage := total / perPage
2024-07-24 09:15:52 -04:00
post.Data.Page.PageInfo.Total = total
post.Data.Page.PageInfo.LastPage = lastPage
2024-07-24 09:15:52 -04:00
return post
2024-07-24 09:15:52 -04:00
}
func (a *App) AniListUpdateEntry(updateBody AniListUpdateVariables) AniListGetSingleAnime {
body := struct {
2024-08-16 15:04:34 -04:00
Query string `json:"query"`
Variables AniListUpdateVariables `json:"variables"`
}{
Query: `
mutation(
$mediaId:Int,
$progress:Int,
$status:MediaListStatus,
$score:Float,
$repeat:Int,
$notes:String,
$startedAt:FuzzyDateInput,
$completedAt:FuzzyDateInput,
){
SaveMediaListEntry(
mediaId:$mediaId,
progress:$progress,
status:$status,
score:$score,
repeat:$repeat,
notes:$notes,
startedAt:$startedAt
completedAt:$completedAt
){
id
mediaId
userId
media {
id
idMal
title {
romaji
english
native
}
description
coverImage {
large
}
season
seasonYear
status
episodes
nextAiringEpisode {
airingAt
timeUntilAiring
episode
}
isAdult
}
status
startedAt{
year
month
day
}
completedAt{
year
month
day
}
notes
progress
score
repeat
user {
id
name
avatar{
large
medium
}
statistics{
anime{
count
statuses{
status
count
}
}
}
}
}
}
`,
2024-08-16 15:04:34 -04:00
Variables: updateBody,
}
returnedBody, _ := AniListQuery(body, true)
var returnedJson AniListUpdateReturn
err := json.Unmarshal(returnedBody, &returnedJson)
if err != nil {
log.Printf("Failed at unmarshal, %s\n", err)
}
var post AniListGetSingleAnime
post.Data.MediaList = returnedJson.Data.SaveMediaListEntry
return post
}