added ability to get anime as needed from MAL

This commit is contained in:
John O'Keefe 2024-08-16 15:07:06 -04:00
parent 3b5518113e
commit fb2d5fbdea
10 changed files with 572 additions and 46 deletions

View File

@ -54,3 +54,21 @@ func (a *App) GetMyAnimeList(count int) MALWatchlist {
return malList
}
func (a *App) MyAnimeListUpdate(anime MALAnime, update interface{}) MyListStatus {
//var body url.Values
return MyListStatus{}
}
func (a *App) GetMyAnimeListAnime(id int) MALAnime {
malUrl := "https://api.myanimelist.net/v2/anime/" + strconv.Itoa(id) + "?fields=id,title,main_picture,alternative_titles,start_date,end_date,synopsis,mean,rank,popularity,num_list_users,num_scoring_users,nsfw,genres,created_at,updated_at,media_type,status,my_list_status,num_episodes,start_season,broadcast,source,average_episode_duration,rating,pictures,background,related_anime,recommendations,studios,statistics"
respBody := MALHelper("GET", malUrl, nil)
var malAnime MALAnime
err := json.Unmarshal(respBody, &malAnime)
if err != nil {
log.Printf("Failed to unmarshal json response, %s\n", err)
}
return malAnime
}

View File

@ -65,3 +65,90 @@ type MALWatchlist struct {
Next string `json:"next" ts_type:"next"`
} `json:"paging" ts_type:"paging"`
}
type MALAnime struct {
Id int `json:"id" ts_type:"id"`
Title string `json:"title" ts_type:"title"`
MainPicture struct {
Large string `json:"large" json:"large"`
Medium string `json:"medium" json:"medium"`
} `json:"main_picture" json:"mainPicture"`
AlternativeTitles struct {
Synonyms []string `json:"synonyms" ts_type:"synonyms"`
En string `json:"en" ts_type:"en"`
Ja string `json:"ja" ts_type:"ja"`
} `json:"alternative_titles" ts_type:"alternativeTitles"`
StartDate string `json:"start_date" ts_type:"startDate"`
EndDate string `json:"end_date" ts_type:"endDate"`
Synopsis string `json:"synopsis" ts_type:"synopsis"`
Mean float64 `json:"mean" ts_type:"mean"`
Rank int `json:"rank" ts_type:"rank"`
Popularity int `json:"popularity" ts_type:"popularity"`
NumListUsers int `json:"num_list_users" ts_type:"numListUsers"`
NumScoringUsers int `json:"num_scoring_users" ts_type:"numScoringUsers"`
NSFW string `json:"nsfw" ts_type:"nsfw"`
Genres []struct {
Id int `json:"id" ts_type:"id"`
Name string `json:"name" ts_type:"name"`
} `json:"genres" ts_type:"genres"`
CreatedAt string `json:"created_at" ts_type:"createdAt"`
UpdatedAt string `json:"updated_at" ts_type:"updatedAt"`
MediaType string `json:"media_type" ts_type:"mediaType"`
Status string `json:"status" ts_type:"status"`
MyListStatus MyListStatus `json:"my_list_status" ts_type:"myListStatus"`
NumEpisodes int `json:"num_episodes" ts_type:"numEpisodes"`
StartSeason struct {
Year int `json:"year" ts_type:"year"`
Season string `json:"season" ts_type:"season"`
} `json:"start_season" ts_type:"startSeason"`
Broadcast struct {
DayOfTheWeek string `json:"day_of_the_week" ts_type:"dayOfTheWeek"`
StartTime string `json:"start_time" ts_type:"startTime"`
} `json:"broadcast" ts_type:"broadcast"`
Source string `json:"source" ts_type:"source"`
AverageEpisodeDuration int `json:"average_episode_duration" ts_type:"averageEpisodeDuration"`
Rating string `json:"rating" ts_type:"rating"`
Studios []struct {
Id int `json:"id" ts_type:"id"`
Name string `json:"name" ts_type:"name"`
} `json:"studios" ts_type:"studios"`
Pictures []struct {
Large string `json:"large" ts_type:"large"`
Medium string `json:"medium" ts_type:"medium"`
} `json:"pictures" ts_type:"pictures"`
Background string `json:"background" ts_type:"background"`
RelatedAnime []struct {
Node MALAnime `json:"node" ts_type:"node"`
RelationType string `json:"relation_type" ts_type:"relationType"`
RelationTypeFormatted string `json:"relation_type_formatted" ts_type:"relationTypeFormatted"`
} `json:"related_anime" ts_type:"relatedAnime"`
Recommendations []struct {
Node MALAnime `json:"node" ts_type:"node"`
NumRecommendations int `json:"num_recommendations" ts_type:"numRecommendations"`
} `json:"recommendations" ts_type:"recommendations"`
Statistics struct {
NumListUsers int `json:"num_list_users" ts_type:"numListUsers"`
Status struct {
Watching string `json:"watching" ts_type:"watching"`
Completed string `json:"completed" ts_type:"completed"`
OnHold string `json:"on_hold" ts_type:"onHold"`
Dropped string `json:"dropped" ts_type:"dropped"`
PlanToWatch string `json:"plan_to_watch" ts_type:"planToWatch"`
}
}
}
type MyListStatus struct {
Status string `json:"status" ts_type:"status"`
Score int `json:"score" ts_type:"score"`
NumEpisodesWatched int `json:"num_episodes_watched" ts_type:"numEpisodesWatched"`
IsRewatching bool `json:"is_rewatching" ts_type:"isRewatching"`
StartDate string `json:"start_date" ts_type:"startDate"`
FinishDate string `json:"finish_date" ts_type:"finishDate"`
Priority int `json:"priority" ts_type:"priority"`
NumTimesRewatched int `json:"num_times_rewatched" ts_type:"numTimesRewatched"`
RewatchValue int `json:"rewatch_value" ts_type:"rewatchValue"`
Tags []string `json:"tags" ts_type:"tags"`
Comments string `json:"comments" ts_type:"comments"`
UpdatedAt string `json:"updated_at" ts_type:"updatedAt"`
}

View File

@ -14,7 +14,8 @@
title,
watchListPage,
animePerPage,
malWatchList
malWatchList,
malPrimary
} from "./GlobalVariablesAndHelperFunctions.svelte";
import {
CheckIfAniListLoggedIn,
@ -38,11 +39,13 @@
let isAniListLoggedIn: boolean
let isAniListPrimary: boolean
let isMalPrimary: boolean
let aniListWatchListLoaded: AniListCurrentUserWatchList
aniListLoggedIn.subscribe((value) => isAniListLoggedIn = value)
aniListPrimary.subscribe((value) => isAniListPrimary = value)
aniListWatchlist.subscribe((value) => aniListWatchListLoaded = value)
malPrimary.subscribe((value) => isMalPrimary = value)
let page: number
@ -72,10 +75,14 @@
if (loggedIn) {
GetMyAnimeListLoggedInUser().then(user => {
malUser.set(user)
GetMyAnimeList(1000).then(watchList => {
malWatchList.set(watchList)
if (isMalPrimary){
GetMyAnimeList(1000).then(watchList => {
malWatchList.set(watchList)
malLoggedIn.set(loggedIn)
})
} else {
malLoggedIn.set(loggedIn)
})
}
})
}
})

View File

@ -3,7 +3,9 @@
anilistModal,
simklWatchList,
aniListLoggedIn,
simklLoggedIn
simklLoggedIn,
malLoggedIn,
malAnime
} from "./GlobalVariablesAndHelperFunctions.svelte";
import {aniListAnime} from "./GlobalVariablesAndHelperFunctions.svelte";
import {Button} from "flowbite-svelte";
@ -14,16 +16,28 @@
import { writable } from 'svelte/store';
import type {SimklAnime} from "./simkl/types/simklTypes";
import { get } from 'svelte/store';
import {AniListUpdateEntry, SimklSyncEpisodes, SimklSyncRating, SimklSyncStatus} from "../wailsjs/go/main/App";
import {
AniListUpdateEntry,
SimklSyncEpisodes,
SimklSyncRating,
SimklSyncStatus
} from "../wailsjs/go/main/App";
import type {MALAnime} from "./mal/types/MALTypes";
import type {AniListUpdateVariables} from "./anilist/types/AniListTypes";
const simklWatch = get(simklWatchList);
let isAniListLoggedIn: boolean
let isMalLoggedIn: boolean
let isSimklLoggedIn: boolean
let simklAnimeIndex: number
let currentMalAnime: MALAnime
let simklAnime: SimklAnime | undefined = undefined
aniListLoggedIn.subscribe((value) => isAniListLoggedIn = value)
malLoggedIn.subscribe((value) => isMalLoggedIn = value)
simklLoggedIn.subscribe((value) => isSimklLoggedIn = value)
malAnime.subscribe((value) => currentMalAnime = value)
for (let i = 0; i < simklWatch.anime.length; i++) {
if (Number(simklWatch.anime[i].show.ids.mal) === aniListAnime.data.MediaList.media.idMal) {
@ -35,23 +49,34 @@
type statusOption = {
id: number,
aniList: string,
mal: string,
simkl: string,
}
const statusOptions: statusOption[] = [
{ id: 0, aniList: "CURRENT", simkl: "watching"},
{ id: 1, aniList: "PLANNING", simkl: "plantowatch"},
{ id: 2, aniList: "COMPLETED", simkl: "completed"},
{ id: 3, aniList: "DROPPED", simkl: "dropped"},
{ id: 4, aniList: "PAUSED", simkl: "hold"},
{ id: 5, aniList: "REPEATING", simkl: "watching"}
{ id: 0, aniList: "CURRENT", mal: "watching", simkl: "watching"},
{ id: 1, aniList: "PLANNING", mal: "plan_to_watch", simkl: "plantowatch"},
{ id: 2, aniList: "COMPLETED", mal: "completed", simkl: "completed"},
{ id: 3, aniList: "DROPPED", mal: "dropped", simkl: "dropped"},
{ id: 4, aniList: "PAUSED", mal: "on_hold", simkl: "hold"},
{ id: 5, aniList: "REPEATING", mal: "rewatching", simkl: "watching"}
]
let startingAnilistStatusOption: statusOption
startingAnilistStatusOption = statusOptions.filter(option => aniListAnime.data.MediaList.status === option.aniList)[0]
let items = [];
let items = [] as {
id: number
service: string
progress: number
status: string
startedAt: string
completedAt: string
score: number
repeat: number
notes: string
}[];
if(isAniListLoggedIn) {
items.push({
@ -67,6 +92,20 @@
})
}
if(isMalLoggedIn) {
items.push({
id: currentMalAnime.id,
service: "MyAnimeList",
progress: currentMalAnime.my_list_status.num_episodes_watched,
status: currentMalAnime.my_list_status.status,
startedAt: currentMalAnime.my_list_status.start_date,
completedAt: currentMalAnime.my_list_status.finish_date,
score: currentMalAnime.my_list_status.score,
repeat: currentMalAnime.my_list_status.num_times_rewatched,
notes: currentMalAnime.my_list_status.comments
})
}
if(isSimklLoggedIn && simklAnime !== undefined) {
items.push({
id: simklAnime.show.ids.simkl,
@ -114,7 +153,7 @@
const ratingInWords = {
0: "Not Reviewed",
1: "Apalling",
1: "Appalling",
2: "Horrible",
3: "Very Bad",
4: "Bad",
@ -213,43 +252,45 @@
}
const submitData = async () => {
await AniListUpdateEntry(
aniListAnime.data.MediaList.mediaId,
values.progress,
values.status.aniList,
values.score,
values.repeat,
values.notes,
values.startedAt.year,
values.startedAt.month,
values.startedAt.day,
values.completedAt.year,
values.completedAt.month,
values.completedAt.day
).then((value) => {
let body: AniListUpdateVariables = {
mediaId: aniListAnime.data.MediaList.mediaId,
progress: values.progress,
status: values.status.aniList,
score: values.score,
repeat: values.repeat,
notes: values.notes,
startedAt: {
year: values.startedAt.year,
month: values.startedAt.month,
day: values.startedAt.day
},
completedAt: {
year: values.completedAt.year,
month: values.completedAt.month,
day: values.completedAt.day
}
}
await AniListUpdateEntry(body).then((value) => {
console.log(value)
})
if (simklLoggedIn) {
if (simklAnime.watched_episodes_count !== values.progress) {
await SimklSyncEpisodes(simklAnime, values.progress).then(value => {
console.log(value)
await SimklSyncEpisodes(simklAnime, values.progress).then(() => {
simklAnime.watched_episodes_count = values.progress
simklWatch.anime[simklAnimeIndex].watched_episodes_count = values.progress
})
}
if (simklAnime.user_rating !== values.score) {
await SimklSyncRating(simklAnime, values.score).then(value => {
console.log(value)
await SimklSyncRating(simklAnime, values.score).then(() => {
simklAnime.user_rating = values.score
simklWatch.anime[simklAnimeIndex].user_rating = values.score
})
}
if (simklAnime.status !== values.status.simkl) {
SimklSyncStatus(simklAnime, values.status.simkl).then(value => {
console.log(value)
SimklSyncStatus(simklAnime, values.status.simkl).then(() => {
simklAnime.status = values.status.simkl
simklWatch.anime[simklAnimeIndex].status = values.status.simkl
})

View File

@ -1,7 +1,7 @@
<script lang="ts" context="module">
import {
GetAniListItem,
GetAniListLoggedInUser, GetAniListUserWatchingList, GetMyAnimeListLoggedInUser,
GetAniListLoggedInUser, GetAniListUserWatchingList, GetMyAnimeListAnime, GetMyAnimeListLoggedInUser,
GetSimklLoggedInUser, LogoutAniList, LogoutMyAnimeList, LogoutSimkl
} from "../wailsjs/go/main/App";
import type {
@ -11,7 +11,7 @@
import {writable} from 'svelte/store'
import type {SimklUser, SimklWatchList} from "./simkl/types/simklTypes";
import {type AniListUser, MediaListSort} from "./anilist/types/AniListTypes";
import type {MALWatchlist, MyAnimeListUser} from "./mal/types/MALTypes";
import type {MALAnime, MALWatchlist, MyAnimeListUser} from "./mal/types/MALTypes";
export let aniListAnime: AniListGetSingleAnime
export let title = writable("")
@ -21,11 +21,13 @@
export let malLoggedIn = writable(false)
export let simklWatchList = writable({} as SimklWatchList)
export let aniListPrimary = writable(true)
export let malPrimary = writable(false)
export let simklUser = writable({} as SimklUser)
export let aniListUser = writable({} as AniListUser)
export let malUser = writable({} as MyAnimeListUser)
export let aniListWatchlist = writable({} as AniListCurrentUserWatchList)
export let malWatchList = writable({} as MALWatchlist)
export let malAnime = writable({} as MALAnime)
export let watchListPage = writable(1)
export let animePerPage = writable(20)
@ -35,18 +37,30 @@
let perPage: number
let aniWatchlist: AniListCurrentUserWatchList
let isMalLoggedIn: boolean
aniListPrimary.subscribe(value => isAniListPrimary = value)
watchListPage.subscribe(value => page = value)
animePerPage.subscribe(value => perPage = value)
aniListWatchlist.subscribe(value => aniWatchlist = value)
malLoggedIn.subscribe(value => isMalLoggedIn = value)
export function GetAniListSingleItemAndOpenModal(aniId: number, login: boolean): void {
GetAniListItem(aniId, login).then(result => {
aniListAnime = result
GetAniListItem(aniId, login).then(aniListResult => {
aniListAnime = aniListResult
title.set(aniListAnime.data.MediaList.media.title.english === "" ?
aniListAnime.data.MediaList.media.title.romaji :
aniListAnime.data.MediaList.media.title.english)
anilistModal.set(true)
if(isMalLoggedIn) {
GetMyAnimeListAnime(aniListAnime.data.MediaList.media.idMal).then(malResult => {
console.log(malResult)
malAnime.set(malResult)
anilistModal.set(true)
})
} else {
anilistModal.set(true)
}
})
}

View File

@ -80,4 +80,27 @@ export enum MediaListSort {
MediaTitleNativeDesc = "MEDIA_TITLE_NATIVE_DESC",
MediaPopularity = "MEDIA_POPULARITY",
MediaPopularityDesc = "MEDIA_POPULARITY_DESC"
}
export interface StartedAt {
year: number
month: number
day: number
}
export interface CompletedAt {
year: number
month: number
day: number
}
export interface AniListUpdateVariables {
mediaId: number
progress: number
status: string
score: number
repeat: number
notes: string
startedAt: StartedAt
completedAt: CompletedAt
}

View File

@ -31,13 +31,15 @@ export interface AnimeStatistics {
}
export interface MALWatchlist {
data: {
node: Node
listStatus: ListStatus
}[]
data: [MALAnimeFromList]
paging: Paging
}
export interface MALAnimeFromList {
node: Node
listStatus: ListStatus | MyListStatus
}
export interface Node {
id: number
title: string
@ -63,3 +65,90 @@ export interface Paging {
previous: string
next: string
}
export interface MALAnime {
id: number;
title: string;
main_picture: {
large: string;
medium: string;
};
alternative_titles: {
synonyms: string[];
en: string;
ja: string;
};
start_date: string;
end_date: string;
synopsis: string;
mean: number;
rank: number;
popularity: number;
num_list_users: number;
num_scoring_users: number;
nsfw: string;
genres: {
id: number;
name: string;
}[];
created_at: string;
updated_at: string;
media_type: string;
status: string;
my_list_status: MyListStatus;
num_episodes: number;
start_season: {
year: number;
season: string;
};
broadcast: {
day_of_the_week: string;
start_time: string;
};
source: string;
average_episode_duration: number;
rating: string;
studios: {
id: number;
name: string;
}[];
pictures: {
large: string;
medium: string;
}[];
background: string;
related_anime: {
node: MALAnime;
relation_type: string;
relation_type_formatted: string;
}[];
recommendations: {
node: MALAnime;
num_recommendations: number;
}[];
Statistics: {
num_list_users: number;
Status: {
watching: string;
completed: string;
on_hold: string;
dropped: string;
plan_to_watch: string;
};
};
}
export interface MyListStatus {
status: string;
score: number;
num_episodes_watched: number;
is_rewatching: boolean;
start_date: string;
finish_date: string;
priority: number;
num_times_rewatched: number;
rewatch_value: number;
tags: string[];
comments: string;
updated_at: string;
}

View File

@ -6,7 +6,7 @@ export function AniListLogin():Promise<void>;
export function AniListSearch(arg1:string):Promise<any>;
export function AniListUpdateEntry(arg1:number,arg2:number,arg3:string,arg4:number,arg5:number,arg6:string,arg7:number,arg8:number,arg9:number,arg10:number,arg11:number,arg12:number):Promise<any>;
export function AniListUpdateEntry(arg1:main.AniListUpdateVariables):Promise<any>;
export function CheckIfAniListLoggedIn():Promise<boolean>;
@ -22,6 +22,8 @@ export function GetAniListUserWatchingList(arg1:number,arg2:number,arg3:string):
export function GetMyAnimeList(arg1:number):Promise<main.MALWatchlist>;
export function GetMyAnimeListAnime(arg1:number):Promise<main.MALAnime>;
export function GetMyAnimeListLoggedInUser():Promise<main.MyAnimeListUser>;
export function GetSimklLoggedInUser():Promise<main.SimklUser>;
@ -34,6 +36,8 @@ export function LogoutSimkl():Promise<string>;
export function MyAnimeListLogin():Promise<void>;
export function MyAnimeListUpdate(arg1:main.MALAnime,arg2:any):Promise<main.MyListStatus>;
export function SimklGetUserWatchlist():Promise<main.SimklWatchList>;
export function SimklLogin():Promise<void>;

View File

@ -10,8 +10,8 @@ export function AniListSearch(arg1) {
return window['go']['main']['App']['AniListSearch'](arg1);
}
export function AniListUpdateEntry(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12) {
return window['go']['main']['App']['AniListUpdateEntry'](arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12);
export function AniListUpdateEntry(arg1) {
return window['go']['main']['App']['AniListUpdateEntry'](arg1);
}
export function CheckIfAniListLoggedIn() {
@ -42,6 +42,10 @@ export function GetMyAnimeList(arg1) {
return window['go']['main']['App']['GetMyAnimeList'](arg1);
}
export function GetMyAnimeListAnime(arg1) {
return window['go']['main']['App']['GetMyAnimeListAnime'](arg1);
}
export function GetMyAnimeListLoggedInUser() {
return window['go']['main']['App']['GetMyAnimeListLoggedInUser']();
}
@ -66,6 +70,10 @@ export function MyAnimeListLogin() {
return window['go']['main']['App']['MyAnimeListLogin']();
}
export function MyAnimeListUpdate(arg1, arg2) {
return window['go']['main']['App']['MyAnimeListUpdate'](arg1, arg2);
}
export function SimklGetUserWatchlist() {
return window['go']['main']['App']['SimklGetUserWatchlist']();
}

View File

@ -60,6 +60,82 @@ export namespace main {
return a;
}
}
export class CompletedAt {
year: number;
month: number;
day: number;
static createFrom(source: any = {}) {
return new CompletedAt(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.year = source["year"];
this.month = source["month"];
this.day = source["day"];
}
}
export class StartedAt {
year: number;
month: number;
day: number;
static createFrom(source: any = {}) {
return new StartedAt(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.year = source["year"];
this.month = source["month"];
this.day = source["day"];
}
}
export class AniListUpdateVariables {
mediaId: number;
progress: number;
status: string;
score: number;
repeat: number;
notes: string;
startedAt: StartedAt;
completedAt: CompletedAt;
static createFrom(source: any = {}) {
return new AniListUpdateVariables(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.mediaId = source["mediaId"];
this.progress = source["progress"];
this.status = source["status"];
this.score = source["score"];
this.repeat = source["repeat"];
this.notes = source["notes"];
this.startedAt = this.convertValues(source["startedAt"], StartedAt);
this.completedAt = this.convertValues(source["completedAt"], CompletedAt);
}
convertValues(a: any, classs: any, asMap: boolean = false): any {
if (!a) {
return a;
}
if (a.slice && a.map) {
return (a as any[]).map(elem => this.convertValues(elem, classs));
} else if ("object" === typeof a) {
if (asMap) {
for (const key of Object.keys(a)) {
a[key] = new classs(a[key]);
}
return a;
}
return new classs(a);
}
return a;
}
}
export class AniListUser {
// Go type: struct { Viewer struct { ID int "json:\"id\""; Name string "json:\"name\""; Avatar struct { Large string "json:\"large\""; Medium string "json:\"medium\"" } "json:\"avatar\""; BannerImage string "json:\"bannerImage\""; SiteUrl string "json:\"siteUrl\"" } "json:\"Viewer\"" }
data: any;
@ -121,6 +197,96 @@ export namespace main {
this.anime_type = source["anime_type"];
}
}
export class MALAnime {
id: id;
title: title;
// Go type: struct { Large string "json:\"large\" json:\"large\""; Medium string "json:\"medium\" json:\"medium\"" }
main_picture: any;
alternative_titles: alternativeTitles;
start_date: startDate;
end_date: endDate;
synopsis: synopsis;
mean: mean;
rank: rank;
popularity: popularity;
num_list_users: numListUsers;
num_scoring_users: numScoringUsers;
nsfw: nsfw;
genres: genres;
created_at: createdAt;
updated_at: updatedAt;
media_type: mediaType;
status: status;
my_list_status: myListStatus;
num_episodes: numEpisodes;
start_season: startSeason;
broadcast: broadcast;
source: source;
average_episode_duration: averageEpisodeDuration;
rating: rating;
studios: studios;
pictures: pictures;
background: background;
related_anime: relatedAnime;
recommendations: recommendations;
static createFrom(source: any = {}) {
return new MALAnime(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.id = source["id"];
this.title = source["title"];
this.main_picture = this.convertValues(source["main_picture"], Object);
this.alternative_titles = source["alternative_titles"];
this.start_date = source["start_date"];
this.end_date = source["end_date"];
this.synopsis = source["synopsis"];
this.mean = source["mean"];
this.rank = source["rank"];
this.popularity = source["popularity"];
this.num_list_users = source["num_list_users"];
this.num_scoring_users = source["num_scoring_users"];
this.nsfw = source["nsfw"];
this.genres = source["genres"];
this.created_at = source["created_at"];
this.updated_at = source["updated_at"];
this.media_type = source["media_type"];
this.status = source["status"];
this.my_list_status = source["my_list_status"];
this.num_episodes = source["num_episodes"];
this.start_season = source["start_season"];
this.broadcast = source["broadcast"];
this.source = source["source"];
this.average_episode_duration = source["average_episode_duration"];
this.rating = source["rating"];
this.studios = source["studios"];
this.pictures = source["pictures"];
this.background = source["background"];
this.related_anime = source["related_anime"];
this.recommendations = source["recommendations"];
}
convertValues(a: any, classs: any, asMap: boolean = false): any {
if (!a) {
return a;
}
if (a.slice && a.map) {
return (a as any[]).map(elem => this.convertValues(elem, classs));
} else if ("object" === typeof a) {
if (asMap) {
for (const key of Object.keys(a)) {
a[key] = new classs(a[key]);
}
return a;
}
return new classs(a);
}
return a;
}
}
export class MALWatchlist {
data: struct { Node struct { Id int "json:\"id\" ts_type:\"id\""; Title string "json:\"title\" ts_type:\"title\""; MainPicture struct { Medium string "json:\"medium\" json:\"medium\""; Large string "json:\"large\" json:\"large\"" } "json:\"main_picture\" json:\"mainPicture\"" } "json:\"node\" json:\"node\""; ListStatus struct { Status string "json:\"status\" ts_type:\"status\""; Score int "json:\"score\" ts_type:\"score\""; NumEpisodesWatched int "json:\"num_episodes_watched\" ts_type:\"numEpisodesWatched\""; IsRewatching bool "json:\"is_rewatching\" ts_type:\"isRewatching\""; UpdatedAt time.Time "json:\"updated_at\" ts_type:\"updatedAt\""; StartDate string "json:\"start_date\" ts_type:\"startDate\""; FinishDate string "json:\"finish_date\" ts_type:\"finishDate\"" } "json:\"list_status\" ts_type:\"listStatus\"" }[];
paging: paging;
@ -267,6 +433,40 @@ export namespace main {
this.is_supporter = source["is_supporter"];
}
}
export class MyListStatus {
status: status;
score: score;
num_episodes_watched: numEpisodesWatched;
is_rewatching: isRewatching;
start_date: startDate;
finish_date: finishDate;
priority: priority;
num_times_rewatched: numTimesRewatched;
rewatch_value: rewatchValue;
tags: tags;
comments: comments;
updated_at: updatedAt;
static createFrom(source: any = {}) {
return new MyListStatus(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.status = source["status"];
this.score = source["score"];
this.num_episodes_watched = source["num_episodes_watched"];
this.is_rewatching = source["is_rewatching"];
this.start_date = source["start_date"];
this.finish_date = source["finish_date"];
this.priority = source["priority"];
this.num_times_rewatched = source["num_times_rewatched"];
this.rewatch_value = source["rewatch_value"];
this.tags = source["tags"];
this.comments = source["comments"];
this.updated_at = source["updated_at"];
}
}
export class SimklUser {
user: user;
account: account;
@ -333,6 +533,41 @@ export namespace struct { MediaList main {
}
export namespace struct { Node main {
export class {
node: node;
num_recommendations: numRecommendations;
static createFrom(source: any = {}) {
return new (source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.node = source["node"];
this.num_recommendations = source["num_recommendations"];
}
}
export class {
node: node;
relation_type: relationType;
relation_type_formatted: relationTypeFormatted;
static createFrom(source: any = {}) {
return new (source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.node = source["node"];
this.relation_type = source["relation_type"];
this.relation_type_formatted = source["relation_type_formatted"];
}
}
}
export namespace struct { Node struct { Id int "json:\"id\" ts_type:\"id\""; Title string "json:\"title\" ts_type:\"title\""; MainPicture struct { Medium string "json:\"medium\" json:\"medium\""; Large string "json:\"large\" json:\"large\"" } "json:\"main_picture\" json:\"mainPicture\"" } "json:\"node\" json:\"node\""; ListStatus struct { Status string "json:\"status\" ts_type:\"status\""; Score int "json:\"score\" ts_type:\"score\""; NumEpisodesWatched int "json:\"num_episodes_watched\" ts_type:\"numEpisodesWatched\""; IsRewatching bool "json:\"is_rewatching\" ts_type:\"isRewatching\""; UpdatedAt time {
export class {