@irfanshadikrishad/anilist 1.0.0-forbidden.0 → 1.0.0-forbidden.2
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/README.md +243 -232
- package/bin/helpers/auth.d.ts +39 -7
- package/bin/helpers/auth.js +281 -106
- package/bin/helpers/fetcher.d.ts +3 -2
- package/bin/helpers/fetcher.js +29 -24
- package/bin/helpers/lists.d.ts +4 -1
- package/bin/helpers/lists.js +357 -268
- package/bin/helpers/mutations.js +35 -35
- package/bin/helpers/queries.d.ts +10 -6
- package/bin/helpers/queries.js +171 -144
- package/bin/helpers/types.d.ts +304 -8
- package/bin/helpers/workers.d.ts +9 -5
- package/bin/helpers/workers.js +155 -69
- package/bin/index.js +13 -5
- package/package.json +81 -73
- /package/{LICENSE → LICENSE.md} +0 -0
package/bin/helpers/auth.js
CHANGED
|
@@ -14,10 +14,10 @@ import open from "open";
|
|
|
14
14
|
import os from "os";
|
|
15
15
|
import path from "path";
|
|
16
16
|
import { fetcher } from "./fetcher.js";
|
|
17
|
-
import { AniList, MyAnimeList } from "./lists.js";
|
|
17
|
+
import { AniDB, AniList, MyAnimeList } from "./lists.js";
|
|
18
18
|
import { deleteActivityMutation, likeActivityMutation, saveTextActivityMutation, } from "./mutations.js";
|
|
19
|
-
import { activityAllQuery, activityAnimeListQuery, activityMangaListQuery, activityMediaList, activityMessageQuery, activityTextQuery, currentUserAnimeList, currentUserMangaList, currentUserQuery, deleteMangaEntryMutation, deleteMediaEntryMutation, followingActivitiesQuery, userActivityQuery, } from "./queries.js";
|
|
20
|
-
import { aniListEndpoint, getTitle, redirectUri } from "./workers.js";
|
|
19
|
+
import { activityAllQuery, activityAnimeListQuery, activityMangaListQuery, activityMediaList, activityMessageQuery, activityTextQuery, currentUserAnimeList, currentUserMangaList, currentUserQuery, deleteMangaEntryMutation, deleteMediaEntryMutation, followingActivitiesQuery, globalActivitiesQuery, specificUserActivitiesQuery, userActivityQuery, userFollowersQuery, userFollowingQuery, userQuery, } from "./queries.js";
|
|
20
|
+
import { activityBy, aniListEndpoint, getTitle, redirectUri, timestampToTimeAgo, } from "./workers.js";
|
|
21
21
|
const home_dir = os.homedir();
|
|
22
22
|
const save_path = path.join(home_dir, ".anilist_token");
|
|
23
23
|
class Auth {
|
|
@@ -109,7 +109,7 @@ class Auth {
|
|
|
109
109
|
}
|
|
110
110
|
static Myself() {
|
|
111
111
|
return __awaiter(this, void 0, void 0, function* () {
|
|
112
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
|
|
112
|
+
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;
|
|
113
113
|
try {
|
|
114
114
|
if (yield Auth.isLoggedIn()) {
|
|
115
115
|
const headers = {
|
|
@@ -130,33 +130,47 @@ class Auth {
|
|
|
130
130
|
perPage: 10,
|
|
131
131
|
});
|
|
132
132
|
const activities = (_b = (_a = activiResponse === null || activiResponse === void 0 ? void 0 : activiResponse.data) === null || _a === void 0 ? void 0 : _a.Page) === null || _b === void 0 ? void 0 : _b.activities;
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
133
|
+
// Get follower/following information
|
|
134
|
+
const req_followers = yield fetcher(userFollowersQuery, {
|
|
135
|
+
userId: user === null || user === void 0 ? void 0 : user.id,
|
|
136
|
+
});
|
|
137
|
+
const req_following = yield fetcher(userFollowingQuery, {
|
|
138
|
+
userId: user === null || user === void 0 ? void 0 : user.id,
|
|
139
|
+
});
|
|
140
|
+
const followersCount = ((_e = (_d = (_c = req_followers === null || req_followers === void 0 ? void 0 : req_followers.data) === null || _c === void 0 ? void 0 : _c.Page) === null || _d === void 0 ? void 0 : _d.pageInfo) === null || _e === void 0 ? void 0 : _e.total) || 0;
|
|
141
|
+
const followingCount = ((_h = (_g = (_f = req_following === null || req_following === void 0 ? void 0 : req_following.data) === null || _f === void 0 ? void 0 : _f.Page) === null || _g === void 0 ? void 0 : _g.pageInfo) === null || _h === void 0 ? void 0 : _h.total) || 0;
|
|
142
|
+
console.log(`
|
|
143
|
+
ID: ${user === null || user === void 0 ? void 0 : user.id}
|
|
144
|
+
Name: ${user === null || user === void 0 ? void 0 : user.name}
|
|
145
|
+
siteUrl: ${user === null || user === void 0 ? void 0 : user.siteUrl}
|
|
146
|
+
profileColor: ${(_j = user === null || user === void 0 ? void 0 : user.options) === null || _j === void 0 ? void 0 : _j.profileColor}
|
|
147
|
+
timeZone: ${(_k = user === null || user === void 0 ? void 0 : user.options) === null || _k === void 0 ? void 0 : _k.timezone}
|
|
148
|
+
activityMergeTime: ${(_l = user === null || user === void 0 ? void 0 : user.options) === null || _l === void 0 ? void 0 : _l.activityMergeTime}
|
|
149
|
+
donatorTier: ${user === null || user === void 0 ? void 0 : user.donatorTier}
|
|
150
|
+
donatorBadge: ${user === null || user === void 0 ? void 0 : user.donatorBadge}
|
|
151
|
+
unreadNotificationCount:${user === null || user === void 0 ? void 0 : user.unreadNotificationCount}
|
|
152
|
+
Account Created: ${new Date((user === null || user === void 0 ? void 0 : user.createdAt) * 1000).toUTCString()}
|
|
153
|
+
Account Updated: ${new Date((user === null || user === void 0 ? void 0 : user.updatedAt) * 1000).toUTCString()}
|
|
154
|
+
|
|
155
|
+
Followers: ${followersCount}
|
|
156
|
+
Following: ${followingCount}
|
|
157
|
+
|
|
158
|
+
Statistics (Anime):
|
|
159
|
+
Count: ${(_o = (_m = user === null || user === void 0 ? void 0 : user.statistics) === null || _m === void 0 ? void 0 : _m.anime) === null || _o === void 0 ? void 0 : _o.count}
|
|
160
|
+
Mean Score: ${(_q = (_p = user === null || user === void 0 ? void 0 : user.statistics) === null || _p === void 0 ? void 0 : _p.anime) === null || _q === void 0 ? void 0 : _q.meanScore}
|
|
161
|
+
Minutes Watched: ${(_s = (_r = user === null || user === void 0 ? void 0 : user.statistics) === null || _r === void 0 ? void 0 : _r.anime) === null || _s === void 0 ? void 0 : _s.minutesWatched}
|
|
162
|
+
Episodes Watched: ${(_u = (_t = user === null || user === void 0 ? void 0 : user.statistics) === null || _t === void 0 ? void 0 : _t.anime) === null || _u === void 0 ? void 0 : _u.episodesWatched}
|
|
163
|
+
|
|
164
|
+
Statistics (Manga):
|
|
165
|
+
Count: ${(_w = (_v = user === null || user === void 0 ? void 0 : user.statistics) === null || _v === void 0 ? void 0 : _v.manga) === null || _w === void 0 ? void 0 : _w.count}
|
|
166
|
+
Mean Score: ${(_y = (_x = user === null || user === void 0 ? void 0 : user.statistics) === null || _x === void 0 ? void 0 : _x.manga) === null || _y === void 0 ? void 0 : _y.meanScore}
|
|
167
|
+
Chapters Read: ${(_0 = (_z = user === null || user === void 0 ? void 0 : user.statistics) === null || _z === void 0 ? void 0 : _z.manga) === null || _0 === void 0 ? void 0 : _0.chaptersRead}
|
|
168
|
+
Volumes Read: ${(_2 = (_1 = user === null || user === void 0 ? void 0 : user.statistics) === null || _1 === void 0 ? void 0 : _1.manga) === null || _2 === void 0 ? void 0 : _2.volumesRead}
|
|
155
169
|
`);
|
|
156
170
|
console.log(`\nRecent Activities:`);
|
|
157
171
|
if (activities.length > 0) {
|
|
158
|
-
activities.map(({ status, progress, media }) => {
|
|
159
|
-
console.log(`${status} ${progress ? `${progress} of ` : ""}${getTitle(media === null || media === void 0 ? void 0 : media.title)}`);
|
|
172
|
+
activities.map(({ status, progress, media, createdAt }) => {
|
|
173
|
+
console.log(`${timestampToTimeAgo(createdAt)}\t${status} ${progress ? `${progress} of ` : ""}${getTitle(media === null || media === void 0 ? void 0 : media.title)}`);
|
|
160
174
|
});
|
|
161
175
|
}
|
|
162
176
|
return user;
|
|
@@ -217,7 +231,7 @@ Statistics (Manga):
|
|
|
217
231
|
return __awaiter(this, void 0, void 0, function* () {
|
|
218
232
|
var _a, _b;
|
|
219
233
|
if (!(yield Auth.isLoggedIn())) {
|
|
220
|
-
console.
|
|
234
|
+
console.warn(`\nUser not logged in.`);
|
|
221
235
|
return null;
|
|
222
236
|
}
|
|
223
237
|
const token = yield Auth.RetriveAccessToken();
|
|
@@ -281,8 +295,6 @@ Statistics (Manga):
|
|
|
281
295
|
],
|
|
282
296
|
},
|
|
283
297
|
]);
|
|
284
|
-
const userId = yield Auth.MyUserId();
|
|
285
|
-
const variables = { page: 1, perPage: 100, userId };
|
|
286
298
|
const queryMap = {
|
|
287
299
|
0: activityAllQuery,
|
|
288
300
|
1: activityTextQuery,
|
|
@@ -293,6 +305,7 @@ Statistics (Manga):
|
|
|
293
305
|
};
|
|
294
306
|
const query = queryMap[activityType];
|
|
295
307
|
let hasMoreActivities = true;
|
|
308
|
+
let totalCount = 0;
|
|
296
309
|
while (hasMoreActivities) {
|
|
297
310
|
const response = yield fetcher(query, {
|
|
298
311
|
page: 1,
|
|
@@ -315,7 +328,8 @@ Statistics (Manga):
|
|
|
315
328
|
});
|
|
316
329
|
const isDeleted = (_f = (_e = deleteResponse === null || deleteResponse === void 0 ? void 0 : deleteResponse.data) === null || _e === void 0 ? void 0 : _e.DeleteActivity) === null || _f === void 0 ? void 0 : _f.deleted;
|
|
317
330
|
count++;
|
|
318
|
-
|
|
331
|
+
totalCount++;
|
|
332
|
+
console.log(`[${count}/${activities.length}/${totalCount}]\t${act === null || act === void 0 ? void 0 : act.id} ${isDeleted ? "✅" : "❌"}`);
|
|
319
333
|
// Avoiding rate-limit
|
|
320
334
|
yield new Promise((resolve) => setTimeout(resolve, 1100));
|
|
321
335
|
}
|
|
@@ -344,19 +358,8 @@ Statistics (Manga):
|
|
|
344
358
|
if (yield Auth.isLoggedIn()) {
|
|
345
359
|
const userID = yield Auth.MyUserId();
|
|
346
360
|
if (userID) {
|
|
347
|
-
const
|
|
348
|
-
|
|
349
|
-
headers: {
|
|
350
|
-
"content-type": "application/json",
|
|
351
|
-
"Authorization": `Bearer ${yield Auth.RetriveAccessToken()}`,
|
|
352
|
-
},
|
|
353
|
-
body: JSON.stringify({
|
|
354
|
-
query: currentUserAnimeList,
|
|
355
|
-
variables: { id: userID },
|
|
356
|
-
}),
|
|
357
|
-
});
|
|
358
|
-
const response = yield request.json();
|
|
359
|
-
if (request.status === 200) {
|
|
361
|
+
const response = yield fetcher(currentUserAnimeList, { id: userID });
|
|
362
|
+
if (response !== null) {
|
|
360
363
|
const lists = (_b = (_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.MediaListCollection) === null || _b === void 0 ? void 0 : _b.lists;
|
|
361
364
|
if (lists.length > 0) {
|
|
362
365
|
const { selectedList } = yield inquirer.prompt([
|
|
@@ -371,7 +374,7 @@ Statistics (Manga):
|
|
|
371
374
|
const selectedEntries = lists.find((list) => list.name === selectedList);
|
|
372
375
|
if (selectedEntries) {
|
|
373
376
|
console.log(`\nDeleting entries of '${selectedEntries.name}':`);
|
|
374
|
-
for (const [
|
|
377
|
+
for (const [, entry] of selectedEntries.entries.entries()) {
|
|
375
378
|
if (entry === null || entry === void 0 ? void 0 : entry.id) {
|
|
376
379
|
yield Auth.DeleteAnimeById(entry === null || entry === void 0 ? void 0 : entry.id, (_c = entry === null || entry === void 0 ? void 0 : entry.media) === null || _c === void 0 ? void 0 : _c.title);
|
|
377
380
|
yield new Promise((resolve) => setTimeout(resolve, 1100));
|
|
@@ -407,19 +410,8 @@ Statistics (Manga):
|
|
|
407
410
|
return __awaiter(this, void 0, void 0, function* () {
|
|
408
411
|
var _a, _b, _c;
|
|
409
412
|
try {
|
|
410
|
-
const
|
|
411
|
-
|
|
412
|
-
headers: {
|
|
413
|
-
"content-type": "application/json",
|
|
414
|
-
"Authorization": `Bearer ${yield Auth.RetriveAccessToken()}`,
|
|
415
|
-
},
|
|
416
|
-
body: JSON.stringify({
|
|
417
|
-
query: deleteMediaEntryMutation,
|
|
418
|
-
variables: { id },
|
|
419
|
-
}),
|
|
420
|
-
});
|
|
421
|
-
const response = yield request.json();
|
|
422
|
-
if (request.status === 200) {
|
|
413
|
+
const response = yield fetcher(deleteMediaEntryMutation, { id: id });
|
|
414
|
+
if (response === null || response === void 0 ? void 0 : response.data) {
|
|
423
415
|
const deleted = (_b = (_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.DeleteMediaListEntry) === null || _b === void 0 ? void 0 : _b.deleted;
|
|
424
416
|
console.log(`del ${title ? getTitle(title) : ""} ${deleted ? "✅" : "❌"}`);
|
|
425
417
|
}
|
|
@@ -440,19 +432,8 @@ Statistics (Manga):
|
|
|
440
432
|
if (yield Auth.isLoggedIn()) {
|
|
441
433
|
const userID = yield Auth.MyUserId();
|
|
442
434
|
if (userID) {
|
|
443
|
-
const
|
|
444
|
-
|
|
445
|
-
headers: {
|
|
446
|
-
"content-type": "application/json",
|
|
447
|
-
"Authorization": `Bearer ${yield Auth.RetriveAccessToken()}`,
|
|
448
|
-
},
|
|
449
|
-
body: JSON.stringify({
|
|
450
|
-
query: currentUserMangaList,
|
|
451
|
-
variables: { id: userID },
|
|
452
|
-
}),
|
|
453
|
-
});
|
|
454
|
-
const response = yield request.json();
|
|
455
|
-
if (request.status === 200) {
|
|
435
|
+
const response = yield fetcher(currentUserMangaList, { id: userID });
|
|
436
|
+
if (response === null || response === void 0 ? void 0 : response.data) {
|
|
456
437
|
const lists = (_b = (_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.MediaListCollection) === null || _b === void 0 ? void 0 : _b.lists;
|
|
457
438
|
if (lists.length > 0) {
|
|
458
439
|
const { selectedList } = yield inquirer.prompt([
|
|
@@ -467,7 +448,7 @@ Statistics (Manga):
|
|
|
467
448
|
const selectedEntries = lists.find((list) => list.name === selectedList);
|
|
468
449
|
if (selectedEntries) {
|
|
469
450
|
console.log(`\nDeleting entries of '${selectedEntries.name}':`);
|
|
470
|
-
for (const [
|
|
451
|
+
for (const [, entry] of selectedEntries.entries.entries()) {
|
|
471
452
|
if (entry === null || entry === void 0 ? void 0 : entry.id) {
|
|
472
453
|
yield Auth.DeleteMangaById(entry === null || entry === void 0 ? void 0 : entry.id, (_c = entry === null || entry === void 0 ? void 0 : entry.media) === null || _c === void 0 ? void 0 : _c.title);
|
|
473
454
|
yield new Promise((resolve) => setTimeout(resolve, 1100));
|
|
@@ -499,33 +480,22 @@ Statistics (Manga):
|
|
|
499
480
|
}
|
|
500
481
|
}
|
|
501
482
|
catch (error) {
|
|
502
|
-
console.error(`\nError deleting manga
|
|
483
|
+
console.error(`\nError deleting manga. ${error.message}`);
|
|
503
484
|
}
|
|
504
485
|
});
|
|
505
486
|
}
|
|
506
487
|
static DeleteMangaById(id, title) {
|
|
507
488
|
return __awaiter(this, void 0, void 0, function* () {
|
|
508
|
-
var _a, _b;
|
|
489
|
+
var _a, _b, _c, _d;
|
|
509
490
|
try {
|
|
510
|
-
const
|
|
511
|
-
method: "POST",
|
|
512
|
-
headers: {
|
|
513
|
-
"Content-Type": "application/json",
|
|
514
|
-
"Authorization": `Bearer ${yield Auth.RetriveAccessToken()}`,
|
|
515
|
-
},
|
|
516
|
-
body: JSON.stringify({
|
|
517
|
-
query: deleteMangaEntryMutation,
|
|
518
|
-
variables: { id },
|
|
519
|
-
}),
|
|
520
|
-
});
|
|
521
|
-
const { data, errors } = yield request.json();
|
|
491
|
+
const response = yield fetcher(deleteMangaEntryMutation, { id });
|
|
522
492
|
const statusMessage = title ? getTitle(title) : "";
|
|
523
|
-
if (
|
|
524
|
-
const deleted = (_a =
|
|
493
|
+
if (response === null || response === void 0 ? void 0 : response.data) {
|
|
494
|
+
const deleted = (_b = (_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.DeleteMediaListEntry) === null || _b === void 0 ? void 0 : _b.deleted;
|
|
525
495
|
console.log(`del ${statusMessage} ${deleted ? "✅" : "❌"}`);
|
|
526
496
|
}
|
|
527
497
|
else {
|
|
528
|
-
console.error(`Error deleting manga. ${(
|
|
498
|
+
console.error(`Error deleting manga. ${(_d = (_c = response === null || response === void 0 ? void 0 : response.errors) === null || _c === void 0 ? void 0 : _c[0]) === null || _d === void 0 ? void 0 : _d.message}`);
|
|
529
499
|
}
|
|
530
500
|
}
|
|
531
501
|
catch (error) {
|
|
@@ -541,12 +511,9 @@ Statistics (Manga):
|
|
|
541
511
|
console.error(`\nPlease login to use this feature.`);
|
|
542
512
|
return;
|
|
543
513
|
}
|
|
544
|
-
const
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
`<br><br><br><br>*Written using [@irfanshadikrishad/anilist](https://www.npmjs.com/package/@irfanshadikrishad/anilist).*`,
|
|
548
|
-
};
|
|
549
|
-
const data = yield fetcher(query, variables);
|
|
514
|
+
const data = yield fetcher(saveTextActivityMutation, {
|
|
515
|
+
status: status,
|
|
516
|
+
});
|
|
550
517
|
if (!data) {
|
|
551
518
|
console.error(`\nSomething went wrong. ${data}.`);
|
|
552
519
|
return;
|
|
@@ -572,6 +539,7 @@ Statistics (Manga):
|
|
|
572
539
|
choices: [
|
|
573
540
|
{ name: "Exported JSON file.", value: 1 },
|
|
574
541
|
{ name: "MyAnimeList (XML)", value: 2 },
|
|
542
|
+
{ name: "AniDB (json-large)", value: 3 },
|
|
575
543
|
],
|
|
576
544
|
pageSize: 10,
|
|
577
545
|
},
|
|
@@ -583,6 +551,9 @@ Statistics (Manga):
|
|
|
583
551
|
case 2:
|
|
584
552
|
yield MyAnimeList.importAnime();
|
|
585
553
|
break;
|
|
554
|
+
case 3:
|
|
555
|
+
yield AniDB.importAnime();
|
|
556
|
+
break;
|
|
586
557
|
default:
|
|
587
558
|
console.log(`\nInvalid Choice.`);
|
|
588
559
|
break;
|
|
@@ -625,29 +596,36 @@ Statistics (Manga):
|
|
|
625
596
|
}
|
|
626
597
|
});
|
|
627
598
|
}
|
|
628
|
-
static
|
|
599
|
+
static LikeFollowing() {
|
|
629
600
|
return __awaiter(this, void 0, void 0, function* () {
|
|
630
|
-
var _a, _b, _c, _d
|
|
601
|
+
var _a, _b, _c, _d;
|
|
631
602
|
try {
|
|
632
603
|
let page = 1;
|
|
633
604
|
let hasMoreActivities = true;
|
|
605
|
+
let retryCount = 0;
|
|
606
|
+
const maxRetries = 5;
|
|
634
607
|
while (hasMoreActivities) {
|
|
635
608
|
const activities = yield fetcher(followingActivitiesQuery, {
|
|
636
609
|
page,
|
|
637
610
|
perPage: 50,
|
|
638
611
|
});
|
|
639
612
|
if (activities && ((_b = (_a = activities === null || activities === void 0 ? void 0 : activities.data) === null || _a === void 0 ? void 0 : _a.Page) === null || _b === void 0 ? void 0 : _b.activities.length) > 0) {
|
|
613
|
+
retryCount = 0; // Reset retry count on successful fetch
|
|
640
614
|
const activiti = (_d = (_c = activities === null || activities === void 0 ? void 0 : activities.data) === null || _c === void 0 ? void 0 : _c.Page) === null || _d === void 0 ? void 0 : _d.activities;
|
|
641
615
|
for (let activ of activiti) {
|
|
642
616
|
if (!activ.isLiked && activ.id) {
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
617
|
+
try {
|
|
618
|
+
const like = yield fetcher(likeActivityMutation, {
|
|
619
|
+
activityId: activ.id,
|
|
620
|
+
});
|
|
621
|
+
console.info(`${activityBy(activ)} ${(like === null || like === void 0 ? void 0 : like.data) ? "✅" : "❌"}`);
|
|
622
|
+
}
|
|
623
|
+
catch (error) {
|
|
624
|
+
console.error(`Activity possibly deleted. ${error.message}`);
|
|
625
|
+
}
|
|
648
626
|
}
|
|
649
627
|
else {
|
|
650
|
-
console.log(
|
|
628
|
+
console.log(`${activityBy(activ)} 🔵`);
|
|
651
629
|
}
|
|
652
630
|
// avoiding rate-limit
|
|
653
631
|
yield new Promise((resolve) => {
|
|
@@ -656,6 +634,66 @@ Statistics (Manga):
|
|
|
656
634
|
}
|
|
657
635
|
page++;
|
|
658
636
|
}
|
|
637
|
+
else {
|
|
638
|
+
if (retryCount < maxRetries) {
|
|
639
|
+
retryCount++;
|
|
640
|
+
console.warn(`Empty activities returned. Retrying... (${retryCount}/${maxRetries})`);
|
|
641
|
+
yield new Promise((resolve) => setTimeout(resolve, 3000));
|
|
642
|
+
}
|
|
643
|
+
else {
|
|
644
|
+
console.log(`\nProbably the end of activities after ${maxRetries} retries.`);
|
|
645
|
+
console.info(activities);
|
|
646
|
+
hasMoreActivities = false;
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
catch (error) {
|
|
652
|
+
console.error(`\nError from likeFollowing. ${error.message}`);
|
|
653
|
+
}
|
|
654
|
+
});
|
|
655
|
+
}
|
|
656
|
+
static Like(type) {
|
|
657
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
658
|
+
var _a, _b, _c, _d;
|
|
659
|
+
try {
|
|
660
|
+
let page = 1;
|
|
661
|
+
let hasMoreActivities = true;
|
|
662
|
+
let activity = type === 0
|
|
663
|
+
? followingActivitiesQuery
|
|
664
|
+
: type === 1
|
|
665
|
+
? globalActivitiesQuery
|
|
666
|
+
: followingActivitiesQuery;
|
|
667
|
+
while (hasMoreActivities) {
|
|
668
|
+
const activities = yield fetcher(activity, {
|
|
669
|
+
page,
|
|
670
|
+
perPage: 50,
|
|
671
|
+
});
|
|
672
|
+
if (activities && ((_b = (_a = activities === null || activities === void 0 ? void 0 : activities.data) === null || _a === void 0 ? void 0 : _a.Page) === null || _b === void 0 ? void 0 : _b.activities.length) > 0) {
|
|
673
|
+
const activiti = (_d = (_c = activities === null || activities === void 0 ? void 0 : activities.data) === null || _c === void 0 ? void 0 : _c.Page) === null || _d === void 0 ? void 0 : _d.activities;
|
|
674
|
+
for (let activ of activiti) {
|
|
675
|
+
if (!activ.isLiked && activ.id) {
|
|
676
|
+
try {
|
|
677
|
+
const like = yield fetcher(likeActivityMutation, {
|
|
678
|
+
activityId: activ.id,
|
|
679
|
+
});
|
|
680
|
+
// const ToggleLike = like?.data?.ToggleLike
|
|
681
|
+
console.info(`${activityBy(activ)} ${(like === null || like === void 0 ? void 0 : like.data) ? "✅" : "❌"}`);
|
|
682
|
+
}
|
|
683
|
+
catch (error) {
|
|
684
|
+
console.error(`Activity possibly deleted. ${error.message}`);
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
else {
|
|
688
|
+
console.log(`${activityBy(activ)} 🔵`);
|
|
689
|
+
}
|
|
690
|
+
// avoiding rate-limit
|
|
691
|
+
yield new Promise((resolve) => {
|
|
692
|
+
setTimeout(resolve, 1500);
|
|
693
|
+
});
|
|
694
|
+
}
|
|
695
|
+
page++;
|
|
696
|
+
}
|
|
659
697
|
else {
|
|
660
698
|
// No more activities to like
|
|
661
699
|
console.log(`\nProbably the end of activities.`);
|
|
@@ -669,6 +707,139 @@ Statistics (Manga):
|
|
|
669
707
|
}
|
|
670
708
|
});
|
|
671
709
|
}
|
|
710
|
+
static LikeSpecificUser() {
|
|
711
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
712
|
+
var _a, _b, _c, _d;
|
|
713
|
+
try {
|
|
714
|
+
const { username } = yield inquirer.prompt([
|
|
715
|
+
{
|
|
716
|
+
type: "input",
|
|
717
|
+
name: "username",
|
|
718
|
+
message: "Username of the user:",
|
|
719
|
+
},
|
|
720
|
+
]);
|
|
721
|
+
const userDetails = yield fetcher(userQuery, { username: username });
|
|
722
|
+
if (userDetails) {
|
|
723
|
+
let page = 1;
|
|
724
|
+
const perPage = 50;
|
|
725
|
+
const userId = (_b = (_a = userDetails === null || userDetails === void 0 ? void 0 : userDetails.data) === null || _a === void 0 ? void 0 : _a.User) === null || _b === void 0 ? void 0 : _b.id;
|
|
726
|
+
if (userId) {
|
|
727
|
+
while (true) {
|
|
728
|
+
const activities = yield fetcher(specificUserActivitiesQuery, {
|
|
729
|
+
page,
|
|
730
|
+
perPage,
|
|
731
|
+
userId,
|
|
732
|
+
});
|
|
733
|
+
const activiti = (_d = (_c = activities === null || activities === void 0 ? void 0 : activities.data) === null || _c === void 0 ? void 0 : _c.Page) === null || _d === void 0 ? void 0 : _d.activities;
|
|
734
|
+
// Break the loop if no more activities are found
|
|
735
|
+
if (!activiti || activiti.length === 0) {
|
|
736
|
+
console.log("No more activities found.");
|
|
737
|
+
break;
|
|
738
|
+
}
|
|
739
|
+
for (let activ of activiti) {
|
|
740
|
+
if (!activ.isLiked && activ.id) {
|
|
741
|
+
try {
|
|
742
|
+
const like = yield fetcher(likeActivityMutation, {
|
|
743
|
+
activityId: activ.id,
|
|
744
|
+
});
|
|
745
|
+
console.info(`${activityBy(activ)} ${(like === null || like === void 0 ? void 0 : like.data) ? "✅" : "❌"}`);
|
|
746
|
+
}
|
|
747
|
+
catch (error) {
|
|
748
|
+
console.error(`Activity possibly deleted. ${error.message}`);
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
else {
|
|
752
|
+
console.log(`${activityBy(activ)} 🔵`);
|
|
753
|
+
}
|
|
754
|
+
// Avoiding rate limit
|
|
755
|
+
yield new Promise((resolve) => {
|
|
756
|
+
setTimeout(resolve, 1500);
|
|
757
|
+
});
|
|
758
|
+
}
|
|
759
|
+
// Go to the next page
|
|
760
|
+
page += 1;
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
catch (error) {
|
|
766
|
+
console.error(`\nError from LikeSpecificUser. ${error.message}`);
|
|
767
|
+
}
|
|
768
|
+
});
|
|
769
|
+
}
|
|
770
|
+
static LikeFollowingActivityV2(perPage) {
|
|
771
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
772
|
+
var _a, _b, _c, _d, _e;
|
|
773
|
+
try {
|
|
774
|
+
if (!(yield Auth.isLoggedIn())) {
|
|
775
|
+
console.error(`\nPlease log in to use this feature.`);
|
|
776
|
+
return;
|
|
777
|
+
}
|
|
778
|
+
const allFollowingUsers = [];
|
|
779
|
+
let hasNextPage = true;
|
|
780
|
+
let page = 1;
|
|
781
|
+
// Fetch all following users
|
|
782
|
+
while (hasNextPage) {
|
|
783
|
+
const followingUsers = yield fetcher(userFollowingQuery, {
|
|
784
|
+
userId: yield Auth.MyUserId(),
|
|
785
|
+
page,
|
|
786
|
+
});
|
|
787
|
+
if (!((_b = (_a = followingUsers === null || followingUsers === void 0 ? void 0 : followingUsers.data) === null || _a === void 0 ? void 0 : _a.Page) === null || _b === void 0 ? void 0 : _b.following)) {
|
|
788
|
+
console.error(`\nFailed to fetch following users.`);
|
|
789
|
+
return;
|
|
790
|
+
}
|
|
791
|
+
allFollowingUsers.push(...followingUsers.data.Page.following);
|
|
792
|
+
hasNextPage = followingUsers.data.Page.pageInfo.hasNextPage;
|
|
793
|
+
page++;
|
|
794
|
+
}
|
|
795
|
+
// Extract the IDs of all following users
|
|
796
|
+
const followingUserIds = allFollowingUsers.map((user) => user.id);
|
|
797
|
+
console.log(`\nTotal Following: ${followingUserIds.length}\nApproximately ${followingUserIds.length * perPage} activities to like.\nWill take around ${((followingUserIds.length * perPage * 1200) /
|
|
798
|
+
1000 /
|
|
799
|
+
60).toFixed(2)} minutes.`);
|
|
800
|
+
// Traverse the array and fetch users' activities one by one
|
|
801
|
+
let userNumber = 0;
|
|
802
|
+
for (const userId of followingUserIds) {
|
|
803
|
+
userNumber++;
|
|
804
|
+
console.log(`\n[${userNumber}]\tID: ${userId}`);
|
|
805
|
+
// Fetch `perPage` activities for the current user
|
|
806
|
+
const activities = yield fetcher(specificUserActivitiesQuery, {
|
|
807
|
+
userId,
|
|
808
|
+
page: 1, // Always fetch from the first page
|
|
809
|
+
perPage,
|
|
810
|
+
});
|
|
811
|
+
if (!((_e = (_d = (_c = activities === null || activities === void 0 ? void 0 : activities.data) === null || _c === void 0 ? void 0 : _c.Page) === null || _d === void 0 ? void 0 : _d.activities) === null || _e === void 0 ? void 0 : _e.length)) {
|
|
812
|
+
console.log(`[${userNumber}] No activities found for User ID: ${userId}`);
|
|
813
|
+
continue;
|
|
814
|
+
}
|
|
815
|
+
const activiti = activities.data.Page.activities;
|
|
816
|
+
for (let i = 0; i < activiti.length; i++) {
|
|
817
|
+
const activ = activiti[i];
|
|
818
|
+
if (!activ.isLiked && activ.id) {
|
|
819
|
+
try {
|
|
820
|
+
const like = yield fetcher(likeActivityMutation, {
|
|
821
|
+
activityId: activ.id,
|
|
822
|
+
});
|
|
823
|
+
console.info(`[${userNumber}/${i + 1}/${activiti.length}] ${activityBy(activ)} ${(like === null || like === void 0 ? void 0 : like.data) ? "✅" : "❌"}`);
|
|
824
|
+
}
|
|
825
|
+
catch (error) {
|
|
826
|
+
console.error(`[${userNumber}/${i + 1}/${activiti.length}] Activity possibly deleted. ${error.message}`);
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
else {
|
|
830
|
+
console.log(`[${userNumber}/${i + 1}/${activiti.length}] ${activityBy(activ)} 🔵`);
|
|
831
|
+
}
|
|
832
|
+
// Avoid rate-limiting
|
|
833
|
+
yield new Promise((resolve) => setTimeout(resolve, 1200));
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
console.log(`\n✅ All activities liked successfully.`);
|
|
837
|
+
}
|
|
838
|
+
catch (error) {
|
|
839
|
+
console.error(`\nError in LikeFollowingActivityV2: ${error.message}`);
|
|
840
|
+
}
|
|
841
|
+
});
|
|
842
|
+
}
|
|
672
843
|
static AutoLike() {
|
|
673
844
|
return __awaiter(this, void 0, void 0, function* () {
|
|
674
845
|
try {
|
|
@@ -684,16 +855,20 @@ Statistics (Manga):
|
|
|
684
855
|
choices: [
|
|
685
856
|
{ name: "Following", value: 1 },
|
|
686
857
|
{ name: "Global", value: 2 },
|
|
858
|
+
{ name: "Specific User", value: 3 },
|
|
687
859
|
],
|
|
688
860
|
pageSize: 10,
|
|
689
861
|
},
|
|
690
862
|
]);
|
|
691
863
|
switch (activityType) {
|
|
692
864
|
case 1:
|
|
693
|
-
yield this.
|
|
865
|
+
yield this.LikeFollowing();
|
|
694
866
|
break;
|
|
695
867
|
case 2:
|
|
696
|
-
|
|
868
|
+
yield this.Like(1);
|
|
869
|
+
break;
|
|
870
|
+
case 3:
|
|
871
|
+
yield this.LikeSpecificUser();
|
|
697
872
|
break;
|
|
698
873
|
default:
|
|
699
874
|
console.error(`\nInvalid choice. (${activityType})`);
|
package/bin/helpers/fetcher.d.ts
CHANGED
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
* Sends a GraphQL request to the AniList API.
|
|
3
3
|
*
|
|
4
4
|
* This function constructs a request with the provided query and variables,
|
|
5
|
-
* handles authorization, and processes the API response.
|
|
5
|
+
* handles authorization, and processes the API response. If a rate-limit error (429) is returned,
|
|
6
|
+
* it waits for 1 minute and retries the request.
|
|
6
7
|
*
|
|
7
8
|
* @param {string} query - The AniList GraphQL query to be executed.
|
|
8
9
|
* @param {object} variables - An object containing the variables for the query.
|
|
9
10
|
* @returns {Promise<object|null>} The response from the API as a JSON object if successful; otherwise, null.
|
|
10
11
|
*/
|
|
11
|
-
declare function fetcher(query: string, variables
|
|
12
|
+
declare function fetcher(query: string, variables: object): Promise<object | null>;
|
|
12
13
|
export { fetcher };
|