Skip to content

Commit

Permalink
Better doc for Lists class + Full API retrieval
Browse files Browse the repository at this point in the history
  • Loading branch information
salixor committed May 31, 2019
1 parent 1caf50b commit 0ebbd92
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 42 deletions.
17 changes: 15 additions & 2 deletions documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,21 @@ Usernames must be strings and ids must be numbers!<br/>
- `list.name` | The user's list name
- `list.isCustomList` | Checks if the list is a custom one (not created by default by AniList)
- `list.isSplitCompletedList` | Checks if the list is a split completed list ie. if the user chose to have each completed media format in a separate list (toggled in user's settings)
- `list.status` | The user's list status ("CURRENT", "PLANNING", "COMPLETED", "PAUSED", "DROPPED", "REREADING", "REWATCHING")
- `list.entries` | List of media entries in this list (refer to `Media` documentation)
- `list.status` | The user's list status ("CURRENT", "PLANNING", "COMPLETED", "PAUSED", "DROPPED", "REPEATING")
- `list.entries` | List of entries in this list, containing the media and related informations
- `entry.media` | The media linked to that entry (refer to the `Media` paragraph for all properties)
- `entry.userId` | The user's id
- `entry.status` | The user's status ("CURRENT", "PLANNING", "COMPLETED", "PAUSED", "DROPPED", "REPEATING") for that media
- `entry.score` | The user's score for that media
- `entry.progress` | The user's progress for that media (episodes for anime, chapters for manga)
- `entry.progressVolumes` | Only if the media is a mange. The user's volume progress for that manga
- `entry.repeat` | The amount of times the user rewatched or read the media
- `entry.priority` | The user's priority for that media
- `entry.private` | Check if the entry should only be visible to authenticated user
- `entry.notes` | The user's note about that media
- `entry.hiddenFromStatusLists` | Check if the entry should be hidden from non-custom lists (ie. default lists)
- `entry.advancedScores` | The user's advanced scores for that media (Story, Characters, Visuals, Audio, Enjoyment, …)
- `entry.dates` | The dates related to that entry in ISO 8601 format. Gives four values per object: startedAt, completedAt, updatedAt and createdAt

# Studio
- `Anilist.studio(id)` | Get information on a studio by an id
Expand Down
73 changes: 47 additions & 26 deletions lib/fetcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,31 @@ module.exports = {
else { list.push(obj[x]); }
}; return list;
},
convertFuzzyDate: function(fuzzyDate) {
if (Object.values(fuzzyDate).some(d => d === null)) return null;
return new Date(fuzzyDate.year, fuzzyDate.month - 1, fuzzyDate.day);
},
formatMedia: async function(media) {
var keys = ["characters", "staff", "relations", "trends"];
if (media.studios) { keys.push("studios"); }
if (media.airingSchedule) { keys.push("airingSchedule"); }

if (media.reviews.edges.length === 0) { media.reviews = null; }
else { keys.push("reviews"); }

for (var x = 0; x < keys.length; x++) { media[keys[x]] = await this.edgeRemove(media[keys[x]].edges); }
media.externalLinks = await this.edgeRemove(media.externalLinks);
media.trends = await this.edgeRemove(media.trends);

if (media.trailer) {
switch (media.trailer.site) {
case "youtube": media.trailer = "https://www.youtube.com/watch?v=" + media.trailer.id; break;
case "dailymotion": media.trailer = "https://www.dailymotion.com/video/" + media.trailer.id; break;
case undefined: media.trailer = null; break;
default: media.trailer = media.trailer; break;
}
}
},
send: async function(query, variables) {
if (!query || !variables) { throw new Error("Query or variables are not given!"); }
var options = {
Expand All @@ -27,28 +52,9 @@ module.exports = {
if (json.data === null) {
if (json.errors[0].status === 404) { return { data: null, status: 404, message: "Search item by that term is not found." } }
else { return { data: null, status: json.errors[0].status, message: json.errors[0].message } }
} else if (json.data !== null) {
} else {
if (json.data.Media) {
var keys = ["characters", "staff", "relations", "trends"];
if (json.data.Media.studios) { keys.push("studios"); }
if (json.data.Media.airingSchedule) { keys.push("airingSchedule"); }

if (json.data.Media.reviews.edges.length === 0) { json.data.Media.reviews = null; }
else { keys.push("reviews"); }

for (var x = 0; x < keys.length; x++) { json.data.Media[keys[x]] = await this.edgeRemove(json.data.Media[keys[x]].edges); }
json.data.Media.externalLinks = await this.edgeRemove(json.data.Media.externalLinks);
json.data.Media.trends = await this.edgeRemove(json.data.Media.trends);

if (json.data.Media.trailer) {
switch (json.data.Media.trailer.site) {
case "youtube": json.data.Media.trailer = "https://www.youtube.com/watch?v=" + json.data.Media.trailer.id; break;
case "dailymotion": json.data.Media.trailer = "https://www.dailymotion.com/video/" + json.data.Media.trailer.id; break;
case undefined: json.data.Media.trailer = null; break;
default: json.data.Media.trailer = json.data.Media.trailer; break;
}
}

this.formatMedia(json.data.Media);
return json.data.Media;
} else if (json.data.Character) {
json.data.Character.media = await this.edgeRemove(json.data.Character.media.edges);
Expand All @@ -58,17 +64,32 @@ module.exports = {
json.data.Staff.characters = await this.edgeRemove(json.data.Staff.characters.edges);
if (json.data.Staff.description.length < 1) { json.data.Staff.description = null; }
return json.data.Staff;
} else if (json.data.Page) { return json.data.Page; }
} else if (json.data.Page) {
return json.data.Page;
}
else if (json.data.Studio) {
json.data.Studio.media = await this.edgeRemove(json.data.Studio.media.edges);
return json.data.Studio;
} else if (json.data.User) {
if (json.data.User.stats) { return json.data.User.stats; }
else { return json.data.User; }
} else if (json.data.MediaListCollection) {
if (json.data.MediaListCollection.lists) { return json.data.MediaListCollection.lists; }
else { return json.data.MediaListCollection; }
} else { return json.data; }
} else if (json.data.MediaListCollection) {
json.data.MediaListCollection.lists.forEach(list => {
list.entries.map(entry => {
this.formatMedia(entry.media);
entry.dates = {
'startedAt': this.convertFuzzyDate(entry.startedAt),
'completedAt': this.convertFuzzyDate(entry.completedAt),
'updatedAt': new Date(entry.updatedAt * 1000),
'createdAt': (entry.createdAt === 0) ? null : new Date(entry.createdAt * 1000)
};
['startedAt', 'completedAt', 'updatedAt', 'createdAt'].forEach(e => delete entry[e]);
});
});
return json.data.MediaListCollection.lists;
} else {
return json.data;
}
}
}
};
22 changes: 12 additions & 10 deletions lib/lists.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,38 @@ const Fetch = require('./fetcher');

module.exports = {
variables: function(user, type) {
if (type === 'ANIME' || type === 'MANGA') {
if (typeof user === 'string') { return [{ name: user, type: type }, `query ($name: String, $type: MediaType) { MediaListCollection(userName: $name, type: $type) { `]; }
else if (typeof user === 'number') { return [{ id: user, type: type }, `query ($id: Int, $type: MediaType) { MediaListCollection(userId: $id,, type: $type) { `]; }
}
if (typeof user === 'string') { return [{ name: user, type: type }, `query ($name: String, $type: MediaType) { MediaListCollection(userName: $name, type: $type) { `]; }
else if (typeof user === 'number') { return [{ id: user, type: type }, `query ($id: Int, $type: MediaType) { MediaListCollection(userId: $id,, type: $type) { `]; }
},
anime: function(user) {
if (!user) { throw new Error("AniList username or id is missing!"); }
var start = this.variables(user, 'ANIME');
var query = start[1] + `lists { name isCustomList isSplitCompletedList status entries { media {
id idMal title { romaji english native userPreferred }
var query = start[1] + `lists { name isCustomList isSplitCompletedList status entries {
media { id idMal title { romaji english native userPreferred }
type episodes description format status startDate { year month day } endDate { year month day }
season duration countryOfOrigin isLicensed source hashtag trailer { id site }
updatedAt coverImage { large medium } bannerImage genres synonyms averageScore meanScore
popularity trending tags { name isMediaSpoiler } relations { edges { id } } characters { edges { id } }
staff { edges { id } } studios { edges { id } } isFavourite isAdult nextAiringEpisode { id } airingSchedule { edges { id } }
trends { edges { node { averageScore popularity inProgress episode } } } externalLinks { url }
streamingEpisodes { title thumbnail url site } rankings { id } mediaListEntry { id }
reviews { edges { node { id summary } } } siteUrl autoCreateForumThread modNotes } } } } }`;
reviews { edges { node { id summary } } } siteUrl autoCreateForumThread modNotes }
userId status score progress repeat priority private notes hiddenFromStatusLists
advancedScores startedAt { year month day } completedAt { year month day } updatedAt createdAt } } } }`;
return Fetch.send(query, start[0]);
},
manga: function(user) {
if (!user) { throw new Error("AniList username or id is missing!"); }
var start = this.variables(user, 'MANGA');
var query = start[1] + `lists { name isCustomList isSplitCompletedList status entries { media {
id idMal title { romaji english native userPreferred }
var query = start[1] + `lists { name isCustomList isSplitCompletedList status entries {
media { id idMal title { romaji english native userPreferred }
type description format status startDate { year month day } endDate { year month day } volumes countryOfOrigin isLicensed updatedAt
coverImage { large medium } bannerImage genres synonyms averageScore meanScore siteUrl autoCreateForumThread modNotes
popularity trending tags { name isMediaSpoiler } relations { edges { id } } characters { edges { id } } staff { edges { id } }
isFavourite isAdult trends { edges { node { averageScore popularity inProgress episode } } }
externalLinks { url } rankings { id } mediaListEntry { id } reviews { edges { node { id } } } } } } } }`;
externalLinks { url } rankings { id } mediaListEntry { id } reviews { edges { node { id } } } }
userId status score progress progressVolumes repeat priority private notes hiddenFromStatusLists
advancedScores startedAt { year month day } completedAt { year month day } updatedAt createdAt } } } }`;
return Fetch.send(query, start[0]);
}
};
15 changes: 11 additions & 4 deletions tests/listsTest.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
const anilist = require('../index');
const AniList = new anilist();

AniList.lists.anime('salixor')
.then(data => { console.log(data.filter(l => l.status === 'CURRENT')); });
AniList.lists.manga('salixor')
.then(data => { console.log(data.filter(l => l.status === 'CURRENT')); });
let animeLists = AniList.lists.anime('salixor');
let mangaLists = AniList.lists.manga('salixor');

// Read an anime list with specified status (here, COMPLETED)
animeLists.then(lists => console.log(lists.filter(list => list.status === 'COMPLETED')));

// Read a manga list with specified status (here, CURRENT)
mangaLists.then(lists => console.log(lists.filter(list => list.status === 'CURRENT')));

// Display a sample user list entry
animeLists.then(lists => console.log(lists.filter(list => list.status === 'COMPLETED')[0].entries.filter(e => e.media.id === 20912)));

0 comments on commit 0ebbd92

Please sign in to comment.