@irfanshadikrishad/anilist 1.0.0 → 1.0.1-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 +165 -26
- package/bin/helpers/auth.d.ts +67 -9
- package/bin/helpers/auth.js +943 -141
- package/bin/helpers/fetcher.d.ts +13 -0
- package/bin/helpers/fetcher.js +59 -0
- package/bin/helpers/lists.d.ts +25 -7
- package/bin/helpers/lists.js +1023 -293
- package/bin/helpers/mutations.d.ts +8 -0
- package/bin/helpers/mutations.js +43 -0
- package/bin/helpers/queries.d.ts +28 -9
- package/bin/helpers/queries.js +150 -154
- package/bin/helpers/types.d.ts +452 -0
- package/bin/helpers/types.js +26 -0
- package/bin/helpers/workers.d.ts +35 -1
- package/bin/helpers/workers.js +360 -6
- package/bin/index.js +169 -24
- package/package.json +51 -9
- package/bin/helpers/more.d.ts +0 -2
- package/bin/helpers/more.js +0 -60
- /package/{LICENSE → LICENSE.md} +0 -0
package/bin/helpers/auth.js
CHANGED
|
@@ -8,157 +8,959 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
import fs from "fs";
|
|
11
|
-
import os from "os";
|
|
12
|
-
import path from "path";
|
|
13
11
|
import inquirer from "inquirer";
|
|
14
|
-
import open from "open";
|
|
15
12
|
import fetch from "node-fetch";
|
|
16
|
-
import
|
|
17
|
-
import
|
|
13
|
+
import open from "open";
|
|
14
|
+
import os from "os";
|
|
15
|
+
import path from "path";
|
|
16
|
+
import Spinner from "tiny-spinner";
|
|
17
|
+
import { fetcher } from "./fetcher.js";
|
|
18
|
+
import { AniDB, AniList, MyAnimeList } from "./lists.js";
|
|
19
|
+
import { deleteActivityMutation, likeActivityMutation, saveTextActivityMutation, } from "./mutations.js";
|
|
20
|
+
import { activityAllQuery, activityAnimeListQuery, activityMangaListQuery, activityMediaList, activityMessageQuery, activityTextQuery, currentUserAnimeList, currentUserMangaList, currentUserQuery, deleteMangaEntryMutation, deleteMediaEntryMutation, followingActivitiesQuery, globalActivitiesQuery, specificUserActivitiesQuery, toggleFollowMutation, userActivityQuery, userFollowersQuery, userFollowingQuery, userQuery, } from "./queries.js";
|
|
21
|
+
import { activityBy, aniListEndpoint, getTitle, redirectUri, timestampToTimeAgo, } from "./workers.js";
|
|
18
22
|
const home_dir = os.homedir();
|
|
19
23
|
const save_path = path.join(home_dir, ".anilist_token");
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
24
|
+
const spinner = new Spinner();
|
|
25
|
+
class Auth {
|
|
26
|
+
/**
|
|
27
|
+
* Get access-token from user
|
|
28
|
+
*/
|
|
29
|
+
static GetAccessToken() {
|
|
30
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
31
|
+
try {
|
|
32
|
+
const { token } = yield inquirer.prompt([
|
|
33
|
+
{
|
|
34
|
+
type: "password",
|
|
35
|
+
name: "token",
|
|
36
|
+
message: "Please enter your AniList access token:",
|
|
37
|
+
},
|
|
38
|
+
]);
|
|
39
|
+
if (!token) {
|
|
40
|
+
console.warn("\nNo token entered. Please try again.");
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
return token;
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
console.error(`\nAn error occurred while getting the access token: ${error.message}`);
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
static StoreAccessToken(token) {
|
|
52
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
53
|
+
try {
|
|
54
|
+
if (!token) {
|
|
55
|
+
console.warn("\nNo token provided. Nothing to store.");
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
fs.writeFileSync(save_path, token, { encoding: "utf8" });
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
console.error(`\nError storing access token: ${error.message}`);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
static RetriveAccessToken() {
|
|
66
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
67
|
+
try {
|
|
68
|
+
if (fs.existsSync(save_path)) {
|
|
69
|
+
return fs.readFileSync(save_path, { encoding: "utf8" });
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
console.error(`\nError retriving acess-token. ${error.message}`);
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
static Login(clientId, clientSecret) {
|
|
82
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
83
|
+
try {
|
|
84
|
+
console.log("Starting AniList login...");
|
|
85
|
+
const authUrl = `https://anilist.co/api/v2/oauth/authorize?client_id=${clientId}&redirect_uri=${redirectUri}&response_type=code`;
|
|
86
|
+
console.log("Opening browser for AniList login...");
|
|
87
|
+
open(authUrl);
|
|
88
|
+
const authCode = yield Auth.GetAccessToken();
|
|
89
|
+
const tokenResponse = yield fetch("https://anilist.co/api/v2/oauth/token", {
|
|
90
|
+
method: "POST",
|
|
91
|
+
headers: {
|
|
92
|
+
"Content-Type": "application/json",
|
|
93
|
+
},
|
|
94
|
+
body: JSON.stringify({
|
|
95
|
+
grant_type: "authorization_code",
|
|
96
|
+
client_id: String(clientId),
|
|
97
|
+
client_secret: clientSecret,
|
|
98
|
+
redirect_uri: redirectUri,
|
|
99
|
+
code: authCode,
|
|
100
|
+
}),
|
|
101
|
+
});
|
|
102
|
+
const token_Data = yield tokenResponse.json();
|
|
103
|
+
if (token_Data === null || token_Data === void 0 ? void 0 : token_Data.access_token) {
|
|
104
|
+
yield Auth.StoreAccessToken(token_Data === null || token_Data === void 0 ? void 0 : token_Data.access_token);
|
|
105
|
+
const name = yield Auth.MyUserName();
|
|
106
|
+
if (name) {
|
|
107
|
+
console.log(`\nWelcome Back, ${name}!`);
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
console.log(`\nLogged in successfull!`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
console.error("\nFailed to get access token:", token_Data);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
catch (error) {
|
|
118
|
+
console.error(`\nFailed logging in. ${error.message}`);
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
static Myself() {
|
|
123
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
124
|
+
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;
|
|
125
|
+
try {
|
|
126
|
+
if (yield Auth.isLoggedIn()) {
|
|
127
|
+
const headers = {
|
|
128
|
+
"Content-Type": "application/json",
|
|
129
|
+
"Authorization": `Bearer ${yield Auth.RetriveAccessToken()}`,
|
|
130
|
+
};
|
|
131
|
+
const request = yield fetch(aniListEndpoint, {
|
|
132
|
+
method: "POST",
|
|
133
|
+
headers: headers,
|
|
134
|
+
body: JSON.stringify({ query: currentUserQuery }),
|
|
135
|
+
});
|
|
136
|
+
const { data, errors } = yield request.json();
|
|
137
|
+
if (request.status === 200) {
|
|
138
|
+
const user = data === null || data === void 0 ? void 0 : data.Viewer;
|
|
139
|
+
const activiResponse = yield fetcher(userActivityQuery, {
|
|
140
|
+
id: user === null || user === void 0 ? void 0 : user.id,
|
|
141
|
+
page: 1,
|
|
142
|
+
perPage: 10,
|
|
143
|
+
});
|
|
144
|
+
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;
|
|
145
|
+
// Get follower/following information
|
|
146
|
+
const req_followers = yield fetcher(userFollowersQuery, {
|
|
147
|
+
userId: user === null || user === void 0 ? void 0 : user.id,
|
|
148
|
+
});
|
|
149
|
+
const req_following = yield fetcher(userFollowingQuery, {
|
|
150
|
+
userId: user === null || user === void 0 ? void 0 : user.id,
|
|
151
|
+
});
|
|
152
|
+
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
|
+
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}
|
|
181
|
+
`);
|
|
182
|
+
console.log(`\nRecent Activities:`);
|
|
183
|
+
if (activities.length > 0) {
|
|
184
|
+
activities.map(({ status, progress, media, createdAt }) => {
|
|
185
|
+
console.log(`${timestampToTimeAgo(createdAt)}\t${status} ${progress ? `${progress} of ` : ""}${getTitle(media === null || media === void 0 ? void 0 : media.title)}`);
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
return user;
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
console.error(`\nSomething went wrong. Please log in again. ${errors[0].message}`);
|
|
192
|
+
return null;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
console.error(`\nPlease login first to use this feature.`);
|
|
197
|
+
return null;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
catch (error) {
|
|
201
|
+
console.error(`\nError from Myself. ${error.message}`);
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
static isLoggedIn() {
|
|
206
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
207
|
+
try {
|
|
208
|
+
const token = yield Auth.RetriveAccessToken();
|
|
209
|
+
return token !== null;
|
|
210
|
+
}
|
|
211
|
+
catch (error) {
|
|
212
|
+
console.error(`Error checking login status: ${error.message}`);
|
|
213
|
+
return false;
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
static Logout() {
|
|
218
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
219
|
+
try {
|
|
220
|
+
const username = yield Auth.MyUserName();
|
|
221
|
+
if (fs.existsSync(save_path)) {
|
|
222
|
+
try {
|
|
223
|
+
fs.unlinkSync(save_path);
|
|
224
|
+
console.log(`\nLogout successful. See you soon, ${username}.`);
|
|
225
|
+
}
|
|
226
|
+
catch (error) {
|
|
227
|
+
console.error("\nFailed to remove the save file during logout:", error.message);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
console.warn("\nNo active session found. You may already be logged out.");
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
catch (error) {
|
|
235
|
+
console.error(`\nAn error occurred during logout: ${error.message}`);
|
|
236
|
+
}
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
static MyUserId() {
|
|
240
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
241
|
+
var _a, _b;
|
|
242
|
+
if (!(yield Auth.isLoggedIn())) {
|
|
243
|
+
console.warn(`\nUser not logged in.`);
|
|
244
|
+
return null;
|
|
245
|
+
}
|
|
246
|
+
const { data } = yield fetcher(currentUserQuery, {});
|
|
247
|
+
return (_b = (_a = data === null || data === void 0 ? void 0 : data.Viewer) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : null;
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
static MyUserName() {
|
|
251
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
252
|
+
var _a, _b;
|
|
253
|
+
if (!(yield Auth.isLoggedIn())) {
|
|
254
|
+
console.log(`\nUser not logged in.`);
|
|
255
|
+
return null;
|
|
256
|
+
}
|
|
257
|
+
const { data } = yield fetcher(currentUserQuery, {});
|
|
258
|
+
return (_b = (_a = data === null || data === void 0 ? void 0 : data.Viewer) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : null;
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
static DeleteMyActivities() {
|
|
262
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
263
|
+
var _a, _b, _c, _d, _e, _f;
|
|
264
|
+
try {
|
|
265
|
+
if (!(yield Auth.isLoggedIn())) {
|
|
266
|
+
console.error(`\nPlease log in to delete your activities.`);
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
const { activityType } = yield inquirer.prompt([
|
|
270
|
+
{
|
|
271
|
+
type: "list",
|
|
272
|
+
name: "activityType",
|
|
273
|
+
message: "What type of activity you want to delete?",
|
|
274
|
+
choices: [
|
|
275
|
+
{ name: "All Activity", value: 0 },
|
|
276
|
+
{ name: "Text Activity", value: 1 },
|
|
277
|
+
{ name: "Media List Activity", value: 2 },
|
|
278
|
+
{ name: "Anime List Activity", value: 3 },
|
|
279
|
+
{ name: "Manga List Activity", value: 4 },
|
|
280
|
+
{ name: "Message Activity", value: 5 },
|
|
281
|
+
],
|
|
282
|
+
},
|
|
283
|
+
]);
|
|
284
|
+
const queryMap = {
|
|
285
|
+
0: activityAllQuery,
|
|
286
|
+
1: activityTextQuery,
|
|
287
|
+
2: activityMediaList,
|
|
288
|
+
3: activityAnimeListQuery,
|
|
289
|
+
4: activityMangaListQuery,
|
|
290
|
+
5: activityMessageQuery,
|
|
291
|
+
};
|
|
292
|
+
const query = queryMap[activityType];
|
|
293
|
+
let hasMoreActivities = true;
|
|
294
|
+
let totalCount = 0;
|
|
295
|
+
while (hasMoreActivities) {
|
|
296
|
+
const response = yield fetcher(query, {
|
|
297
|
+
page: 1,
|
|
298
|
+
perPage: 50,
|
|
299
|
+
userId: yield Auth.MyUserId(),
|
|
300
|
+
});
|
|
301
|
+
if ((_b = (_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.Page) === null || _b === void 0 ? void 0 : _b.activities) {
|
|
302
|
+
let count = 0;
|
|
303
|
+
const activities = (_d = (_c = response === null || response === void 0 ? void 0 : response.data) === null || _c === void 0 ? void 0 : _c.Page) === null || _d === void 0 ? void 0 : _d.activities;
|
|
304
|
+
if (!activities || activities.length === 0) {
|
|
305
|
+
console.log(`\nNo more activities available.`);
|
|
306
|
+
hasMoreActivities = false;
|
|
307
|
+
}
|
|
308
|
+
else {
|
|
309
|
+
for (const act of activities) {
|
|
310
|
+
if (act === null || act === void 0 ? void 0 : act.id) {
|
|
311
|
+
const deleteResponse = yield fetcher(deleteActivityMutation, {
|
|
312
|
+
id: act === null || act === void 0 ? void 0 : act.id,
|
|
313
|
+
});
|
|
314
|
+
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;
|
|
315
|
+
count++;
|
|
316
|
+
totalCount++;
|
|
317
|
+
console.log(`[${count}/${activities.length}/${totalCount}]\t${act === null || act === void 0 ? void 0 : act.id} ${isDeleted ? "✅" : "❌"}`);
|
|
318
|
+
// Avoiding rate-limit
|
|
319
|
+
yield new Promise((resolve) => setTimeout(resolve, 1100));
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
else {
|
|
325
|
+
// In case of an unexpected null response, exit the loop
|
|
326
|
+
console.log(`\nProbably deleted all the activities of this type.`);
|
|
327
|
+
hasMoreActivities = false;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
catch (error) {
|
|
332
|
+
console.error(`\nSomething went wrong. ${error.message}`);
|
|
333
|
+
}
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
static DeleteMyAnimeList() {
|
|
337
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
338
|
+
var _a, _b, _c, _d;
|
|
339
|
+
if (!(yield Auth.isLoggedIn())) {
|
|
340
|
+
console.error(`\nPlease log in first to delete your lists.`);
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
if (!(yield Auth.MyUserId())) {
|
|
344
|
+
console.log(`\nFailed getting current user Id.`);
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
347
|
+
const response = yield fetcher(currentUserAnimeList, { id: yield Auth.MyUserId() });
|
|
348
|
+
if (response !== null) {
|
|
349
|
+
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;
|
|
350
|
+
if (lists.length > 0) {
|
|
351
|
+
const { selectedList } = yield inquirer.prompt([
|
|
352
|
+
{
|
|
353
|
+
type: "list",
|
|
354
|
+
name: "selectedList",
|
|
355
|
+
message: "Select an anime list:",
|
|
356
|
+
choices: lists.map((list) => list.name),
|
|
357
|
+
pageSize: 10,
|
|
358
|
+
},
|
|
359
|
+
]);
|
|
360
|
+
const selectedEntries = lists.find((list) => list.name === selectedList);
|
|
361
|
+
if (selectedEntries) {
|
|
362
|
+
console.log(`\nDeleting entries of '${selectedEntries.name}':`);
|
|
363
|
+
for (const [, entry] of selectedEntries.entries.entries()) {
|
|
364
|
+
if (entry === null || entry === void 0 ? void 0 : entry.id) {
|
|
365
|
+
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);
|
|
366
|
+
yield new Promise((resolve) => setTimeout(resolve, 1100));
|
|
367
|
+
}
|
|
368
|
+
else {
|
|
369
|
+
console.log(`No id in entry.`);
|
|
370
|
+
console.log(entry);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
else {
|
|
375
|
+
console.log("No entries found.");
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
else {
|
|
379
|
+
console.log(`\nNo anime(s) found in any list.`);
|
|
380
|
+
}
|
|
107
381
|
}
|
|
108
382
|
else {
|
|
109
|
-
console.log(
|
|
383
|
+
console.log(`\nSomething went wrong. ${(_d = response === null || response === void 0 ? void 0 : response.errors[0]) === null || _d === void 0 ? void 0 : _d.message}`);
|
|
110
384
|
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
}
|
|
117
|
-
function isLoggedIn() {
|
|
118
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
119
|
-
const isTokenStored = yield retriveAccessToken();
|
|
120
|
-
if (isTokenStored !== null) {
|
|
121
|
-
return true;
|
|
122
|
-
}
|
|
123
|
-
else {
|
|
124
|
-
return false;
|
|
125
|
-
}
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
|
-
function logoutUser() {
|
|
129
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
130
|
-
if (fs.existsSync(save_path)) {
|
|
385
|
+
});
|
|
386
|
+
}
|
|
387
|
+
static DeleteAnimeById(id, title) {
|
|
388
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
389
|
+
var _a, _b, _c;
|
|
131
390
|
try {
|
|
132
|
-
|
|
133
|
-
|
|
391
|
+
const response = yield fetcher(deleteMediaEntryMutation, { id: id });
|
|
392
|
+
if (response === null || response === void 0 ? void 0 : response.data) {
|
|
393
|
+
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;
|
|
394
|
+
console.log(`del ${title ? getTitle(title) : ""} ${deleted ? "✅" : "❌"}`);
|
|
395
|
+
}
|
|
396
|
+
else {
|
|
397
|
+
console.log(`\nError deleting anime. ${(_c = response === null || response === void 0 ? void 0 : response.errors[0]) === null || _c === void 0 ? void 0 : _c.message}`);
|
|
398
|
+
console.log(response);
|
|
399
|
+
}
|
|
134
400
|
}
|
|
135
401
|
catch (error) {
|
|
136
|
-
console.
|
|
402
|
+
console.log(`\nError deleting anime. ${id} ${error.message}`);
|
|
137
403
|
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
static DeleteMyMangaList() {
|
|
407
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
408
|
+
var _a, _b, _c, _d;
|
|
409
|
+
try {
|
|
410
|
+
if (!(yield Auth.isLoggedIn())) {
|
|
411
|
+
console.error(`\nPlease log in first to delete your lists.`);
|
|
412
|
+
return;
|
|
413
|
+
}
|
|
414
|
+
if (!(yield Auth.MyUserId())) {
|
|
415
|
+
console.error(`\nFailed getting current user Id.`);
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
418
|
+
const response = yield fetcher(currentUserMangaList, { id: yield Auth.MyUserId() });
|
|
419
|
+
if (!(response === null || response === void 0 ? void 0 : response.data)) {
|
|
420
|
+
console.error(`\nSomething went wrong. ${(_a = response === null || response === void 0 ? void 0 : response.errors[0]) === null || _a === void 0 ? void 0 : _a.message}`);
|
|
421
|
+
return;
|
|
422
|
+
}
|
|
423
|
+
const lists = (_c = (_b = response === null || response === void 0 ? void 0 : response.data) === null || _b === void 0 ? void 0 : _b.MediaListCollection) === null || _c === void 0 ? void 0 : _c.lists;
|
|
424
|
+
if (lists.length > 0) {
|
|
425
|
+
const { selectedList } = yield inquirer.prompt([
|
|
426
|
+
{
|
|
427
|
+
type: "list",
|
|
428
|
+
name: "selectedList",
|
|
429
|
+
message: "Select a manga list:",
|
|
430
|
+
choices: lists.map((list) => list.name),
|
|
431
|
+
pageSize: 10,
|
|
432
|
+
},
|
|
433
|
+
]);
|
|
434
|
+
const selectedEntries = lists.find((list) => list.name === selectedList);
|
|
435
|
+
if (selectedEntries) {
|
|
436
|
+
console.log(`\nDeleting entries of '${selectedEntries.name}':`);
|
|
437
|
+
for (const [, entry] of selectedEntries.entries.entries()) {
|
|
438
|
+
if (entry === null || entry === void 0 ? void 0 : entry.id) {
|
|
439
|
+
yield Auth.DeleteMangaById(entry === null || entry === void 0 ? void 0 : entry.id, (_d = entry === null || entry === void 0 ? void 0 : entry.media) === null || _d === void 0 ? void 0 : _d.title);
|
|
440
|
+
yield new Promise((resolve) => setTimeout(resolve, 1100));
|
|
441
|
+
}
|
|
442
|
+
else {
|
|
443
|
+
console.log(`No id in entry.`);
|
|
444
|
+
console.log(entry);
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
else {
|
|
449
|
+
console.error("\nNo entries found.");
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
else {
|
|
453
|
+
console.error(`\nNo manga(s) found in any list.`);
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
catch (error) {
|
|
457
|
+
console.error(`\nError deleting manga. ${error.message}`);
|
|
458
|
+
}
|
|
459
|
+
});
|
|
460
|
+
}
|
|
461
|
+
static DeleteMangaById(id, title) {
|
|
462
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
463
|
+
var _a, _b, _c, _d;
|
|
464
|
+
try {
|
|
465
|
+
const response = yield fetcher(deleteMangaEntryMutation, { id });
|
|
466
|
+
const statusMessage = title ? getTitle(title) : "";
|
|
467
|
+
if (response === null || response === void 0 ? void 0 : response.data) {
|
|
468
|
+
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;
|
|
469
|
+
console.log(`del ${statusMessage} ${deleted ? "✅" : "❌"}`);
|
|
470
|
+
}
|
|
471
|
+
else {
|
|
472
|
+
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}`);
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
catch (error) {
|
|
476
|
+
console.error(`Error deleting manga. ${id} ${error instanceof Error ? error.message : error}`);
|
|
477
|
+
}
|
|
478
|
+
});
|
|
479
|
+
}
|
|
480
|
+
static Write(status) {
|
|
481
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
482
|
+
try {
|
|
483
|
+
if (!(yield Auth.isLoggedIn())) {
|
|
484
|
+
console.error(`\nPlease login to use this feature.`);
|
|
485
|
+
return;
|
|
486
|
+
}
|
|
487
|
+
const { data } = yield fetcher(saveTextActivityMutation, {
|
|
488
|
+
status: status,
|
|
489
|
+
});
|
|
490
|
+
if (!data) {
|
|
491
|
+
console.error(`\nSomething went wrong. ${data}.`);
|
|
492
|
+
return;
|
|
493
|
+
}
|
|
494
|
+
if (data.SaveTextActivity.id) {
|
|
495
|
+
console.log(`\n[${data.SaveTextActivity.id}] status saved successfully!`);
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
catch (error) {
|
|
499
|
+
console.error(`\n${error.message}`);
|
|
500
|
+
}
|
|
501
|
+
});
|
|
502
|
+
}
|
|
503
|
+
static callAnimeImporter() {
|
|
504
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
505
|
+
try {
|
|
506
|
+
const { source } = yield inquirer.prompt([
|
|
507
|
+
{
|
|
508
|
+
type: "list",
|
|
509
|
+
name: "source",
|
|
510
|
+
message: "Select a source:",
|
|
511
|
+
choices: [
|
|
512
|
+
{ name: "Exported JSON file.", value: 1 },
|
|
513
|
+
{ name: "MyAnimeList (XML)", value: 2 },
|
|
514
|
+
{ name: "AniDB (json-large)", value: 3 },
|
|
515
|
+
],
|
|
516
|
+
pageSize: 10,
|
|
517
|
+
},
|
|
518
|
+
]);
|
|
519
|
+
switch (source) {
|
|
520
|
+
case 1:
|
|
521
|
+
yield AniList.importAnime();
|
|
522
|
+
break;
|
|
523
|
+
case 2:
|
|
524
|
+
yield MyAnimeList.importAnime();
|
|
525
|
+
break;
|
|
526
|
+
case 3:
|
|
527
|
+
yield AniDB.importAnime();
|
|
528
|
+
break;
|
|
529
|
+
default:
|
|
530
|
+
console.log(`\nInvalid Choice.`);
|
|
531
|
+
break;
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
catch (error) {
|
|
535
|
+
console.error(`\n${error.message}`);
|
|
536
|
+
}
|
|
537
|
+
});
|
|
538
|
+
}
|
|
539
|
+
static callMangaImporter() {
|
|
540
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
541
|
+
try {
|
|
542
|
+
const { source } = yield inquirer.prompt([
|
|
543
|
+
{
|
|
544
|
+
type: "list",
|
|
545
|
+
name: "source",
|
|
546
|
+
message: "Select a source:",
|
|
547
|
+
choices: [
|
|
548
|
+
{ name: "Exported JSON file.", value: 1 },
|
|
549
|
+
{ name: "MyAnimeList (XML)", value: 2 },
|
|
550
|
+
],
|
|
551
|
+
pageSize: 10,
|
|
552
|
+
},
|
|
553
|
+
]);
|
|
554
|
+
switch (source) {
|
|
555
|
+
case 1:
|
|
556
|
+
yield AniList.importManga();
|
|
557
|
+
break;
|
|
558
|
+
case 2:
|
|
559
|
+
yield MyAnimeList.importManga();
|
|
560
|
+
break;
|
|
561
|
+
default:
|
|
562
|
+
console.log(`\nInvalid Choice.`);
|
|
563
|
+
break;
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
catch (error) {
|
|
567
|
+
console.error(`\n${error.message}`);
|
|
568
|
+
}
|
|
569
|
+
});
|
|
570
|
+
}
|
|
571
|
+
static LikeFollowing() {
|
|
572
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
573
|
+
var _a, _b, _c, _d;
|
|
574
|
+
try {
|
|
575
|
+
let page = 1;
|
|
576
|
+
let hasMoreActivities = true;
|
|
577
|
+
let retryCount = 0;
|
|
578
|
+
const maxRetries = 5;
|
|
579
|
+
while (hasMoreActivities) {
|
|
580
|
+
const activities = yield fetcher(followingActivitiesQuery, {
|
|
581
|
+
page,
|
|
582
|
+
perPage: 50,
|
|
583
|
+
});
|
|
584
|
+
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) {
|
|
585
|
+
retryCount = 0; // Reset retry count on successful fetch
|
|
586
|
+
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;
|
|
587
|
+
for (let activ of activiti) {
|
|
588
|
+
if (!activ.isLiked && activ.id) {
|
|
589
|
+
try {
|
|
590
|
+
const like = yield fetcher(likeActivityMutation, {
|
|
591
|
+
activityId: activ.id,
|
|
592
|
+
});
|
|
593
|
+
console.info(`${activityBy(activ)} ${(like === null || like === void 0 ? void 0 : like.data) ? "✅" : "❌"}`);
|
|
594
|
+
}
|
|
595
|
+
catch (error) {
|
|
596
|
+
console.error(`Activity possibly deleted. ${error.message}`);
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
else {
|
|
600
|
+
console.log(`${activityBy(activ)} 🔵`);
|
|
601
|
+
}
|
|
602
|
+
// avoiding rate-limit
|
|
603
|
+
yield new Promise((resolve) => {
|
|
604
|
+
setTimeout(resolve, 2000);
|
|
605
|
+
});
|
|
606
|
+
}
|
|
607
|
+
page++;
|
|
608
|
+
}
|
|
609
|
+
else {
|
|
610
|
+
if (retryCount < maxRetries) {
|
|
611
|
+
retryCount++;
|
|
612
|
+
console.warn(`Empty activities returned. Retrying... (${retryCount}/${maxRetries})`);
|
|
613
|
+
yield new Promise((resolve) => setTimeout(resolve, 3000));
|
|
614
|
+
}
|
|
615
|
+
else {
|
|
616
|
+
console.log(`\nProbably the end of activities after ${maxRetries} retries.`);
|
|
617
|
+
console.info(activities);
|
|
618
|
+
hasMoreActivities = false;
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
catch (error) {
|
|
624
|
+
console.error(`\nError from likeFollowing. ${error.message}`);
|
|
625
|
+
}
|
|
626
|
+
});
|
|
627
|
+
}
|
|
628
|
+
static Like(type) {
|
|
629
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
630
|
+
var _a, _b, _c, _d;
|
|
631
|
+
try {
|
|
632
|
+
let page = 1;
|
|
633
|
+
let hasMoreActivities = true;
|
|
634
|
+
let activity = type === 0
|
|
635
|
+
? followingActivitiesQuery
|
|
636
|
+
: type === 1
|
|
637
|
+
? globalActivitiesQuery
|
|
638
|
+
: followingActivitiesQuery;
|
|
639
|
+
while (hasMoreActivities) {
|
|
640
|
+
const activities = yield fetcher(activity, {
|
|
641
|
+
page,
|
|
642
|
+
perPage: 50,
|
|
643
|
+
});
|
|
644
|
+
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) {
|
|
645
|
+
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;
|
|
646
|
+
for (let activ of activiti) {
|
|
647
|
+
if (!activ.isLiked && activ.id) {
|
|
648
|
+
try {
|
|
649
|
+
const like = yield fetcher(likeActivityMutation, {
|
|
650
|
+
activityId: activ.id,
|
|
651
|
+
});
|
|
652
|
+
// const ToggleLike = like?.data?.ToggleLike
|
|
653
|
+
console.info(`${activityBy(activ)} ${(like === null || like === void 0 ? void 0 : like.data) ? "✅" : "❌"}`);
|
|
654
|
+
}
|
|
655
|
+
catch (error) {
|
|
656
|
+
console.error(`Activity possibly deleted. ${error.message}`);
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
else {
|
|
660
|
+
console.log(`${activityBy(activ)} 🔵`);
|
|
661
|
+
}
|
|
662
|
+
// avoiding rate-limit
|
|
663
|
+
yield new Promise((resolve) => {
|
|
664
|
+
setTimeout(resolve, 1500);
|
|
665
|
+
});
|
|
666
|
+
}
|
|
667
|
+
page++;
|
|
668
|
+
}
|
|
669
|
+
else {
|
|
670
|
+
// No more activities to like
|
|
671
|
+
console.log(`\nProbably the end of activities.`);
|
|
672
|
+
console.info(activities);
|
|
673
|
+
hasMoreActivities = false;
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
catch (error) {
|
|
678
|
+
console.error(`\nError from likeFollowing. ${error.message}`);
|
|
679
|
+
}
|
|
680
|
+
});
|
|
681
|
+
}
|
|
682
|
+
static LikeSpecificUser() {
|
|
683
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
684
|
+
var _a, _b, _c, _d;
|
|
685
|
+
try {
|
|
686
|
+
const { username } = yield inquirer.prompt([
|
|
687
|
+
{
|
|
688
|
+
type: "input",
|
|
689
|
+
name: "username",
|
|
690
|
+
message: "Username of the user:",
|
|
691
|
+
},
|
|
692
|
+
]);
|
|
693
|
+
const userDetails = yield fetcher(userQuery, { username: username });
|
|
694
|
+
if (userDetails) {
|
|
695
|
+
let page = 1;
|
|
696
|
+
const perPage = 50;
|
|
697
|
+
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;
|
|
698
|
+
if (userId) {
|
|
699
|
+
while (true) {
|
|
700
|
+
const activities = yield fetcher(specificUserActivitiesQuery, {
|
|
701
|
+
page,
|
|
702
|
+
perPage,
|
|
703
|
+
userId,
|
|
704
|
+
});
|
|
705
|
+
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;
|
|
706
|
+
// Break the loop if no more activities are found
|
|
707
|
+
if (!activiti || activiti.length === 0) {
|
|
708
|
+
console.log("No more activities found.");
|
|
709
|
+
break;
|
|
710
|
+
}
|
|
711
|
+
for (let activ of activiti) {
|
|
712
|
+
if (!activ.isLiked && activ.id) {
|
|
713
|
+
try {
|
|
714
|
+
const like = yield fetcher(likeActivityMutation, {
|
|
715
|
+
activityId: activ.id,
|
|
716
|
+
});
|
|
717
|
+
console.info(`${activityBy(activ)} ${(like === null || like === void 0 ? void 0 : like.data) ? "✅" : "❌"}`);
|
|
718
|
+
}
|
|
719
|
+
catch (error) {
|
|
720
|
+
console.error(`Activity possibly deleted. ${error.message}`);
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
else {
|
|
724
|
+
console.log(`${activityBy(activ)} 🔵`);
|
|
725
|
+
}
|
|
726
|
+
// Avoiding rate limit
|
|
727
|
+
yield new Promise((resolve) => {
|
|
728
|
+
setTimeout(resolve, 1500);
|
|
729
|
+
});
|
|
730
|
+
}
|
|
731
|
+
// Go to the next page
|
|
732
|
+
page += 1;
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
catch (error) {
|
|
738
|
+
console.error(`\nError from LikeSpecificUser. ${error.message}`);
|
|
739
|
+
}
|
|
740
|
+
});
|
|
741
|
+
}
|
|
742
|
+
static LikeFollowingActivityV2(perPage) {
|
|
743
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
744
|
+
var _a, _b, _c, _d, _e;
|
|
745
|
+
try {
|
|
746
|
+
if (!(yield Auth.isLoggedIn())) {
|
|
747
|
+
console.error(`\nPlease log in to use this feature.`);
|
|
748
|
+
return;
|
|
749
|
+
}
|
|
750
|
+
const allFollowingUsers = [];
|
|
751
|
+
let hasNextPage = true;
|
|
752
|
+
let page = 1;
|
|
753
|
+
// Fetch all following users
|
|
754
|
+
while (hasNextPage) {
|
|
755
|
+
const followingUsers = yield fetcher(userFollowingQuery, {
|
|
756
|
+
userId: yield Auth.MyUserId(),
|
|
757
|
+
page,
|
|
758
|
+
});
|
|
759
|
+
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)) {
|
|
760
|
+
console.error(`\nFailed to fetch following users.`);
|
|
761
|
+
return;
|
|
762
|
+
}
|
|
763
|
+
allFollowingUsers.push(...followingUsers.data.Page.following);
|
|
764
|
+
hasNextPage = followingUsers.data.Page.pageInfo.hasNextPage;
|
|
765
|
+
page++;
|
|
766
|
+
}
|
|
767
|
+
// Extract the IDs of all following users
|
|
768
|
+
const followingUserIds = allFollowingUsers.map((user) => user.id);
|
|
769
|
+
console.log(`\nTotal Following: ${followingUserIds.length}\nApproximately ${followingUserIds.length * perPage} activities to like.\nWill take around ${((followingUserIds.length * perPage * 1200) /
|
|
770
|
+
1000 /
|
|
771
|
+
60).toFixed(2)} minutes.`);
|
|
772
|
+
// Traverse the array and fetch users' activities one by one
|
|
773
|
+
let userNumber = 0;
|
|
774
|
+
for (const userId of followingUserIds) {
|
|
775
|
+
userNumber++;
|
|
776
|
+
console.log(`\n[${userNumber}]\tID: ${userId}`);
|
|
777
|
+
// Fetch `perPage` activities for the current user
|
|
778
|
+
const activities = yield fetcher(specificUserActivitiesQuery, {
|
|
779
|
+
userId,
|
|
780
|
+
page: 1, // Always fetch from the first page
|
|
781
|
+
perPage,
|
|
782
|
+
});
|
|
783
|
+
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)) {
|
|
784
|
+
console.log(`[${userNumber}] No activities found for User ID: ${userId}`);
|
|
785
|
+
continue;
|
|
786
|
+
}
|
|
787
|
+
const activiti = activities.data.Page.activities;
|
|
788
|
+
for (let i = 0; i < activiti.length; i++) {
|
|
789
|
+
const activ = activiti[i];
|
|
790
|
+
if (!activ.isLiked && activ.id) {
|
|
791
|
+
try {
|
|
792
|
+
const like = yield fetcher(likeActivityMutation, {
|
|
793
|
+
activityId: activ.id,
|
|
794
|
+
});
|
|
795
|
+
console.info(`[${userNumber}/${i + 1}/${activiti.length}] ${activityBy(activ)} ${(like === null || like === void 0 ? void 0 : like.data) ? "✅" : "❌"}`);
|
|
796
|
+
}
|
|
797
|
+
catch (error) {
|
|
798
|
+
console.error(`[${userNumber}/${i + 1}/${activiti.length}] Activity possibly deleted. ${error.message}`);
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
else {
|
|
802
|
+
console.log(`[${userNumber}/${i + 1}/${activiti.length}] ${activityBy(activ)} 🔵`);
|
|
803
|
+
}
|
|
804
|
+
// Avoid rate-limiting
|
|
805
|
+
yield new Promise((resolve) => setTimeout(resolve, 1200));
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
console.log(`\n✅ All activities liked successfully.`);
|
|
809
|
+
}
|
|
810
|
+
catch (error) {
|
|
811
|
+
console.error(`\nError in LikeFollowingActivityV2: ${error.message}`);
|
|
812
|
+
}
|
|
813
|
+
});
|
|
814
|
+
}
|
|
815
|
+
static AutoLike() {
|
|
816
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
817
|
+
try {
|
|
818
|
+
if (!(yield Auth.isLoggedIn())) {
|
|
819
|
+
console.error(`\nPlease login to use this feature.`);
|
|
820
|
+
return;
|
|
821
|
+
}
|
|
822
|
+
const { activityType } = yield inquirer.prompt([
|
|
823
|
+
{
|
|
824
|
+
type: "list",
|
|
825
|
+
name: "activityType",
|
|
826
|
+
message: "Select activity type:",
|
|
827
|
+
choices: [
|
|
828
|
+
{ name: "Following", value: 1 },
|
|
829
|
+
{ name: "Global", value: 2 },
|
|
830
|
+
{ name: "Specific User", value: 3 },
|
|
831
|
+
],
|
|
832
|
+
pageSize: 10,
|
|
833
|
+
},
|
|
834
|
+
]);
|
|
835
|
+
switch (activityType) {
|
|
836
|
+
case 1:
|
|
837
|
+
yield this.LikeFollowing();
|
|
838
|
+
break;
|
|
839
|
+
case 2:
|
|
840
|
+
yield this.Like(1);
|
|
841
|
+
break;
|
|
842
|
+
case 3:
|
|
843
|
+
yield this.LikeSpecificUser();
|
|
844
|
+
break;
|
|
845
|
+
default:
|
|
846
|
+
console.error(`\nInvalid choice. (${activityType})`);
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
catch (error) {
|
|
850
|
+
console.error(`\nError from autolike. ${error.message}`);
|
|
851
|
+
}
|
|
852
|
+
});
|
|
853
|
+
}
|
|
143
854
|
}
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
855
|
+
class Social {
|
|
856
|
+
/**
|
|
857
|
+
* Follow the users that follows you
|
|
858
|
+
*/
|
|
859
|
+
static follow() {
|
|
860
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
861
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
862
|
+
try {
|
|
863
|
+
let pager = 1;
|
|
864
|
+
let hasNextPage = true;
|
|
865
|
+
let allFollowerUsers = [];
|
|
866
|
+
spinner.start("Fetching all the followers...");
|
|
867
|
+
while (hasNextPage) {
|
|
868
|
+
const followerUsers = yield fetcher(userFollowersQuery, {
|
|
869
|
+
userId: yield Auth.MyUserId(),
|
|
870
|
+
page: pager,
|
|
871
|
+
});
|
|
872
|
+
spinner.update(`Fetched page ${pager} of ${(_c = (_b = (_a = followerUsers === null || followerUsers === void 0 ? void 0 : followerUsers.data) === null || _a === void 0 ? void 0 : _a.Page) === null || _b === void 0 ? void 0 : _b.pageInfo) === null || _c === void 0 ? void 0 : _c.lastPage}...`);
|
|
873
|
+
if (!((_f = (_e = (_d = followerUsers === null || followerUsers === void 0 ? void 0 : followerUsers.data) === null || _d === void 0 ? void 0 : _d.Page) === null || _e === void 0 ? void 0 : _e.pageInfo) === null || _f === void 0 ? void 0 : _f.hasNextPage)) {
|
|
874
|
+
hasNextPage = false;
|
|
875
|
+
}
|
|
876
|
+
allFollowerUsers.push(...(((_h = (_g = followerUsers === null || followerUsers === void 0 ? void 0 : followerUsers.data) === null || _g === void 0 ? void 0 : _g.Page) === null || _h === void 0 ? void 0 : _h.followers) || []));
|
|
877
|
+
pager++;
|
|
878
|
+
}
|
|
879
|
+
spinner.stop("Fetched all the followers. Starting follow back.");
|
|
880
|
+
// Filter users that do no follow me
|
|
881
|
+
const notFollowing = allFollowerUsers
|
|
882
|
+
.filter(({ isFollowing }) => !isFollowing)
|
|
883
|
+
.map(({ id, name }) => ({ id: id, name: name }));
|
|
884
|
+
console.log(`\nTotal follower ${allFollowerUsers.length}.\nNot followed back ${notFollowing.length}\n`);
|
|
885
|
+
if (notFollowing.length <= 0) {
|
|
886
|
+
console.log(`Probably followed back all the users.`);
|
|
887
|
+
return;
|
|
888
|
+
}
|
|
889
|
+
// Traverse and follow back
|
|
890
|
+
const maxIdLength = Math.max(...notFollowing.map(({ id }) => String(id).length));
|
|
891
|
+
const maxNameLength = Math.max(...notFollowing.map(({ name }) => name.length));
|
|
892
|
+
for (let nf of notFollowing) {
|
|
893
|
+
try {
|
|
894
|
+
const follow = yield fetcher(toggleFollowMutation, { userId: nf.id });
|
|
895
|
+
console.log(`${String(`[${nf.id}]`).padEnd(maxIdLength)}` +
|
|
896
|
+
`\t${String(`[${(_k = (_j = follow === null || follow === void 0 ? void 0 : follow.data) === null || _j === void 0 ? void 0 : _j.ToggleFollow) === null || _k === void 0 ? void 0 : _k.name}]`).padEnd(maxNameLength)}` +
|
|
897
|
+
`\t${((_m = (_l = follow === null || follow === void 0 ? void 0 : follow.data) === null || _l === void 0 ? void 0 : _l.ToggleFollow) === null || _m === void 0 ? void 0 : _m.id) ? "✅" : "🈵"}`);
|
|
898
|
+
}
|
|
899
|
+
catch (error) {
|
|
900
|
+
console.log(`automate_follow_toggle_follow: ${error.message}`);
|
|
901
|
+
}
|
|
902
|
+
}
|
|
903
|
+
console.log(`\n✅ Followed back ${notFollowing.length} users.`);
|
|
904
|
+
}
|
|
905
|
+
catch (error) {
|
|
906
|
+
console.log(`\nautomate_follow ${error.message}`);
|
|
907
|
+
}
|
|
908
|
+
});
|
|
909
|
+
}
|
|
910
|
+
/**
|
|
911
|
+
* Unfollow the users thats not following you
|
|
912
|
+
*/
|
|
913
|
+
static unfollow() {
|
|
914
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
915
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
916
|
+
try {
|
|
917
|
+
let pager = 1;
|
|
918
|
+
let hasNextPage = true;
|
|
919
|
+
let allFollowingUsers = [];
|
|
920
|
+
spinner.start("Fetching all following users...");
|
|
921
|
+
while (hasNextPage) {
|
|
922
|
+
const followingUsers = yield fetcher(userFollowingQuery, {
|
|
923
|
+
userId: yield Auth.MyUserId(),
|
|
924
|
+
page: pager,
|
|
925
|
+
});
|
|
926
|
+
spinner.update(`Fetched page ${pager} of ${(_c = (_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.pageInfo) === null || _c === void 0 ? void 0 : _c.lastPage} ...`);
|
|
927
|
+
if (!((_f = (_e = (_d = followingUsers === null || followingUsers === void 0 ? void 0 : followingUsers.data) === null || _d === void 0 ? void 0 : _d.Page) === null || _e === void 0 ? void 0 : _e.pageInfo) === null || _f === void 0 ? void 0 : _f.hasNextPage)) {
|
|
928
|
+
hasNextPage = false;
|
|
929
|
+
}
|
|
930
|
+
allFollowingUsers.push(...(((_h = (_g = followingUsers === null || followingUsers === void 0 ? void 0 : followingUsers.data) === null || _g === void 0 ? void 0 : _g.Page) === null || _h === void 0 ? void 0 : _h.following) || []));
|
|
931
|
+
pager++;
|
|
932
|
+
}
|
|
933
|
+
spinner.update(`Fetching complete. Total got ${allFollowingUsers.length} users.`);
|
|
934
|
+
// Filter users that do no follow me
|
|
935
|
+
const notFollowingMe = allFollowingUsers
|
|
936
|
+
.filter((user) => !user.isFollower)
|
|
937
|
+
.map((u3r) => ({ id: u3r.id, name: u3r.name }));
|
|
938
|
+
if (notFollowingMe.length <= 0) {
|
|
939
|
+
console.warn(`\nNot following list is empty!`);
|
|
940
|
+
spinner.stop(`No users to unfollow. Aborting process...`);
|
|
941
|
+
return;
|
|
942
|
+
}
|
|
943
|
+
spinner.stop(`Unfollow process activated with ${notFollowingMe.length} users.`);
|
|
944
|
+
let nfmCount = 0;
|
|
945
|
+
console.log(`\n`);
|
|
946
|
+
for (let nfm of notFollowingMe) {
|
|
947
|
+
nfmCount++;
|
|
948
|
+
try {
|
|
949
|
+
const unfollow = yield fetcher(toggleFollowMutation, {
|
|
950
|
+
userId: nfm.id,
|
|
951
|
+
});
|
|
952
|
+
console.log(`[${nfm.id}]\t[${(_k = (_j = unfollow === null || unfollow === void 0 ? void 0 : unfollow.data) === null || _j === void 0 ? void 0 : _j.ToggleFollow) === null || _k === void 0 ? void 0 : _k.name}]\t${((_m = (_l = unfollow === null || unfollow === void 0 ? void 0 : unfollow.data) === null || _l === void 0 ? void 0 : _l.ToggleFollow) === null || _m === void 0 ? void 0 : _m.id) ? "✅" : "🈵"}`);
|
|
953
|
+
}
|
|
954
|
+
catch (error) {
|
|
955
|
+
console.log(`unfollow_toggle_follow. ${error.message}`);
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
console.log(`\nTotal Unfollowed: ${nfmCount}`);
|
|
959
|
+
}
|
|
960
|
+
catch (error) {
|
|
961
|
+
console.error(`\nautomate_unfollow: ${error.message}`);
|
|
962
|
+
}
|
|
963
|
+
});
|
|
964
|
+
}
|
|
163
965
|
}
|
|
164
|
-
export {
|
|
966
|
+
export { Auth, Social };
|