@irfanshadikrishad/anilist 1.0.11 → 1.1.0-forbidden.7
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 +373 -382
- package/LICENSE.md +382 -0
- package/README.md +87 -58
- package/bin/helpers/auth.d.ts +24 -8
- package/bin/helpers/auth.js +661 -258
- package/bin/helpers/fetcher.d.ts +2 -1
- package/bin/helpers/fetcher.js +14 -7
- package/bin/helpers/lists.d.ts +5 -1
- package/bin/helpers/lists.js +516 -405
- package/bin/helpers/mutations.d.ts +8 -4
- package/bin/helpers/mutations.js +14 -10
- package/bin/helpers/queries.d.ts +13 -9
- package/bin/helpers/queries.js +62 -16
- package/bin/helpers/truncate.d.ts +6 -0
- package/bin/helpers/truncate.js +10 -0
- package/bin/helpers/types.d.ts +319 -28
- package/bin/helpers/validation.d.ts +29 -0
- package/bin/helpers/validation.js +117 -0
- package/bin/helpers/workers.d.ts +24 -9
- package/bin/helpers/workers.js +210 -16
- package/bin/index.js +43 -4
- package/package.json +29 -16
- package/assets/binance.jpg +0 -0
package/bin/helpers/lists.js
CHANGED
|
@@ -8,27 +8,35 @@ 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, mangaDetailsQuery, mangaSearchQuery, popularQuery, trendingQuery, upcomingAnimesQuery, userActivityQuery, userFollowersQuery, userFollowingQuery, userQuery, } from "./queries.js";
|
|
19
|
+
import { responsiveOutput } from "./truncate.js";
|
|
19
20
|
import { AniListMediaStatus, } from "./types.js";
|
|
20
|
-
import {
|
|
21
|
+
import { Validate } from "./validation.js";
|
|
22
|
+
import { anidbToanilistMapper, formatDateObject, getDownloadFolderPath, getNextSeasonAndYear, getTitle, logUserDetails, removeHtmlAndMarkdown, saveJSONasCSV, saveJSONasJSON, saveJSONasXML, selectFile, simpleDateFormat, timestampToTimeAgo, } from "./workers.js";
|
|
21
23
|
class AniList {
|
|
22
24
|
static importAnime() {
|
|
23
25
|
return __awaiter(this, void 0, void 0, function* () {
|
|
24
26
|
try {
|
|
25
27
|
const filename = yield selectFile(".json");
|
|
28
|
+
if (!filename) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
26
31
|
const filePath = join(getDownloadFolderPath(), filename);
|
|
27
32
|
const fileContent = yield readFile(filePath, "utf8");
|
|
28
33
|
const importedData = JSON.parse(fileContent);
|
|
34
|
+
if (!Validate.Import_JSON(importedData)) {
|
|
35
|
+
console.error(`\nInvalid JSON file.`);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
29
38
|
let count = 0;
|
|
30
|
-
const batchSize = 1;
|
|
31
|
-
const delay = 1100; // delay to avoid rate-limiting
|
|
39
|
+
const batchSize = 1;
|
|
32
40
|
for (let i = 0; i < importedData.length; i += batchSize) {
|
|
33
41
|
const batch = importedData.slice(i, i + batchSize);
|
|
34
42
|
yield Promise.all(batch.map((anime) => __awaiter(this, void 0, void 0, function* () {
|
|
@@ -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}`);
|
|
@@ -55,8 +63,6 @@ class AniList {
|
|
|
55
63
|
console.error(`\nError saving ${anime === null || anime === void 0 ? void 0 : anime.id}: ${error.message}`);
|
|
56
64
|
}
|
|
57
65
|
})));
|
|
58
|
-
// Avoid rate-limiting: Wait before sending the next batch
|
|
59
|
-
yield new Promise((resolve) => setTimeout(resolve, delay));
|
|
60
66
|
}
|
|
61
67
|
console.log(`\nTotal ${count} anime(s) imported successfully.`);
|
|
62
68
|
}
|
|
@@ -69,13 +75,18 @@ class AniList {
|
|
|
69
75
|
return __awaiter(this, void 0, void 0, function* () {
|
|
70
76
|
try {
|
|
71
77
|
const filename = yield selectFile(".json");
|
|
78
|
+
if (!filename) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
72
81
|
const filePath = join(getDownloadFolderPath(), filename);
|
|
73
82
|
const fileContent = yield readFile(filePath, "utf8");
|
|
74
83
|
const importedData = JSON.parse(fileContent);
|
|
84
|
+
if (!Validate.Import_JSON(importedData)) {
|
|
85
|
+
console.error(`\nInvalid JSON file.`);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
75
88
|
let count = 0;
|
|
76
|
-
const batchSize = 1;
|
|
77
|
-
const delay = 1100; // 2 seconds delay to avoid rate-limit
|
|
78
|
-
// Process in batches
|
|
89
|
+
const batchSize = 1;
|
|
79
90
|
for (let i = 0; i < importedData.length; i += batchSize) {
|
|
80
91
|
const batch = importedData.slice(i, i + batchSize);
|
|
81
92
|
yield Promise.all(batch.map((manga) => __awaiter(this, void 0, void 0, function* () {
|
|
@@ -93,15 +104,13 @@ class AniList {
|
|
|
93
104
|
if (save) {
|
|
94
105
|
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
106
|
count++;
|
|
96
|
-
console.log(`[${count}]
|
|
107
|
+
console.log(`[${count}]\t${id}\t${manga === null || manga === void 0 ? void 0 : manga.id} ✅`);
|
|
97
108
|
}
|
|
98
109
|
}
|
|
99
110
|
catch (err) {
|
|
100
111
|
console.error(`\nError saving ${manga === null || manga === void 0 ? void 0 : manga.id}: ${err.message}`);
|
|
101
112
|
}
|
|
102
113
|
})));
|
|
103
|
-
// Avoid rate-limit by adding delay after processing each batch
|
|
104
|
-
yield new Promise((resolve) => setTimeout(resolve, delay));
|
|
105
114
|
}
|
|
106
115
|
console.log(`\nTotal ${count} manga(s) imported successfully.`);
|
|
107
116
|
}
|
|
@@ -113,7 +122,76 @@ class AniList {
|
|
|
113
122
|
static exportAnime() {
|
|
114
123
|
return __awaiter(this, void 0, void 0, function* () {
|
|
115
124
|
var _a, _b, _c;
|
|
116
|
-
if (yield Auth.isLoggedIn()) {
|
|
125
|
+
if (!(yield Auth.isLoggedIn())) {
|
|
126
|
+
console.error(`\nMust login to use this feature.`);
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
const { exportType } = yield inquirer.prompt([
|
|
130
|
+
{
|
|
131
|
+
type: "list",
|
|
132
|
+
name: "exportType",
|
|
133
|
+
message: "Choose export type:",
|
|
134
|
+
choices: [
|
|
135
|
+
{ name: "CSV", value: 1 },
|
|
136
|
+
{ name: "JSON", value: 2 },
|
|
137
|
+
{ name: "XML (MyAnimeList/AniDB)", value: 3 },
|
|
138
|
+
],
|
|
139
|
+
pageSize: 10,
|
|
140
|
+
},
|
|
141
|
+
]);
|
|
142
|
+
const animeList = yield fetcher(currentUserAnimeList, {
|
|
143
|
+
id: yield Auth.MyUserId(),
|
|
144
|
+
});
|
|
145
|
+
if (animeList) {
|
|
146
|
+
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 : [];
|
|
147
|
+
const mediaWithProgress = lists.flatMap((list) => list.entries.map((entry) => {
|
|
148
|
+
var _a, _b, _c, _d;
|
|
149
|
+
return ({
|
|
150
|
+
id: (_a = entry === null || entry === void 0 ? void 0 : entry.media) === null || _a === void 0 ? void 0 : _a.id,
|
|
151
|
+
title: (_b = entry === null || entry === void 0 ? void 0 : entry.media) === null || _b === void 0 ? void 0 : _b.title,
|
|
152
|
+
episodes: (_c = entry === null || entry === void 0 ? void 0 : entry.media) === null || _c === void 0 ? void 0 : _c.episodes,
|
|
153
|
+
siteUrl: (_d = entry === null || entry === void 0 ? void 0 : entry.media) === null || _d === void 0 ? void 0 : _d.siteUrl,
|
|
154
|
+
progress: entry.progress,
|
|
155
|
+
status: entry === null || entry === void 0 ? void 0 : entry.status,
|
|
156
|
+
hiddenFromStatusLists: entry.hiddenFromStatusLists,
|
|
157
|
+
});
|
|
158
|
+
}));
|
|
159
|
+
switch (exportType) {
|
|
160
|
+
case 1:
|
|
161
|
+
yield saveJSONasCSV(mediaWithProgress, "anime");
|
|
162
|
+
break;
|
|
163
|
+
case 2:
|
|
164
|
+
yield saveJSONasJSON(mediaWithProgress, "anime");
|
|
165
|
+
break;
|
|
166
|
+
case 3:
|
|
167
|
+
yield MyAnimeList.exportAnime();
|
|
168
|
+
break;
|
|
169
|
+
default:
|
|
170
|
+
console.log(`\nInvalid export type. ${exportType}`);
|
|
171
|
+
break;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
console.error(`\nNo anime(s) found in your lists.`);
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
static exportManga() {
|
|
180
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
181
|
+
var _a, _b;
|
|
182
|
+
if (!(yield Auth.isLoggedIn())) {
|
|
183
|
+
console.error(`\nPlease login to use this feature.`);
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
const mangaLists = yield fetcher(currentUserMangaList, {
|
|
187
|
+
id: yield Auth.MyUserId(),
|
|
188
|
+
});
|
|
189
|
+
if (!(mangaLists === null || mangaLists === void 0 ? void 0 : mangaLists.data)) {
|
|
190
|
+
console.error(`\nCould not get manga list.`);
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
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) || [];
|
|
194
|
+
if (lists.length > 0) {
|
|
117
195
|
const { exportType } = yield inquirer.prompt([
|
|
118
196
|
{
|
|
119
197
|
type: "list",
|
|
@@ -127,141 +205,53 @@ class AniList {
|
|
|
127
205
|
pageSize: 10,
|
|
128
206
|
},
|
|
129
207
|
]);
|
|
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.`);
|
|
208
|
+
const mediaWithProgress = lists.flatMap((list) => list.entries.map((entry) => {
|
|
209
|
+
var _a, _b;
|
|
210
|
+
return ({
|
|
211
|
+
id: (_a = entry === null || entry === void 0 ? void 0 : entry.media) === null || _a === void 0 ? void 0 : _a.id,
|
|
212
|
+
title: (_b = entry === null || entry === void 0 ? void 0 : entry.media) === null || _b === void 0 ? void 0 : _b.title,
|
|
213
|
+
private: entry.private,
|
|
214
|
+
chapters: entry.media.chapters,
|
|
215
|
+
progress: entry.progress,
|
|
216
|
+
status: entry === null || entry === void 0 ? void 0 : entry.status,
|
|
217
|
+
hiddenFromStatusLists: entry.hiddenFromStatusLists,
|
|
218
|
+
});
|
|
219
|
+
}));
|
|
220
|
+
switch (exportType) {
|
|
221
|
+
case 1:
|
|
222
|
+
yield saveJSONasCSV(mediaWithProgress, "manga");
|
|
223
|
+
break;
|
|
224
|
+
case 2:
|
|
225
|
+
yield saveJSONasJSON(mediaWithProgress, "manga");
|
|
226
|
+
break;
|
|
227
|
+
case 3:
|
|
228
|
+
yield MyAnimeList.exportManga();
|
|
229
|
+
break;
|
|
230
|
+
default:
|
|
231
|
+
console.log(`\nInvalid export type. ${exportType}`);
|
|
232
|
+
break;
|
|
231
233
|
}
|
|
232
234
|
}
|
|
233
235
|
else {
|
|
234
|
-
console.
|
|
236
|
+
console.log(`\nList seems to be empty.`);
|
|
235
237
|
}
|
|
236
238
|
});
|
|
237
239
|
}
|
|
238
240
|
static MyAnime() {
|
|
239
241
|
return __awaiter(this, void 0, void 0, function* () {
|
|
240
|
-
var _a, _b, _c;
|
|
242
|
+
var _a, _b, _c, _d, _e;
|
|
241
243
|
try {
|
|
242
244
|
if (!(yield Auth.isLoggedIn())) {
|
|
243
245
|
return console.error(`\nPlease log in first to access your lists.`);
|
|
244
246
|
}
|
|
245
|
-
|
|
246
|
-
if (!userId) {
|
|
247
|
+
if (!(yield Auth.MyUserId())) {
|
|
247
248
|
return console.log(`\nFailed getting current user Id.`);
|
|
248
249
|
}
|
|
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}`);
|
|
250
|
+
const data = yield fetcher(currentUserAnimeList, { id: yield Auth.MyUserId() });
|
|
251
|
+
if (data === null || data === void 0 ? void 0 : data.errors) {
|
|
252
|
+
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
253
|
}
|
|
264
|
-
const lists = (
|
|
254
|
+
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
255
|
if (!lists || lists.length === 0) {
|
|
266
256
|
return console.log(`\nYou seem to have no anime(s) in your lists.`);
|
|
267
257
|
}
|
|
@@ -304,11 +294,12 @@ class AniList {
|
|
|
304
294
|
],
|
|
305
295
|
},
|
|
306
296
|
]);
|
|
307
|
-
const
|
|
308
|
-
|
|
309
|
-
|
|
297
|
+
const saveResponse = yield fetcher(addAnimeToListMutation, {
|
|
298
|
+
mediaId: selectedAnime,
|
|
299
|
+
status: selectedListType,
|
|
300
|
+
});
|
|
310
301
|
if (saveResponse) {
|
|
311
|
-
const savedEntry = (
|
|
302
|
+
const savedEntry = (_e = saveResponse.data) === null || _e === void 0 ? void 0 : _e.SaveMediaListEntry;
|
|
312
303
|
console.log(`\nEntry ${savedEntry === null || savedEntry === void 0 ? void 0 : savedEntry.id}. Saved as ${savedEntry === null || savedEntry === void 0 ? void 0 : savedEntry.status}.`);
|
|
313
304
|
}
|
|
314
305
|
else {
|
|
@@ -322,7 +313,7 @@ class AniList {
|
|
|
322
313
|
}
|
|
323
314
|
static MyManga() {
|
|
324
315
|
return __awaiter(this, void 0, void 0, function* () {
|
|
325
|
-
var _a, _b, _c, _d, _e;
|
|
316
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
326
317
|
try {
|
|
327
318
|
if (!(yield Auth.isLoggedIn())) {
|
|
328
319
|
return console.error(`\nPlease log in first to access your lists.`);
|
|
@@ -331,23 +322,11 @@ class AniList {
|
|
|
331
322
|
if (!userId) {
|
|
332
323
|
return console.error(`\nFailed to get the current user ID.`);
|
|
333
324
|
}
|
|
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"}`);
|
|
325
|
+
const response = yield fetcher(currentUserMangaList, { id: userId });
|
|
326
|
+
if (!(response === null || response === void 0 ? void 0 : response.data)) {
|
|
327
|
+
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
328
|
}
|
|
350
|
-
const lists = (
|
|
329
|
+
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
330
|
if (!lists || lists.length === 0) {
|
|
352
331
|
return console.log("\nYou don't seem to have any manga in your lists.");
|
|
353
332
|
}
|
|
@@ -393,24 +372,16 @@ class AniList {
|
|
|
393
372
|
],
|
|
394
373
|
},
|
|
395
374
|
]);
|
|
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
|
-
}),
|
|
375
|
+
const saveResponse = yield fetcher(addMangaToListMutation, {
|
|
376
|
+
mediaId: selectedManga,
|
|
377
|
+
status: selectedListType,
|
|
406
378
|
});
|
|
407
|
-
const
|
|
408
|
-
const saved = (_c = saveResponse === null || saveResponse === void 0 ? void 0 : saveResponse.data) === null || _c === void 0 ? void 0 : _c.SaveMediaListEntry;
|
|
379
|
+
const saved = (_e = saveResponse === null || saveResponse === void 0 ? void 0 : saveResponse.data) === null || _e === void 0 ? void 0 : _e.SaveMediaListEntry;
|
|
409
380
|
if (saved) {
|
|
410
381
|
console.log(`\nEntry ${saved.id}. Saved as ${saved.status}.`);
|
|
411
382
|
}
|
|
412
383
|
else {
|
|
413
|
-
console.error(`\nFailed to save the manga. ${((
|
|
384
|
+
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
385
|
}
|
|
415
386
|
}
|
|
416
387
|
catch (error) {
|
|
@@ -420,63 +391,70 @@ class AniList {
|
|
|
420
391
|
}
|
|
421
392
|
static getTrendingAnime(count) {
|
|
422
393
|
return __awaiter(this, void 0, void 0, function* () {
|
|
423
|
-
var _a, _b, _c, _d, _e;
|
|
394
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
424
395
|
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
|
-
|
|
396
|
+
let page = 1;
|
|
397
|
+
let allTrending = [];
|
|
398
|
+
while (true) {
|
|
399
|
+
const response = yield fetcher(trendingQuery, { page, perPage: count });
|
|
400
|
+
if (response === null || response === void 0 ? void 0 : response.errors) {
|
|
401
|
+
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"}`);
|
|
402
|
+
return;
|
|
403
|
+
}
|
|
404
|
+
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;
|
|
405
|
+
if (!media || media.length === 0) {
|
|
406
|
+
console.log(`\nNo more trending anime available.`);
|
|
407
|
+
break;
|
|
408
|
+
}
|
|
409
|
+
allTrending = [...allTrending, ...media];
|
|
410
|
+
const choices = allTrending.map((anime, idx) => ({
|
|
411
|
+
name: `[${idx + 1}] ${getTitle(anime === null || anime === void 0 ? void 0 : anime.title)}`,
|
|
412
|
+
value: String(anime === null || anime === void 0 ? void 0 : anime.id),
|
|
413
|
+
}));
|
|
414
|
+
choices.push({ name: "See more", value: "see_more" });
|
|
415
|
+
const { selectedAnime } = yield inquirer.prompt([
|
|
416
|
+
{
|
|
417
|
+
type: "list",
|
|
418
|
+
name: "selectedAnime",
|
|
419
|
+
message: "Select anime to add to the list:",
|
|
420
|
+
choices,
|
|
421
|
+
pageSize: choices.length + 1,
|
|
422
|
+
},
|
|
423
|
+
]);
|
|
424
|
+
if (selectedAnime === "see_more") {
|
|
425
|
+
page++;
|
|
426
|
+
continue;
|
|
427
|
+
}
|
|
428
|
+
else {
|
|
429
|
+
const { selectedListType } = yield inquirer.prompt([
|
|
430
|
+
{
|
|
431
|
+
type: "list",
|
|
432
|
+
name: "selectedListType",
|
|
433
|
+
message: "Select the list where you want to save this anime:",
|
|
434
|
+
choices: [
|
|
435
|
+
{ name: "Planning", value: "PLANNING" },
|
|
436
|
+
{ name: "Watching", value: "CURRENT" },
|
|
437
|
+
{ name: "Completed", value: "COMPLETED" },
|
|
438
|
+
{ name: "Paused", value: "PAUSED" },
|
|
439
|
+
{ name: "Dropped", value: "DROPPED" },
|
|
440
|
+
],
|
|
441
|
+
},
|
|
442
|
+
]);
|
|
443
|
+
if (!(yield Auth.isLoggedIn())) {
|
|
444
|
+
console.error(`\nPlease log in first to use this feature.`);
|
|
445
|
+
return;
|
|
446
|
+
}
|
|
447
|
+
const variables = { mediaId: selectedAnime, status: selectedListType };
|
|
448
|
+
const saveResponse = yield fetcher(addAnimeToListMutation, variables);
|
|
449
|
+
const saved = (_e = saveResponse === null || saveResponse === void 0 ? void 0 : saveResponse.data) === null || _e === void 0 ? void 0 : _e.SaveMediaListEntry;
|
|
450
|
+
if (saved) {
|
|
451
|
+
console.log(`\nEntry ${saved.id}. Saved as ${saved.status}.`);
|
|
452
|
+
}
|
|
453
|
+
else {
|
|
454
|
+
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"}`);
|
|
455
|
+
}
|
|
456
|
+
break;
|
|
457
|
+
}
|
|
480
458
|
}
|
|
481
459
|
}
|
|
482
460
|
catch (error) {
|
|
@@ -486,63 +464,69 @@ class AniList {
|
|
|
486
464
|
}
|
|
487
465
|
static getPopularAnime(count) {
|
|
488
466
|
return __awaiter(this, void 0, void 0, function* () {
|
|
489
|
-
var _a, _b, _c, _d, _e;
|
|
467
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
490
468
|
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
|
-
|
|
469
|
+
let page = 1;
|
|
470
|
+
let allMedia = [];
|
|
471
|
+
while (true) {
|
|
472
|
+
const response = yield fetcher(popularQuery, { page, perPage: count });
|
|
473
|
+
if (!(response === null || response === void 0 ? void 0 : response.data)) {
|
|
474
|
+
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"}`);
|
|
475
|
+
return;
|
|
476
|
+
}
|
|
477
|
+
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;
|
|
478
|
+
if (!newMedia || newMedia.length === 0) {
|
|
479
|
+
console.log(`\nNo more popular anime available.`);
|
|
480
|
+
break;
|
|
481
|
+
}
|
|
482
|
+
allMedia = [...allMedia, ...newMedia];
|
|
483
|
+
const choices = allMedia.map((anime, idx) => ({
|
|
484
|
+
name: `[${idx + 1}] ${getTitle(anime === null || anime === void 0 ? void 0 : anime.title)}`,
|
|
485
|
+
value: String(anime === null || anime === void 0 ? void 0 : anime.id),
|
|
486
|
+
}));
|
|
487
|
+
choices.push({ name: "See more", value: "see_more" });
|
|
488
|
+
const { selectedAnime } = yield inquirer.prompt([
|
|
489
|
+
{
|
|
490
|
+
type: "list",
|
|
491
|
+
name: "selectedAnime",
|
|
492
|
+
message: "Select anime to add to the list:",
|
|
493
|
+
choices,
|
|
494
|
+
pageSize: choices.length,
|
|
495
|
+
},
|
|
496
|
+
]);
|
|
497
|
+
if (selectedAnime === "see_more") {
|
|
498
|
+
page++;
|
|
499
|
+
continue;
|
|
500
|
+
}
|
|
501
|
+
else {
|
|
502
|
+
const { selectedListType } = yield inquirer.prompt([
|
|
503
|
+
{
|
|
504
|
+
type: "list",
|
|
505
|
+
name: "selectedListType",
|
|
506
|
+
message: "Select the list where you want to save this anime:",
|
|
507
|
+
choices: [
|
|
508
|
+
{ name: "Planning", value: "PLANNING" },
|
|
509
|
+
{ name: "Watching", value: "CURRENT" },
|
|
510
|
+
{ name: "Completed", value: "COMPLETED" },
|
|
511
|
+
{ name: "Paused", value: "PAUSED" },
|
|
512
|
+
{ name: "Dropped", value: "DROPPED" },
|
|
513
|
+
],
|
|
514
|
+
},
|
|
515
|
+
]);
|
|
516
|
+
if (!(yield Auth.isLoggedIn())) {
|
|
517
|
+
return console.error(`\nPlease log in first to use this feature.`);
|
|
518
|
+
}
|
|
519
|
+
const variables = { mediaId: selectedAnime, status: selectedListType };
|
|
520
|
+
const saveResponse = yield fetcher(addAnimeToListMutation, variables);
|
|
521
|
+
const saved = (_e = saveResponse === null || saveResponse === void 0 ? void 0 : saveResponse.data) === null || _e === void 0 ? void 0 : _e.SaveMediaListEntry;
|
|
522
|
+
if (saved) {
|
|
523
|
+
console.log(`\nEntry ${saved.id}. Saved as ${saved.status}.`);
|
|
524
|
+
}
|
|
525
|
+
else {
|
|
526
|
+
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"}`);
|
|
527
|
+
}
|
|
528
|
+
break;
|
|
529
|
+
}
|
|
546
530
|
}
|
|
547
531
|
}
|
|
548
532
|
catch (error) {
|
|
@@ -555,55 +539,72 @@ class AniList {
|
|
|
555
539
|
var _a, _b, _c, _d, _e, _f;
|
|
556
540
|
try {
|
|
557
541
|
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
|
-
|
|
542
|
+
let page = 1;
|
|
543
|
+
let allUpcoming = [];
|
|
544
|
+
while (true) {
|
|
545
|
+
const request = yield fetcher(upcomingAnimesQuery, {
|
|
546
|
+
nextSeason,
|
|
547
|
+
nextYear,
|
|
548
|
+
page,
|
|
549
|
+
perPage: count,
|
|
550
|
+
});
|
|
551
|
+
if (!request || !request.data) {
|
|
552
|
+
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"}`);
|
|
553
|
+
return;
|
|
554
|
+
}
|
|
555
|
+
const newUpcoming = (_c = request.data.Page.media) !== null && _c !== void 0 ? _c : [];
|
|
556
|
+
if (newUpcoming.length === 0) {
|
|
557
|
+
console.log(`\nNo more upcoming anime available.`);
|
|
558
|
+
break;
|
|
559
|
+
}
|
|
560
|
+
allUpcoming = [...allUpcoming, ...newUpcoming];
|
|
561
|
+
const choices = allUpcoming.map((anime, idx) => ({
|
|
562
|
+
name: `[${idx + 1}] ${getTitle(anime === null || anime === void 0 ? void 0 : anime.title)}`,
|
|
563
|
+
value: String(anime === null || anime === void 0 ? void 0 : anime.id),
|
|
564
|
+
}));
|
|
565
|
+
choices.push({ name: "See more", value: "see_more" });
|
|
566
|
+
const { selectedAnime } = yield inquirer.prompt([
|
|
567
|
+
{
|
|
568
|
+
type: "list",
|
|
569
|
+
name: "selectedAnime",
|
|
570
|
+
message: "Select anime to add to the list:",
|
|
571
|
+
choices,
|
|
572
|
+
pageSize: choices.length + 2,
|
|
573
|
+
},
|
|
574
|
+
]);
|
|
575
|
+
if (selectedAnime === "see_more") {
|
|
576
|
+
page++;
|
|
577
|
+
continue;
|
|
578
|
+
}
|
|
579
|
+
else {
|
|
580
|
+
const { selectedListType } = yield inquirer.prompt([
|
|
581
|
+
{
|
|
582
|
+
type: "list",
|
|
583
|
+
name: "selectedListType",
|
|
584
|
+
message: "Select the list where you want to save this anime:",
|
|
585
|
+
choices: [
|
|
586
|
+
{ name: "Planning", value: "PLANNING" },
|
|
587
|
+
{ name: "Watching", value: "CURRENT" },
|
|
588
|
+
{ name: "Completed", value: "COMPLETED" },
|
|
589
|
+
{ name: "Paused", value: "PAUSED" },
|
|
590
|
+
{ name: "Dropped", value: "DROPPED" },
|
|
591
|
+
],
|
|
592
|
+
},
|
|
593
|
+
]);
|
|
594
|
+
if (!(yield Auth.isLoggedIn())) {
|
|
595
|
+
return console.error(`\nPlease log in first to use this feature.`);
|
|
596
|
+
}
|
|
597
|
+
const variables = { mediaId: selectedAnime, status: selectedListType };
|
|
598
|
+
const saveResponse = yield fetcher(addAnimeToListMutation, variables);
|
|
599
|
+
const saved = (_d = saveResponse === null || saveResponse === void 0 ? void 0 : saveResponse.data) === null || _d === void 0 ? void 0 : _d.SaveMediaListEntry;
|
|
600
|
+
if (saved) {
|
|
601
|
+
console.log(`\nEntry ${saved.id}. Saved as ${saved.status}.`);
|
|
602
|
+
}
|
|
603
|
+
else {
|
|
604
|
+
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"}`);
|
|
605
|
+
}
|
|
606
|
+
break;
|
|
607
|
+
}
|
|
607
608
|
}
|
|
608
609
|
}
|
|
609
610
|
catch (error) {
|
|
@@ -613,22 +614,11 @@ class AniList {
|
|
|
613
614
|
}
|
|
614
615
|
static getUserByUsername(username) {
|
|
615
616
|
return __awaiter(this, void 0, void 0, function* () {
|
|
616
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m
|
|
617
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
617
618
|
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"}`);
|
|
619
|
+
const response = yield fetcher(userQuery, { username });
|
|
620
|
+
if (!((_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.User)) {
|
|
621
|
+
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
622
|
}
|
|
633
623
|
const user = response.data.User;
|
|
634
624
|
const userActivityResponse = yield fetcher(userActivityQuery, {
|
|
@@ -637,24 +627,20 @@ class AniList {
|
|
|
637
627
|
perPage: 10,
|
|
638
628
|
});
|
|
639
629
|
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 : [];
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
console.log(`Profile Color:\t${(_g = user.options) === null || _g === void 0 ? void 0 : _g.profileColor}`);
|
|
651
|
-
console.log(`Timezone:\t${(_h = user.options) === null || _h === void 0 ? void 0 : _h.timezone}`);
|
|
652
|
-
console.log(`\nStatistics (Anime)\nCount: ${((_k = (_j = user.statistics) === null || _j === void 0 ? void 0 : _j.anime) === null || _k === void 0 ? void 0 : _k.count) || 0} Episodes Watched: ${((_m = (_l = user.statistics) === null || _l === void 0 ? void 0 : _l.anime) === null || _m === void 0 ? void 0 : _m.episodesWatched) || 0} Minutes Watched: ${((_p = (_o = user.statistics) === null || _o === void 0 ? void 0 : _o.anime) === null || _p === void 0 ? void 0 : _p.minutesWatched) || 0}`);
|
|
653
|
-
console.log(`Statistics (Manga)\nCount: ${((_r = (_q = user.statistics) === null || _q === void 0 ? void 0 : _q.manga) === null || _r === void 0 ? void 0 : _r.count) || 0} Chapters Read: ${((_t = (_s = user.statistics) === null || _s === void 0 ? void 0 : _s.manga) === null || _t === void 0 ? void 0 : _t.chaptersRead) || 0} Volumes Read: ${((_v = (_u = user.statistics) === null || _u === void 0 ? void 0 : _u.manga) === null || _v === void 0 ? void 0 : _v.volumesRead) || 0}`);
|
|
630
|
+
// Get follower/following information
|
|
631
|
+
const req_followers = yield fetcher(userFollowersQuery, {
|
|
632
|
+
userId: user === null || user === void 0 ? void 0 : user.id,
|
|
633
|
+
});
|
|
634
|
+
const req_following = yield fetcher(userFollowingQuery, {
|
|
635
|
+
userId: user === null || user === void 0 ? void 0 : user.id,
|
|
636
|
+
});
|
|
637
|
+
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;
|
|
638
|
+
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;
|
|
639
|
+
logUserDetails(user, followersCount, followingCount);
|
|
654
640
|
if (activities.length > 0) {
|
|
655
641
|
console.log(`\nRecent Activities:`);
|
|
656
|
-
activities.forEach(({ status, progress, media }) => {
|
|
657
|
-
|
|
642
|
+
activities.forEach(({ status, progress, media, createdAt }) => {
|
|
643
|
+
responsiveOutput(`${timestampToTimeAgo(createdAt)}\t${status} ${progress ? `${progress} of ` : ""}${getTitle(media === null || media === void 0 ? void 0 : media.title)}`);
|
|
658
644
|
});
|
|
659
645
|
}
|
|
660
646
|
else {
|
|
@@ -669,9 +655,9 @@ class AniList {
|
|
|
669
655
|
static getAnimeDetailsByID(anilistID) {
|
|
670
656
|
return __awaiter(this, void 0, void 0, function* () {
|
|
671
657
|
var _a;
|
|
672
|
-
const
|
|
673
|
-
|
|
674
|
-
|
|
658
|
+
const details = yield fetcher(animeDetailsQuery, {
|
|
659
|
+
id: anilistID,
|
|
660
|
+
});
|
|
675
661
|
if ((_a = details === null || details === void 0 ? void 0 : details.data) === null || _a === void 0 ? void 0 : _a.Media) {
|
|
676
662
|
const { id, title, description, duration, startDate, endDate, countryOfOrigin, isAdult, status, season, format, genres, siteUrl, } = details.data.Media;
|
|
677
663
|
console.log(`\nID: ${id}`);
|
|
@@ -690,12 +676,41 @@ class AniList {
|
|
|
690
676
|
}
|
|
691
677
|
});
|
|
692
678
|
}
|
|
679
|
+
static getMangaDetailsByID(mangaID) {
|
|
680
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
681
|
+
var _a;
|
|
682
|
+
try {
|
|
683
|
+
const response = yield fetcher(mangaDetailsQuery, {
|
|
684
|
+
id: mangaID,
|
|
685
|
+
});
|
|
686
|
+
if (response === null || response === void 0 ? void 0 : response.errors) {
|
|
687
|
+
console.error(`${response.errors[0].message}`);
|
|
688
|
+
return;
|
|
689
|
+
}
|
|
690
|
+
const manga = (_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.Media;
|
|
691
|
+
if (manga) {
|
|
692
|
+
console.log(`\n[${getTitle(manga.title)}]`);
|
|
693
|
+
console.log(`${manga.description}`);
|
|
694
|
+
console.log(`Chapters: ${manga.chapters}\t Volumes: ${manga.volumes}`);
|
|
695
|
+
console.log(`Status:\t${manga.status}`);
|
|
696
|
+
console.log(`Genres:\t${manga.genres.join(", ")}`);
|
|
697
|
+
console.log(`Start:\t${simpleDateFormat(manga.startDate)}`);
|
|
698
|
+
console.log(`End:\t${simpleDateFormat(manga.endDate)}`);
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
catch (error) {
|
|
702
|
+
console.error(`${error.message}`);
|
|
703
|
+
}
|
|
704
|
+
});
|
|
705
|
+
}
|
|
693
706
|
static searchAnime(search, count) {
|
|
694
707
|
return __awaiter(this, void 0, void 0, function* () {
|
|
695
708
|
var _a, _b, _c;
|
|
696
|
-
const
|
|
697
|
-
|
|
698
|
-
|
|
709
|
+
const searchResults = yield fetcher(animeSearchQuery, {
|
|
710
|
+
search,
|
|
711
|
+
page: 1,
|
|
712
|
+
perPage: count,
|
|
713
|
+
});
|
|
699
714
|
if (searchResults) {
|
|
700
715
|
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
716
|
if (results.length > 0) {
|
|
@@ -727,12 +742,10 @@ class AniList {
|
|
|
727
742
|
]);
|
|
728
743
|
// Save selected anime to chosen list type
|
|
729
744
|
if (yield Auth.isLoggedIn()) {
|
|
730
|
-
const
|
|
731
|
-
const saveVariables = {
|
|
745
|
+
const response = yield fetcher(addAnimeToListMutation, {
|
|
732
746
|
mediaId: selectedAnime,
|
|
733
747
|
status: selectedListType,
|
|
734
|
-
};
|
|
735
|
-
const response = yield fetcher(saveQuery, saveVariables);
|
|
748
|
+
});
|
|
736
749
|
if (response) {
|
|
737
750
|
const saved = (_c = response === null || response === void 0 ? void 0 : response.data) === null || _c === void 0 ? void 0 : _c.SaveMediaListEntry;
|
|
738
751
|
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 +767,11 @@ class AniList {
|
|
|
754
767
|
static searchManga(search, count) {
|
|
755
768
|
return __awaiter(this, void 0, void 0, function* () {
|
|
756
769
|
var _a, _b, _c;
|
|
757
|
-
const
|
|
758
|
-
|
|
759
|
-
|
|
770
|
+
const mangaSearchResult = yield fetcher(mangaSearchQuery, {
|
|
771
|
+
search,
|
|
772
|
+
page: 1,
|
|
773
|
+
perPage: count,
|
|
774
|
+
});
|
|
760
775
|
if (mangaSearchResult) {
|
|
761
776
|
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
777
|
// List of manga search results
|
|
@@ -789,9 +804,10 @@ class AniList {
|
|
|
789
804
|
]);
|
|
790
805
|
// If logged in save to the list
|
|
791
806
|
if (yield Auth.isLoggedIn()) {
|
|
792
|
-
const
|
|
793
|
-
|
|
794
|
-
|
|
807
|
+
const response = yield fetcher(addMangaToListMutation, {
|
|
808
|
+
mediaId: selectedMangaId,
|
|
809
|
+
status: selectedListType,
|
|
810
|
+
});
|
|
795
811
|
if (response) {
|
|
796
812
|
const saved = (_c = response === null || response === void 0 ? void 0 : response.data) === null || _c === void 0 ? void 0 : _c.SaveMediaListEntry;
|
|
797
813
|
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 +829,15 @@ class MyAnimeList {
|
|
|
813
829
|
var _a, _b, _c, _d, _e;
|
|
814
830
|
try {
|
|
815
831
|
const filename = yield selectFile(".xml");
|
|
832
|
+
if (!filename) {
|
|
833
|
+
return;
|
|
834
|
+
}
|
|
816
835
|
const filePath = join(getDownloadFolderPath(), filename);
|
|
817
836
|
const fileContent = yield readFile(filePath, "utf8");
|
|
837
|
+
if (!(yield Validate.Import_AnimeXML(fileContent))) {
|
|
838
|
+
console.error(`\nInvalid XML file.`);
|
|
839
|
+
return;
|
|
840
|
+
}
|
|
818
841
|
const parser = new XMLParser();
|
|
819
842
|
if (fileContent) {
|
|
820
843
|
const XMLObject = parser.parse(fileContent);
|
|
@@ -850,8 +873,6 @@ class MyAnimeList {
|
|
|
850
873
|
count++;
|
|
851
874
|
console.log(`[${count}] ${entryId} ✅`);
|
|
852
875
|
}
|
|
853
|
-
// Rate limit each API call to avoid server overload
|
|
854
|
-
yield new Promise((resolve) => setTimeout(resolve, 1100));
|
|
855
876
|
}
|
|
856
877
|
else {
|
|
857
878
|
console.error(`Could not retrieve AniList ID for MAL ID ${malId}`);
|
|
@@ -878,8 +899,15 @@ class MyAnimeList {
|
|
|
878
899
|
var _a, _b, _c, _d, _e;
|
|
879
900
|
try {
|
|
880
901
|
const filename = yield selectFile(".xml");
|
|
902
|
+
if (!filename) {
|
|
903
|
+
return;
|
|
904
|
+
}
|
|
881
905
|
const filePath = join(getDownloadFolderPath(), filename);
|
|
882
906
|
const fileContent = yield readFile(filePath, "utf8");
|
|
907
|
+
if (!(yield Validate.Import_MangaXML(fileContent))) {
|
|
908
|
+
console.error(`\nInvalid XML file.`);
|
|
909
|
+
return;
|
|
910
|
+
}
|
|
883
911
|
const parser = new XMLParser();
|
|
884
912
|
if (fileContent) {
|
|
885
913
|
const XMLObject = parser.parse(fileContent);
|
|
@@ -950,7 +978,7 @@ class MyAnimeList {
|
|
|
950
978
|
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
979
|
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
980
|
const mediaWithProgress = lists.flatMap((list) => list.entries.map((entry) => {
|
|
953
|
-
var _a, _b, _c, _d, _e;
|
|
981
|
+
var _a, _b, _c, _d, _e, _f;
|
|
954
982
|
return ({
|
|
955
983
|
id: (_a = entry === null || entry === void 0 ? void 0 : entry.media) === null || _a === void 0 ? void 0 : _a.id,
|
|
956
984
|
malId: (_b = entry === null || entry === void 0 ? void 0 : entry.media) === null || _b === void 0 ? void 0 : _b.idMal,
|
|
@@ -960,13 +988,10 @@ class MyAnimeList {
|
|
|
960
988
|
progress: entry.progress,
|
|
961
989
|
status: entry === null || entry === void 0 ? void 0 : entry.status,
|
|
962
990
|
hiddenFromStatusLists: false,
|
|
991
|
+
format: (_f = entry === null || entry === void 0 ? void 0 : entry.media) === null || _f === void 0 ? void 0 : _f.format,
|
|
963
992
|
});
|
|
964
993
|
}));
|
|
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());
|
|
994
|
+
yield saveJSONasXML(mediaWithProgress, 0);
|
|
970
995
|
}
|
|
971
996
|
else {
|
|
972
997
|
console.log(`\nHey, ${yield Auth.MyUserName()}. Your anime list seems to be empty.`);
|
|
@@ -991,24 +1016,17 @@ class MyAnimeList {
|
|
|
991
1016
|
});
|
|
992
1017
|
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
1018
|
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());
|
|
1019
|
+
const mediaWithProgress = lists.flatMap((list) => list.entries.map((entry) => ({
|
|
1020
|
+
id: entry.media.id,
|
|
1021
|
+
malId: entry.media.idMal,
|
|
1022
|
+
title: entry.media.title,
|
|
1023
|
+
private: entry.private,
|
|
1024
|
+
chapters: entry.media.chapters,
|
|
1025
|
+
progress: entry.progress,
|
|
1026
|
+
status: entry.status,
|
|
1027
|
+
hiddenFromStatusLists: entry.hiddenFromStatusLists,
|
|
1028
|
+
})));
|
|
1029
|
+
yield saveJSONasXML(mediaWithProgress, 1);
|
|
1012
1030
|
}
|
|
1013
1031
|
else {
|
|
1014
1032
|
console.log(`\nHey, ${yield Auth.MyUserName()}. Your anime list seems to be empty.`);
|
|
@@ -1020,4 +1038,97 @@ class MyAnimeList {
|
|
|
1020
1038
|
});
|
|
1021
1039
|
}
|
|
1022
1040
|
}
|
|
1023
|
-
|
|
1041
|
+
class AniDB {
|
|
1042
|
+
static importAnime() {
|
|
1043
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1044
|
+
var _a, _b;
|
|
1045
|
+
try {
|
|
1046
|
+
const filename = yield selectFile(".json");
|
|
1047
|
+
if (!filename) {
|
|
1048
|
+
return;
|
|
1049
|
+
}
|
|
1050
|
+
const filePath = join(getDownloadFolderPath(), filename);
|
|
1051
|
+
const fileContent = yield readFile(filePath, "utf8");
|
|
1052
|
+
const js0n_repaired = jsonrepair(fileContent);
|
|
1053
|
+
if (!(yield Validate.Import_AniDBJSONLarge(js0n_repaired))) {
|
|
1054
|
+
console.error(`\nInvalid JSON Large file.`);
|
|
1055
|
+
return;
|
|
1056
|
+
}
|
|
1057
|
+
if (js0n_repaired) {
|
|
1058
|
+
const obj3ct = yield JSON.parse(js0n_repaired);
|
|
1059
|
+
const animeList = obj3ct === null || obj3ct === void 0 ? void 0 : obj3ct.anime;
|
|
1060
|
+
if ((animeList === null || animeList === void 0 ? void 0 : animeList.length) > 0) {
|
|
1061
|
+
let count = 0;
|
|
1062
|
+
let iteration = 0;
|
|
1063
|
+
let missed = [];
|
|
1064
|
+
for (const anime of animeList) {
|
|
1065
|
+
iteration++;
|
|
1066
|
+
const anidbId = anime.id;
|
|
1067
|
+
const released = anime.broadcastDate; // DD-MM-YYYY (eg: "23.07.2016")
|
|
1068
|
+
const status = anime.status;
|
|
1069
|
+
// const type = anime.type
|
|
1070
|
+
const totalEpisodes = anime.totalEpisodes;
|
|
1071
|
+
const ownEpisodes = anime.ownEpisodes;
|
|
1072
|
+
const romanjiName = anime.romanjiName;
|
|
1073
|
+
const englishName = anime.englishName;
|
|
1074
|
+
function getStatus(anidbStatus, episodesSeen) {
|
|
1075
|
+
if (anidbStatus === "complete") {
|
|
1076
|
+
return AniListMediaStatus.COMPLETED;
|
|
1077
|
+
}
|
|
1078
|
+
else if (anidbStatus === "incomplete" &&
|
|
1079
|
+
Number(episodesSeen) > 0) {
|
|
1080
|
+
return AniListMediaStatus.CURRENT;
|
|
1081
|
+
}
|
|
1082
|
+
else {
|
|
1083
|
+
return AniListMediaStatus.PLANNING;
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1086
|
+
let anilistId = yield anidbToanilistMapper(romanjiName, Number(released.split(".")[2]), englishName);
|
|
1087
|
+
if (anilistId) {
|
|
1088
|
+
try {
|
|
1089
|
+
const saveResponse = yield fetcher(saveAnimeWithProgressMutation, {
|
|
1090
|
+
mediaId: anilistId,
|
|
1091
|
+
progress: ownEpisodes - 2,
|
|
1092
|
+
status: getStatus(status, ownEpisodes),
|
|
1093
|
+
hiddenFromStatusLists: false,
|
|
1094
|
+
private: false,
|
|
1095
|
+
});
|
|
1096
|
+
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;
|
|
1097
|
+
if (entryId) {
|
|
1098
|
+
count++;
|
|
1099
|
+
responsiveOutput(`[${count}]\t${entryId} ✅\t${anidbId}\t${anilistId}\t(${ownEpisodes}/${totalEpisodes})\t${status}–>${getStatus(status, ownEpisodes)}`);
|
|
1100
|
+
}
|
|
1101
|
+
}
|
|
1102
|
+
catch (error) {
|
|
1103
|
+
console.error(`Error processing AniDB ID ${anidbId}: ${error.message}`);
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
else {
|
|
1107
|
+
missed.push({
|
|
1108
|
+
anidbId: anidbId,
|
|
1109
|
+
englishTitle: englishName,
|
|
1110
|
+
romajiTitle: romanjiName,
|
|
1111
|
+
});
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
responsiveOutput(`\nAccuracy: ${(((animeList.length - missed.length) / animeList.length) * 100).toFixed(2)}%\tTotal Processed: ${iteration}\tMissed: ${missed.length}`);
|
|
1115
|
+
if (missed.length > 0) {
|
|
1116
|
+
responsiveOutput(`Exporting missed entries to JSON file, Please add them manually.`);
|
|
1117
|
+
yield saveJSONasJSON(missed, "anidb-missed");
|
|
1118
|
+
}
|
|
1119
|
+
}
|
|
1120
|
+
else {
|
|
1121
|
+
console.log(`\nNo anime list found in the file.`);
|
|
1122
|
+
}
|
|
1123
|
+
}
|
|
1124
|
+
else {
|
|
1125
|
+
console.log(`\nNo content found in the file or unable to read.`);
|
|
1126
|
+
}
|
|
1127
|
+
}
|
|
1128
|
+
catch (error) {
|
|
1129
|
+
console.error(`\nError in AniDB import process: ${error.message}`);
|
|
1130
|
+
}
|
|
1131
|
+
});
|
|
1132
|
+
}
|
|
1133
|
+
}
|
|
1134
|
+
export { AniDB, AniList, MyAnimeList };
|