@irfanshadikrishad/anilist 1.2.16 → 1.3.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 -373
- package/LICENSE.md +382 -0
- package/bin/helpers/auth.d.ts +5 -0
- package/bin/helpers/auth.js +350 -33
- package/bin/helpers/lists.js +5 -4
- package/bin/helpers/mutations.d.ts +2 -1
- package/bin/helpers/mutations.js +37 -32
- package/bin/helpers/queries.d.ts +6 -3
- package/bin/helpers/queries.js +180 -150
- package/bin/helpers/truncate.d.ts +6 -0
- package/bin/helpers/truncate.js +10 -0
- package/bin/helpers/types.d.ts +53 -1
- package/bin/helpers/workers.d.ts +3 -2
- package/bin/helpers/workers.js +88 -68
- package/bin/index.js +7 -0
- package/package.json +16 -14
package/bin/helpers/auth.js
CHANGED
|
@@ -7,21 +7,25 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
+
import { Cipher } from "@irfanshadikrishad/cipher";
|
|
10
11
|
import fs from "fs";
|
|
11
12
|
import inquirer from "inquirer";
|
|
12
13
|
import fetch from "node-fetch";
|
|
13
14
|
import open from "open";
|
|
14
15
|
import os from "os";
|
|
15
16
|
import path from "path";
|
|
17
|
+
import { exit } from "process";
|
|
16
18
|
import Spinner from "tiny-spinner";
|
|
17
19
|
import { fetcher } from "./fetcher.js";
|
|
18
20
|
import { AniDB, AniList, MyAnimeList } from "./lists.js";
|
|
19
|
-
import { deleteActivityMutation, saveTextActivityMutation, } from "./mutations.js";
|
|
20
|
-
import { activityAllQuery, activityAnimeListQuery, activityMangaListQuery, activityMediaList, activityMessageQuery, activityTextQuery, currentUserAnimeList, currentUserMangaList, currentUserQuery, deleteMangaEntryMutation, deleteMediaEntryMutation, toggleFollowMutation, userActivityQuery, userFollowersQuery, userFollowingQuery, } from "./queries.js";
|
|
21
|
-
import {
|
|
21
|
+
import { deleteActivityMutation, likeActivityMutation, saveTextActivityMutation, } from "./mutations.js";
|
|
22
|
+
import { activityAllQuery, activityAnimeListQuery, activityMangaListQuery, activityMediaList, activityMessageQuery, activityTextQuery, currentUserAnimeList, currentUserMangaList, currentUserQuery, deleteMangaEntryMutation, deleteMediaEntryMutation, followingActivitiesQuery, globalActivitiesQuery, specificUserActivitiesQuery, toggleFollowMutation, userActivityQuery, userFollowersQuery, userFollowingQuery, userQuery, } from "./queries.js";
|
|
23
|
+
import { responsiveOutput } from "./truncate.js";
|
|
24
|
+
import { activityBy, aniListEndpoint, getTitle, redirectUri, timestampToTimeAgo, } from "./workers.js";
|
|
22
25
|
const home_dir = os.homedir();
|
|
23
26
|
const save_path = path.join(home_dir, ".anilist_token");
|
|
24
27
|
const spinner = new Spinner();
|
|
28
|
+
const vigenere = new Cipher.Vigenere("anilist");
|
|
25
29
|
class Auth {
|
|
26
30
|
/**
|
|
27
31
|
* Get access-token from user
|
|
@@ -55,7 +59,7 @@ class Auth {
|
|
|
55
59
|
console.warn("\nNo token provided. Nothing to store.");
|
|
56
60
|
return;
|
|
57
61
|
}
|
|
58
|
-
fs.writeFileSync(save_path, token, { encoding: "utf8" });
|
|
62
|
+
fs.writeFileSync(save_path, vigenere.encrypt(token), { encoding: "utf8" });
|
|
59
63
|
}
|
|
60
64
|
catch (error) {
|
|
61
65
|
console.error(`\nError storing access token: ${error.message}`);
|
|
@@ -66,7 +70,7 @@ class Auth {
|
|
|
66
70
|
return __awaiter(this, void 0, void 0, function* () {
|
|
67
71
|
try {
|
|
68
72
|
if (fs.existsSync(save_path)) {
|
|
69
|
-
return fs.readFileSync(save_path, { encoding: "utf8" });
|
|
73
|
+
return vigenere.decrypt(fs.readFileSync(save_path, { encoding: "utf8" }));
|
|
70
74
|
}
|
|
71
75
|
else {
|
|
72
76
|
return null;
|
|
@@ -151,38 +155,38 @@ class Auth {
|
|
|
151
155
|
});
|
|
152
156
|
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;
|
|
153
157
|
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;
|
|
154
|
-
console.log(`
|
|
155
|
-
ID: ${user === null || user === void 0 ? void 0 : user.id}
|
|
156
|
-
Name: ${user === null || user === void 0 ? void 0 : user.name}
|
|
157
|
-
siteUrl: ${user === null || user === void 0 ? void 0 : user.siteUrl}
|
|
158
|
-
profileColor: ${(_j = user === null || user === void 0 ? void 0 : user.options) === null || _j === void 0 ? void 0 : _j.profileColor}
|
|
159
|
-
timeZone: ${(_k = user === null || user === void 0 ? void 0 : user.options) === null || _k === void 0 ? void 0 : _k.timezone}
|
|
160
|
-
activityMergeTime: ${(_l = user === null || user === void 0 ? void 0 : user.options) === null || _l === void 0 ? void 0 : _l.activityMergeTime}
|
|
161
|
-
donatorTier: ${user === null || user === void 0 ? void 0 : user.donatorTier}
|
|
162
|
-
donatorBadge: ${user === null || user === void 0 ? void 0 : user.donatorBadge}
|
|
163
|
-
unreadNotificationCount:${user === null || user === void 0 ? void 0 : user.unreadNotificationCount}
|
|
164
|
-
Account Created: ${new Date((user === null || user === void 0 ? void 0 : user.createdAt) * 1000).toUTCString()}
|
|
165
|
-
Account Updated: ${new Date((user === null || user === void 0 ? void 0 : user.updatedAt) * 1000).toUTCString()}
|
|
166
|
-
|
|
167
|
-
Followers: ${followersCount}
|
|
168
|
-
Following: ${followingCount}
|
|
169
|
-
|
|
170
|
-
Statistics (Anime):
|
|
171
|
-
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}
|
|
172
|
-
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}
|
|
173
|
-
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}
|
|
174
|
-
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}
|
|
175
|
-
|
|
176
|
-
Statistics (Manga):
|
|
177
|
-
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}
|
|
178
|
-
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}
|
|
179
|
-
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}
|
|
180
|
-
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}
|
|
158
|
+
console.log(`
|
|
159
|
+
ID: ${user === null || user === void 0 ? void 0 : user.id}
|
|
160
|
+
Name: ${user === null || user === void 0 ? void 0 : user.name}
|
|
161
|
+
siteUrl: ${user === null || user === void 0 ? void 0 : user.siteUrl}
|
|
162
|
+
profileColor: ${(_j = user === null || user === void 0 ? void 0 : user.options) === null || _j === void 0 ? void 0 : _j.profileColor}
|
|
163
|
+
timeZone: ${(_k = user === null || user === void 0 ? void 0 : user.options) === null || _k === void 0 ? void 0 : _k.timezone}
|
|
164
|
+
activityMergeTime: ${(_l = user === null || user === void 0 ? void 0 : user.options) === null || _l === void 0 ? void 0 : _l.activityMergeTime}
|
|
165
|
+
donatorTier: ${user === null || user === void 0 ? void 0 : user.donatorTier}
|
|
166
|
+
donatorBadge: ${user === null || user === void 0 ? void 0 : user.donatorBadge}
|
|
167
|
+
unreadNotificationCount:${user === null || user === void 0 ? void 0 : user.unreadNotificationCount}
|
|
168
|
+
Account Created: ${new Date((user === null || user === void 0 ? void 0 : user.createdAt) * 1000).toUTCString()}
|
|
169
|
+
Account Updated: ${new Date((user === null || user === void 0 ? void 0 : user.updatedAt) * 1000).toUTCString()}
|
|
170
|
+
|
|
171
|
+
Followers: ${followersCount}
|
|
172
|
+
Following: ${followingCount}
|
|
173
|
+
|
|
174
|
+
Statistics (Anime):
|
|
175
|
+
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}
|
|
176
|
+
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}
|
|
177
|
+
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}
|
|
178
|
+
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}
|
|
179
|
+
|
|
180
|
+
Statistics (Manga):
|
|
181
|
+
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}
|
|
182
|
+
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}
|
|
183
|
+
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}
|
|
184
|
+
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}
|
|
181
185
|
`);
|
|
182
186
|
console.log(`\nRecent Activities:`);
|
|
183
187
|
if (activities.length > 0) {
|
|
184
188
|
activities.map(({ status, progress, media, createdAt }) => {
|
|
185
|
-
|
|
189
|
+
responsiveOutput(`${timestampToTimeAgo(createdAt)}\t${status} ${progress ? `${progress} of ` : ""}${getTitle(media === null || media === void 0 ? void 0 : media.title)}`);
|
|
186
190
|
});
|
|
187
191
|
}
|
|
188
192
|
return user;
|
|
@@ -568,6 +572,319 @@ Statistics (Manga):
|
|
|
568
572
|
}
|
|
569
573
|
});
|
|
570
574
|
}
|
|
575
|
+
static LikeFollowing() {
|
|
576
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
577
|
+
var _a, _b, _c, _d, _e, _f;
|
|
578
|
+
try {
|
|
579
|
+
let page = 1;
|
|
580
|
+
let hasMoreActivities = true;
|
|
581
|
+
let retryCount = 0;
|
|
582
|
+
const maxRetries = 5;
|
|
583
|
+
let likedCount = 0;
|
|
584
|
+
while (hasMoreActivities) {
|
|
585
|
+
const activities = yield fetcher(followingActivitiesQuery, {
|
|
586
|
+
page,
|
|
587
|
+
perPage: 50,
|
|
588
|
+
});
|
|
589
|
+
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) {
|
|
590
|
+
spinner.success(`Got ${(_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.length} activities..`);
|
|
591
|
+
retryCount = 0; // Reset retry count on successful fetch
|
|
592
|
+
const activiti = (_f = (_e = activities === null || activities === void 0 ? void 0 : activities.data) === null || _e === void 0 ? void 0 : _e.Page) === null || _f === void 0 ? void 0 : _f.activities;
|
|
593
|
+
for (let activ of activiti) {
|
|
594
|
+
if (!activ.isLiked && activ.id) {
|
|
595
|
+
try {
|
|
596
|
+
const like = yield fetcher(likeActivityMutation, {
|
|
597
|
+
activityId: activ.id,
|
|
598
|
+
});
|
|
599
|
+
if (like === null || like === void 0 ? void 0 : like.data) {
|
|
600
|
+
likedCount++;
|
|
601
|
+
}
|
|
602
|
+
responsiveOutput(`${(like === null || like === void 0 ? void 0 : like.data) ? "✅" : "❌"} ${activityBy(activ, likedCount)}`);
|
|
603
|
+
}
|
|
604
|
+
catch (error) {
|
|
605
|
+
console.error(`Activity possibly deleted. ${error.message}`);
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
else {
|
|
609
|
+
responsiveOutput(`"🔵" ${activityBy(activ, likedCount)}`);
|
|
610
|
+
}
|
|
611
|
+
// avoiding rate-limit
|
|
612
|
+
yield new Promise((resolve) => {
|
|
613
|
+
setTimeout(resolve, 2000);
|
|
614
|
+
});
|
|
615
|
+
}
|
|
616
|
+
page++;
|
|
617
|
+
}
|
|
618
|
+
else {
|
|
619
|
+
if (retryCount < maxRetries) {
|
|
620
|
+
spinner.start("Getting activities...");
|
|
621
|
+
retryCount++;
|
|
622
|
+
spinner.update(`Empty activities returned. Retrying... (${retryCount}/${maxRetries})`);
|
|
623
|
+
yield new Promise((resolve) => setTimeout(resolve, 2000));
|
|
624
|
+
}
|
|
625
|
+
else {
|
|
626
|
+
spinner.error(`Probably the end of activities after ${maxRetries} retries.`);
|
|
627
|
+
hasMoreActivities = false;
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
catch (error) {
|
|
633
|
+
console.error(`\nError from likeFollowing. ${error.message}`);
|
|
634
|
+
}
|
|
635
|
+
});
|
|
636
|
+
}
|
|
637
|
+
static LikeGlobal() {
|
|
638
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
639
|
+
var _a, _b, _c, _d, _e, _f;
|
|
640
|
+
try {
|
|
641
|
+
let page = 1;
|
|
642
|
+
let hasMoreActivities = true;
|
|
643
|
+
let likedCount = 0;
|
|
644
|
+
spinner.start(`Getting global activities...`);
|
|
645
|
+
while (hasMoreActivities) {
|
|
646
|
+
const activities = yield fetcher(globalActivitiesQuery, {
|
|
647
|
+
page,
|
|
648
|
+
perPage: 50,
|
|
649
|
+
});
|
|
650
|
+
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) {
|
|
651
|
+
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;
|
|
652
|
+
spinner.success(`Got ${activiti.length} activities...`);
|
|
653
|
+
for (let activ of activiti) {
|
|
654
|
+
if (!activ.isLiked && activ.id) {
|
|
655
|
+
try {
|
|
656
|
+
const like = yield fetcher(likeActivityMutation, {
|
|
657
|
+
activityId: activ.id,
|
|
658
|
+
});
|
|
659
|
+
// const ToggleLike = like?.data?.ToggleLike
|
|
660
|
+
likedCount++;
|
|
661
|
+
responsiveOutput(`${(like === null || like === void 0 ? void 0 : like.data) ? "✅" : "❌"} ${activityBy(activ, likedCount)}`);
|
|
662
|
+
}
|
|
663
|
+
catch (error) {
|
|
664
|
+
console.error(`Activity possibly deleted. ${error.message}`);
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
else {
|
|
668
|
+
responsiveOutput(`🔵 ${activityBy(activ, likedCount)}`);
|
|
669
|
+
}
|
|
670
|
+
// avoiding rate-limit
|
|
671
|
+
yield new Promise((resolve) => {
|
|
672
|
+
setTimeout(resolve, 1500);
|
|
673
|
+
});
|
|
674
|
+
}
|
|
675
|
+
page++;
|
|
676
|
+
}
|
|
677
|
+
else {
|
|
678
|
+
// No more activities to like
|
|
679
|
+
spinner.error(`Probably the end of activities. ${(_f = (_e = activities === null || activities === void 0 ? void 0 : activities.data) === null || _e === void 0 ? void 0 : _e.Page) === null || _f === void 0 ? void 0 : _f.activities}`);
|
|
680
|
+
hasMoreActivities = false;
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
catch (error) {
|
|
685
|
+
console.error(`\nError from likeFollowing. ${error.message}`);
|
|
686
|
+
}
|
|
687
|
+
});
|
|
688
|
+
}
|
|
689
|
+
static LikeSpecificUser() {
|
|
690
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
691
|
+
var _a, _b, _c, _d, _e, _f;
|
|
692
|
+
try {
|
|
693
|
+
const { username } = yield inquirer.prompt([
|
|
694
|
+
{
|
|
695
|
+
type: "input",
|
|
696
|
+
name: "username",
|
|
697
|
+
message: "Username of the user:",
|
|
698
|
+
},
|
|
699
|
+
]);
|
|
700
|
+
const userDetails = yield fetcher(userQuery, { username: username });
|
|
701
|
+
spinner.start(`Getting activities by ${username}`);
|
|
702
|
+
if ((_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) {
|
|
703
|
+
let page = 1;
|
|
704
|
+
const perPage = 50;
|
|
705
|
+
const userId = (_d = (_c = userDetails === null || userDetails === void 0 ? void 0 : userDetails.data) === null || _c === void 0 ? void 0 : _c.User) === null || _d === void 0 ? void 0 : _d.id;
|
|
706
|
+
let likedCount = 0;
|
|
707
|
+
if (userId) {
|
|
708
|
+
while (true) {
|
|
709
|
+
const activities = yield fetcher(specificUserActivitiesQuery, {
|
|
710
|
+
page,
|
|
711
|
+
perPage,
|
|
712
|
+
userId,
|
|
713
|
+
});
|
|
714
|
+
const activiti = (_f = (_e = activities === null || activities === void 0 ? void 0 : activities.data) === null || _e === void 0 ? void 0 : _e.Page) === null || _f === void 0 ? void 0 : _f.activities;
|
|
715
|
+
// Break the loop if no more activities are found
|
|
716
|
+
if (!activiti || activiti.length === 0) {
|
|
717
|
+
spinner.error("No more activities found.");
|
|
718
|
+
break;
|
|
719
|
+
}
|
|
720
|
+
spinner.success(`Got ${activiti.length} activities...`);
|
|
721
|
+
for (let activ of activiti) {
|
|
722
|
+
if (!activ.isLiked && activ.id) {
|
|
723
|
+
try {
|
|
724
|
+
const like = yield fetcher(likeActivityMutation, {
|
|
725
|
+
activityId: activ.id,
|
|
726
|
+
});
|
|
727
|
+
likedCount++;
|
|
728
|
+
responsiveOutput(`${(like === null || like === void 0 ? void 0 : like.data) ? "✅" : "❌"} ${activityBy(activ, likedCount)}`);
|
|
729
|
+
}
|
|
730
|
+
catch (error) {
|
|
731
|
+
console.error(`Activity possibly deleted. ${error.message}`);
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
else {
|
|
735
|
+
responsiveOutput(`🔵 ${activityBy(activ, likedCount)}`);
|
|
736
|
+
}
|
|
737
|
+
// Avoiding rate limit
|
|
738
|
+
yield new Promise((resolve) => {
|
|
739
|
+
setTimeout(resolve, 1500);
|
|
740
|
+
});
|
|
741
|
+
}
|
|
742
|
+
// Go to the next page
|
|
743
|
+
page += 1;
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
else {
|
|
748
|
+
spinner.error(`User ${username} does not exist.`);
|
|
749
|
+
exit(1);
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
catch (error) {
|
|
753
|
+
console.error(`\nError from LikeSpecificUser. ${error.message}`);
|
|
754
|
+
}
|
|
755
|
+
});
|
|
756
|
+
}
|
|
757
|
+
static LikeFollowingActivityV2(perPage) {
|
|
758
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
759
|
+
var _a, _b, _c, _d, _e;
|
|
760
|
+
try {
|
|
761
|
+
if (!(yield Auth.isLoggedIn())) {
|
|
762
|
+
console.error(`\nPlease log in to use this feature.`);
|
|
763
|
+
return;
|
|
764
|
+
}
|
|
765
|
+
const allFollowingUsers = [];
|
|
766
|
+
let hasNextPage = true;
|
|
767
|
+
let page = 1;
|
|
768
|
+
let liked = 0;
|
|
769
|
+
// Fetch all following users
|
|
770
|
+
spinner.start(`Gathering following information...`);
|
|
771
|
+
while (hasNextPage) {
|
|
772
|
+
spinner.update(`Fetched page ${page}...`);
|
|
773
|
+
const followingUsers = yield fetcher(userFollowingQuery, {
|
|
774
|
+
userId: yield Auth.MyUserId(),
|
|
775
|
+
page,
|
|
776
|
+
});
|
|
777
|
+
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)) {
|
|
778
|
+
console.error(`\nFailed to fetch following users.`);
|
|
779
|
+
return;
|
|
780
|
+
}
|
|
781
|
+
allFollowingUsers.push(...followingUsers.data.Page.following);
|
|
782
|
+
hasNextPage = followingUsers.data.Page.pageInfo.hasNextPage;
|
|
783
|
+
page++;
|
|
784
|
+
}
|
|
785
|
+
spinner.stop(`Got ${allFollowingUsers.length} following user.`);
|
|
786
|
+
// Extract the IDs of all following users
|
|
787
|
+
const followingUserIds = allFollowingUsers.map((user) => user.id);
|
|
788
|
+
console.log(`\nTotal Following: ${followingUserIds.length}\nApproximately ${followingUserIds.length * perPage} activities to like.\nWill take around ${((followingUserIds.length * perPage * 1200) /
|
|
789
|
+
1000 /
|
|
790
|
+
60).toFixed(2)} minutes.`);
|
|
791
|
+
// Traverse the array and fetch users' activities one by one
|
|
792
|
+
let userNumber = 0;
|
|
793
|
+
for (const userId of followingUserIds) {
|
|
794
|
+
userNumber++;
|
|
795
|
+
console.log(`\n[${userNumber}]\tID: ${userId}`);
|
|
796
|
+
// Fetch `perPage` activities for the current user
|
|
797
|
+
const activities = yield fetcher(specificUserActivitiesQuery, {
|
|
798
|
+
userId,
|
|
799
|
+
page: 1, // Always fetch from the first page
|
|
800
|
+
perPage,
|
|
801
|
+
});
|
|
802
|
+
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)) {
|
|
803
|
+
console.log(`[${userNumber}] No activities found for User ID: ${userId}`);
|
|
804
|
+
continue;
|
|
805
|
+
}
|
|
806
|
+
const activiti = activities.data.Page.activities;
|
|
807
|
+
for (let i = 0; i < activiti.length; i++) {
|
|
808
|
+
const activ = activiti[i];
|
|
809
|
+
if (!activ.isLiked && activ.id) {
|
|
810
|
+
try {
|
|
811
|
+
const like = yield fetcher(likeActivityMutation, {
|
|
812
|
+
activityId: activ.id,
|
|
813
|
+
});
|
|
814
|
+
responsiveOutput(`${(like === null || like === void 0 ? void 0 : like.data) ? "✅" : "❌"} ${activityBy(activ, i + 1)}`);
|
|
815
|
+
if (like === null || like === void 0 ? void 0 : like.data) {
|
|
816
|
+
liked++;
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
catch (error) {
|
|
820
|
+
console.error(`Activity possibly deleted. ${error.message}`);
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
else {
|
|
824
|
+
responsiveOutput(`🔵 ${activityBy(activ, i + 1)}`);
|
|
825
|
+
}
|
|
826
|
+
// Avoid rate-limiting
|
|
827
|
+
yield new Promise((resolve) => setTimeout(resolve, 1200));
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
console.log(`\n✅ All ${liked} activities liked successfully.`);
|
|
831
|
+
}
|
|
832
|
+
catch (error) {
|
|
833
|
+
console.error(`\nError in LikeFollowingActivityV2: ${error.message}`);
|
|
834
|
+
}
|
|
835
|
+
});
|
|
836
|
+
}
|
|
837
|
+
static AutoLike() {
|
|
838
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
839
|
+
try {
|
|
840
|
+
if (!(yield Auth.isLoggedIn())) {
|
|
841
|
+
console.error(`\nPlease login to use this feature.`);
|
|
842
|
+
return;
|
|
843
|
+
}
|
|
844
|
+
const { activityType } = yield inquirer.prompt([
|
|
845
|
+
{
|
|
846
|
+
type: "list",
|
|
847
|
+
name: "activityType",
|
|
848
|
+
message: "Select activity type:",
|
|
849
|
+
choices: [
|
|
850
|
+
{ name: "Following • v1", value: 1 },
|
|
851
|
+
{ name: "Following • v2", value: 2 },
|
|
852
|
+
{ name: "Global", value: 3 },
|
|
853
|
+
{ name: "Specific User", value: 4 },
|
|
854
|
+
],
|
|
855
|
+
pageSize: 10,
|
|
856
|
+
},
|
|
857
|
+
]);
|
|
858
|
+
switch (activityType) {
|
|
859
|
+
case 1:
|
|
860
|
+
yield this.LikeFollowing();
|
|
861
|
+
break;
|
|
862
|
+
case 2: {
|
|
863
|
+
const { count } = yield inquirer.prompt([
|
|
864
|
+
{
|
|
865
|
+
type: "number",
|
|
866
|
+
name: "count",
|
|
867
|
+
message: "Likes to give:",
|
|
868
|
+
},
|
|
869
|
+
]);
|
|
870
|
+
yield this.LikeFollowingActivityV2(count);
|
|
871
|
+
break;
|
|
872
|
+
}
|
|
873
|
+
case 3:
|
|
874
|
+
yield this.LikeGlobal();
|
|
875
|
+
break;
|
|
876
|
+
case 4:
|
|
877
|
+
yield this.LikeSpecificUser();
|
|
878
|
+
break;
|
|
879
|
+
default:
|
|
880
|
+
console.error(`\nInvalid choice. (${activityType})`);
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
catch (error) {
|
|
884
|
+
console.error(`\nError from autolike. ${error.message}`);
|
|
885
|
+
}
|
|
886
|
+
});
|
|
887
|
+
}
|
|
571
888
|
}
|
|
572
889
|
class Social {
|
|
573
890
|
/**
|
package/bin/helpers/lists.js
CHANGED
|
@@ -16,6 +16,7 @@ import { Auth } from "./auth.js";
|
|
|
16
16
|
import { fetcher } from "./fetcher.js";
|
|
17
17
|
import { addAnimeToListMutation, addMangaToListMutation, saveAnimeWithProgressMutation, saveMangaWithProgressMutation, } from "./mutations.js";
|
|
18
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
21
|
import { Validate } from "./validation.js";
|
|
21
22
|
import { anidbToanilistMapper, formatDateObject, getDownloadFolderPath, getNextSeasonAndYear, getTitle, removeHtmlAndMarkdown, saveJSONasCSV, saveJSONasJSON, saveJSONasXML, selectFile, simpleDateFormat, timestampToTimeAgo, } from "./workers.js";
|
|
@@ -661,7 +662,7 @@ class AniList {
|
|
|
661
662
|
if (activities.length > 0) {
|
|
662
663
|
console.log(`\nRecent Activities:`);
|
|
663
664
|
activities.forEach(({ status, progress, media, createdAt }) => {
|
|
664
|
-
|
|
665
|
+
responsiveOutput(`${timestampToTimeAgo(createdAt)}\t${status} ${progress ? `${progress} of ` : ""}${getTitle(media === null || media === void 0 ? void 0 : media.title)}`);
|
|
665
666
|
});
|
|
666
667
|
}
|
|
667
668
|
else {
|
|
@@ -1119,7 +1120,7 @@ class AniDB {
|
|
|
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;
|
|
1120
1121
|
if (entryId) {
|
|
1121
1122
|
count++;
|
|
1122
|
-
|
|
1123
|
+
responsiveOutput(`[${count}]\t${entryId} ✅\t${anidbId}\t${anilistId}\t(${ownEpisodes}/${totalEpisodes})\t${status}–>${getStatus(status, ownEpisodes)}`);
|
|
1123
1124
|
}
|
|
1124
1125
|
// Rate limit each API call to avoid server overload
|
|
1125
1126
|
// await new Promise((resolve) => setTimeout(resolve, 1100))
|
|
@@ -1136,9 +1137,9 @@ class AniDB {
|
|
|
1136
1137
|
});
|
|
1137
1138
|
}
|
|
1138
1139
|
}
|
|
1139
|
-
|
|
1140
|
+
responsiveOutput(`\nAccuracy: ${(((animeList.length - missed.length) / animeList.length) * 100).toFixed(2)}%\tTotal Processed: ${iteration}\tMissed: ${missed.length}`);
|
|
1140
1141
|
if (missed.length > 0) {
|
|
1141
|
-
|
|
1142
|
+
responsiveOutput(`Exporting missed entries to JSON file, Please add them manually.`);
|
|
1142
1143
|
yield saveJSONasJSON(missed, "anidb-missed");
|
|
1143
1144
|
}
|
|
1144
1145
|
}
|
|
@@ -4,4 +4,5 @@ declare const deleteActivityMutation = "\nmutation($id: Int!) {\n DeleteActivit
|
|
|
4
4
|
declare const saveTextActivityMutation = "\nmutation SaveTextActivity($status: String!) {\n SaveTextActivity(text: $status) { id text userId createdAt }\n}\n";
|
|
5
5
|
declare const saveAnimeWithProgressMutation = "\nmutation ($mediaId: Int, $progress: Int, $status: MediaListStatus, $hiddenFromStatusLists: Boolean) {\n SaveMediaListEntry(mediaId: $mediaId, progress: $progress, status: $status, hiddenFromStatusLists: $hiddenFromStatusLists) {\n id progress hiddenFromStatusLists\n }\n}\n";
|
|
6
6
|
declare const saveMangaWithProgressMutation = "\nmutation ($mediaId: Int, $progress: Int, $status: MediaListStatus, $hiddenFromStatusLists: Boolean, $private: Boolean) {\n SaveMediaListEntry( mediaId: $mediaId, progress: $progress, status: $status, hiddenFromStatusLists: $hiddenFromStatusLists, private: $private\n ) { id progress hiddenFromStatusLists private }\n}\n";
|
|
7
|
-
|
|
7
|
+
declare const likeActivityMutation = "\nmutation($activityId: Int!) {\n ToggleLike(id: $activityId, type: ACTIVITY) { id }\n}\n";
|
|
8
|
+
export { addAnimeToListMutation, addMangaToListMutation, deleteActivityMutation, likeActivityMutation, saveAnimeWithProgressMutation, saveMangaWithProgressMutation, saveTextActivityMutation, };
|
package/bin/helpers/mutations.js
CHANGED
|
@@ -1,38 +1,43 @@
|
|
|
1
|
-
const addAnimeToListMutation = `
|
|
2
|
-
mutation($mediaId: Int, $status: MediaListStatus) {
|
|
3
|
-
SaveMediaListEntry(mediaId: $mediaId, status: $status) { id status }
|
|
4
|
-
}
|
|
1
|
+
const addAnimeToListMutation = `
|
|
2
|
+
mutation($mediaId: Int, $status: MediaListStatus) {
|
|
3
|
+
SaveMediaListEntry(mediaId: $mediaId, status: $status) { id status }
|
|
4
|
+
}
|
|
5
5
|
`;
|
|
6
|
-
const addMangaToListMutation = `
|
|
7
|
-
mutation($mediaId: Int, $status: MediaListStatus) {
|
|
8
|
-
SaveMediaListEntry(mediaId: $mediaId, status: $status) {
|
|
9
|
-
id
|
|
10
|
-
status
|
|
11
|
-
media { id title { romaji english } }
|
|
12
|
-
}
|
|
13
|
-
}
|
|
6
|
+
const addMangaToListMutation = `
|
|
7
|
+
mutation($mediaId: Int, $status: MediaListStatus) {
|
|
8
|
+
SaveMediaListEntry(mediaId: $mediaId, status: $status) {
|
|
9
|
+
id
|
|
10
|
+
status
|
|
11
|
+
media { id title { romaji english } }
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
14
|
`;
|
|
15
|
-
const deleteActivityMutation = `
|
|
16
|
-
mutation($id: Int!) {
|
|
17
|
-
DeleteActivity(id: $id) { deleted }
|
|
18
|
-
}
|
|
15
|
+
const deleteActivityMutation = `
|
|
16
|
+
mutation($id: Int!) {
|
|
17
|
+
DeleteActivity(id: $id) { deleted }
|
|
18
|
+
}
|
|
19
19
|
`;
|
|
20
|
-
const saveTextActivityMutation = `
|
|
21
|
-
mutation SaveTextActivity($status: String!) {
|
|
22
|
-
SaveTextActivity(text: $status) { id text userId createdAt }
|
|
23
|
-
}
|
|
20
|
+
const saveTextActivityMutation = `
|
|
21
|
+
mutation SaveTextActivity($status: String!) {
|
|
22
|
+
SaveTextActivity(text: $status) { id text userId createdAt }
|
|
23
|
+
}
|
|
24
24
|
`;
|
|
25
|
-
const saveAnimeWithProgressMutation = `
|
|
26
|
-
mutation ($mediaId: Int, $progress: Int, $status: MediaListStatus, $hiddenFromStatusLists: Boolean) {
|
|
27
|
-
SaveMediaListEntry(mediaId: $mediaId, progress: $progress, status: $status, hiddenFromStatusLists: $hiddenFromStatusLists) {
|
|
28
|
-
id progress hiddenFromStatusLists
|
|
29
|
-
}
|
|
30
|
-
}
|
|
25
|
+
const saveAnimeWithProgressMutation = `
|
|
26
|
+
mutation ($mediaId: Int, $progress: Int, $status: MediaListStatus, $hiddenFromStatusLists: Boolean) {
|
|
27
|
+
SaveMediaListEntry(mediaId: $mediaId, progress: $progress, status: $status, hiddenFromStatusLists: $hiddenFromStatusLists) {
|
|
28
|
+
id progress hiddenFromStatusLists
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
31
|
`;
|
|
32
|
-
const saveMangaWithProgressMutation = `
|
|
33
|
-
mutation ($mediaId: Int, $progress: Int, $status: MediaListStatus, $hiddenFromStatusLists: Boolean, $private: Boolean) {
|
|
34
|
-
SaveMediaListEntry( mediaId: $mediaId, progress: $progress, status: $status, hiddenFromStatusLists: $hiddenFromStatusLists, private: $private
|
|
35
|
-
) { id progress hiddenFromStatusLists private }
|
|
36
|
-
}
|
|
32
|
+
const saveMangaWithProgressMutation = `
|
|
33
|
+
mutation ($mediaId: Int, $progress: Int, $status: MediaListStatus, $hiddenFromStatusLists: Boolean, $private: Boolean) {
|
|
34
|
+
SaveMediaListEntry( mediaId: $mediaId, progress: $progress, status: $status, hiddenFromStatusLists: $hiddenFromStatusLists, private: $private
|
|
35
|
+
) { id progress hiddenFromStatusLists private }
|
|
36
|
+
}
|
|
37
37
|
`;
|
|
38
|
-
|
|
38
|
+
const likeActivityMutation = `
|
|
39
|
+
mutation($activityId: Int!) {
|
|
40
|
+
ToggleLike(id: $activityId, type: ACTIVITY) { id }
|
|
41
|
+
}
|
|
42
|
+
`;
|
|
43
|
+
export { addAnimeToListMutation, addMangaToListMutation, deleteActivityMutation, likeActivityMutation, saveAnimeWithProgressMutation, saveMangaWithProgressMutation, saveTextActivityMutation, };
|
package/bin/helpers/queries.d.ts
CHANGED
|
@@ -17,10 +17,13 @@ declare const activityMangaListQuery = "query ($userId: Int, $page: Int, $perPag
|
|
|
17
17
|
declare const activityMessageQuery = "query ($userId: Int, $page: Int, $perPage: Int) {\n Page(page: $page, perPage: $perPage) {\n activities(userId: $userId, type: MESSAGE, sort: ID_DESC) {\n ... on MessageActivity { id type message recipient { id name } createdAt }\n }\n }\n}";
|
|
18
18
|
declare const activityAllQuery = "query ($userId: Int, $page: Int, $perPage: Int) {\n Page(page: $page, perPage: $perPage) {\n activities(userId: $userId, sort: ID_DESC) {\n ... on TextActivity { id type text createdAt user { id name } }\n ... on ListActivity { id type status progress createdAt media { id title { romaji english native } } }\n ... on MessageActivity { id type message recipient { id name } createdAt }\n }\n }\n}";
|
|
19
19
|
declare const activityMediaList = "query ($userId: Int, $page: Int, $perPage: Int, $type: ActivityType) {\n Page(page: $page, perPage: $perPage) {\n pageInfo { total currentPage lastPage hasNextPage perPage }\n activities(userId: $userId, type: $type, sort: ID_DESC) {\n ... on ListActivity { id type status progress media { id title { romaji english native } format } createdAt }\n }\n }\n}";
|
|
20
|
-
declare const malIdToAnilistAnimeId = "query ($malId: Int) {\n Media(idMal: $malId, type: ANIME) {
|
|
21
|
-
declare const malIdToAnilistMangaId = "query ($malId: Int) {\n Media(idMal: $malId, type: MANGA) {
|
|
20
|
+
declare const malIdToAnilistAnimeId = "query ($malId: Int) {\n Media(idMal: $malId, type: ANIME) { id title { romaji english } } }\n";
|
|
21
|
+
declare const malIdToAnilistMangaId = "query ($malId: Int) {\n Media(idMal: $malId, type: MANGA) { id title { romaji english } } }\n";
|
|
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
|
+
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
|
+
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";
|
|
22
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";
|
|
23
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";
|
|
24
27
|
declare const toggleFollowMutation = "mutation ($userId: Int!) {\n ToggleFollow(userId: $userId) { id name isFollower isFollowing }\n}\n";
|
|
25
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";
|
|
26
|
-
export { activityAllQuery, activityAnimeListQuery, activityMangaListQuery, activityMediaList, activityMessageQuery, activityTextQuery, animeDetailsQuery, animeSearchQuery, currentUserAnimeList, currentUserMangaList, currentUserQuery, deleteMangaEntryMutation, deleteMediaEntryMutation, malIdToAnilistAnimeId, malIdToAnilistMangaId, mangaDetailsQuery, mangaSearchQuery, popularQuery, toggleFollowMutation, trendingQuery, upcomingAnimesQuery, userActivityQuery, userFollowersQuery, userFollowingQuery, userQuery, };
|
|
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, };
|