@irfanshadikrishad/anilist 1.0.0-forbidden.2 → 1.0.0-forbidden.4
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 -0
- package/README.md +76 -53
- package/bin/helpers/auth.d.ts +14 -4
- package/bin/helpers/auth.js +316 -209
- package/bin/helpers/lists.d.ts +1 -0
- package/bin/helpers/lists.js +171 -124
- package/bin/helpers/queries.d.ts +5 -3
- package/bin/helpers/queries.js +18 -6
- package/bin/helpers/types.d.ts +138 -83
- package/bin/helpers/validation.d.ts +29 -0
- package/bin/helpers/validation.js +117 -0
- package/bin/helpers/workers.d.ts +16 -7
- package/bin/helpers/workers.js +86 -34
- package/bin/index.js +32 -1
- package/package.json +19 -16
package/bin/helpers/lists.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ declare class AniList {
|
|
|
10
10
|
static getUpcomingAnime(count: number): Promise<void>;
|
|
11
11
|
static getUserByUsername(username: string): Promise<void>;
|
|
12
12
|
static getAnimeDetailsByID(anilistID: number): Promise<void>;
|
|
13
|
+
static getMangaDetailsByID(mangaID: number): Promise<void>;
|
|
13
14
|
static searchAnime(search: string, count: number): Promise<void>;
|
|
14
15
|
static searchManga(search: string, count: number): Promise<void>;
|
|
15
16
|
}
|
package/bin/helpers/lists.js
CHANGED
|
@@ -8,25 +8,32 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
import { XMLParser } from "fast-xml-parser";
|
|
11
|
-
import { readFile
|
|
11
|
+
import { readFile } from "fs/promises";
|
|
12
12
|
import inquirer from "inquirer";
|
|
13
13
|
import { jsonrepair } from "jsonrepair";
|
|
14
|
-
import open from "open";
|
|
15
14
|
import { join } from "path";
|
|
16
15
|
import { Auth } from "./auth.js";
|
|
17
16
|
import { fetcher } from "./fetcher.js";
|
|
18
17
|
import { addAnimeToListMutation, addMangaToListMutation, saveAnimeWithProgressMutation, saveMangaWithProgressMutation, } from "./mutations.js";
|
|
19
|
-
import { animeDetailsQuery, animeSearchQuery, currentUserAnimeList, currentUserMangaList, malIdToAnilistAnimeId, malIdToAnilistMangaId, mangaSearchQuery, popularQuery, trendingQuery, upcomingAnimesQuery, userActivityQuery, userFollowersQuery, userFollowingQuery, userQuery, } from "./queries.js";
|
|
18
|
+
import { animeDetailsQuery, animeSearchQuery, currentUserAnimeList, currentUserMangaList, malIdToAnilistAnimeId, malIdToAnilistMangaId, mangaDetailsQuery, mangaSearchQuery, popularQuery, trendingQuery, upcomingAnimesQuery, userActivityQuery, userFollowersQuery, userFollowingQuery, userQuery, } from "./queries.js";
|
|
20
19
|
import { AniListMediaStatus, } from "./types.js";
|
|
21
|
-
import {
|
|
20
|
+
import { Validate } from "./validation.js";
|
|
21
|
+
import { anidbToanilistMapper, formatDateObject, getDownloadFolderPath, getNextSeasonAndYear, getTitle, removeHtmlAndMarkdown, saveJSONasCSV, saveJSONasJSON, saveJSONasXML, selectFile, simpleDateFormat, timestampToTimeAgo, } from "./workers.js";
|
|
22
22
|
class AniList {
|
|
23
23
|
static importAnime() {
|
|
24
24
|
return __awaiter(this, void 0, void 0, function* () {
|
|
25
25
|
try {
|
|
26
26
|
const filename = yield selectFile(".json");
|
|
27
|
+
if (!filename) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
27
30
|
const filePath = join(getDownloadFolderPath(), filename);
|
|
28
31
|
const fileContent = yield readFile(filePath, "utf8");
|
|
29
32
|
const importedData = JSON.parse(fileContent);
|
|
33
|
+
if (!Validate.Import_JSON(importedData)) {
|
|
34
|
+
console.error(`\nInvalid JSON file.`);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
30
37
|
let count = 0;
|
|
31
38
|
const batchSize = 1; // Number of requests in each batch
|
|
32
39
|
const delay = 1100; // delay to avoid rate-limiting
|
|
@@ -70,9 +77,16 @@ class AniList {
|
|
|
70
77
|
return __awaiter(this, void 0, void 0, function* () {
|
|
71
78
|
try {
|
|
72
79
|
const filename = yield selectFile(".json");
|
|
80
|
+
if (!filename) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
73
83
|
const filePath = join(getDownloadFolderPath(), filename);
|
|
74
84
|
const fileContent = yield readFile(filePath, "utf8");
|
|
75
85
|
const importedData = JSON.parse(fileContent);
|
|
86
|
+
if (!Validate.Import_JSON(importedData)) {
|
|
87
|
+
console.error(`\nInvalid JSON file.`);
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
76
90
|
let count = 0;
|
|
77
91
|
const batchSize = 1; // Adjust batch size as per rate-limit constraints
|
|
78
92
|
const delay = 1100; // 2 seconds delay to avoid rate-limit
|
|
@@ -114,7 +128,76 @@ class AniList {
|
|
|
114
128
|
static exportAnime() {
|
|
115
129
|
return __awaiter(this, void 0, void 0, function* () {
|
|
116
130
|
var _a, _b, _c;
|
|
117
|
-
if (yield Auth.isLoggedIn()) {
|
|
131
|
+
if (!(yield Auth.isLoggedIn())) {
|
|
132
|
+
console.error(`\nMust login to use this feature.`);
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
const { exportType } = yield inquirer.prompt([
|
|
136
|
+
{
|
|
137
|
+
type: "list",
|
|
138
|
+
name: "exportType",
|
|
139
|
+
message: "Choose export type:",
|
|
140
|
+
choices: [
|
|
141
|
+
{ name: "CSV", value: 1 },
|
|
142
|
+
{ name: "JSON", value: 2 },
|
|
143
|
+
{ name: "XML (MyAnimeList/AniDB)", value: 3 },
|
|
144
|
+
],
|
|
145
|
+
pageSize: 10,
|
|
146
|
+
},
|
|
147
|
+
]);
|
|
148
|
+
const animeList = yield fetcher(currentUserAnimeList, {
|
|
149
|
+
id: yield Auth.MyUserId(),
|
|
150
|
+
});
|
|
151
|
+
if (animeList) {
|
|
152
|
+
const lists = (_c = (_b = (_a = animeList === null || animeList === void 0 ? void 0 : animeList.data) === null || _a === void 0 ? void 0 : _a.MediaListCollection) === null || _b === void 0 ? void 0 : _b.lists) !== null && _c !== void 0 ? _c : [];
|
|
153
|
+
const mediaWithProgress = lists.flatMap((list) => list.entries.map((entry) => {
|
|
154
|
+
var _a, _b, _c, _d;
|
|
155
|
+
return ({
|
|
156
|
+
id: (_a = entry === null || entry === void 0 ? void 0 : entry.media) === null || _a === void 0 ? void 0 : _a.id,
|
|
157
|
+
title: (_b = entry === null || entry === void 0 ? void 0 : entry.media) === null || _b === void 0 ? void 0 : _b.title,
|
|
158
|
+
episodes: (_c = entry === null || entry === void 0 ? void 0 : entry.media) === null || _c === void 0 ? void 0 : _c.episodes,
|
|
159
|
+
siteUrl: (_d = entry === null || entry === void 0 ? void 0 : entry.media) === null || _d === void 0 ? void 0 : _d.siteUrl,
|
|
160
|
+
progress: entry.progress,
|
|
161
|
+
status: entry === null || entry === void 0 ? void 0 : entry.status,
|
|
162
|
+
hiddenFromStatusLists: entry.hiddenFromStatusLists,
|
|
163
|
+
});
|
|
164
|
+
}));
|
|
165
|
+
switch (exportType) {
|
|
166
|
+
case 1:
|
|
167
|
+
yield saveJSONasCSV(mediaWithProgress, "anime");
|
|
168
|
+
break;
|
|
169
|
+
case 2:
|
|
170
|
+
yield saveJSONasJSON(mediaWithProgress, "anime");
|
|
171
|
+
break;
|
|
172
|
+
case 3:
|
|
173
|
+
yield MyAnimeList.exportAnime();
|
|
174
|
+
break;
|
|
175
|
+
default:
|
|
176
|
+
console.log(`\nInvalid export type. ${exportType}`);
|
|
177
|
+
break;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
console.error(`\nNo anime(s) found in your lists.`);
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
static exportManga() {
|
|
186
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
187
|
+
var _a, _b;
|
|
188
|
+
if (!(yield Auth.isLoggedIn())) {
|
|
189
|
+
console.error(`\nPlease login to use this feature.`);
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
const mangaLists = yield fetcher(currentUserMangaList, {
|
|
193
|
+
id: yield Auth.MyUserId(),
|
|
194
|
+
});
|
|
195
|
+
if (!(mangaLists === null || mangaLists === void 0 ? void 0 : mangaLists.data)) {
|
|
196
|
+
console.error(`\nCould not get manga list.`);
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
const lists = ((_b = (_a = mangaLists === null || mangaLists === void 0 ? void 0 : mangaLists.data) === null || _a === void 0 ? void 0 : _a.MediaListCollection) === null || _b === void 0 ? void 0 : _b.lists) || [];
|
|
200
|
+
if (lists.length > 0) {
|
|
118
201
|
const { exportType } = yield inquirer.prompt([
|
|
119
202
|
{
|
|
120
203
|
type: "list",
|
|
@@ -123,116 +206,40 @@ class AniList {
|
|
|
123
206
|
choices: [
|
|
124
207
|
{ name: "CSV", value: 1 },
|
|
125
208
|
{ name: "JSON", value: 2 },
|
|
126
|
-
{ name: "XML (MyAnimeList
|
|
209
|
+
{ name: "XML (MyAnimeList)", value: 3 },
|
|
127
210
|
],
|
|
128
211
|
pageSize: 10,
|
|
129
212
|
},
|
|
130
213
|
]);
|
|
131
|
-
const
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
break;
|
|
157
|
-
case 3:
|
|
158
|
-
yield MyAnimeList.exportAnime();
|
|
159
|
-
break;
|
|
160
|
-
default:
|
|
161
|
-
console.log(`\nInvalid export type. ${exportType}`);
|
|
162
|
-
break;
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
else {
|
|
166
|
-
console.error(`\nNo anime(s) found in your lists.`);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
else {
|
|
170
|
-
console.error(`\nMust login to use this feature.`);
|
|
171
|
-
}
|
|
172
|
-
});
|
|
173
|
-
}
|
|
174
|
-
static exportManga() {
|
|
175
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
176
|
-
var _a, _b;
|
|
177
|
-
if (yield Auth.isLoggedIn()) {
|
|
178
|
-
const mangaLists = yield fetcher(currentUserMangaList, {
|
|
179
|
-
id: yield Auth.MyUserId(),
|
|
180
|
-
});
|
|
181
|
-
if (mangaLists) {
|
|
182
|
-
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) || [];
|
|
183
|
-
if (lists.length > 0) {
|
|
184
|
-
const { exportType } = yield inquirer.prompt([
|
|
185
|
-
{
|
|
186
|
-
type: "list",
|
|
187
|
-
name: "exportType",
|
|
188
|
-
message: "Choose export type:",
|
|
189
|
-
choices: [
|
|
190
|
-
{ name: "CSV", value: 1 },
|
|
191
|
-
{ name: "JSON", value: 2 },
|
|
192
|
-
{ name: "XML (MyAnimeList)", value: 3 },
|
|
193
|
-
],
|
|
194
|
-
pageSize: 10,
|
|
195
|
-
},
|
|
196
|
-
]);
|
|
197
|
-
const mediaWithProgress = lists.flatMap((list) => list.entries.map((entry) => {
|
|
198
|
-
var _a, _b, _c;
|
|
199
|
-
return ({
|
|
200
|
-
id: (_a = entry === null || entry === void 0 ? void 0 : entry.media) === null || _a === void 0 ? void 0 : _a.id,
|
|
201
|
-
title: exportType === 1
|
|
202
|
-
? getTitle((_b = entry === null || entry === void 0 ? void 0 : entry.media) === null || _b === void 0 ? void 0 : _b.title)
|
|
203
|
-
: (_c = entry === null || entry === void 0 ? void 0 : entry.media) === null || _c === void 0 ? void 0 : _c.title,
|
|
204
|
-
private: entry.private,
|
|
205
|
-
chapters: entry.media.chapters,
|
|
206
|
-
progress: entry.progress,
|
|
207
|
-
status: entry === null || entry === void 0 ? void 0 : entry.status,
|
|
208
|
-
hiddenFromStatusLists: entry.hiddenFromStatusLists,
|
|
209
|
-
});
|
|
210
|
-
}));
|
|
211
|
-
switch (exportType) {
|
|
212
|
-
case 1:
|
|
213
|
-
yield saveJSONasCSV(mediaWithProgress, "manga");
|
|
214
|
-
break;
|
|
215
|
-
case 2:
|
|
216
|
-
yield saveJSONasJSON(mediaWithProgress, "manga");
|
|
217
|
-
break;
|
|
218
|
-
case 3:
|
|
219
|
-
yield MyAnimeList.exportManga();
|
|
220
|
-
break;
|
|
221
|
-
default:
|
|
222
|
-
console.log(`\nInvalid export type. ${exportType}`);
|
|
223
|
-
break;
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
else {
|
|
227
|
-
console.log(`\nList seems to be empty.`);
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
else {
|
|
231
|
-
console.error(`\nCould not get manga list.`);
|
|
214
|
+
const mediaWithProgress = lists.flatMap((list) => list.entries.map((entry) => {
|
|
215
|
+
var _a, _b;
|
|
216
|
+
return ({
|
|
217
|
+
id: (_a = entry === null || entry === void 0 ? void 0 : entry.media) === null || _a === void 0 ? void 0 : _a.id,
|
|
218
|
+
title: (_b = entry === null || entry === void 0 ? void 0 : entry.media) === null || _b === void 0 ? void 0 : _b.title,
|
|
219
|
+
private: entry.private,
|
|
220
|
+
chapters: entry.media.chapters,
|
|
221
|
+
progress: entry.progress,
|
|
222
|
+
status: entry === null || entry === void 0 ? void 0 : entry.status,
|
|
223
|
+
hiddenFromStatusLists: entry.hiddenFromStatusLists,
|
|
224
|
+
});
|
|
225
|
+
}));
|
|
226
|
+
switch (exportType) {
|
|
227
|
+
case 1:
|
|
228
|
+
yield saveJSONasCSV(mediaWithProgress, "manga");
|
|
229
|
+
break;
|
|
230
|
+
case 2:
|
|
231
|
+
yield saveJSONasJSON(mediaWithProgress, "manga");
|
|
232
|
+
break;
|
|
233
|
+
case 3:
|
|
234
|
+
yield MyAnimeList.exportManga();
|
|
235
|
+
break;
|
|
236
|
+
default:
|
|
237
|
+
console.log(`\nInvalid export type. ${exportType}`);
|
|
238
|
+
break;
|
|
232
239
|
}
|
|
233
240
|
}
|
|
234
241
|
else {
|
|
235
|
-
console.
|
|
242
|
+
console.log(`\nList seems to be empty.`);
|
|
236
243
|
}
|
|
237
244
|
});
|
|
238
245
|
}
|
|
@@ -243,11 +250,10 @@ class AniList {
|
|
|
243
250
|
if (!(yield Auth.isLoggedIn())) {
|
|
244
251
|
return console.error(`\nPlease log in first to access your lists.`);
|
|
245
252
|
}
|
|
246
|
-
|
|
247
|
-
if (!userId) {
|
|
253
|
+
if (!(yield Auth.MyUserId())) {
|
|
248
254
|
return console.log(`\nFailed getting current user Id.`);
|
|
249
255
|
}
|
|
250
|
-
const data = yield fetcher(currentUserAnimeList, { id:
|
|
256
|
+
const data = yield fetcher(currentUserAnimeList, { id: yield Auth.MyUserId() });
|
|
251
257
|
if (data === null || data === void 0 ? void 0 : data.errors) {
|
|
252
258
|
return console.log(`\nSomething went wrong. ${(_b = (_a = data === null || data === void 0 ? void 0 : data.errors) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.message}`);
|
|
253
259
|
}
|
|
@@ -691,6 +697,33 @@ class AniList {
|
|
|
691
697
|
}
|
|
692
698
|
});
|
|
693
699
|
}
|
|
700
|
+
static getMangaDetailsByID(mangaID) {
|
|
701
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
702
|
+
var _a;
|
|
703
|
+
try {
|
|
704
|
+
const response = yield fetcher(mangaDetailsQuery, {
|
|
705
|
+
id: mangaID,
|
|
706
|
+
});
|
|
707
|
+
if (response === null || response === void 0 ? void 0 : response.errors) {
|
|
708
|
+
console.error(`${response.errors[0].message}`);
|
|
709
|
+
return;
|
|
710
|
+
}
|
|
711
|
+
const manga = (_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.Media;
|
|
712
|
+
if (manga) {
|
|
713
|
+
console.log(`\n[${getTitle(manga.title)}]`);
|
|
714
|
+
console.log(`${manga.description}`);
|
|
715
|
+
console.log(`Chapters: ${manga.chapters}\t Volumes: ${manga.volumes}`);
|
|
716
|
+
console.log(`Status:\t${manga.status}`);
|
|
717
|
+
console.log(`Genres:\t${manga.genres.join(", ")}`);
|
|
718
|
+
console.log(`Start:\t${simpleDateFormat(manga.startDate)}`);
|
|
719
|
+
console.log(`End:\t${simpleDateFormat(manga.endDate)}`);
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
catch (error) {
|
|
723
|
+
console.error(`${error.message}`);
|
|
724
|
+
}
|
|
725
|
+
});
|
|
726
|
+
}
|
|
694
727
|
static searchAnime(search, count) {
|
|
695
728
|
return __awaiter(this, void 0, void 0, function* () {
|
|
696
729
|
var _a, _b, _c;
|
|
@@ -817,8 +850,15 @@ class MyAnimeList {
|
|
|
817
850
|
var _a, _b, _c, _d, _e;
|
|
818
851
|
try {
|
|
819
852
|
const filename = yield selectFile(".xml");
|
|
853
|
+
if (!filename) {
|
|
854
|
+
return;
|
|
855
|
+
}
|
|
820
856
|
const filePath = join(getDownloadFolderPath(), filename);
|
|
821
857
|
const fileContent = yield readFile(filePath, "utf8");
|
|
858
|
+
if (!(yield Validate.Import_AnimeXML(fileContent))) {
|
|
859
|
+
console.error(`\nInvalid XML file.`);
|
|
860
|
+
return;
|
|
861
|
+
}
|
|
822
862
|
const parser = new XMLParser();
|
|
823
863
|
if (fileContent) {
|
|
824
864
|
const XMLObject = parser.parse(fileContent);
|
|
@@ -882,8 +922,15 @@ class MyAnimeList {
|
|
|
882
922
|
var _a, _b, _c, _d, _e;
|
|
883
923
|
try {
|
|
884
924
|
const filename = yield selectFile(".xml");
|
|
925
|
+
if (!filename) {
|
|
926
|
+
return;
|
|
927
|
+
}
|
|
885
928
|
const filePath = join(getDownloadFolderPath(), filename);
|
|
886
929
|
const fileContent = yield readFile(filePath, "utf8");
|
|
930
|
+
if (!(yield Validate.Import_MangaXML(fileContent))) {
|
|
931
|
+
console.error(`\nInvalid XML file.`);
|
|
932
|
+
return;
|
|
933
|
+
}
|
|
887
934
|
const parser = new XMLParser();
|
|
888
935
|
if (fileContent) {
|
|
889
936
|
const XMLObject = parser.parse(fileContent);
|
|
@@ -954,7 +1001,7 @@ class MyAnimeList {
|
|
|
954
1001
|
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) {
|
|
955
1002
|
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;
|
|
956
1003
|
const mediaWithProgress = lists.flatMap((list) => list.entries.map((entry) => {
|
|
957
|
-
var _a, _b, _c, _d, _e;
|
|
1004
|
+
var _a, _b, _c, _d, _e, _f;
|
|
958
1005
|
return ({
|
|
959
1006
|
id: (_a = entry === null || entry === void 0 ? void 0 : entry.media) === null || _a === void 0 ? void 0 : _a.id,
|
|
960
1007
|
malId: (_b = entry === null || entry === void 0 ? void 0 : entry.media) === null || _b === void 0 ? void 0 : _b.idMal,
|
|
@@ -964,13 +1011,10 @@ class MyAnimeList {
|
|
|
964
1011
|
progress: entry.progress,
|
|
965
1012
|
status: entry === null || entry === void 0 ? void 0 : entry.status,
|
|
966
1013
|
hiddenFromStatusLists: false,
|
|
1014
|
+
format: (_f = entry === null || entry === void 0 ? void 0 : entry.media) === null || _f === void 0 ? void 0 : _f.format,
|
|
967
1015
|
});
|
|
968
1016
|
}));
|
|
969
|
-
|
|
970
|
-
const path = join(getDownloadFolderPath(), `${yield Auth.MyUserName()}@irfanshadikrishad-anilist-myanimelist(anime)-${getFormattedDate()}.xml`);
|
|
971
|
-
yield writeFile(path, yield xmlContent, "utf8");
|
|
972
|
-
console.log(`Generated XML for MyAnimeList.`);
|
|
973
|
-
open(getDownloadFolderPath());
|
|
1017
|
+
yield saveJSONasXML(mediaWithProgress, 0);
|
|
974
1018
|
}
|
|
975
1019
|
else {
|
|
976
1020
|
console.log(`\nHey, ${yield Auth.MyUserName()}. Your anime list seems to be empty.`);
|
|
@@ -1005,11 +1049,7 @@ class MyAnimeList {
|
|
|
1005
1049
|
status: entry.status,
|
|
1006
1050
|
hiddenFromStatusLists: entry.hiddenFromStatusLists,
|
|
1007
1051
|
})));
|
|
1008
|
-
|
|
1009
|
-
const path = join(getDownloadFolderPath(), `${yield Auth.MyUserName()}@irfanshadikrishad-anilist-myanimelist(manga)-${getFormattedDate()}.xml`);
|
|
1010
|
-
yield writeFile(path, yield XMLContent, "utf8");
|
|
1011
|
-
console.log(`Generated XML for MyAnimeList.`);
|
|
1012
|
-
open(getDownloadFolderPath());
|
|
1052
|
+
yield saveJSONasXML(mediaWithProgress, 1);
|
|
1013
1053
|
}
|
|
1014
1054
|
else {
|
|
1015
1055
|
console.log(`\nHey, ${yield Auth.MyUserName()}. Your anime list seems to be empty.`);
|
|
@@ -1027,10 +1067,17 @@ class AniDB {
|
|
|
1027
1067
|
var _a, _b;
|
|
1028
1068
|
try {
|
|
1029
1069
|
const filename = yield selectFile(".json");
|
|
1070
|
+
if (!filename) {
|
|
1071
|
+
return;
|
|
1072
|
+
}
|
|
1030
1073
|
const filePath = join(getDownloadFolderPath(), filename);
|
|
1031
1074
|
const fileContent = yield readFile(filePath, "utf8");
|
|
1032
1075
|
const js0n_repaired = jsonrepair(fileContent);
|
|
1033
|
-
if (
|
|
1076
|
+
if (!(yield Validate.Import_AniDBJSONLarge(js0n_repaired))) {
|
|
1077
|
+
console.error(`\nInvalid JSON Large file.`);
|
|
1078
|
+
return;
|
|
1079
|
+
}
|
|
1080
|
+
if (js0n_repaired) {
|
|
1034
1081
|
const obj3ct = yield JSON.parse(js0n_repaired);
|
|
1035
1082
|
const animeList = obj3ct === null || obj3ct === void 0 ? void 0 : obj3ct.anime;
|
|
1036
1083
|
if ((animeList === null || animeList === void 0 ? void 0 : animeList.length) > 0) {
|
|
@@ -1072,7 +1119,7 @@ class AniDB {
|
|
|
1072
1119
|
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;
|
|
1073
1120
|
if (entryId) {
|
|
1074
1121
|
count++;
|
|
1075
|
-
console.log(`[${count}]\t${entryId} ✅\t${anidbId}\t${anilistId}\t(${ownEpisodes}/${totalEpisodes})\t${status}
|
|
1122
|
+
console.log(`[${count}]\t${entryId} ✅\t${anidbId}\t${anilistId}\t(${ownEpisodes}/${totalEpisodes})\t${status}–>${getStatus(status, ownEpisodes)}`);
|
|
1076
1123
|
}
|
|
1077
1124
|
// Rate limit each API call to avoid server overload
|
|
1078
1125
|
// await new Promise((resolve) => setTimeout(resolve, 1100))
|
package/bin/helpers/queries.d.ts
CHANGED
|
@@ -22,6 +22,8 @@ declare const malIdToAnilistMangaId = "query ($malId: Int) {\n Media(idMal: $ma
|
|
|
22
22
|
declare const followingActivitiesQuery = "\nquery ($page: Int, $perPage: Int) {\n Page(page: $page, perPage: $perPage) {\n activities(isFollowing: true, sort: ID_DESC) {\n ... on TextActivity { id type isLiked createdAt user { id name } }\n ... on ListActivity { id type isLiked status progress media { title { userPreferred } } createdAt user { id name } }\n ... on MessageActivity { id type isLiked message createdAt recipient { id name } }\n }\n }\n}\n";
|
|
23
23
|
declare const globalActivitiesQuery = "\nquery ($page: Int, $perPage: Int) {\n Page(page: $page, perPage: $perPage) {\n activities(sort: ID_DESC) {\n ... on TextActivity { id type isLiked createdAt user { id name } }\n ... on ListActivity { id type isLiked status progress media { title { userPreferred } } createdAt user { id name } }\n ... on MessageActivity { id type isLiked message createdAt recipient { id name } }\n }\n }\n}\n";
|
|
24
24
|
declare const specificUserActivitiesQuery = "\nquery ($page: Int, $perPage: Int, $userId: Int) {\n Page(page: $page, perPage: $perPage) {\n pageInfo { total perPage currentPage lastPage hasNextPage }\n activities(userId: $userId, sort: ID_DESC) {\n ... on TextActivity { id type isLiked createdAt user { id name } }\n ... on ListActivity { id type isLiked status progress media { title { userPreferred } } createdAt user { id name } }\n ... on MessageActivity { messenger { name } id type isLiked message createdAt recipient { id name } }\n }\n }\n}\n";
|
|
25
|
-
declare const userFollowingQuery = "query ($userId: Int!, $page:Int) {\n Page (page: $page) {\n pageInfo { total perPage currentPage lastPage hasNextPage }\n following(userId: $userId, sort: [USERNAME]) { id name avatar { large medium } bannerImage }\n }\n}\n";
|
|
26
|
-
declare const userFollowersQuery = "query ($userId: Int
|
|
27
|
-
|
|
25
|
+
declare const userFollowingQuery = "query ($userId: Int!, $page: Int) {\n Page (page: $page) {\n pageInfo { total perPage currentPage lastPage hasNextPage }\n following(userId: $userId, sort: [USERNAME]) { id name avatar { large medium } bannerImage isFollowing isFollower }\n }\n}\n";
|
|
26
|
+
declare const userFollowersQuery = "query ($userId: Int!, $page: Int) {\n Page (page: $page) {\n pageInfo { total perPage currentPage lastPage hasNextPage }\n followers(userId: $userId, sort: [USERNAME]) { id name avatar { large medium } bannerImage isFollowing isFollower }\n }\n}\n";
|
|
27
|
+
declare const toggleFollowMutation = "mutation ($userId: Int!) {\n ToggleFollow(userId: $userId) { id name isFollower isFollowing }\n}\n";
|
|
28
|
+
declare const mangaDetailsQuery = "query ($id: Int) {\n Media(id: $id, type: MANGA) {\n id title { romaji english native userPreferred } coverImage { color medium large extraLarge } \n bannerImage description chapters volumes status genres\n startDate { year month day } endDate { year month day }\n }\n}\n";
|
|
29
|
+
export { activityAllQuery, activityAnimeListQuery, activityMangaListQuery, activityMediaList, activityMessageQuery, activityTextQuery, animeDetailsQuery, animeSearchQuery, currentUserAnimeList, currentUserMangaList, currentUserQuery, deleteMangaEntryMutation, deleteMediaEntryMutation, followingActivitiesQuery, globalActivitiesQuery, malIdToAnilistAnimeId, malIdToAnilistMangaId, mangaDetailsQuery, mangaSearchQuery, popularQuery, specificUserActivitiesQuery, toggleFollowMutation, trendingQuery, upcomingAnimesQuery, userActivityQuery, userFollowersQuery, userFollowingQuery, userQuery, };
|
package/bin/helpers/queries.js
CHANGED
|
@@ -159,18 +159,30 @@ query ($page: Int, $perPage: Int, $userId: Int) {
|
|
|
159
159
|
}
|
|
160
160
|
}
|
|
161
161
|
`;
|
|
162
|
-
const userFollowingQuery = `query ($userId: Int!, $page:Int) {
|
|
162
|
+
const userFollowingQuery = `query ($userId: Int!, $page: Int) {
|
|
163
163
|
Page (page: $page) {
|
|
164
164
|
pageInfo { total perPage currentPage lastPage hasNextPage }
|
|
165
|
-
following(userId: $userId, sort: [USERNAME]) { id name avatar { large medium } bannerImage }
|
|
165
|
+
following(userId: $userId, sort: [USERNAME]) { id name avatar { large medium } bannerImage isFollowing isFollower }
|
|
166
166
|
}
|
|
167
167
|
}
|
|
168
168
|
`;
|
|
169
|
-
const userFollowersQuery = `query ($userId: Int
|
|
170
|
-
Page {
|
|
169
|
+
const userFollowersQuery = `query ($userId: Int!, $page: Int) {
|
|
170
|
+
Page (page: $page) {
|
|
171
171
|
pageInfo { total perPage currentPage lastPage hasNextPage }
|
|
172
|
-
followers(userId: $userId, sort: [USERNAME]) { id name avatar { large medium } bannerImage }
|
|
172
|
+
followers(userId: $userId, sort: [USERNAME]) { id name avatar { large medium } bannerImage isFollowing isFollower }
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
`;
|
|
176
|
+
const toggleFollowMutation = `mutation ($userId: Int!) {
|
|
177
|
+
ToggleFollow(userId: $userId) { id name isFollower isFollowing }
|
|
178
|
+
}
|
|
179
|
+
`;
|
|
180
|
+
const mangaDetailsQuery = `query ($id: Int) {
|
|
181
|
+
Media(id: $id, type: MANGA) {
|
|
182
|
+
id title { romaji english native userPreferred } coverImage { color medium large extraLarge }
|
|
183
|
+
bannerImage description chapters volumes status genres
|
|
184
|
+
startDate { year month day } endDate { year month day }
|
|
173
185
|
}
|
|
174
186
|
}
|
|
175
187
|
`;
|
|
176
|
-
export { activityAllQuery, activityAnimeListQuery, activityMangaListQuery, activityMediaList, activityMessageQuery, activityTextQuery, animeDetailsQuery, animeSearchQuery, currentUserAnimeList, currentUserMangaList, currentUserQuery, deleteMangaEntryMutation, deleteMediaEntryMutation, followingActivitiesQuery, globalActivitiesQuery, malIdToAnilistAnimeId, malIdToAnilistMangaId, mangaSearchQuery, popularQuery, specificUserActivitiesQuery, trendingQuery, upcomingAnimesQuery, userActivityQuery, userFollowersQuery, userFollowingQuery, userQuery, };
|
|
188
|
+
export { activityAllQuery, activityAnimeListQuery, activityMangaListQuery, activityMediaList, activityMessageQuery, activityTextQuery, animeDetailsQuery, animeSearchQuery, currentUserAnimeList, currentUserMangaList, currentUserQuery, deleteMangaEntryMutation, deleteMediaEntryMutation, followingActivitiesQuery, globalActivitiesQuery, malIdToAnilistAnimeId, malIdToAnilistMangaId, mangaDetailsQuery, mangaSearchQuery, popularQuery, specificUserActivitiesQuery, toggleFollowMutation, trendingQuery, upcomingAnimesQuery, userActivityQuery, userFollowersQuery, userFollowingQuery, userQuery, };
|