@irfanshadikrishad/anilist 1.1.10 → 1.2.0-forbidden.6
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 -53
- package/bin/helpers/auth.d.ts +52 -8
- package/bin/helpers/auth.js +639 -271
- package/bin/helpers/fetcher.d.ts +2 -1
- package/bin/helpers/fetcher.js +9 -3
- package/bin/helpers/lists.d.ts +5 -1
- package/bin/helpers/lists.js +347 -260
- package/bin/helpers/mutations.d.ts +2 -1
- package/bin/helpers/mutations.js +37 -32
- package/bin/helpers/queries.d.ts +14 -7
- package/bin/helpers/queries.js +184 -128
- package/bin/helpers/truncate.d.ts +6 -0
- package/bin/helpers/truncate.js +10 -0
- package/bin/helpers/types.d.ts +367 -16
- package/bin/helpers/validation.d.ts +29 -0
- package/bin/helpers/validation.js +117 -0
- package/bin/helpers/workers.d.ts +22 -9
- package/bin/helpers/workers.js +220 -81
- package/bin/index.js +50 -8
- package/package.json +86 -75
package/bin/helpers/lists.js
CHANGED
|
@@ -8,24 +8,33 @@ 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, 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
39
|
const batchSize = 1; // Number of requests in each batch
|
|
31
40
|
const delay = 1100; // delay to avoid rate-limiting
|
|
@@ -45,7 +54,7 @@ class AniList {
|
|
|
45
54
|
if (save) {
|
|
46
55
|
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
56
|
count++;
|
|
48
|
-
console.log(`[${count}]
|
|
57
|
+
console.log(`[${count}]\t${id}\t${anime === null || anime === void 0 ? void 0 : anime.id} ✅`);
|
|
49
58
|
}
|
|
50
59
|
else {
|
|
51
60
|
console.error(`\nError saving ${anime === null || anime === void 0 ? void 0 : anime.id}`);
|
|
@@ -69,9 +78,16 @@ class AniList {
|
|
|
69
78
|
return __awaiter(this, void 0, void 0, function* () {
|
|
70
79
|
try {
|
|
71
80
|
const filename = yield selectFile(".json");
|
|
81
|
+
if (!filename) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
72
84
|
const filePath = join(getDownloadFolderPath(), filename);
|
|
73
85
|
const fileContent = yield readFile(filePath, "utf8");
|
|
74
86
|
const importedData = JSON.parse(fileContent);
|
|
87
|
+
if (!Validate.Import_JSON(importedData)) {
|
|
88
|
+
console.error(`\nInvalid JSON file.`);
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
75
91
|
let count = 0;
|
|
76
92
|
const batchSize = 1; // Adjust batch size as per rate-limit constraints
|
|
77
93
|
const delay = 1100; // 2 seconds delay to avoid rate-limit
|
|
@@ -93,7 +109,7 @@ class AniList {
|
|
|
93
109
|
if (save) {
|
|
94
110
|
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
111
|
count++;
|
|
96
|
-
console.log(`[${count}]
|
|
112
|
+
console.log(`[${count}]\t${id}\t${manga === null || manga === void 0 ? void 0 : manga.id} ✅`);
|
|
97
113
|
}
|
|
98
114
|
}
|
|
99
115
|
catch (err) {
|
|
@@ -113,7 +129,76 @@ class AniList {
|
|
|
113
129
|
static exportAnime() {
|
|
114
130
|
return __awaiter(this, void 0, void 0, function* () {
|
|
115
131
|
var _a, _b, _c;
|
|
116
|
-
if (yield Auth.isLoggedIn()) {
|
|
132
|
+
if (!(yield Auth.isLoggedIn())) {
|
|
133
|
+
console.error(`\nMust login to use this feature.`);
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
const { exportType } = yield inquirer.prompt([
|
|
137
|
+
{
|
|
138
|
+
type: "list",
|
|
139
|
+
name: "exportType",
|
|
140
|
+
message: "Choose export type:",
|
|
141
|
+
choices: [
|
|
142
|
+
{ name: "CSV", value: 1 },
|
|
143
|
+
{ name: "JSON", value: 2 },
|
|
144
|
+
{ name: "XML (MyAnimeList/AniDB)", value: 3 },
|
|
145
|
+
],
|
|
146
|
+
pageSize: 10,
|
|
147
|
+
},
|
|
148
|
+
]);
|
|
149
|
+
const animeList = yield fetcher(currentUserAnimeList, {
|
|
150
|
+
id: yield Auth.MyUserId(),
|
|
151
|
+
});
|
|
152
|
+
if (animeList) {
|
|
153
|
+
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 : [];
|
|
154
|
+
const mediaWithProgress = lists.flatMap((list) => list.entries.map((entry) => {
|
|
155
|
+
var _a, _b, _c, _d;
|
|
156
|
+
return ({
|
|
157
|
+
id: (_a = entry === null || entry === void 0 ? void 0 : entry.media) === null || _a === void 0 ? void 0 : _a.id,
|
|
158
|
+
title: (_b = entry === null || entry === void 0 ? void 0 : entry.media) === null || _b === void 0 ? void 0 : _b.title,
|
|
159
|
+
episodes: (_c = entry === null || entry === void 0 ? void 0 : entry.media) === null || _c === void 0 ? void 0 : _c.episodes,
|
|
160
|
+
siteUrl: (_d = entry === null || entry === void 0 ? void 0 : entry.media) === null || _d === void 0 ? void 0 : _d.siteUrl,
|
|
161
|
+
progress: entry.progress,
|
|
162
|
+
status: entry === null || entry === void 0 ? void 0 : entry.status,
|
|
163
|
+
hiddenFromStatusLists: entry.hiddenFromStatusLists,
|
|
164
|
+
});
|
|
165
|
+
}));
|
|
166
|
+
switch (exportType) {
|
|
167
|
+
case 1:
|
|
168
|
+
yield saveJSONasCSV(mediaWithProgress, "anime");
|
|
169
|
+
break;
|
|
170
|
+
case 2:
|
|
171
|
+
yield saveJSONasJSON(mediaWithProgress, "anime");
|
|
172
|
+
break;
|
|
173
|
+
case 3:
|
|
174
|
+
yield MyAnimeList.exportAnime();
|
|
175
|
+
break;
|
|
176
|
+
default:
|
|
177
|
+
console.log(`\nInvalid export type. ${exportType}`);
|
|
178
|
+
break;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
console.error(`\nNo anime(s) found in your lists.`);
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
static exportManga() {
|
|
187
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
188
|
+
var _a, _b;
|
|
189
|
+
if (!(yield Auth.isLoggedIn())) {
|
|
190
|
+
console.error(`\nPlease login to use this feature.`);
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
const mangaLists = yield fetcher(currentUserMangaList, {
|
|
194
|
+
id: yield Auth.MyUserId(),
|
|
195
|
+
});
|
|
196
|
+
if (!(mangaLists === null || mangaLists === void 0 ? void 0 : mangaLists.data)) {
|
|
197
|
+
console.error(`\nCould not get manga list.`);
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
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) || [];
|
|
201
|
+
if (lists.length > 0) {
|
|
117
202
|
const { exportType } = yield inquirer.prompt([
|
|
118
203
|
{
|
|
119
204
|
type: "list",
|
|
@@ -127,141 +212,53 @@ class AniList {
|
|
|
127
212
|
pageSize: 10,
|
|
128
213
|
},
|
|
129
214
|
]);
|
|
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.`);
|
|
215
|
+
const mediaWithProgress = lists.flatMap((list) => list.entries.map((entry) => {
|
|
216
|
+
var _a, _b;
|
|
217
|
+
return ({
|
|
218
|
+
id: (_a = entry === null || entry === void 0 ? void 0 : entry.media) === null || _a === void 0 ? void 0 : _a.id,
|
|
219
|
+
title: (_b = entry === null || entry === void 0 ? void 0 : entry.media) === null || _b === void 0 ? void 0 : _b.title,
|
|
220
|
+
private: entry.private,
|
|
221
|
+
chapters: entry.media.chapters,
|
|
222
|
+
progress: entry.progress,
|
|
223
|
+
status: entry === null || entry === void 0 ? void 0 : entry.status,
|
|
224
|
+
hiddenFromStatusLists: entry.hiddenFromStatusLists,
|
|
225
|
+
});
|
|
226
|
+
}));
|
|
227
|
+
switch (exportType) {
|
|
228
|
+
case 1:
|
|
229
|
+
yield saveJSONasCSV(mediaWithProgress, "manga");
|
|
230
|
+
break;
|
|
231
|
+
case 2:
|
|
232
|
+
yield saveJSONasJSON(mediaWithProgress, "manga");
|
|
233
|
+
break;
|
|
234
|
+
case 3:
|
|
235
|
+
yield MyAnimeList.exportManga();
|
|
236
|
+
break;
|
|
237
|
+
default:
|
|
238
|
+
console.log(`\nInvalid export type. ${exportType}`);
|
|
239
|
+
break;
|
|
231
240
|
}
|
|
232
241
|
}
|
|
233
242
|
else {
|
|
234
|
-
console.
|
|
243
|
+
console.log(`\nList seems to be empty.`);
|
|
235
244
|
}
|
|
236
245
|
});
|
|
237
246
|
}
|
|
238
247
|
static MyAnime() {
|
|
239
248
|
return __awaiter(this, void 0, void 0, function* () {
|
|
240
|
-
var _a, _b, _c;
|
|
249
|
+
var _a, _b, _c, _d, _e;
|
|
241
250
|
try {
|
|
242
251
|
if (!(yield Auth.isLoggedIn())) {
|
|
243
252
|
return console.error(`\nPlease log in first to access your lists.`);
|
|
244
253
|
}
|
|
245
|
-
|
|
246
|
-
if (!userId) {
|
|
254
|
+
if (!(yield Auth.MyUserId())) {
|
|
247
255
|
return console.log(`\nFailed getting current user Id.`);
|
|
248
256
|
}
|
|
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}`);
|
|
257
|
+
const data = yield fetcher(currentUserAnimeList, { id: yield Auth.MyUserId() });
|
|
258
|
+
if (data === null || data === void 0 ? void 0 : data.errors) {
|
|
259
|
+
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
260
|
}
|
|
264
|
-
const lists = (
|
|
261
|
+
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
262
|
if (!lists || lists.length === 0) {
|
|
266
263
|
return console.log(`\nYou seem to have no anime(s) in your lists.`);
|
|
267
264
|
}
|
|
@@ -304,11 +301,12 @@ class AniList {
|
|
|
304
301
|
],
|
|
305
302
|
},
|
|
306
303
|
]);
|
|
307
|
-
const
|
|
308
|
-
|
|
309
|
-
|
|
304
|
+
const saveResponse = yield fetcher(addAnimeToListMutation, {
|
|
305
|
+
mediaId: selectedAnime,
|
|
306
|
+
status: selectedListType,
|
|
307
|
+
});
|
|
310
308
|
if (saveResponse) {
|
|
311
|
-
const savedEntry = (
|
|
309
|
+
const savedEntry = (_e = saveResponse.data) === null || _e === void 0 ? void 0 : _e.SaveMediaListEntry;
|
|
312
310
|
console.log(`\nEntry ${savedEntry === null || savedEntry === void 0 ? void 0 : savedEntry.id}. Saved as ${savedEntry === null || savedEntry === void 0 ? void 0 : savedEntry.status}.`);
|
|
313
311
|
}
|
|
314
312
|
else {
|
|
@@ -322,7 +320,7 @@ class AniList {
|
|
|
322
320
|
}
|
|
323
321
|
static MyManga() {
|
|
324
322
|
return __awaiter(this, void 0, void 0, function* () {
|
|
325
|
-
var _a, _b, _c, _d, _e;
|
|
323
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
326
324
|
try {
|
|
327
325
|
if (!(yield Auth.isLoggedIn())) {
|
|
328
326
|
return console.error(`\nPlease log in first to access your lists.`);
|
|
@@ -331,23 +329,11 @@ class AniList {
|
|
|
331
329
|
if (!userId) {
|
|
332
330
|
return console.error(`\nFailed to get the current user ID.`);
|
|
333
331
|
}
|
|
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"}`);
|
|
332
|
+
const response = yield fetcher(currentUserMangaList, { id: userId });
|
|
333
|
+
if (!(response === null || response === void 0 ? void 0 : response.data)) {
|
|
334
|
+
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
335
|
}
|
|
350
|
-
const lists = (
|
|
336
|
+
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
337
|
if (!lists || lists.length === 0) {
|
|
352
338
|
return console.log("\nYou don't seem to have any manga in your lists.");
|
|
353
339
|
}
|
|
@@ -393,24 +379,16 @@ class AniList {
|
|
|
393
379
|
],
|
|
394
380
|
},
|
|
395
381
|
]);
|
|
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
|
-
}),
|
|
382
|
+
const saveResponse = yield fetcher(addMangaToListMutation, {
|
|
383
|
+
mediaId: selectedManga,
|
|
384
|
+
status: selectedListType,
|
|
406
385
|
});
|
|
407
|
-
const
|
|
408
|
-
const saved = (_c = saveResponse === null || saveResponse === void 0 ? void 0 : saveResponse.data) === null || _c === void 0 ? void 0 : _c.SaveMediaListEntry;
|
|
386
|
+
const saved = (_e = saveResponse === null || saveResponse === void 0 ? void 0 : saveResponse.data) === null || _e === void 0 ? void 0 : _e.SaveMediaListEntry;
|
|
409
387
|
if (saved) {
|
|
410
388
|
console.log(`\nEntry ${saved.id}. Saved as ${saved.status}.`);
|
|
411
389
|
}
|
|
412
390
|
else {
|
|
413
|
-
console.error(`\nFailed to save the manga. ${((
|
|
391
|
+
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
392
|
}
|
|
415
393
|
}
|
|
416
394
|
catch (error) {
|
|
@@ -420,27 +398,17 @@ class AniList {
|
|
|
420
398
|
}
|
|
421
399
|
static getTrendingAnime(count) {
|
|
422
400
|
return __awaiter(this, void 0, void 0, function* () {
|
|
423
|
-
var _a, _b, _c, _d, _e;
|
|
401
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
424
402
|
try {
|
|
425
403
|
let page = 1;
|
|
426
404
|
let allTrending = [];
|
|
427
405
|
while (true) {
|
|
428
|
-
const
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
"Content-Type": "application/json",
|
|
432
|
-
},
|
|
433
|
-
body: JSON.stringify({
|
|
434
|
-
query: trendingQuery,
|
|
435
|
-
variables: { page, perPage: count },
|
|
436
|
-
}),
|
|
437
|
-
});
|
|
438
|
-
const { data, errors } = yield request.json();
|
|
439
|
-
if (request.status !== 200 || errors) {
|
|
440
|
-
console.error(`\nSomething went wrong. ${((_a = errors === null || errors === void 0 ? void 0 : errors[0]) === null || _a === void 0 ? void 0 : _a.message) || "Unknown error"}`);
|
|
406
|
+
const response = yield fetcher(trendingQuery, { page, perPage: count });
|
|
407
|
+
if (response === null || response === void 0 ? void 0 : response.errors) {
|
|
408
|
+
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"}`);
|
|
441
409
|
return;
|
|
442
410
|
}
|
|
443
|
-
const media = (
|
|
411
|
+
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;
|
|
444
412
|
if (!media || media.length === 0) {
|
|
445
413
|
console.log(`\nNo more trending anime available.`);
|
|
446
414
|
break;
|
|
@@ -448,7 +416,7 @@ class AniList {
|
|
|
448
416
|
allTrending = [...allTrending, ...media];
|
|
449
417
|
const choices = allTrending.map((anime, idx) => ({
|
|
450
418
|
name: `[${idx + 1}] ${getTitle(anime === null || anime === void 0 ? void 0 : anime.title)}`,
|
|
451
|
-
value: anime === null || anime === void 0 ? void 0 : anime.id,
|
|
419
|
+
value: String(anime === null || anime === void 0 ? void 0 : anime.id),
|
|
452
420
|
}));
|
|
453
421
|
choices.push({ name: "See more", value: "see_more" });
|
|
454
422
|
const { selectedAnime } = yield inquirer.prompt([
|
|
@@ -485,12 +453,12 @@ class AniList {
|
|
|
485
453
|
}
|
|
486
454
|
const variables = { mediaId: selectedAnime, status: selectedListType };
|
|
487
455
|
const saveResponse = yield fetcher(addAnimeToListMutation, variables);
|
|
488
|
-
const saved = (
|
|
456
|
+
const saved = (_e = saveResponse === null || saveResponse === void 0 ? void 0 : saveResponse.data) === null || _e === void 0 ? void 0 : _e.SaveMediaListEntry;
|
|
489
457
|
if (saved) {
|
|
490
458
|
console.log(`\nEntry ${saved.id}. Saved as ${saved.status}.`);
|
|
491
459
|
}
|
|
492
460
|
else {
|
|
493
|
-
console.error(`\nFailed to save the anime. ${((
|
|
461
|
+
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"}`);
|
|
494
462
|
}
|
|
495
463
|
break;
|
|
496
464
|
}
|
|
@@ -503,27 +471,17 @@ class AniList {
|
|
|
503
471
|
}
|
|
504
472
|
static getPopularAnime(count) {
|
|
505
473
|
return __awaiter(this, void 0, void 0, function* () {
|
|
506
|
-
var _a, _b, _c, _d, _e;
|
|
474
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
507
475
|
try {
|
|
508
476
|
let page = 1;
|
|
509
477
|
let allMedia = [];
|
|
510
478
|
while (true) {
|
|
511
|
-
const
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
"Content-Type": "application/json",
|
|
515
|
-
},
|
|
516
|
-
body: JSON.stringify({
|
|
517
|
-
query: popularQuery,
|
|
518
|
-
variables: { page, perPage: count },
|
|
519
|
-
}),
|
|
520
|
-
});
|
|
521
|
-
const { data, errors } = yield request.json();
|
|
522
|
-
if (request.status !== 200 || errors) {
|
|
523
|
-
console.error(`\nSomething went wrong. ${((_a = errors === null || errors === void 0 ? void 0 : errors[0]) === null || _a === void 0 ? void 0 : _a.message) || "Unknown error"}`);
|
|
479
|
+
const response = yield fetcher(popularQuery, { page, perPage: count });
|
|
480
|
+
if (!(response === null || response === void 0 ? void 0 : response.data)) {
|
|
481
|
+
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"}`);
|
|
524
482
|
return;
|
|
525
483
|
}
|
|
526
|
-
const newMedia = (
|
|
484
|
+
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;
|
|
527
485
|
if (!newMedia || newMedia.length === 0) {
|
|
528
486
|
console.log(`\nNo more popular anime available.`);
|
|
529
487
|
break;
|
|
@@ -531,7 +489,7 @@ class AniList {
|
|
|
531
489
|
allMedia = [...allMedia, ...newMedia];
|
|
532
490
|
const choices = allMedia.map((anime, idx) => ({
|
|
533
491
|
name: `[${idx + 1}] ${getTitle(anime === null || anime === void 0 ? void 0 : anime.title)}`,
|
|
534
|
-
value: anime === null || anime === void 0 ? void 0 : anime.id,
|
|
492
|
+
value: String(anime === null || anime === void 0 ? void 0 : anime.id),
|
|
535
493
|
}));
|
|
536
494
|
choices.push({ name: "See more", value: "see_more" });
|
|
537
495
|
const { selectedAnime } = yield inquirer.prompt([
|
|
@@ -567,12 +525,12 @@ class AniList {
|
|
|
567
525
|
}
|
|
568
526
|
const variables = { mediaId: selectedAnime, status: selectedListType };
|
|
569
527
|
const saveResponse = yield fetcher(addAnimeToListMutation, variables);
|
|
570
|
-
const saved = (
|
|
528
|
+
const saved = (_e = saveResponse === null || saveResponse === void 0 ? void 0 : saveResponse.data) === null || _e === void 0 ? void 0 : _e.SaveMediaListEntry;
|
|
571
529
|
if (saved) {
|
|
572
530
|
console.log(`\nEntry ${saved.id}. Saved as ${saved.status}.`);
|
|
573
531
|
}
|
|
574
532
|
else {
|
|
575
|
-
console.error(`\nFailed to save the anime. ${((
|
|
533
|
+
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"}`);
|
|
576
534
|
}
|
|
577
535
|
break;
|
|
578
536
|
}
|
|
@@ -609,7 +567,7 @@ class AniList {
|
|
|
609
567
|
allUpcoming = [...allUpcoming, ...newUpcoming];
|
|
610
568
|
const choices = allUpcoming.map((anime, idx) => ({
|
|
611
569
|
name: `[${idx + 1}] ${getTitle(anime === null || anime === void 0 ? void 0 : anime.title)}`,
|
|
612
|
-
value: anime === null || anime === void 0 ? void 0 : anime.id,
|
|
570
|
+
value: String(anime === null || anime === void 0 ? void 0 : anime.id),
|
|
613
571
|
}));
|
|
614
572
|
choices.push({ name: "See more", value: "see_more" });
|
|
615
573
|
const { selectedAnime } = yield inquirer.prompt([
|
|
@@ -663,22 +621,11 @@ class AniList {
|
|
|
663
621
|
}
|
|
664
622
|
static getUserByUsername(username) {
|
|
665
623
|
return __awaiter(this, void 0, void 0, function* () {
|
|
666
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v;
|
|
624
|
+
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;
|
|
667
625
|
try {
|
|
668
|
-
const
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
if (yield Auth.isLoggedIn()) {
|
|
672
|
-
headers["Authorization"] = `Bearer ${yield Auth.RetriveAccessToken()}`;
|
|
673
|
-
}
|
|
674
|
-
const request = yield fetch(aniListEndpoint, {
|
|
675
|
-
method: "POST",
|
|
676
|
-
headers,
|
|
677
|
-
body: JSON.stringify({ query: userQuery, variables: { username } }),
|
|
678
|
-
});
|
|
679
|
-
const response = yield request.json();
|
|
680
|
-
if (request.status !== 200 || !((_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.User)) {
|
|
681
|
-
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"}`);
|
|
626
|
+
const response = yield fetcher(userQuery, { username });
|
|
627
|
+
if (!((_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.User)) {
|
|
628
|
+
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"}`);
|
|
682
629
|
}
|
|
683
630
|
const user = response.data.User;
|
|
684
631
|
const userActivityResponse = yield fetcher(userActivityQuery, {
|
|
@@ -687,6 +634,15 @@ class AniList {
|
|
|
687
634
|
perPage: 10,
|
|
688
635
|
});
|
|
689
636
|
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 : [];
|
|
637
|
+
// Get follower/following information
|
|
638
|
+
const req_followers = yield fetcher(userFollowersQuery, {
|
|
639
|
+
userId: user === null || user === void 0 ? void 0 : user.id,
|
|
640
|
+
});
|
|
641
|
+
const req_following = yield fetcher(userFollowingQuery, {
|
|
642
|
+
userId: user === null || user === void 0 ? void 0 : user.id,
|
|
643
|
+
});
|
|
644
|
+
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;
|
|
645
|
+
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;
|
|
690
646
|
console.log(`\nID:\t\t${user.id}`);
|
|
691
647
|
console.log(`Name:\t\t${user.name}`);
|
|
692
648
|
console.log(`Site URL:\t${user.siteUrl}`);
|
|
@@ -697,14 +653,16 @@ class AniList {
|
|
|
697
653
|
console.log(`Blocked:\t${user.isBlocked}`);
|
|
698
654
|
console.log(`Follower:\t${user.isFollower}`);
|
|
699
655
|
console.log(`Following:\t${user.isFollowing}`);
|
|
700
|
-
console.log(`Profile Color:\t${(
|
|
701
|
-
console.log(`Timezone:\t${(
|
|
702
|
-
console.log(`\
|
|
703
|
-
console.log(`
|
|
656
|
+
console.log(`Profile Color:\t${(_o = user.options) === null || _o === void 0 ? void 0 : _o.profileColor}`);
|
|
657
|
+
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"}`);
|
|
658
|
+
console.log(`\nFollowers:\t${followersCount}`);
|
|
659
|
+
console.log(`Following:\t${followingCount}`);
|
|
660
|
+
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}`);
|
|
661
|
+
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}`);
|
|
704
662
|
if (activities.length > 0) {
|
|
705
663
|
console.log(`\nRecent Activities:`);
|
|
706
|
-
activities.forEach(({ status, progress, media }) => {
|
|
707
|
-
|
|
664
|
+
activities.forEach(({ status, progress, media, createdAt }) => {
|
|
665
|
+
responsiveOutput(`${timestampToTimeAgo(createdAt)}\t${status} ${progress ? `${progress} of ` : ""}${getTitle(media === null || media === void 0 ? void 0 : media.title)}`);
|
|
708
666
|
});
|
|
709
667
|
}
|
|
710
668
|
else {
|
|
@@ -719,9 +677,9 @@ class AniList {
|
|
|
719
677
|
static getAnimeDetailsByID(anilistID) {
|
|
720
678
|
return __awaiter(this, void 0, void 0, function* () {
|
|
721
679
|
var _a;
|
|
722
|
-
const
|
|
723
|
-
|
|
724
|
-
|
|
680
|
+
const details = yield fetcher(animeDetailsQuery, {
|
|
681
|
+
id: anilistID,
|
|
682
|
+
});
|
|
725
683
|
if ((_a = details === null || details === void 0 ? void 0 : details.data) === null || _a === void 0 ? void 0 : _a.Media) {
|
|
726
684
|
const { id, title, description, duration, startDate, endDate, countryOfOrigin, isAdult, status, season, format, genres, siteUrl, } = details.data.Media;
|
|
727
685
|
console.log(`\nID: ${id}`);
|
|
@@ -740,12 +698,41 @@ class AniList {
|
|
|
740
698
|
}
|
|
741
699
|
});
|
|
742
700
|
}
|
|
701
|
+
static getMangaDetailsByID(mangaID) {
|
|
702
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
703
|
+
var _a;
|
|
704
|
+
try {
|
|
705
|
+
const response = yield fetcher(mangaDetailsQuery, {
|
|
706
|
+
id: mangaID,
|
|
707
|
+
});
|
|
708
|
+
if (response === null || response === void 0 ? void 0 : response.errors) {
|
|
709
|
+
console.error(`${response.errors[0].message}`);
|
|
710
|
+
return;
|
|
711
|
+
}
|
|
712
|
+
const manga = (_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.Media;
|
|
713
|
+
if (manga) {
|
|
714
|
+
console.log(`\n[${getTitle(manga.title)}]`);
|
|
715
|
+
console.log(`${manga.description}`);
|
|
716
|
+
console.log(`Chapters: ${manga.chapters}\t Volumes: ${manga.volumes}`);
|
|
717
|
+
console.log(`Status:\t${manga.status}`);
|
|
718
|
+
console.log(`Genres:\t${manga.genres.join(", ")}`);
|
|
719
|
+
console.log(`Start:\t${simpleDateFormat(manga.startDate)}`);
|
|
720
|
+
console.log(`End:\t${simpleDateFormat(manga.endDate)}`);
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
catch (error) {
|
|
724
|
+
console.error(`${error.message}`);
|
|
725
|
+
}
|
|
726
|
+
});
|
|
727
|
+
}
|
|
743
728
|
static searchAnime(search, count) {
|
|
744
729
|
return __awaiter(this, void 0, void 0, function* () {
|
|
745
730
|
var _a, _b, _c;
|
|
746
|
-
const
|
|
747
|
-
|
|
748
|
-
|
|
731
|
+
const searchResults = yield fetcher(animeSearchQuery, {
|
|
732
|
+
search,
|
|
733
|
+
page: 1,
|
|
734
|
+
perPage: count,
|
|
735
|
+
});
|
|
749
736
|
if (searchResults) {
|
|
750
737
|
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;
|
|
751
738
|
if (results.length > 0) {
|
|
@@ -777,12 +764,10 @@ class AniList {
|
|
|
777
764
|
]);
|
|
778
765
|
// Save selected anime to chosen list type
|
|
779
766
|
if (yield Auth.isLoggedIn()) {
|
|
780
|
-
const
|
|
781
|
-
const saveVariables = {
|
|
767
|
+
const response = yield fetcher(addAnimeToListMutation, {
|
|
782
768
|
mediaId: selectedAnime,
|
|
783
769
|
status: selectedListType,
|
|
784
|
-
};
|
|
785
|
-
const response = yield fetcher(saveQuery, saveVariables);
|
|
770
|
+
});
|
|
786
771
|
if (response) {
|
|
787
772
|
const saved = (_c = response === null || response === void 0 ? void 0 : response.data) === null || _c === void 0 ? void 0 : _c.SaveMediaListEntry;
|
|
788
773
|
console.log(`\nEntry ${saved === null || saved === void 0 ? void 0 : saved.id}. Saved as ${saved === null || saved === void 0 ? void 0 : saved.status}.`);
|
|
@@ -804,9 +789,11 @@ class AniList {
|
|
|
804
789
|
static searchManga(search, count) {
|
|
805
790
|
return __awaiter(this, void 0, void 0, function* () {
|
|
806
791
|
var _a, _b, _c;
|
|
807
|
-
const
|
|
808
|
-
|
|
809
|
-
|
|
792
|
+
const mangaSearchResult = yield fetcher(mangaSearchQuery, {
|
|
793
|
+
search,
|
|
794
|
+
page: 1,
|
|
795
|
+
perPage: count,
|
|
796
|
+
});
|
|
810
797
|
if (mangaSearchResult) {
|
|
811
798
|
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;
|
|
812
799
|
// List of manga search results
|
|
@@ -839,9 +826,10 @@ class AniList {
|
|
|
839
826
|
]);
|
|
840
827
|
// If logged in save to the list
|
|
841
828
|
if (yield Auth.isLoggedIn()) {
|
|
842
|
-
const
|
|
843
|
-
|
|
844
|
-
|
|
829
|
+
const response = yield fetcher(addMangaToListMutation, {
|
|
830
|
+
mediaId: selectedMangaId,
|
|
831
|
+
status: selectedListType,
|
|
832
|
+
});
|
|
845
833
|
if (response) {
|
|
846
834
|
const saved = (_c = response === null || response === void 0 ? void 0 : response.data) === null || _c === void 0 ? void 0 : _c.SaveMediaListEntry;
|
|
847
835
|
console.log(`\nEntry ${saved === null || saved === void 0 ? void 0 : saved.id}. Saved as ${saved === null || saved === void 0 ? void 0 : saved.status}.`);
|
|
@@ -863,8 +851,15 @@ class MyAnimeList {
|
|
|
863
851
|
var _a, _b, _c, _d, _e;
|
|
864
852
|
try {
|
|
865
853
|
const filename = yield selectFile(".xml");
|
|
854
|
+
if (!filename) {
|
|
855
|
+
return;
|
|
856
|
+
}
|
|
866
857
|
const filePath = join(getDownloadFolderPath(), filename);
|
|
867
858
|
const fileContent = yield readFile(filePath, "utf8");
|
|
859
|
+
if (!(yield Validate.Import_AnimeXML(fileContent))) {
|
|
860
|
+
console.error(`\nInvalid XML file.`);
|
|
861
|
+
return;
|
|
862
|
+
}
|
|
868
863
|
const parser = new XMLParser();
|
|
869
864
|
if (fileContent) {
|
|
870
865
|
const XMLObject = parser.parse(fileContent);
|
|
@@ -928,8 +923,15 @@ class MyAnimeList {
|
|
|
928
923
|
var _a, _b, _c, _d, _e;
|
|
929
924
|
try {
|
|
930
925
|
const filename = yield selectFile(".xml");
|
|
926
|
+
if (!filename) {
|
|
927
|
+
return;
|
|
928
|
+
}
|
|
931
929
|
const filePath = join(getDownloadFolderPath(), filename);
|
|
932
930
|
const fileContent = yield readFile(filePath, "utf8");
|
|
931
|
+
if (!(yield Validate.Import_MangaXML(fileContent))) {
|
|
932
|
+
console.error(`\nInvalid XML file.`);
|
|
933
|
+
return;
|
|
934
|
+
}
|
|
933
935
|
const parser = new XMLParser();
|
|
934
936
|
if (fileContent) {
|
|
935
937
|
const XMLObject = parser.parse(fileContent);
|
|
@@ -1000,7 +1002,7 @@ class MyAnimeList {
|
|
|
1000
1002
|
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) {
|
|
1001
1003
|
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;
|
|
1002
1004
|
const mediaWithProgress = lists.flatMap((list) => list.entries.map((entry) => {
|
|
1003
|
-
var _a, _b, _c, _d, _e;
|
|
1005
|
+
var _a, _b, _c, _d, _e, _f;
|
|
1004
1006
|
return ({
|
|
1005
1007
|
id: (_a = entry === null || entry === void 0 ? void 0 : entry.media) === null || _a === void 0 ? void 0 : _a.id,
|
|
1006
1008
|
malId: (_b = entry === null || entry === void 0 ? void 0 : entry.media) === null || _b === void 0 ? void 0 : _b.idMal,
|
|
@@ -1010,13 +1012,10 @@ class MyAnimeList {
|
|
|
1010
1012
|
progress: entry.progress,
|
|
1011
1013
|
status: entry === null || entry === void 0 ? void 0 : entry.status,
|
|
1012
1014
|
hiddenFromStatusLists: false,
|
|
1015
|
+
format: (_f = entry === null || entry === void 0 ? void 0 : entry.media) === null || _f === void 0 ? void 0 : _f.format,
|
|
1013
1016
|
});
|
|
1014
1017
|
}));
|
|
1015
|
-
|
|
1016
|
-
const path = join(getDownloadFolderPath(), `${yield Auth.MyUserName()}@irfanshadikrishad-anilist-myanimelist(anime)-${getFormattedDate()}.xml`);
|
|
1017
|
-
yield writeFile(path, yield xmlContent, "utf8");
|
|
1018
|
-
console.log(`Generated XML for MyAnimeList.`);
|
|
1019
|
-
open(getDownloadFolderPath());
|
|
1018
|
+
yield saveJSONasXML(mediaWithProgress, 0);
|
|
1020
1019
|
}
|
|
1021
1020
|
else {
|
|
1022
1021
|
console.log(`\nHey, ${yield Auth.MyUserName()}. Your anime list seems to be empty.`);
|
|
@@ -1041,24 +1040,17 @@ class MyAnimeList {
|
|
|
1041
1040
|
});
|
|
1042
1041
|
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) {
|
|
1043
1042
|
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;
|
|
1044
|
-
const mediaWithProgress = lists.flatMap((list) => list.entries.map((entry) => {
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
});
|
|
1056
|
-
}));
|
|
1057
|
-
const XMLContent = createMangaListXML(mediaWithProgress);
|
|
1058
|
-
const path = join(getDownloadFolderPath(), `${yield Auth.MyUserName()}@irfanshadikrishad-anilist-myanimelist(manga)-${getFormattedDate()}.xml`);
|
|
1059
|
-
yield writeFile(path, yield XMLContent, "utf8");
|
|
1060
|
-
console.log(`Generated XML for MyAnimeList.`);
|
|
1061
|
-
open(getDownloadFolderPath());
|
|
1043
|
+
const mediaWithProgress = lists.flatMap((list) => list.entries.map((entry) => ({
|
|
1044
|
+
id: entry.media.id,
|
|
1045
|
+
malId: entry.media.idMal,
|
|
1046
|
+
title: entry.media.title,
|
|
1047
|
+
private: entry.private,
|
|
1048
|
+
chapters: entry.media.chapters,
|
|
1049
|
+
progress: entry.progress,
|
|
1050
|
+
status: entry.status,
|
|
1051
|
+
hiddenFromStatusLists: entry.hiddenFromStatusLists,
|
|
1052
|
+
})));
|
|
1053
|
+
yield saveJSONasXML(mediaWithProgress, 1);
|
|
1062
1054
|
}
|
|
1063
1055
|
else {
|
|
1064
1056
|
console.log(`\nHey, ${yield Auth.MyUserName()}. Your anime list seems to be empty.`);
|
|
@@ -1070,4 +1062,99 @@ class MyAnimeList {
|
|
|
1070
1062
|
});
|
|
1071
1063
|
}
|
|
1072
1064
|
}
|
|
1073
|
-
|
|
1065
|
+
class AniDB {
|
|
1066
|
+
static importAnime() {
|
|
1067
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1068
|
+
var _a, _b;
|
|
1069
|
+
try {
|
|
1070
|
+
const filename = yield selectFile(".json");
|
|
1071
|
+
if (!filename) {
|
|
1072
|
+
return;
|
|
1073
|
+
}
|
|
1074
|
+
const filePath = join(getDownloadFolderPath(), filename);
|
|
1075
|
+
const fileContent = yield readFile(filePath, "utf8");
|
|
1076
|
+
const js0n_repaired = jsonrepair(fileContent);
|
|
1077
|
+
if (!(yield Validate.Import_AniDBJSONLarge(js0n_repaired))) {
|
|
1078
|
+
console.error(`\nInvalid JSON Large file.`);
|
|
1079
|
+
return;
|
|
1080
|
+
}
|
|
1081
|
+
if (js0n_repaired) {
|
|
1082
|
+
const obj3ct = yield JSON.parse(js0n_repaired);
|
|
1083
|
+
const animeList = obj3ct === null || obj3ct === void 0 ? void 0 : obj3ct.anime;
|
|
1084
|
+
if ((animeList === null || animeList === void 0 ? void 0 : animeList.length) > 0) {
|
|
1085
|
+
let count = 0;
|
|
1086
|
+
let iteration = 0;
|
|
1087
|
+
let missed = [];
|
|
1088
|
+
for (const anime of animeList) {
|
|
1089
|
+
iteration++;
|
|
1090
|
+
const anidbId = anime.id;
|
|
1091
|
+
const released = anime.broadcastDate; // DD-MM-YYYY (eg: "23.07.2016")
|
|
1092
|
+
const status = anime.status;
|
|
1093
|
+
// const type = anime.type
|
|
1094
|
+
const totalEpisodes = anime.totalEpisodes;
|
|
1095
|
+
const ownEpisodes = anime.ownEpisodes;
|
|
1096
|
+
const romanjiName = anime.romanjiName;
|
|
1097
|
+
const englishName = anime.englishName;
|
|
1098
|
+
function getStatus(anidbStatus, episodesSeen) {
|
|
1099
|
+
if (anidbStatus === "complete") {
|
|
1100
|
+
return AniListMediaStatus.COMPLETED;
|
|
1101
|
+
}
|
|
1102
|
+
else if (anidbStatus === "incomplete" &&
|
|
1103
|
+
Number(episodesSeen) > 0) {
|
|
1104
|
+
return AniListMediaStatus.CURRENT;
|
|
1105
|
+
}
|
|
1106
|
+
else {
|
|
1107
|
+
return AniListMediaStatus.PLANNING;
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1110
|
+
let anilistId = yield anidbToanilistMapper(romanjiName, Number(released.split(".")[2]), englishName);
|
|
1111
|
+
if (anilistId) {
|
|
1112
|
+
try {
|
|
1113
|
+
const saveResponse = yield fetcher(saveAnimeWithProgressMutation, {
|
|
1114
|
+
mediaId: anilistId,
|
|
1115
|
+
progress: ownEpisodes - 2,
|
|
1116
|
+
status: getStatus(status, ownEpisodes),
|
|
1117
|
+
hiddenFromStatusLists: false,
|
|
1118
|
+
private: false,
|
|
1119
|
+
});
|
|
1120
|
+
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;
|
|
1121
|
+
if (entryId) {
|
|
1122
|
+
count++;
|
|
1123
|
+
responsiveOutput(`[${count}]\t${entryId} ✅\t${anidbId}\t${anilistId}\t(${ownEpisodes}/${totalEpisodes})\t${status}–>${getStatus(status, ownEpisodes)}`);
|
|
1124
|
+
}
|
|
1125
|
+
// Rate limit each API call to avoid server overload
|
|
1126
|
+
// await new Promise((resolve) => setTimeout(resolve, 1100))
|
|
1127
|
+
}
|
|
1128
|
+
catch (error) {
|
|
1129
|
+
console.error(`Error processing AniDB ID ${anidbId}: ${error.message}`);
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
else {
|
|
1133
|
+
missed.push({
|
|
1134
|
+
anidbId: anidbId,
|
|
1135
|
+
englishTitle: englishName,
|
|
1136
|
+
romajiTitle: romanjiName,
|
|
1137
|
+
});
|
|
1138
|
+
}
|
|
1139
|
+
}
|
|
1140
|
+
responsiveOutput(`\nAccuracy: ${(((animeList.length - missed.length) / animeList.length) * 100).toFixed(2)}%\tTotal Processed: ${iteration}\tMissed: ${missed.length}`);
|
|
1141
|
+
if (missed.length > 0) {
|
|
1142
|
+
responsiveOutput(`Exporting missed entries to JSON file, Please add them manually.`);
|
|
1143
|
+
yield saveJSONasJSON(missed, "anidb-missed");
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
1146
|
+
else {
|
|
1147
|
+
console.log(`\nNo anime list found in the file.`);
|
|
1148
|
+
}
|
|
1149
|
+
}
|
|
1150
|
+
else {
|
|
1151
|
+
console.log(`\nNo content found in the file or unable to read.`);
|
|
1152
|
+
}
|
|
1153
|
+
}
|
|
1154
|
+
catch (error) {
|
|
1155
|
+
console.error(`\nError in AniDB import process: ${error.message}`);
|
|
1156
|
+
}
|
|
1157
|
+
});
|
|
1158
|
+
}
|
|
1159
|
+
}
|
|
1160
|
+
export { AniDB, AniList, MyAnimeList };
|