@irfanshadikrishad/anilist 1.0.0-forbidden.1 → 1.0.0-forbidden.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +115 -124
- package/LICENSE.md +382 -0
- package/README.md +255 -237
- package/bin/helpers/auth.d.ts +49 -9
- package/bin/helpers/auth.js +429 -287
- package/bin/helpers/fetcher.d.ts +3 -2
- package/bin/helpers/fetcher.js +29 -24
- package/bin/helpers/lists.d.ts +4 -1
- package/bin/helpers/lists.js +493 -384
- package/bin/helpers/queries.d.ts +7 -4
- package/bin/helpers/queries.js +23 -4
- package/bin/helpers/types.d.ts +340 -16
- package/bin/helpers/validation.d.ts +29 -0
- package/bin/helpers/validation.js +117 -0
- package/bin/helpers/workers.d.ts +21 -9
- package/bin/helpers/workers.js +213 -81
- package/bin/index.js +38 -10
- package/package.json +84 -73
- package/assets/binance.jpg +0 -0
package/bin/helpers/lists.js
CHANGED
|
@@ -8,24 +8,32 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
import { XMLParser } from "fast-xml-parser";
|
|
11
|
-
import { readFile
|
|
11
|
+
import { readFile } from "fs/promises";
|
|
12
12
|
import inquirer from "inquirer";
|
|
13
|
-
import
|
|
13
|
+
import { jsonrepair } from "jsonrepair";
|
|
14
14
|
import { join } from "path";
|
|
15
15
|
import { Auth } from "./auth.js";
|
|
16
16
|
import { fetcher } from "./fetcher.js";
|
|
17
17
|
import { addAnimeToListMutation, addMangaToListMutation, saveAnimeWithProgressMutation, saveMangaWithProgressMutation, } from "./mutations.js";
|
|
18
|
-
import { animeDetailsQuery, animeSearchQuery, currentUserAnimeList, currentUserMangaList, malIdToAnilistAnimeId, malIdToAnilistMangaId, mangaSearchQuery, popularQuery, trendingQuery, upcomingAnimesQuery, userActivityQuery, userQuery, } from "./queries.js";
|
|
18
|
+
import { animeDetailsQuery, animeSearchQuery, currentUserAnimeList, currentUserMangaList, malIdToAnilistAnimeId, malIdToAnilistMangaId, mangaSearchQuery, popularQuery, trendingQuery, upcomingAnimesQuery, userActivityQuery, userFollowersQuery, userFollowingQuery, userQuery, } from "./queries.js";
|
|
19
19
|
import { AniListMediaStatus, } from "./types.js";
|
|
20
|
-
import {
|
|
20
|
+
import { Validate } from "./validation.js";
|
|
21
|
+
import { anidbToanilistMapper, formatDateObject, getDownloadFolderPath, getNextSeasonAndYear, getTitle, removeHtmlAndMarkdown, saveJSONasCSV, saveJSONasJSON, saveJSONasXML, selectFile, timestampToTimeAgo, } from "./workers.js";
|
|
21
22
|
class AniList {
|
|
22
23
|
static importAnime() {
|
|
23
24
|
return __awaiter(this, void 0, void 0, function* () {
|
|
24
25
|
try {
|
|
25
26
|
const filename = yield selectFile(".json");
|
|
27
|
+
if (!filename) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
26
30
|
const filePath = join(getDownloadFolderPath(), filename);
|
|
27
31
|
const fileContent = yield readFile(filePath, "utf8");
|
|
28
32
|
const importedData = JSON.parse(fileContent);
|
|
33
|
+
if (!Validate.Import_JSON(importedData)) {
|
|
34
|
+
console.error(`\nInvalid JSON file.`);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
29
37
|
let count = 0;
|
|
30
38
|
const batchSize = 1; // Number of requests in each batch
|
|
31
39
|
const delay = 1100; // delay to avoid rate-limiting
|
|
@@ -45,7 +53,7 @@ class AniList {
|
|
|
45
53
|
if (save) {
|
|
46
54
|
const id = (_b = (_a = save === null || save === void 0 ? void 0 : save.data) === null || _a === void 0 ? void 0 : _a.SaveMediaListEntry) === null || _b === void 0 ? void 0 : _b.id;
|
|
47
55
|
count++;
|
|
48
|
-
console.log(`[${count}]
|
|
56
|
+
console.log(`[${count}]\t${id}\t${anime === null || anime === void 0 ? void 0 : anime.id} ✅`);
|
|
49
57
|
}
|
|
50
58
|
else {
|
|
51
59
|
console.error(`\nError saving ${anime === null || anime === void 0 ? void 0 : anime.id}`);
|
|
@@ -69,9 +77,16 @@ class AniList {
|
|
|
69
77
|
return __awaiter(this, void 0, void 0, function* () {
|
|
70
78
|
try {
|
|
71
79
|
const filename = yield selectFile(".json");
|
|
80
|
+
if (!filename) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
72
83
|
const filePath = join(getDownloadFolderPath(), filename);
|
|
73
84
|
const fileContent = yield readFile(filePath, "utf8");
|
|
74
85
|
const importedData = JSON.parse(fileContent);
|
|
86
|
+
if (!Validate.Import_JSON(importedData)) {
|
|
87
|
+
console.error(`\nInvalid JSON file.`);
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
75
90
|
let count = 0;
|
|
76
91
|
const batchSize = 1; // Adjust batch size as per rate-limit constraints
|
|
77
92
|
const delay = 1100; // 2 seconds delay to avoid rate-limit
|
|
@@ -93,7 +108,7 @@ class AniList {
|
|
|
93
108
|
if (save) {
|
|
94
109
|
const id = (_b = (_a = save === null || save === void 0 ? void 0 : save.data) === null || _a === void 0 ? void 0 : _a.SaveMediaListEntry) === null || _b === void 0 ? void 0 : _b.id;
|
|
95
110
|
count++;
|
|
96
|
-
console.log(`[${count}]
|
|
111
|
+
console.log(`[${count}]\t${id}\t${manga === null || manga === void 0 ? void 0 : manga.id} ✅`);
|
|
97
112
|
}
|
|
98
113
|
}
|
|
99
114
|
catch (err) {
|
|
@@ -113,7 +128,76 @@ class AniList {
|
|
|
113
128
|
static exportAnime() {
|
|
114
129
|
return __awaiter(this, void 0, void 0, function* () {
|
|
115
130
|
var _a, _b, _c;
|
|
116
|
-
if (yield Auth.isLoggedIn()) {
|
|
131
|
+
if (!(yield Auth.isLoggedIn())) {
|
|
132
|
+
console.error(`\nMust login to use this feature.`);
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
const { exportType } = yield inquirer.prompt([
|
|
136
|
+
{
|
|
137
|
+
type: "list",
|
|
138
|
+
name: "exportType",
|
|
139
|
+
message: "Choose export type:",
|
|
140
|
+
choices: [
|
|
141
|
+
{ name: "CSV", value: 1 },
|
|
142
|
+
{ name: "JSON", value: 2 },
|
|
143
|
+
{ name: "XML (MyAnimeList/AniDB)", value: 3 },
|
|
144
|
+
],
|
|
145
|
+
pageSize: 10,
|
|
146
|
+
},
|
|
147
|
+
]);
|
|
148
|
+
const animeList = yield fetcher(currentUserAnimeList, {
|
|
149
|
+
id: yield Auth.MyUserId(),
|
|
150
|
+
});
|
|
151
|
+
if (animeList) {
|
|
152
|
+
const lists = (_c = (_b = (_a = animeList === null || animeList === void 0 ? void 0 : animeList.data) === null || _a === void 0 ? void 0 : _a.MediaListCollection) === null || _b === void 0 ? void 0 : _b.lists) !== null && _c !== void 0 ? _c : [];
|
|
153
|
+
const mediaWithProgress = lists.flatMap((list) => list.entries.map((entry) => {
|
|
154
|
+
var _a, _b, _c, _d;
|
|
155
|
+
return ({
|
|
156
|
+
id: (_a = entry === null || entry === void 0 ? void 0 : entry.media) === null || _a === void 0 ? void 0 : _a.id,
|
|
157
|
+
title: (_b = entry === null || entry === void 0 ? void 0 : entry.media) === null || _b === void 0 ? void 0 : _b.title,
|
|
158
|
+
episodes: (_c = entry === null || entry === void 0 ? void 0 : entry.media) === null || _c === void 0 ? void 0 : _c.episodes,
|
|
159
|
+
siteUrl: (_d = entry === null || entry === void 0 ? void 0 : entry.media) === null || _d === void 0 ? void 0 : _d.siteUrl,
|
|
160
|
+
progress: entry.progress,
|
|
161
|
+
status: entry === null || entry === void 0 ? void 0 : entry.status,
|
|
162
|
+
hiddenFromStatusLists: entry.hiddenFromStatusLists,
|
|
163
|
+
});
|
|
164
|
+
}));
|
|
165
|
+
switch (exportType) {
|
|
166
|
+
case 1:
|
|
167
|
+
yield saveJSONasCSV(mediaWithProgress, "anime");
|
|
168
|
+
break;
|
|
169
|
+
case 2:
|
|
170
|
+
yield saveJSONasJSON(mediaWithProgress, "anime");
|
|
171
|
+
break;
|
|
172
|
+
case 3:
|
|
173
|
+
yield MyAnimeList.exportAnime();
|
|
174
|
+
break;
|
|
175
|
+
default:
|
|
176
|
+
console.log(`\nInvalid export type. ${exportType}`);
|
|
177
|
+
break;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
console.error(`\nNo anime(s) found in your lists.`);
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
static exportManga() {
|
|
186
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
187
|
+
var _a, _b;
|
|
188
|
+
if (!(yield Auth.isLoggedIn())) {
|
|
189
|
+
console.error(`\nPlease login to use this feature.`);
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
const mangaLists = yield fetcher(currentUserMangaList, {
|
|
193
|
+
id: yield Auth.MyUserId(),
|
|
194
|
+
});
|
|
195
|
+
if (!(mangaLists === null || mangaLists === void 0 ? void 0 : mangaLists.data)) {
|
|
196
|
+
console.error(`\nCould not get manga list.`);
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
const lists = ((_b = (_a = mangaLists === null || mangaLists === void 0 ? void 0 : mangaLists.data) === null || _a === void 0 ? void 0 : _a.MediaListCollection) === null || _b === void 0 ? void 0 : _b.lists) || [];
|
|
200
|
+
if (lists.length > 0) {
|
|
117
201
|
const { exportType } = yield inquirer.prompt([
|
|
118
202
|
{
|
|
119
203
|
type: "list",
|
|
@@ -127,141 +211,53 @@ class AniList {
|
|
|
127
211
|
pageSize: 10,
|
|
128
212
|
},
|
|
129
213
|
]);
|
|
130
|
-
const
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
break;
|
|
156
|
-
case 3:
|
|
157
|
-
yield MyAnimeList.exportAnime();
|
|
158
|
-
break;
|
|
159
|
-
default:
|
|
160
|
-
console.log(`\nInvalid export type. ${exportType}`);
|
|
161
|
-
break;
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
else {
|
|
165
|
-
console.error(`\nNo anime(s) found in your lists.`);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
else {
|
|
169
|
-
console.error(`\nMust login to use this feature.`);
|
|
170
|
-
}
|
|
171
|
-
});
|
|
172
|
-
}
|
|
173
|
-
static exportManga() {
|
|
174
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
175
|
-
var _a, _b;
|
|
176
|
-
if (yield Auth.isLoggedIn()) {
|
|
177
|
-
const mangaLists = yield fetcher(currentUserMangaList, {
|
|
178
|
-
id: yield Auth.MyUserId(),
|
|
179
|
-
});
|
|
180
|
-
if (mangaLists) {
|
|
181
|
-
const lists = ((_b = (_a = mangaLists === null || mangaLists === void 0 ? void 0 : mangaLists.data) === null || _a === void 0 ? void 0 : _a.MediaListCollection) === null || _b === void 0 ? void 0 : _b.lists) || [];
|
|
182
|
-
if (lists.length > 0) {
|
|
183
|
-
const { exportType } = yield inquirer.prompt([
|
|
184
|
-
{
|
|
185
|
-
type: "list",
|
|
186
|
-
name: "exportType",
|
|
187
|
-
message: "Choose export type:",
|
|
188
|
-
choices: [
|
|
189
|
-
{ name: "CSV", value: 1 },
|
|
190
|
-
{ name: "JSON", value: 2 },
|
|
191
|
-
{ name: "XML (MyAnimeList)", value: 3 },
|
|
192
|
-
],
|
|
193
|
-
pageSize: 10,
|
|
194
|
-
},
|
|
195
|
-
]);
|
|
196
|
-
const mediaWithProgress = lists.flatMap((list) => list.entries.map((entry) => {
|
|
197
|
-
var _a, _b, _c;
|
|
198
|
-
return ({
|
|
199
|
-
id: (_a = entry === null || entry === void 0 ? void 0 : entry.media) === null || _a === void 0 ? void 0 : _a.id,
|
|
200
|
-
title: exportType === 1
|
|
201
|
-
? getTitle((_b = entry === null || entry === void 0 ? void 0 : entry.media) === null || _b === void 0 ? void 0 : _b.title)
|
|
202
|
-
: (_c = entry === null || entry === void 0 ? void 0 : entry.media) === null || _c === void 0 ? void 0 : _c.title,
|
|
203
|
-
private: entry.private,
|
|
204
|
-
chapters: entry.media.chapters,
|
|
205
|
-
progress: entry.progress,
|
|
206
|
-
status: entry === null || entry === void 0 ? void 0 : entry.status,
|
|
207
|
-
hiddenFromStatusLists: entry.hiddenFromStatusLists,
|
|
208
|
-
});
|
|
209
|
-
}));
|
|
210
|
-
switch (exportType) {
|
|
211
|
-
case 1:
|
|
212
|
-
yield saveJSONasCSV(mediaWithProgress, "manga");
|
|
213
|
-
break;
|
|
214
|
-
case 2:
|
|
215
|
-
yield saveJSONasJSON(mediaWithProgress, "manga");
|
|
216
|
-
break;
|
|
217
|
-
case 3:
|
|
218
|
-
yield MyAnimeList.exportManga();
|
|
219
|
-
break;
|
|
220
|
-
default:
|
|
221
|
-
console.log(`\nInvalid export type. ${exportType}`);
|
|
222
|
-
break;
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
else {
|
|
226
|
-
console.log(`\nList seems to be empty.`);
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
else {
|
|
230
|
-
console.error(`\nCould not get manga list.`);
|
|
214
|
+
const mediaWithProgress = lists.flatMap((list) => list.entries.map((entry) => {
|
|
215
|
+
var _a, _b;
|
|
216
|
+
return ({
|
|
217
|
+
id: (_a = entry === null || entry === void 0 ? void 0 : entry.media) === null || _a === void 0 ? void 0 : _a.id,
|
|
218
|
+
title: (_b = entry === null || entry === void 0 ? void 0 : entry.media) === null || _b === void 0 ? void 0 : _b.title,
|
|
219
|
+
private: entry.private,
|
|
220
|
+
chapters: entry.media.chapters,
|
|
221
|
+
progress: entry.progress,
|
|
222
|
+
status: entry === null || entry === void 0 ? void 0 : entry.status,
|
|
223
|
+
hiddenFromStatusLists: entry.hiddenFromStatusLists,
|
|
224
|
+
});
|
|
225
|
+
}));
|
|
226
|
+
switch (exportType) {
|
|
227
|
+
case 1:
|
|
228
|
+
yield saveJSONasCSV(mediaWithProgress, "manga");
|
|
229
|
+
break;
|
|
230
|
+
case 2:
|
|
231
|
+
yield saveJSONasJSON(mediaWithProgress, "manga");
|
|
232
|
+
break;
|
|
233
|
+
case 3:
|
|
234
|
+
yield MyAnimeList.exportManga();
|
|
235
|
+
break;
|
|
236
|
+
default:
|
|
237
|
+
console.log(`\nInvalid export type. ${exportType}`);
|
|
238
|
+
break;
|
|
231
239
|
}
|
|
232
240
|
}
|
|
233
241
|
else {
|
|
234
|
-
console.
|
|
242
|
+
console.log(`\nList seems to be empty.`);
|
|
235
243
|
}
|
|
236
244
|
});
|
|
237
245
|
}
|
|
238
246
|
static MyAnime() {
|
|
239
247
|
return __awaiter(this, void 0, void 0, function* () {
|
|
240
|
-
var _a, _b, _c;
|
|
248
|
+
var _a, _b, _c, _d, _e;
|
|
241
249
|
try {
|
|
242
250
|
if (!(yield Auth.isLoggedIn())) {
|
|
243
251
|
return console.error(`\nPlease log in first to access your lists.`);
|
|
244
252
|
}
|
|
245
|
-
|
|
246
|
-
if (!userId) {
|
|
253
|
+
if (!(yield Auth.MyUserId())) {
|
|
247
254
|
return console.log(`\nFailed getting current user Id.`);
|
|
248
255
|
}
|
|
249
|
-
const
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
"content-type": "application/json",
|
|
253
|
-
"Authorization": `Bearer ${yield Auth.RetriveAccessToken()}`,
|
|
254
|
-
},
|
|
255
|
-
body: JSON.stringify({
|
|
256
|
-
query: currentUserAnimeList,
|
|
257
|
-
variables: { id: userId },
|
|
258
|
-
}),
|
|
259
|
-
});
|
|
260
|
-
const { data, errors } = yield request.json();
|
|
261
|
-
if (request.status !== 200 || errors) {
|
|
262
|
-
return console.log(`\nSomething went wrong. ${(_a = errors === null || errors === void 0 ? void 0 : errors[0]) === null || _a === void 0 ? void 0 : _a.message}`);
|
|
256
|
+
const data = yield fetcher(currentUserAnimeList, { id: yield Auth.MyUserId() });
|
|
257
|
+
if (data === null || data === void 0 ? void 0 : data.errors) {
|
|
258
|
+
return console.log(`\nSomething went wrong. ${(_b = (_a = data === null || data === void 0 ? void 0 : data.errors) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.message}`);
|
|
263
259
|
}
|
|
264
|
-
const lists = (
|
|
260
|
+
const lists = (_d = (_c = data === null || data === void 0 ? void 0 : data.data) === null || _c === void 0 ? void 0 : _c.MediaListCollection) === null || _d === void 0 ? void 0 : _d.lists;
|
|
265
261
|
if (!lists || lists.length === 0) {
|
|
266
262
|
return console.log(`\nYou seem to have no anime(s) in your lists.`);
|
|
267
263
|
}
|
|
@@ -304,11 +300,12 @@ class AniList {
|
|
|
304
300
|
],
|
|
305
301
|
},
|
|
306
302
|
]);
|
|
307
|
-
const
|
|
308
|
-
|
|
309
|
-
|
|
303
|
+
const saveResponse = yield fetcher(addAnimeToListMutation, {
|
|
304
|
+
mediaId: selectedAnime,
|
|
305
|
+
status: selectedListType,
|
|
306
|
+
});
|
|
310
307
|
if (saveResponse) {
|
|
311
|
-
const savedEntry = (
|
|
308
|
+
const savedEntry = (_e = saveResponse.data) === null || _e === void 0 ? void 0 : _e.SaveMediaListEntry;
|
|
312
309
|
console.log(`\nEntry ${savedEntry === null || savedEntry === void 0 ? void 0 : savedEntry.id}. Saved as ${savedEntry === null || savedEntry === void 0 ? void 0 : savedEntry.status}.`);
|
|
313
310
|
}
|
|
314
311
|
else {
|
|
@@ -322,7 +319,7 @@ class AniList {
|
|
|
322
319
|
}
|
|
323
320
|
static MyManga() {
|
|
324
321
|
return __awaiter(this, void 0, void 0, function* () {
|
|
325
|
-
var _a, _b, _c, _d, _e;
|
|
322
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
326
323
|
try {
|
|
327
324
|
if (!(yield Auth.isLoggedIn())) {
|
|
328
325
|
return console.error(`\nPlease log in first to access your lists.`);
|
|
@@ -331,23 +328,11 @@ class AniList {
|
|
|
331
328
|
if (!userId) {
|
|
332
329
|
return console.error(`\nFailed to get the current user ID.`);
|
|
333
330
|
}
|
|
334
|
-
const
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
headers: {
|
|
338
|
-
"Content-Type": "application/json",
|
|
339
|
-
"Authorization": `Bearer ${token}`,
|
|
340
|
-
},
|
|
341
|
-
body: JSON.stringify({
|
|
342
|
-
query: currentUserMangaList,
|
|
343
|
-
variables: { id: userId },
|
|
344
|
-
}),
|
|
345
|
-
});
|
|
346
|
-
const { data, errors } = yield request.json();
|
|
347
|
-
if (request.status !== 200 || errors) {
|
|
348
|
-
return console.error(`\nFailed to fetch manga lists. ${((_a = errors === null || errors === void 0 ? void 0 : errors[0]) === null || _a === void 0 ? void 0 : _a.message) || "Unknown error"}`);
|
|
331
|
+
const response = yield fetcher(currentUserMangaList, { id: userId });
|
|
332
|
+
if (!(response === null || response === void 0 ? void 0 : response.data)) {
|
|
333
|
+
return console.error(`\nFailed to fetch manga lists. ${((_b = (_a = response === null || response === void 0 ? void 0 : response.errors) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.message) || "Unknown error"}`);
|
|
349
334
|
}
|
|
350
|
-
const lists = (
|
|
335
|
+
const lists = (_d = (_c = response === null || response === void 0 ? void 0 : response.data) === null || _c === void 0 ? void 0 : _c.MediaListCollection) === null || _d === void 0 ? void 0 : _d.lists;
|
|
351
336
|
if (!lists || lists.length === 0) {
|
|
352
337
|
return console.log("\nYou don't seem to have any manga in your lists.");
|
|
353
338
|
}
|
|
@@ -393,24 +378,16 @@ class AniList {
|
|
|
393
378
|
],
|
|
394
379
|
},
|
|
395
380
|
]);
|
|
396
|
-
const
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
"Content-Type": "application/json",
|
|
400
|
-
"Authorization": `Bearer ${token}`,
|
|
401
|
-
},
|
|
402
|
-
body: JSON.stringify({
|
|
403
|
-
query: addMangaToListMutation,
|
|
404
|
-
variables: { mediaId: selectedManga, status: selectedListType },
|
|
405
|
-
}),
|
|
381
|
+
const saveResponse = yield fetcher(addMangaToListMutation, {
|
|
382
|
+
mediaId: selectedManga,
|
|
383
|
+
status: selectedListType,
|
|
406
384
|
});
|
|
407
|
-
const
|
|
408
|
-
const saved = (_c = saveResponse === null || saveResponse === void 0 ? void 0 : saveResponse.data) === null || _c === void 0 ? void 0 : _c.SaveMediaListEntry;
|
|
385
|
+
const saved = (_e = saveResponse === null || saveResponse === void 0 ? void 0 : saveResponse.data) === null || _e === void 0 ? void 0 : _e.SaveMediaListEntry;
|
|
409
386
|
if (saved) {
|
|
410
387
|
console.log(`\nEntry ${saved.id}. Saved as ${saved.status}.`);
|
|
411
388
|
}
|
|
412
389
|
else {
|
|
413
|
-
console.error(`\nFailed to save the manga. ${((
|
|
390
|
+
console.error(`\nFailed to save the manga. ${((_g = (_f = saveResponse === null || saveResponse === void 0 ? void 0 : saveResponse.errors) === null || _f === void 0 ? void 0 : _f[0]) === null || _g === void 0 ? void 0 : _g.message) || "Unknown error"}`);
|
|
414
391
|
}
|
|
415
392
|
}
|
|
416
393
|
catch (error) {
|
|
@@ -420,63 +397,70 @@ class AniList {
|
|
|
420
397
|
}
|
|
421
398
|
static getTrendingAnime(count) {
|
|
422
399
|
return __awaiter(this, void 0, void 0, function* () {
|
|
423
|
-
var _a, _b, _c, _d, _e;
|
|
400
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
424
401
|
try {
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
{
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
402
|
+
let page = 1;
|
|
403
|
+
let allTrending = [];
|
|
404
|
+
while (true) {
|
|
405
|
+
const response = yield fetcher(trendingQuery, { page, perPage: count });
|
|
406
|
+
if (response === null || response === void 0 ? void 0 : response.errors) {
|
|
407
|
+
console.error(`\nSomething went wrong. ${((_b = (_a = response === null || response === void 0 ? void 0 : response.errors) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.message) || "Unknown error"}`);
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
410
|
+
const media = (_d = (_c = response === null || response === void 0 ? void 0 : response.data) === null || _c === void 0 ? void 0 : _c.Page) === null || _d === void 0 ? void 0 : _d.media;
|
|
411
|
+
if (!media || media.length === 0) {
|
|
412
|
+
console.log(`\nNo more trending anime available.`);
|
|
413
|
+
break;
|
|
414
|
+
}
|
|
415
|
+
allTrending = [...allTrending, ...media];
|
|
416
|
+
const choices = allTrending.map((anime, idx) => ({
|
|
417
|
+
name: `[${idx + 1}] ${getTitle(anime === null || anime === void 0 ? void 0 : anime.title)}`,
|
|
418
|
+
value: String(anime === null || anime === void 0 ? void 0 : anime.id),
|
|
419
|
+
}));
|
|
420
|
+
choices.push({ name: "See more", value: "see_more" });
|
|
421
|
+
const { selectedAnime } = yield inquirer.prompt([
|
|
422
|
+
{
|
|
423
|
+
type: "list",
|
|
424
|
+
name: "selectedAnime",
|
|
425
|
+
message: "Select anime to add to the list:",
|
|
426
|
+
choices,
|
|
427
|
+
pageSize: choices.length + 1,
|
|
428
|
+
},
|
|
429
|
+
]);
|
|
430
|
+
if (selectedAnime === "see_more") {
|
|
431
|
+
page++;
|
|
432
|
+
continue;
|
|
433
|
+
}
|
|
434
|
+
else {
|
|
435
|
+
const { selectedListType } = yield inquirer.prompt([
|
|
436
|
+
{
|
|
437
|
+
type: "list",
|
|
438
|
+
name: "selectedListType",
|
|
439
|
+
message: "Select the list where you want to save this anime:",
|
|
440
|
+
choices: [
|
|
441
|
+
{ name: "Planning", value: "PLANNING" },
|
|
442
|
+
{ name: "Watching", value: "CURRENT" },
|
|
443
|
+
{ name: "Completed", value: "COMPLETED" },
|
|
444
|
+
{ name: "Paused", value: "PAUSED" },
|
|
445
|
+
{ name: "Dropped", value: "DROPPED" },
|
|
446
|
+
],
|
|
447
|
+
},
|
|
448
|
+
]);
|
|
449
|
+
if (!(yield Auth.isLoggedIn())) {
|
|
450
|
+
console.error(`\nPlease log in first to use this feature.`);
|
|
451
|
+
return;
|
|
452
|
+
}
|
|
453
|
+
const variables = { mediaId: selectedAnime, status: selectedListType };
|
|
454
|
+
const saveResponse = yield fetcher(addAnimeToListMutation, variables);
|
|
455
|
+
const saved = (_e = saveResponse === null || saveResponse === void 0 ? void 0 : saveResponse.data) === null || _e === void 0 ? void 0 : _e.SaveMediaListEntry;
|
|
456
|
+
if (saved) {
|
|
457
|
+
console.log(`\nEntry ${saved.id}. Saved as ${saved.status}.`);
|
|
458
|
+
}
|
|
459
|
+
else {
|
|
460
|
+
console.error(`\nFailed to save the anime. ${((_g = (_f = saveResponse === null || saveResponse === void 0 ? void 0 : saveResponse.errors) === null || _f === void 0 ? void 0 : _f[0]) === null || _g === void 0 ? void 0 : _g.message) || "Unknown error"}`);
|
|
461
|
+
}
|
|
462
|
+
break;
|
|
463
|
+
}
|
|
480
464
|
}
|
|
481
465
|
}
|
|
482
466
|
catch (error) {
|
|
@@ -486,63 +470,69 @@ class AniList {
|
|
|
486
470
|
}
|
|
487
471
|
static getPopularAnime(count) {
|
|
488
472
|
return __awaiter(this, void 0, void 0, function* () {
|
|
489
|
-
var _a, _b, _c, _d, _e;
|
|
473
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
490
474
|
try {
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
{
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
475
|
+
let page = 1;
|
|
476
|
+
let allMedia = [];
|
|
477
|
+
while (true) {
|
|
478
|
+
const response = yield fetcher(popularQuery, { page, perPage: count });
|
|
479
|
+
if (!(response === null || response === void 0 ? void 0 : response.data)) {
|
|
480
|
+
console.error(`\nSomething went wrong. ${((_b = (_a = response === null || response === void 0 ? void 0 : response.errors) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.message) || "Unknown error"}`);
|
|
481
|
+
return;
|
|
482
|
+
}
|
|
483
|
+
const newMedia = (_d = (_c = response === null || response === void 0 ? void 0 : response.data) === null || _c === void 0 ? void 0 : _c.Page) === null || _d === void 0 ? void 0 : _d.media;
|
|
484
|
+
if (!newMedia || newMedia.length === 0) {
|
|
485
|
+
console.log(`\nNo more popular anime available.`);
|
|
486
|
+
break;
|
|
487
|
+
}
|
|
488
|
+
allMedia = [...allMedia, ...newMedia];
|
|
489
|
+
const choices = allMedia.map((anime, idx) => ({
|
|
490
|
+
name: `[${idx + 1}] ${getTitle(anime === null || anime === void 0 ? void 0 : anime.title)}`,
|
|
491
|
+
value: String(anime === null || anime === void 0 ? void 0 : anime.id),
|
|
492
|
+
}));
|
|
493
|
+
choices.push({ name: "See more", value: "see_more" });
|
|
494
|
+
const { selectedAnime } = yield inquirer.prompt([
|
|
495
|
+
{
|
|
496
|
+
type: "list",
|
|
497
|
+
name: "selectedAnime",
|
|
498
|
+
message: "Select anime to add to the list:",
|
|
499
|
+
choices,
|
|
500
|
+
pageSize: choices.length,
|
|
501
|
+
},
|
|
502
|
+
]);
|
|
503
|
+
if (selectedAnime === "see_more") {
|
|
504
|
+
page++;
|
|
505
|
+
continue;
|
|
506
|
+
}
|
|
507
|
+
else {
|
|
508
|
+
const { selectedListType } = yield inquirer.prompt([
|
|
509
|
+
{
|
|
510
|
+
type: "list",
|
|
511
|
+
name: "selectedListType",
|
|
512
|
+
message: "Select the list where you want to save this anime:",
|
|
513
|
+
choices: [
|
|
514
|
+
{ name: "Planning", value: "PLANNING" },
|
|
515
|
+
{ name: "Watching", value: "CURRENT" },
|
|
516
|
+
{ name: "Completed", value: "COMPLETED" },
|
|
517
|
+
{ name: "Paused", value: "PAUSED" },
|
|
518
|
+
{ name: "Dropped", value: "DROPPED" },
|
|
519
|
+
],
|
|
520
|
+
},
|
|
521
|
+
]);
|
|
522
|
+
if (!(yield Auth.isLoggedIn())) {
|
|
523
|
+
return console.error(`\nPlease log in first to use this feature.`);
|
|
524
|
+
}
|
|
525
|
+
const variables = { mediaId: selectedAnime, status: selectedListType };
|
|
526
|
+
const saveResponse = yield fetcher(addAnimeToListMutation, variables);
|
|
527
|
+
const saved = (_e = saveResponse === null || saveResponse === void 0 ? void 0 : saveResponse.data) === null || _e === void 0 ? void 0 : _e.SaveMediaListEntry;
|
|
528
|
+
if (saved) {
|
|
529
|
+
console.log(`\nEntry ${saved.id}. Saved as ${saved.status}.`);
|
|
530
|
+
}
|
|
531
|
+
else {
|
|
532
|
+
console.error(`\nFailed to save the anime. ${((_g = (_f = saveResponse === null || saveResponse === void 0 ? void 0 : saveResponse.errors) === null || _f === void 0 ? void 0 : _f[0]) === null || _g === void 0 ? void 0 : _g.message) || "Unknown error"}`);
|
|
533
|
+
}
|
|
534
|
+
break;
|
|
535
|
+
}
|
|
546
536
|
}
|
|
547
537
|
}
|
|
548
538
|
catch (error) {
|
|
@@ -555,55 +545,72 @@ class AniList {
|
|
|
555
545
|
var _a, _b, _c, _d, _e, _f;
|
|
556
546
|
try {
|
|
557
547
|
const { nextSeason, nextYear } = getNextSeasonAndYear();
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
})
|
|
579
|
-
|
|
580
|
-
}
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
}
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
548
|
+
let page = 1;
|
|
549
|
+
let allUpcoming = [];
|
|
550
|
+
while (true) {
|
|
551
|
+
const request = yield fetcher(upcomingAnimesQuery, {
|
|
552
|
+
nextSeason,
|
|
553
|
+
nextYear,
|
|
554
|
+
page,
|
|
555
|
+
perPage: count,
|
|
556
|
+
});
|
|
557
|
+
if (!request || !request.data) {
|
|
558
|
+
console.error(`\nSomething went wrong. ${((_b = (_a = request === null || request === void 0 ? void 0 : request.errors) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.message) || "Unknown error"}`);
|
|
559
|
+
return;
|
|
560
|
+
}
|
|
561
|
+
const newUpcoming = (_c = request.data.Page.media) !== null && _c !== void 0 ? _c : [];
|
|
562
|
+
if (newUpcoming.length === 0) {
|
|
563
|
+
console.log(`\nNo more upcoming anime available.`);
|
|
564
|
+
break;
|
|
565
|
+
}
|
|
566
|
+
allUpcoming = [...allUpcoming, ...newUpcoming];
|
|
567
|
+
const choices = allUpcoming.map((anime, idx) => ({
|
|
568
|
+
name: `[${idx + 1}] ${getTitle(anime === null || anime === void 0 ? void 0 : anime.title)}`,
|
|
569
|
+
value: String(anime === null || anime === void 0 ? void 0 : anime.id),
|
|
570
|
+
}));
|
|
571
|
+
choices.push({ name: "See more", value: "see_more" });
|
|
572
|
+
const { selectedAnime } = yield inquirer.prompt([
|
|
573
|
+
{
|
|
574
|
+
type: "list",
|
|
575
|
+
name: "selectedAnime",
|
|
576
|
+
message: "Select anime to add to the list:",
|
|
577
|
+
choices,
|
|
578
|
+
pageSize: choices.length + 2,
|
|
579
|
+
},
|
|
580
|
+
]);
|
|
581
|
+
if (selectedAnime === "see_more") {
|
|
582
|
+
page++;
|
|
583
|
+
continue;
|
|
584
|
+
}
|
|
585
|
+
else {
|
|
586
|
+
const { selectedListType } = yield inquirer.prompt([
|
|
587
|
+
{
|
|
588
|
+
type: "list",
|
|
589
|
+
name: "selectedListType",
|
|
590
|
+
message: "Select the list where you want to save this anime:",
|
|
591
|
+
choices: [
|
|
592
|
+
{ name: "Planning", value: "PLANNING" },
|
|
593
|
+
{ name: "Watching", value: "CURRENT" },
|
|
594
|
+
{ name: "Completed", value: "COMPLETED" },
|
|
595
|
+
{ name: "Paused", value: "PAUSED" },
|
|
596
|
+
{ name: "Dropped", value: "DROPPED" },
|
|
597
|
+
],
|
|
598
|
+
},
|
|
599
|
+
]);
|
|
600
|
+
if (!(yield Auth.isLoggedIn())) {
|
|
601
|
+
return console.error(`\nPlease log in first to use this feature.`);
|
|
602
|
+
}
|
|
603
|
+
const variables = { mediaId: selectedAnime, status: selectedListType };
|
|
604
|
+
const saveResponse = yield fetcher(addAnimeToListMutation, variables);
|
|
605
|
+
const saved = (_d = saveResponse === null || saveResponse === void 0 ? void 0 : saveResponse.data) === null || _d === void 0 ? void 0 : _d.SaveMediaListEntry;
|
|
606
|
+
if (saved) {
|
|
607
|
+
console.log(`\nEntry ${saved.id}. Saved as ${saved.status}.`);
|
|
608
|
+
}
|
|
609
|
+
else {
|
|
610
|
+
console.error(`\nFailed to save the anime. ${((_f = (_e = saveResponse === null || saveResponse === void 0 ? void 0 : saveResponse.errors) === null || _e === void 0 ? void 0 : _e[0]) === null || _f === void 0 ? void 0 : _f.message) || "Unknown error"}`);
|
|
611
|
+
}
|
|
612
|
+
break;
|
|
613
|
+
}
|
|
607
614
|
}
|
|
608
615
|
}
|
|
609
616
|
catch (error) {
|
|
@@ -613,22 +620,11 @@ class AniList {
|
|
|
613
620
|
}
|
|
614
621
|
static getUserByUsername(username) {
|
|
615
622
|
return __awaiter(this, void 0, void 0, function* () {
|
|
616
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v;
|
|
623
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2;
|
|
617
624
|
try {
|
|
618
|
-
const
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
if (yield Auth.isLoggedIn()) {
|
|
622
|
-
headers["Authorization"] = `Bearer ${yield Auth.RetriveAccessToken()}`;
|
|
623
|
-
}
|
|
624
|
-
const request = yield fetch(aniListEndpoint, {
|
|
625
|
-
method: "POST",
|
|
626
|
-
headers,
|
|
627
|
-
body: JSON.stringify({ query: userQuery, variables: { username } }),
|
|
628
|
-
});
|
|
629
|
-
const response = yield request.json();
|
|
630
|
-
if (request.status !== 200 || !((_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.User)) {
|
|
631
|
-
return console.error(`\n${request.status} ${((_c = (_b = response === null || response === void 0 ? void 0 : response.errors) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.message) || "Unknown error"}`);
|
|
625
|
+
const response = yield fetcher(userQuery, { username });
|
|
626
|
+
if (!((_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.User)) {
|
|
627
|
+
return console.error(`\n${((_c = (_b = response === null || response === void 0 ? void 0 : response.errors) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.message) || "Unknown error"}`);
|
|
632
628
|
}
|
|
633
629
|
const user = response.data.User;
|
|
634
630
|
const userActivityResponse = yield fetcher(userActivityQuery, {
|
|
@@ -637,6 +633,15 @@ class AniList {
|
|
|
637
633
|
perPage: 10,
|
|
638
634
|
});
|
|
639
635
|
const activities = (_f = (_e = (_d = userActivityResponse === null || userActivityResponse === void 0 ? void 0 : userActivityResponse.data) === null || _d === void 0 ? void 0 : _d.Page) === null || _e === void 0 ? void 0 : _e.activities) !== null && _f !== void 0 ? _f : [];
|
|
636
|
+
// Get follower/following information
|
|
637
|
+
const req_followers = yield fetcher(userFollowersQuery, {
|
|
638
|
+
userId: user === null || user === void 0 ? void 0 : user.id,
|
|
639
|
+
});
|
|
640
|
+
const req_following = yield fetcher(userFollowingQuery, {
|
|
641
|
+
userId: user === null || user === void 0 ? void 0 : user.id,
|
|
642
|
+
});
|
|
643
|
+
const followersCount = ((_j = (_h = (_g = req_followers === null || req_followers === void 0 ? void 0 : req_followers.data) === null || _g === void 0 ? void 0 : _g.Page) === null || _h === void 0 ? void 0 : _h.pageInfo) === null || _j === void 0 ? void 0 : _j.total) || 0;
|
|
644
|
+
const followingCount = ((_m = (_l = (_k = req_following === null || req_following === void 0 ? void 0 : req_following.data) === null || _k === void 0 ? void 0 : _k.Page) === null || _l === void 0 ? void 0 : _l.pageInfo) === null || _m === void 0 ? void 0 : _m.total) || 0;
|
|
640
645
|
console.log(`\nID:\t\t${user.id}`);
|
|
641
646
|
console.log(`Name:\t\t${user.name}`);
|
|
642
647
|
console.log(`Site URL:\t${user.siteUrl}`);
|
|
@@ -647,14 +652,16 @@ class AniList {
|
|
|
647
652
|
console.log(`Blocked:\t${user.isBlocked}`);
|
|
648
653
|
console.log(`Follower:\t${user.isFollower}`);
|
|
649
654
|
console.log(`Following:\t${user.isFollowing}`);
|
|
650
|
-
console.log(`Profile Color:\t${(
|
|
651
|
-
console.log(`Timezone:\t${(
|
|
652
|
-
console.log(`\
|
|
653
|
-
console.log(`
|
|
655
|
+
console.log(`Profile Color:\t${(_o = user.options) === null || _o === void 0 ? void 0 : _o.profileColor}`);
|
|
656
|
+
console.log(`Timezone:\t${((_p = user.options) === null || _p === void 0 ? void 0 : _p.timezone) ? (_q = user.options) === null || _q === void 0 ? void 0 : _q.timezone : "N/A"}`);
|
|
657
|
+
console.log(`\nFollowers:\t${followersCount}`);
|
|
658
|
+
console.log(`Following:\t${followingCount}`);
|
|
659
|
+
console.log(`\nStatistics (Anime)\n\tCount: ${((_s = (_r = user.statistics) === null || _r === void 0 ? void 0 : _r.anime) === null || _s === void 0 ? void 0 : _s.count) || 0}\tEpisodes Watched: ${((_u = (_t = user.statistics) === null || _t === void 0 ? void 0 : _t.anime) === null || _u === void 0 ? void 0 : _u.episodesWatched) || 0}\tMinutes Watched: ${((_w = (_v = user.statistics) === null || _v === void 0 ? void 0 : _v.anime) === null || _w === void 0 ? void 0 : _w.minutesWatched) || 0}`);
|
|
660
|
+
console.log(`Statistics (Manga)\n\tCount: ${((_y = (_x = user.statistics) === null || _x === void 0 ? void 0 : _x.manga) === null || _y === void 0 ? void 0 : _y.count) || 0}\tChapters Read: ${((_0 = (_z = user.statistics) === null || _z === void 0 ? void 0 : _z.manga) === null || _0 === void 0 ? void 0 : _0.chaptersRead) || 0}\tVolumes Read: ${((_2 = (_1 = user.statistics) === null || _1 === void 0 ? void 0 : _1.manga) === null || _2 === void 0 ? void 0 : _2.volumesRead) || 0}`);
|
|
654
661
|
if (activities.length > 0) {
|
|
655
662
|
console.log(`\nRecent Activities:`);
|
|
656
|
-
activities.forEach(({ status, progress, media }) => {
|
|
657
|
-
console.log(`${status} ${progress ? `${progress} of ` : ""}${getTitle(media === null || media === void 0 ? void 0 : media.title)}`);
|
|
663
|
+
activities.forEach(({ status, progress, media, createdAt }) => {
|
|
664
|
+
console.log(`${timestampToTimeAgo(createdAt)}\t${status} ${progress ? `${progress} of ` : ""}${getTitle(media === null || media === void 0 ? void 0 : media.title)}`);
|
|
658
665
|
});
|
|
659
666
|
}
|
|
660
667
|
else {
|
|
@@ -669,9 +676,9 @@ class AniList {
|
|
|
669
676
|
static getAnimeDetailsByID(anilistID) {
|
|
670
677
|
return __awaiter(this, void 0, void 0, function* () {
|
|
671
678
|
var _a;
|
|
672
|
-
const
|
|
673
|
-
|
|
674
|
-
|
|
679
|
+
const details = yield fetcher(animeDetailsQuery, {
|
|
680
|
+
id: anilistID,
|
|
681
|
+
});
|
|
675
682
|
if ((_a = details === null || details === void 0 ? void 0 : details.data) === null || _a === void 0 ? void 0 : _a.Media) {
|
|
676
683
|
const { id, title, description, duration, startDate, endDate, countryOfOrigin, isAdult, status, season, format, genres, siteUrl, } = details.data.Media;
|
|
677
684
|
console.log(`\nID: ${id}`);
|
|
@@ -693,9 +700,11 @@ class AniList {
|
|
|
693
700
|
static searchAnime(search, count) {
|
|
694
701
|
return __awaiter(this, void 0, void 0, function* () {
|
|
695
702
|
var _a, _b, _c;
|
|
696
|
-
const
|
|
697
|
-
|
|
698
|
-
|
|
703
|
+
const searchResults = yield fetcher(animeSearchQuery, {
|
|
704
|
+
search,
|
|
705
|
+
page: 1,
|
|
706
|
+
perPage: count,
|
|
707
|
+
});
|
|
699
708
|
if (searchResults) {
|
|
700
709
|
const results = (_b = (_a = searchResults === null || searchResults === void 0 ? void 0 : searchResults.data) === null || _a === void 0 ? void 0 : _a.Page) === null || _b === void 0 ? void 0 : _b.media;
|
|
701
710
|
if (results.length > 0) {
|
|
@@ -727,12 +736,10 @@ class AniList {
|
|
|
727
736
|
]);
|
|
728
737
|
// Save selected anime to chosen list type
|
|
729
738
|
if (yield Auth.isLoggedIn()) {
|
|
730
|
-
const
|
|
731
|
-
const saveVariables = {
|
|
739
|
+
const response = yield fetcher(addAnimeToListMutation, {
|
|
732
740
|
mediaId: selectedAnime,
|
|
733
741
|
status: selectedListType,
|
|
734
|
-
};
|
|
735
|
-
const response = yield fetcher(saveQuery, saveVariables);
|
|
742
|
+
});
|
|
736
743
|
if (response) {
|
|
737
744
|
const saved = (_c = response === null || response === void 0 ? void 0 : response.data) === null || _c === void 0 ? void 0 : _c.SaveMediaListEntry;
|
|
738
745
|
console.log(`\nEntry ${saved === null || saved === void 0 ? void 0 : saved.id}. Saved as ${saved === null || saved === void 0 ? void 0 : saved.status}.`);
|
|
@@ -754,9 +761,11 @@ class AniList {
|
|
|
754
761
|
static searchManga(search, count) {
|
|
755
762
|
return __awaiter(this, void 0, void 0, function* () {
|
|
756
763
|
var _a, _b, _c;
|
|
757
|
-
const
|
|
758
|
-
|
|
759
|
-
|
|
764
|
+
const mangaSearchResult = yield fetcher(mangaSearchQuery, {
|
|
765
|
+
search,
|
|
766
|
+
page: 1,
|
|
767
|
+
perPage: count,
|
|
768
|
+
});
|
|
760
769
|
if (mangaSearchResult) {
|
|
761
770
|
const results = (_b = (_a = mangaSearchResult === null || mangaSearchResult === void 0 ? void 0 : mangaSearchResult.data) === null || _a === void 0 ? void 0 : _a.Page) === null || _b === void 0 ? void 0 : _b.media;
|
|
762
771
|
// List of manga search results
|
|
@@ -789,9 +798,10 @@ class AniList {
|
|
|
789
798
|
]);
|
|
790
799
|
// If logged in save to the list
|
|
791
800
|
if (yield Auth.isLoggedIn()) {
|
|
792
|
-
const
|
|
793
|
-
|
|
794
|
-
|
|
801
|
+
const response = yield fetcher(addMangaToListMutation, {
|
|
802
|
+
mediaId: selectedMangaId,
|
|
803
|
+
status: selectedListType,
|
|
804
|
+
});
|
|
795
805
|
if (response) {
|
|
796
806
|
const saved = (_c = response === null || response === void 0 ? void 0 : response.data) === null || _c === void 0 ? void 0 : _c.SaveMediaListEntry;
|
|
797
807
|
console.log(`\nEntry ${saved === null || saved === void 0 ? void 0 : saved.id}. Saved as ${saved === null || saved === void 0 ? void 0 : saved.status}.`);
|
|
@@ -813,8 +823,15 @@ class MyAnimeList {
|
|
|
813
823
|
var _a, _b, _c, _d, _e;
|
|
814
824
|
try {
|
|
815
825
|
const filename = yield selectFile(".xml");
|
|
826
|
+
if (!filename) {
|
|
827
|
+
return;
|
|
828
|
+
}
|
|
816
829
|
const filePath = join(getDownloadFolderPath(), filename);
|
|
817
830
|
const fileContent = yield readFile(filePath, "utf8");
|
|
831
|
+
if (!(yield Validate.Import_AnimeXML(fileContent))) {
|
|
832
|
+
console.error(`\nInvalid XML file.`);
|
|
833
|
+
return;
|
|
834
|
+
}
|
|
818
835
|
const parser = new XMLParser();
|
|
819
836
|
if (fileContent) {
|
|
820
837
|
const XMLObject = parser.parse(fileContent);
|
|
@@ -878,8 +895,15 @@ class MyAnimeList {
|
|
|
878
895
|
var _a, _b, _c, _d, _e;
|
|
879
896
|
try {
|
|
880
897
|
const filename = yield selectFile(".xml");
|
|
898
|
+
if (!filename) {
|
|
899
|
+
return;
|
|
900
|
+
}
|
|
881
901
|
const filePath = join(getDownloadFolderPath(), filename);
|
|
882
902
|
const fileContent = yield readFile(filePath, "utf8");
|
|
903
|
+
if (!(yield Validate.Import_MangaXML(fileContent))) {
|
|
904
|
+
console.error(`\nInvalid XML file.`);
|
|
905
|
+
return;
|
|
906
|
+
}
|
|
883
907
|
const parser = new XMLParser();
|
|
884
908
|
if (fileContent) {
|
|
885
909
|
const XMLObject = parser.parse(fileContent);
|
|
@@ -950,7 +974,7 @@ class MyAnimeList {
|
|
|
950
974
|
if (((_b = (_a = animeList === null || animeList === void 0 ? void 0 : animeList.data) === null || _a === void 0 ? void 0 : _a.MediaListCollection) === null || _b === void 0 ? void 0 : _b.lists.length) > 0) {
|
|
951
975
|
const lists = (_d = (_c = animeList === null || animeList === void 0 ? void 0 : animeList.data) === null || _c === void 0 ? void 0 : _c.MediaListCollection) === null || _d === void 0 ? void 0 : _d.lists;
|
|
952
976
|
const mediaWithProgress = lists.flatMap((list) => list.entries.map((entry) => {
|
|
953
|
-
var _a, _b, _c, _d, _e;
|
|
977
|
+
var _a, _b, _c, _d, _e, _f;
|
|
954
978
|
return ({
|
|
955
979
|
id: (_a = entry === null || entry === void 0 ? void 0 : entry.media) === null || _a === void 0 ? void 0 : _a.id,
|
|
956
980
|
malId: (_b = entry === null || entry === void 0 ? void 0 : entry.media) === null || _b === void 0 ? void 0 : _b.idMal,
|
|
@@ -960,13 +984,10 @@ class MyAnimeList {
|
|
|
960
984
|
progress: entry.progress,
|
|
961
985
|
status: entry === null || entry === void 0 ? void 0 : entry.status,
|
|
962
986
|
hiddenFromStatusLists: false,
|
|
987
|
+
format: (_f = entry === null || entry === void 0 ? void 0 : entry.media) === null || _f === void 0 ? void 0 : _f.format,
|
|
963
988
|
});
|
|
964
989
|
}));
|
|
965
|
-
|
|
966
|
-
const path = join(getDownloadFolderPath(), `${yield Auth.MyUserName()}@irfanshadikrishad-anilist-myanimelist(anime)-${getFormattedDate()}.xml`);
|
|
967
|
-
yield writeFile(path, yield xmlContent, "utf8");
|
|
968
|
-
console.log(`Generated XML for MyAnimeList.`);
|
|
969
|
-
open(getDownloadFolderPath());
|
|
990
|
+
yield saveJSONasXML(mediaWithProgress, 0);
|
|
970
991
|
}
|
|
971
992
|
else {
|
|
972
993
|
console.log(`\nHey, ${yield Auth.MyUserName()}. Your anime list seems to be empty.`);
|
|
@@ -991,24 +1012,17 @@ class MyAnimeList {
|
|
|
991
1012
|
});
|
|
992
1013
|
if (mangaList && ((_b = (_a = mangaList === null || mangaList === void 0 ? void 0 : mangaList.data) === null || _a === void 0 ? void 0 : _a.MediaListCollection) === null || _b === void 0 ? void 0 : _b.lists.length) > 0) {
|
|
993
1014
|
const lists = (_d = (_c = mangaList === null || mangaList === void 0 ? void 0 : mangaList.data) === null || _c === void 0 ? void 0 : _c.MediaListCollection) === null || _d === void 0 ? void 0 : _d.lists;
|
|
994
|
-
const mediaWithProgress = lists.flatMap((list) => list.entries.map((entry) => {
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
});
|
|
1006
|
-
}));
|
|
1007
|
-
const XMLContent = createMangaListXML(mediaWithProgress);
|
|
1008
|
-
const path = join(getDownloadFolderPath(), `${yield Auth.MyUserName()}@irfanshadikrishad-anilist-myanimelist(manga)-${getFormattedDate()}.xml`);
|
|
1009
|
-
yield writeFile(path, yield XMLContent, "utf8");
|
|
1010
|
-
console.log(`Generated XML for MyAnimeList.`);
|
|
1011
|
-
open(getDownloadFolderPath());
|
|
1015
|
+
const mediaWithProgress = lists.flatMap((list) => list.entries.map((entry) => ({
|
|
1016
|
+
id: entry.media.id,
|
|
1017
|
+
malId: entry.media.idMal,
|
|
1018
|
+
title: entry.media.title,
|
|
1019
|
+
private: entry.private,
|
|
1020
|
+
chapters: entry.media.chapters,
|
|
1021
|
+
progress: entry.progress,
|
|
1022
|
+
status: entry.status,
|
|
1023
|
+
hiddenFromStatusLists: entry.hiddenFromStatusLists,
|
|
1024
|
+
})));
|
|
1025
|
+
yield saveJSONasXML(mediaWithProgress, 1);
|
|
1012
1026
|
}
|
|
1013
1027
|
else {
|
|
1014
1028
|
console.log(`\nHey, ${yield Auth.MyUserName()}. Your anime list seems to be empty.`);
|
|
@@ -1020,4 +1034,99 @@ class MyAnimeList {
|
|
|
1020
1034
|
});
|
|
1021
1035
|
}
|
|
1022
1036
|
}
|
|
1023
|
-
|
|
1037
|
+
class AniDB {
|
|
1038
|
+
static importAnime() {
|
|
1039
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1040
|
+
var _a, _b;
|
|
1041
|
+
try {
|
|
1042
|
+
const filename = yield selectFile(".json");
|
|
1043
|
+
if (!filename) {
|
|
1044
|
+
return;
|
|
1045
|
+
}
|
|
1046
|
+
const filePath = join(getDownloadFolderPath(), filename);
|
|
1047
|
+
const fileContent = yield readFile(filePath, "utf8");
|
|
1048
|
+
const js0n_repaired = jsonrepair(fileContent);
|
|
1049
|
+
if (!(yield Validate.Import_AniDBJSONLarge(js0n_repaired))) {
|
|
1050
|
+
console.error(`\nInvalid JSON Large file.`);
|
|
1051
|
+
return;
|
|
1052
|
+
}
|
|
1053
|
+
if (js0n_repaired) {
|
|
1054
|
+
const obj3ct = yield JSON.parse(js0n_repaired);
|
|
1055
|
+
const animeList = obj3ct === null || obj3ct === void 0 ? void 0 : obj3ct.anime;
|
|
1056
|
+
if ((animeList === null || animeList === void 0 ? void 0 : animeList.length) > 0) {
|
|
1057
|
+
let count = 0;
|
|
1058
|
+
let iteration = 0;
|
|
1059
|
+
let missed = [];
|
|
1060
|
+
for (const anime of animeList) {
|
|
1061
|
+
iteration++;
|
|
1062
|
+
const anidbId = anime.id;
|
|
1063
|
+
const released = anime.broadcastDate; // DD-MM-YYYY (eg: "23.07.2016")
|
|
1064
|
+
const status = anime.status;
|
|
1065
|
+
// const type = anime.type
|
|
1066
|
+
const totalEpisodes = anime.totalEpisodes;
|
|
1067
|
+
const ownEpisodes = anime.ownEpisodes;
|
|
1068
|
+
const romanjiName = anime.romanjiName;
|
|
1069
|
+
const englishName = anime.englishName;
|
|
1070
|
+
function getStatus(anidbStatus, episodesSeen) {
|
|
1071
|
+
if (anidbStatus === "complete") {
|
|
1072
|
+
return AniListMediaStatus.COMPLETED;
|
|
1073
|
+
}
|
|
1074
|
+
else if (anidbStatus === "incomplete" &&
|
|
1075
|
+
Number(episodesSeen) > 0) {
|
|
1076
|
+
return AniListMediaStatus.CURRENT;
|
|
1077
|
+
}
|
|
1078
|
+
else {
|
|
1079
|
+
return AniListMediaStatus.PLANNING;
|
|
1080
|
+
}
|
|
1081
|
+
}
|
|
1082
|
+
let anilistId = yield anidbToanilistMapper(romanjiName, Number(released.split(".")[2]), englishName);
|
|
1083
|
+
if (anilistId) {
|
|
1084
|
+
try {
|
|
1085
|
+
const saveResponse = yield fetcher(saveAnimeWithProgressMutation, {
|
|
1086
|
+
mediaId: anilistId,
|
|
1087
|
+
progress: ownEpisodes - 2,
|
|
1088
|
+
status: getStatus(status, ownEpisodes),
|
|
1089
|
+
hiddenFromStatusLists: false,
|
|
1090
|
+
private: false,
|
|
1091
|
+
});
|
|
1092
|
+
const entryId = (_b = (_a = saveResponse === null || saveResponse === void 0 ? void 0 : saveResponse.data) === null || _a === void 0 ? void 0 : _a.SaveMediaListEntry) === null || _b === void 0 ? void 0 : _b.id;
|
|
1093
|
+
if (entryId) {
|
|
1094
|
+
count++;
|
|
1095
|
+
console.log(`[${count}]\t${entryId} ✅\t${anidbId}\t${anilistId}\t(${ownEpisodes}/${totalEpisodes})\t${status}–>${getStatus(status, ownEpisodes)}`);
|
|
1096
|
+
}
|
|
1097
|
+
// Rate limit each API call to avoid server overload
|
|
1098
|
+
// await new Promise((resolve) => setTimeout(resolve, 1100))
|
|
1099
|
+
}
|
|
1100
|
+
catch (error) {
|
|
1101
|
+
console.error(`Error processing AniDB ID ${anidbId}: ${error.message}`);
|
|
1102
|
+
}
|
|
1103
|
+
}
|
|
1104
|
+
else {
|
|
1105
|
+
missed.push({
|
|
1106
|
+
anidbId: anidbId,
|
|
1107
|
+
englishTitle: englishName,
|
|
1108
|
+
romajiTitle: romanjiName,
|
|
1109
|
+
});
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
1112
|
+
console.log(`\nAccuracy: ${(((animeList.length - missed.length) / animeList.length) * 100).toFixed(2)}%\tTotal Processed: ${iteration}\tMissed: ${missed.length}`);
|
|
1113
|
+
if (missed.length > 0) {
|
|
1114
|
+
console.log(`Exporting missed entries to JSON file, Please add them manually.`);
|
|
1115
|
+
yield saveJSONasJSON(missed, "anidb-missed");
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1118
|
+
else {
|
|
1119
|
+
console.log(`\nNo anime list found in the file.`);
|
|
1120
|
+
}
|
|
1121
|
+
}
|
|
1122
|
+
else {
|
|
1123
|
+
console.log(`\nNo content found in the file or unable to read.`);
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
catch (error) {
|
|
1127
|
+
console.error(`\nError in AniDB import process: ${error.message}`);
|
|
1128
|
+
}
|
|
1129
|
+
});
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
export { AniDB, AniList, MyAnimeList };
|