@irfanshadikrishad/anilist 1.3.2-forbidden.1 ā 1.4.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 -0
- package/README.md +79 -53
- package/bin/helpers/auth.d.ts +15 -4
- package/bin/helpers/auth.js +468 -234
- package/bin/helpers/lists.d.ts +5 -1
- package/bin/helpers/lists.js +276 -127
- package/bin/helpers/queries.d.ts +9 -5
- package/bin/helpers/queries.js +31 -4
- package/bin/helpers/truncate.d.ts +6 -0
- package/bin/helpers/truncate.js +10 -0
- package/bin/helpers/types.d.ts +239 -17
- package/bin/helpers/validation.d.ts +29 -0
- package/bin/helpers/validation.js +117 -0
- package/bin/helpers/workers.d.ts +20 -10
- package/bin/helpers/workers.js +104 -20
- package/bin/index.js +32 -1
- package/package.json +23 -17
package/bin/helpers/auth.js
CHANGED
|
@@ -7,19 +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";
|
|
18
|
+
import Spinner from "tiny-spinner";
|
|
16
19
|
import { fetcher } from "./fetcher.js";
|
|
17
|
-
import { AniList, MyAnimeList } from "./lists.js";
|
|
20
|
+
import { AniDB, AniList, MyAnimeList } from "./lists.js";
|
|
18
21
|
import { deleteActivityMutation, likeActivityMutation, saveTextActivityMutation, } from "./mutations.js";
|
|
19
|
-
import { activityAllQuery, activityAnimeListQuery, activityMangaListQuery, activityMediaList, activityMessageQuery, activityTextQuery, currentUserAnimeList, currentUserMangaList, currentUserQuery, deleteMangaEntryMutation, deleteMediaEntryMutation, followingActivitiesQuery, globalActivitiesQuery, specificUserActivitiesQuery, userActivityQuery, userQuery, } from "./queries.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";
|
|
20
24
|
import { activityBy, aniListEndpoint, getTitle, redirectUri, timestampToTimeAgo, } from "./workers.js";
|
|
21
25
|
const home_dir = os.homedir();
|
|
22
26
|
const save_path = path.join(home_dir, ".anilist_token");
|
|
27
|
+
const spinner = new Spinner();
|
|
28
|
+
const vigenere = new Cipher.Vigenere("anilist");
|
|
23
29
|
class Auth {
|
|
24
30
|
/**
|
|
25
31
|
* Get access-token from user
|
|
@@ -34,20 +40,29 @@ class Auth {
|
|
|
34
40
|
message: "Please enter your AniList access token:",
|
|
35
41
|
},
|
|
36
42
|
]);
|
|
43
|
+
if (!token) {
|
|
44
|
+
console.warn("\nNo token entered. Please try again.");
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
37
47
|
return token;
|
|
38
48
|
}
|
|
39
49
|
catch (error) {
|
|
40
|
-
console.error(`\
|
|
50
|
+
console.error(`\nAn error occurred while getting the access token: ${error.message}`);
|
|
51
|
+
return null;
|
|
41
52
|
}
|
|
42
53
|
});
|
|
43
54
|
}
|
|
44
55
|
static StoreAccessToken(token) {
|
|
45
56
|
return __awaiter(this, void 0, void 0, function* () {
|
|
46
57
|
try {
|
|
47
|
-
|
|
58
|
+
if (!token) {
|
|
59
|
+
console.warn("\nNo token provided. Nothing to store.");
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
fs.writeFileSync(save_path, vigenere.encrypt(token), { encoding: "utf8" });
|
|
48
63
|
}
|
|
49
64
|
catch (error) {
|
|
50
|
-
console.error(`\nError storing
|
|
65
|
+
console.error(`\nError storing access token: ${error.message}`);
|
|
51
66
|
}
|
|
52
67
|
});
|
|
53
68
|
}
|
|
@@ -55,7 +70,7 @@ class Auth {
|
|
|
55
70
|
return __awaiter(this, void 0, void 0, function* () {
|
|
56
71
|
try {
|
|
57
72
|
if (fs.existsSync(save_path)) {
|
|
58
|
-
return fs.readFileSync(save_path, { encoding: "utf8" });
|
|
73
|
+
return vigenere.decrypt(fs.readFileSync(save_path, { encoding: "utf8" }));
|
|
59
74
|
}
|
|
60
75
|
else {
|
|
61
76
|
return null;
|
|
@@ -63,6 +78,7 @@ class Auth {
|
|
|
63
78
|
}
|
|
64
79
|
catch (error) {
|
|
65
80
|
console.error(`\nError retriving acess-token. ${error.message}`);
|
|
81
|
+
return null;
|
|
66
82
|
}
|
|
67
83
|
});
|
|
68
84
|
}
|
|
@@ -109,7 +125,7 @@ class Auth {
|
|
|
109
125
|
}
|
|
110
126
|
static Myself() {
|
|
111
127
|
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, _t, _u, _v, _w;
|
|
128
|
+
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
129
|
try {
|
|
114
130
|
if (yield Auth.isLoggedIn()) {
|
|
115
131
|
const headers = {
|
|
@@ -130,35 +146,47 @@ class Auth {
|
|
|
130
146
|
perPage: 10,
|
|
131
147
|
});
|
|
132
148
|
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;
|
|
149
|
+
// Get follower/following information
|
|
150
|
+
const req_followers = yield fetcher(userFollowersQuery, {
|
|
151
|
+
userId: user === null || user === void 0 ? void 0 : user.id,
|
|
152
|
+
});
|
|
153
|
+
const req_following = yield fetcher(userFollowingQuery, {
|
|
154
|
+
userId: user === null || user === void 0 ? void 0 : user.id,
|
|
155
|
+
});
|
|
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;
|
|
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;
|
|
133
158
|
console.log(`
|
|
134
159
|
ID: ${user === null || user === void 0 ? void 0 : user.id}
|
|
135
160
|
Name: ${user === null || user === void 0 ? void 0 : user.name}
|
|
136
161
|
siteUrl: ${user === null || user === void 0 ? void 0 : user.siteUrl}
|
|
137
|
-
profileColor: ${(
|
|
138
|
-
timeZone: ${(
|
|
139
|
-
activityMergeTime: ${(
|
|
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}
|
|
140
165
|
donatorTier: ${user === null || user === void 0 ? void 0 : user.donatorTier}
|
|
141
166
|
donatorBadge: ${user === null || user === void 0 ? void 0 : user.donatorBadge}
|
|
142
167
|
unreadNotificationCount:${user === null || user === void 0 ? void 0 : user.unreadNotificationCount}
|
|
143
168
|
Account Created: ${new Date((user === null || user === void 0 ? void 0 : user.createdAt) * 1000).toUTCString()}
|
|
144
169
|
Account Updated: ${new Date((user === null || user === void 0 ? void 0 : user.updatedAt) * 1000).toUTCString()}
|
|
170
|
+
|
|
171
|
+
Followers: ${followersCount}
|
|
172
|
+
Following: ${followingCount}
|
|
145
173
|
|
|
146
174
|
Statistics (Anime):
|
|
147
|
-
Count: ${(
|
|
148
|
-
Mean Score: ${(
|
|
149
|
-
Minutes Watched: ${(
|
|
150
|
-
Episodes Watched: ${(
|
|
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}
|
|
151
179
|
|
|
152
180
|
Statistics (Manga):
|
|
153
|
-
Count: ${(
|
|
154
|
-
Mean Score: ${(
|
|
155
|
-
Chapters Read: ${(
|
|
156
|
-
Volumes Read: ${(
|
|
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}
|
|
157
185
|
`);
|
|
158
186
|
console.log(`\nRecent Activities:`);
|
|
159
187
|
if (activities.length > 0) {
|
|
160
188
|
activities.map(({ status, progress, media, createdAt }) => {
|
|
161
|
-
|
|
189
|
+
responsiveOutput(`${timestampToTimeAgo(createdAt)}\t${status} ${progress ? `${progress} of ` : ""}${getTitle(media === null || media === void 0 ? void 0 : media.title)}`);
|
|
162
190
|
});
|
|
163
191
|
}
|
|
164
192
|
return user;
|
|
@@ -181,15 +209,12 @@ Statistics (Manga):
|
|
|
181
209
|
static isLoggedIn() {
|
|
182
210
|
return __awaiter(this, void 0, void 0, function* () {
|
|
183
211
|
try {
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
}
|
|
187
|
-
else {
|
|
188
|
-
return false;
|
|
189
|
-
}
|
|
212
|
+
const token = yield Auth.RetriveAccessToken();
|
|
213
|
+
return token !== null;
|
|
190
214
|
}
|
|
191
215
|
catch (error) {
|
|
192
|
-
console.error(
|
|
216
|
+
console.error(`Error checking login status: ${error.message}`);
|
|
217
|
+
return false;
|
|
193
218
|
}
|
|
194
219
|
});
|
|
195
220
|
}
|
|
@@ -203,15 +228,15 @@ Statistics (Manga):
|
|
|
203
228
|
console.log(`\nLogout successful. See you soon, ${username}.`);
|
|
204
229
|
}
|
|
205
230
|
catch (error) {
|
|
206
|
-
console.error("\
|
|
231
|
+
console.error("\nFailed to remove the save file during logout:", error.message);
|
|
207
232
|
}
|
|
208
233
|
}
|
|
209
234
|
else {
|
|
210
|
-
console.
|
|
235
|
+
console.warn("\nNo active session found. You may already be logged out.");
|
|
211
236
|
}
|
|
212
237
|
}
|
|
213
238
|
catch (error) {
|
|
214
|
-
console.error(`\
|
|
239
|
+
console.error(`\nAn error occurred during logout: ${error.message}`);
|
|
215
240
|
}
|
|
216
241
|
});
|
|
217
242
|
}
|
|
@@ -222,20 +247,7 @@ Statistics (Manga):
|
|
|
222
247
|
console.warn(`\nUser not logged in.`);
|
|
223
248
|
return null;
|
|
224
249
|
}
|
|
225
|
-
const
|
|
226
|
-
const request = yield fetch(aniListEndpoint, {
|
|
227
|
-
method: "POST",
|
|
228
|
-
headers: {
|
|
229
|
-
"Content-Type": "application/json",
|
|
230
|
-
"Authorization": `Bearer ${token}`,
|
|
231
|
-
},
|
|
232
|
-
body: JSON.stringify({ query: currentUserQuery }),
|
|
233
|
-
});
|
|
234
|
-
if (!(request.status === 200)) {
|
|
235
|
-
console.error(`Failed to fetch user data. Status: ${request.status}`);
|
|
236
|
-
return null;
|
|
237
|
-
}
|
|
238
|
-
const { data } = yield request.json();
|
|
250
|
+
const { data } = yield fetcher(currentUserQuery, {});
|
|
239
251
|
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;
|
|
240
252
|
});
|
|
241
253
|
}
|
|
@@ -246,20 +258,7 @@ Statistics (Manga):
|
|
|
246
258
|
console.log(`\nUser not logged in.`);
|
|
247
259
|
return null;
|
|
248
260
|
}
|
|
249
|
-
const
|
|
250
|
-
const request = yield fetch(aniListEndpoint, {
|
|
251
|
-
method: "POST",
|
|
252
|
-
headers: {
|
|
253
|
-
"Content-Type": "application/json",
|
|
254
|
-
"Authorization": `Bearer ${token}`,
|
|
255
|
-
},
|
|
256
|
-
body: JSON.stringify({ query: currentUserQuery }),
|
|
257
|
-
});
|
|
258
|
-
if (!request.ok) {
|
|
259
|
-
console.error(`Failed to fetch user data. Status: ${request.status}`);
|
|
260
|
-
return null;
|
|
261
|
-
}
|
|
262
|
-
const { data } = yield request.json();
|
|
261
|
+
const { data } = yield fetcher(currentUserQuery, {});
|
|
263
262
|
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;
|
|
264
263
|
});
|
|
265
264
|
}
|
|
@@ -267,72 +266,70 @@ Statistics (Manga):
|
|
|
267
266
|
return __awaiter(this, void 0, void 0, function* () {
|
|
268
267
|
var _a, _b, _c, _d, _e, _f;
|
|
269
268
|
try {
|
|
270
|
-
if (yield Auth.isLoggedIn()) {
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
// Ensure ID is present to avoid unintended errors
|
|
313
|
-
if (act === null || act === void 0 ? void 0 : act.id) {
|
|
314
|
-
const deleteResponse = yield fetcher(deleteActivityMutation, {
|
|
315
|
-
id: act === null || act === void 0 ? void 0 : act.id,
|
|
316
|
-
});
|
|
317
|
-
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;
|
|
318
|
-
count++;
|
|
319
|
-
totalCount++;
|
|
320
|
-
console.log(`[${count}/${activities.length}/${totalCount}]\t${act === null || act === void 0 ? void 0 : act.id} ${isDeleted ? "ā
" : "ā"}`);
|
|
321
|
-
// Avoiding rate-limit
|
|
322
|
-
yield new Promise((resolve) => setTimeout(resolve, 1100));
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
}
|
|
269
|
+
if (!(yield Auth.isLoggedIn())) {
|
|
270
|
+
console.error(`\nPlease log in to delete your activities.`);
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
const { activityType } = yield inquirer.prompt([
|
|
274
|
+
{
|
|
275
|
+
type: "list",
|
|
276
|
+
name: "activityType",
|
|
277
|
+
message: "What type of activity you want to delete?",
|
|
278
|
+
choices: [
|
|
279
|
+
{ name: "All Activity", value: 0 },
|
|
280
|
+
{ name: "Text Activity", value: 1 },
|
|
281
|
+
{ name: "Media List Activity", value: 2 },
|
|
282
|
+
{ name: "Anime List Activity", value: 3 },
|
|
283
|
+
{ name: "Manga List Activity", value: 4 },
|
|
284
|
+
{ name: "Message Activity", value: 5 },
|
|
285
|
+
],
|
|
286
|
+
},
|
|
287
|
+
]);
|
|
288
|
+
const queryMap = {
|
|
289
|
+
0: activityAllQuery,
|
|
290
|
+
1: activityTextQuery,
|
|
291
|
+
2: activityMediaList,
|
|
292
|
+
3: activityAnimeListQuery,
|
|
293
|
+
4: activityMangaListQuery,
|
|
294
|
+
5: activityMessageQuery,
|
|
295
|
+
};
|
|
296
|
+
const query = queryMap[activityType];
|
|
297
|
+
let hasMoreActivities = true;
|
|
298
|
+
let totalCount = 0;
|
|
299
|
+
while (hasMoreActivities) {
|
|
300
|
+
const response = yield fetcher(query, {
|
|
301
|
+
page: 1,
|
|
302
|
+
perPage: 50,
|
|
303
|
+
userId: yield Auth.MyUserId(),
|
|
304
|
+
});
|
|
305
|
+
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) {
|
|
306
|
+
let count = 0;
|
|
307
|
+
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;
|
|
308
|
+
if (!activities || activities.length === 0) {
|
|
309
|
+
console.log(`\nNo more activities available.`);
|
|
310
|
+
hasMoreActivities = false;
|
|
326
311
|
}
|
|
327
312
|
else {
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
313
|
+
for (const act of activities) {
|
|
314
|
+
if (act === null || act === void 0 ? void 0 : act.id) {
|
|
315
|
+
const deleteResponse = yield fetcher(deleteActivityMutation, {
|
|
316
|
+
id: act === null || act === void 0 ? void 0 : act.id,
|
|
317
|
+
});
|
|
318
|
+
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;
|
|
319
|
+
count++;
|
|
320
|
+
totalCount++;
|
|
321
|
+
console.log(`[${count}/${activities.length}/${totalCount}]\t${act === null || act === void 0 ? void 0 : act.id} ${isDeleted ? "ā
" : "ā"}`);
|
|
322
|
+
// Avoiding rate-limit
|
|
323
|
+
yield new Promise((resolve) => setTimeout(resolve, 1100));
|
|
324
|
+
}
|
|
325
|
+
}
|
|
331
326
|
}
|
|
332
327
|
}
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
328
|
+
else {
|
|
329
|
+
// In case of an unexpected null response, exit the loop
|
|
330
|
+
console.log(`\nProbably deleted all the activities of this type.`);
|
|
331
|
+
hasMoreActivities = false;
|
|
332
|
+
}
|
|
336
333
|
}
|
|
337
334
|
}
|
|
338
335
|
catch (error) {
|
|
@@ -343,54 +340,51 @@ Statistics (Manga):
|
|
|
343
340
|
static DeleteMyAnimeList() {
|
|
344
341
|
return __awaiter(this, void 0, void 0, function* () {
|
|
345
342
|
var _a, _b, _c, _d;
|
|
346
|
-
if (yield Auth.isLoggedIn()) {
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
}
|
|
343
|
+
if (!(yield Auth.isLoggedIn())) {
|
|
344
|
+
console.error(`\nPlease log in first to delete your lists.`);
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
347
|
+
if (!(yield Auth.MyUserId())) {
|
|
348
|
+
console.log(`\nFailed getting current user Id.`);
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
351
|
+
const response = yield fetcher(currentUserAnimeList, { id: yield Auth.MyUserId() });
|
|
352
|
+
if (response !== null) {
|
|
353
|
+
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;
|
|
354
|
+
if (lists.length > 0) {
|
|
355
|
+
const { selectedList } = yield inquirer.prompt([
|
|
356
|
+
{
|
|
357
|
+
type: "list",
|
|
358
|
+
name: "selectedList",
|
|
359
|
+
message: "Select an anime list:",
|
|
360
|
+
choices: lists.map((list) => list.name),
|
|
361
|
+
pageSize: 10,
|
|
362
|
+
},
|
|
363
|
+
]);
|
|
364
|
+
const selectedEntries = lists.find((list) => list.name === selectedList);
|
|
365
|
+
if (selectedEntries) {
|
|
366
|
+
console.log(`\nDeleting entries of '${selectedEntries.name}':`);
|
|
367
|
+
for (const [, entry] of selectedEntries.entries.entries()) {
|
|
368
|
+
if (entry === null || entry === void 0 ? void 0 : entry.id) {
|
|
369
|
+
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);
|
|
370
|
+
yield new Promise((resolve) => setTimeout(resolve, 1100));
|
|
375
371
|
}
|
|
376
372
|
else {
|
|
377
|
-
console.log(
|
|
373
|
+
console.log(`No id in entry.`);
|
|
374
|
+
console.log(entry);
|
|
378
375
|
}
|
|
379
376
|
}
|
|
380
|
-
else {
|
|
381
|
-
console.log(`\nNo anime(s) found in any list.`);
|
|
382
|
-
}
|
|
383
377
|
}
|
|
384
378
|
else {
|
|
385
|
-
console.log(
|
|
379
|
+
console.log("No entries found.");
|
|
386
380
|
}
|
|
387
381
|
}
|
|
388
382
|
else {
|
|
389
|
-
console.log(`\
|
|
383
|
+
console.log(`\nNo anime(s) found in any list.`);
|
|
390
384
|
}
|
|
391
385
|
}
|
|
392
386
|
else {
|
|
393
|
-
console.
|
|
387
|
+
console.log(`\nSomething went wrong. ${(_d = response === null || response === void 0 ? void 0 : response.errors[0]) === null || _d === void 0 ? void 0 : _d.message}`);
|
|
394
388
|
}
|
|
395
389
|
});
|
|
396
390
|
}
|
|
@@ -417,54 +411,50 @@ Statistics (Manga):
|
|
|
417
411
|
return __awaiter(this, void 0, void 0, function* () {
|
|
418
412
|
var _a, _b, _c, _d;
|
|
419
413
|
try {
|
|
420
|
-
if (yield Auth.isLoggedIn()) {
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
console.error("\nNo entries found.");
|
|
452
|
-
}
|
|
414
|
+
if (!(yield Auth.isLoggedIn())) {
|
|
415
|
+
console.error(`\nPlease log in first to delete your lists.`);
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
418
|
+
if (!(yield Auth.MyUserId())) {
|
|
419
|
+
console.error(`\nFailed getting current user Id.`);
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
422
|
+
const response = yield fetcher(currentUserMangaList, { id: yield Auth.MyUserId() });
|
|
423
|
+
if (!(response === null || response === void 0 ? void 0 : response.data)) {
|
|
424
|
+
console.error(`\nSomething went wrong. ${(_a = response === null || response === void 0 ? void 0 : response.errors[0]) === null || _a === void 0 ? void 0 : _a.message}`);
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
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;
|
|
428
|
+
if (lists.length > 0) {
|
|
429
|
+
const { selectedList } = yield inquirer.prompt([
|
|
430
|
+
{
|
|
431
|
+
type: "list",
|
|
432
|
+
name: "selectedList",
|
|
433
|
+
message: "Select a manga list:",
|
|
434
|
+
choices: lists.map((list) => list.name),
|
|
435
|
+
pageSize: 10,
|
|
436
|
+
},
|
|
437
|
+
]);
|
|
438
|
+
const selectedEntries = lists.find((list) => list.name === selectedList);
|
|
439
|
+
if (selectedEntries) {
|
|
440
|
+
console.log(`\nDeleting entries of '${selectedEntries.name}':`);
|
|
441
|
+
for (const [, entry] of selectedEntries.entries.entries()) {
|
|
442
|
+
if (entry === null || entry === void 0 ? void 0 : entry.id) {
|
|
443
|
+
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);
|
|
444
|
+
yield new Promise((resolve) => setTimeout(resolve, 1100));
|
|
453
445
|
}
|
|
454
446
|
else {
|
|
455
|
-
console.
|
|
447
|
+
console.log(`No id in entry.`);
|
|
448
|
+
console.log(entry);
|
|
456
449
|
}
|
|
457
450
|
}
|
|
458
|
-
else {
|
|
459
|
-
console.error(`\nSomething went wrong. ${(_d = response === null || response === void 0 ? void 0 : response.errors[0]) === null || _d === void 0 ? void 0 : _d.message}`);
|
|
460
|
-
}
|
|
461
451
|
}
|
|
462
452
|
else {
|
|
463
|
-
console.error(
|
|
453
|
+
console.error("\nNo entries found.");
|
|
464
454
|
}
|
|
465
455
|
}
|
|
466
456
|
else {
|
|
467
|
-
console.error(`\
|
|
457
|
+
console.error(`\nNo manga(s) found in any list.`);
|
|
468
458
|
}
|
|
469
459
|
}
|
|
470
460
|
catch (error) {
|
|
@@ -493,23 +483,20 @@ Statistics (Manga):
|
|
|
493
483
|
}
|
|
494
484
|
static Write(status) {
|
|
495
485
|
return __awaiter(this, void 0, void 0, function* () {
|
|
496
|
-
var _a;
|
|
497
486
|
try {
|
|
498
487
|
if (!(yield Auth.isLoggedIn())) {
|
|
499
488
|
console.error(`\nPlease login to use this feature.`);
|
|
500
489
|
return;
|
|
501
490
|
}
|
|
502
|
-
const data = yield fetcher(saveTextActivityMutation, {
|
|
503
|
-
status: status
|
|
504
|
-
`<br><br><br><br>*Written using [@irfanshadikrishad/anilist](https://www.npmjs.com/package/@irfanshadikrishad/anilist).*`,
|
|
491
|
+
const { data } = yield fetcher(saveTextActivityMutation, {
|
|
492
|
+
status: status,
|
|
505
493
|
});
|
|
506
494
|
if (!data) {
|
|
507
495
|
console.error(`\nSomething went wrong. ${data}.`);
|
|
508
496
|
return;
|
|
509
497
|
}
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
console.log(`\n[${savedActivity.id}] status saved successfully!`);
|
|
498
|
+
if (data.SaveTextActivity.id) {
|
|
499
|
+
console.log(`\n[${data.SaveTextActivity.id}] status saved successfully!`);
|
|
513
500
|
}
|
|
514
501
|
}
|
|
515
502
|
catch (error) {
|
|
@@ -528,6 +515,7 @@ Statistics (Manga):
|
|
|
528
515
|
choices: [
|
|
529
516
|
{ name: "Exported JSON file.", value: 1 },
|
|
530
517
|
{ name: "MyAnimeList (XML)", value: 2 },
|
|
518
|
+
{ name: "AniDB (json-large)", value: 3 },
|
|
531
519
|
],
|
|
532
520
|
pageSize: 10,
|
|
533
521
|
},
|
|
@@ -539,6 +527,9 @@ Statistics (Manga):
|
|
|
539
527
|
case 2:
|
|
540
528
|
yield MyAnimeList.importAnime();
|
|
541
529
|
break;
|
|
530
|
+
case 3:
|
|
531
|
+
yield AniDB.importAnime();
|
|
532
|
+
break;
|
|
542
533
|
default:
|
|
543
534
|
console.log(`\nInvalid Choice.`);
|
|
544
535
|
break;
|
|
@@ -583,34 +574,39 @@ Statistics (Manga):
|
|
|
583
574
|
}
|
|
584
575
|
static LikeFollowing() {
|
|
585
576
|
return __awaiter(this, void 0, void 0, function* () {
|
|
586
|
-
var _a, _b, _c, _d;
|
|
577
|
+
var _a, _b, _c, _d, _e, _f;
|
|
587
578
|
try {
|
|
588
579
|
let page = 1;
|
|
589
580
|
let hasMoreActivities = true;
|
|
590
581
|
let retryCount = 0;
|
|
591
582
|
const maxRetries = 5;
|
|
583
|
+
let likedCount = 0;
|
|
592
584
|
while (hasMoreActivities) {
|
|
593
585
|
const activities = yield fetcher(followingActivitiesQuery, {
|
|
594
586
|
page,
|
|
595
587
|
perPage: 50,
|
|
596
588
|
});
|
|
597
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..`);
|
|
598
591
|
retryCount = 0; // Reset retry count on successful fetch
|
|
599
|
-
const activiti = (
|
|
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;
|
|
600
593
|
for (let activ of activiti) {
|
|
601
594
|
if (!activ.isLiked && activ.id) {
|
|
602
595
|
try {
|
|
603
596
|
const like = yield fetcher(likeActivityMutation, {
|
|
604
597
|
activityId: activ.id,
|
|
605
598
|
});
|
|
606
|
-
|
|
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)}`);
|
|
607
603
|
}
|
|
608
604
|
catch (error) {
|
|
609
605
|
console.error(`Activity possibly deleted. ${error.message}`);
|
|
610
606
|
}
|
|
611
607
|
}
|
|
612
608
|
else {
|
|
613
|
-
|
|
609
|
+
responsiveOutput(`"šµ" ${activityBy(activ, likedCount)}`);
|
|
614
610
|
}
|
|
615
611
|
// avoiding rate-limit
|
|
616
612
|
yield new Promise((resolve) => {
|
|
@@ -621,13 +617,13 @@ Statistics (Manga):
|
|
|
621
617
|
}
|
|
622
618
|
else {
|
|
623
619
|
if (retryCount < maxRetries) {
|
|
620
|
+
spinner.start("Getting activities...");
|
|
624
621
|
retryCount++;
|
|
625
|
-
|
|
626
|
-
yield new Promise((resolve) => setTimeout(resolve,
|
|
622
|
+
spinner.update(`Empty activities returned. Retrying... (${retryCount}/${maxRetries})`);
|
|
623
|
+
yield new Promise((resolve) => setTimeout(resolve, 2000));
|
|
627
624
|
}
|
|
628
625
|
else {
|
|
629
|
-
|
|
630
|
-
console.info(activities);
|
|
626
|
+
spinner.error(`Probably the end of activities after ${maxRetries} retries.`);
|
|
631
627
|
hasMoreActivities = false;
|
|
632
628
|
}
|
|
633
629
|
}
|
|
@@ -638,24 +634,22 @@ Statistics (Manga):
|
|
|
638
634
|
}
|
|
639
635
|
});
|
|
640
636
|
}
|
|
641
|
-
static
|
|
637
|
+
static LikeGlobal() {
|
|
642
638
|
return __awaiter(this, void 0, void 0, function* () {
|
|
643
|
-
var _a, _b, _c, _d;
|
|
639
|
+
var _a, _b, _c, _d, _e, _f;
|
|
644
640
|
try {
|
|
645
641
|
let page = 1;
|
|
646
642
|
let hasMoreActivities = true;
|
|
647
|
-
let
|
|
648
|
-
|
|
649
|
-
: type === 1
|
|
650
|
-
? globalActivitiesQuery
|
|
651
|
-
: followingActivitiesQuery;
|
|
643
|
+
let likedCount = 0;
|
|
644
|
+
spinner.start(`Getting global activities...`);
|
|
652
645
|
while (hasMoreActivities) {
|
|
653
|
-
const activities = yield fetcher(
|
|
646
|
+
const activities = yield fetcher(globalActivitiesQuery, {
|
|
654
647
|
page,
|
|
655
648
|
perPage: 50,
|
|
656
649
|
});
|
|
657
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) {
|
|
658
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...`);
|
|
659
653
|
for (let activ of activiti) {
|
|
660
654
|
if (!activ.isLiked && activ.id) {
|
|
661
655
|
try {
|
|
@@ -663,14 +657,15 @@ Statistics (Manga):
|
|
|
663
657
|
activityId: activ.id,
|
|
664
658
|
});
|
|
665
659
|
// const ToggleLike = like?.data?.ToggleLike
|
|
666
|
-
|
|
660
|
+
likedCount++;
|
|
661
|
+
responsiveOutput(`${(like === null || like === void 0 ? void 0 : like.data) ? "ā
" : "ā"} ${activityBy(activ, likedCount)}`);
|
|
667
662
|
}
|
|
668
663
|
catch (error) {
|
|
669
664
|
console.error(`Activity possibly deleted. ${error.message}`);
|
|
670
665
|
}
|
|
671
666
|
}
|
|
672
667
|
else {
|
|
673
|
-
|
|
668
|
+
responsiveOutput(`šµ ${activityBy(activ, likedCount)}`);
|
|
674
669
|
}
|
|
675
670
|
// avoiding rate-limit
|
|
676
671
|
yield new Promise((resolve) => {
|
|
@@ -681,8 +676,7 @@ Statistics (Manga):
|
|
|
681
676
|
}
|
|
682
677
|
else {
|
|
683
678
|
// No more activities to like
|
|
684
|
-
|
|
685
|
-
console.info(activities);
|
|
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}`);
|
|
686
680
|
hasMoreActivities = false;
|
|
687
681
|
}
|
|
688
682
|
}
|
|
@@ -694,7 +688,7 @@ Statistics (Manga):
|
|
|
694
688
|
}
|
|
695
689
|
static LikeSpecificUser() {
|
|
696
690
|
return __awaiter(this, void 0, void 0, function* () {
|
|
697
|
-
var _a, _b, _c, _d;
|
|
691
|
+
var _a, _b, _c, _d, _e, _f;
|
|
698
692
|
try {
|
|
699
693
|
const { username } = yield inquirer.prompt([
|
|
700
694
|
{
|
|
@@ -704,10 +698,12 @@ Statistics (Manga):
|
|
|
704
698
|
},
|
|
705
699
|
]);
|
|
706
700
|
const userDetails = yield fetcher(userQuery, { username: username });
|
|
707
|
-
|
|
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) {
|
|
708
703
|
let page = 1;
|
|
709
704
|
const perPage = 50;
|
|
710
|
-
const userId = (
|
|
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;
|
|
711
707
|
if (userId) {
|
|
712
708
|
while (true) {
|
|
713
709
|
const activities = yield fetcher(specificUserActivitiesQuery, {
|
|
@@ -715,26 +711,28 @@ Statistics (Manga):
|
|
|
715
711
|
perPage,
|
|
716
712
|
userId,
|
|
717
713
|
});
|
|
718
|
-
const activiti = (
|
|
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;
|
|
719
715
|
// Break the loop if no more activities are found
|
|
720
716
|
if (!activiti || activiti.length === 0) {
|
|
721
|
-
|
|
717
|
+
spinner.error("No more activities found.");
|
|
722
718
|
break;
|
|
723
719
|
}
|
|
720
|
+
spinner.success(`Got ${activiti.length} activities...`);
|
|
724
721
|
for (let activ of activiti) {
|
|
725
722
|
if (!activ.isLiked && activ.id) {
|
|
726
723
|
try {
|
|
727
724
|
const like = yield fetcher(likeActivityMutation, {
|
|
728
725
|
activityId: activ.id,
|
|
729
726
|
});
|
|
730
|
-
|
|
727
|
+
likedCount++;
|
|
728
|
+
responsiveOutput(`${(like === null || like === void 0 ? void 0 : like.data) ? "ā
" : "ā"} ${activityBy(activ, likedCount)}`);
|
|
731
729
|
}
|
|
732
730
|
catch (error) {
|
|
733
731
|
console.error(`Activity possibly deleted. ${error.message}`);
|
|
734
732
|
}
|
|
735
733
|
}
|
|
736
734
|
else {
|
|
737
|
-
|
|
735
|
+
responsiveOutput(`šµ ${activityBy(activ, likedCount)}`);
|
|
738
736
|
}
|
|
739
737
|
// Avoiding rate limit
|
|
740
738
|
yield new Promise((resolve) => {
|
|
@@ -746,12 +744,116 @@ Statistics (Manga):
|
|
|
746
744
|
}
|
|
747
745
|
}
|
|
748
746
|
}
|
|
747
|
+
else {
|
|
748
|
+
spinner.error(`User ${username} does not exist.`);
|
|
749
|
+
exit(1);
|
|
750
|
+
}
|
|
749
751
|
}
|
|
750
752
|
catch (error) {
|
|
751
753
|
console.error(`\nError from LikeSpecificUser. ${error.message}`);
|
|
752
754
|
}
|
|
753
755
|
});
|
|
754
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
|
+
// ------------------------
|
|
770
|
+
// Fetch all following users
|
|
771
|
+
// ------------------------
|
|
772
|
+
spinner.start(`Gathering following information...`);
|
|
773
|
+
while (hasNextPage) {
|
|
774
|
+
spinner.update(`Fetched page ${page}...`);
|
|
775
|
+
const followingUsers = yield fetcher(userFollowingQuery, {
|
|
776
|
+
userId: yield Auth.MyUserId(),
|
|
777
|
+
page,
|
|
778
|
+
});
|
|
779
|
+
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)) {
|
|
780
|
+
console.error(`\nFailed to fetch following users.`);
|
|
781
|
+
return;
|
|
782
|
+
}
|
|
783
|
+
allFollowingUsers.push(...followingUsers.data.Page.following);
|
|
784
|
+
hasNextPage = followingUsers.data.Page.pageInfo.hasNextPage;
|
|
785
|
+
page++;
|
|
786
|
+
}
|
|
787
|
+
spinner.stop(`Got ${allFollowingUsers.length} following user.`);
|
|
788
|
+
// Extract the IDs of all following users
|
|
789
|
+
const followingUserIds = allFollowingUsers.map((user) => user.id);
|
|
790
|
+
// --------------------
|
|
791
|
+
// APPROXIMATE TIME
|
|
792
|
+
// --------------------
|
|
793
|
+
const totalActivities = followingUserIds.length * perPage;
|
|
794
|
+
const perActivityTimeInSec = 1;
|
|
795
|
+
const rateLimitTimeInSec = 60;
|
|
796
|
+
const batchSize = 29;
|
|
797
|
+
const batches = Math.floor(totalActivities / batchSize);
|
|
798
|
+
const remaining = totalActivities % batchSize;
|
|
799
|
+
const processingTime = batches * batchSize * perActivityTimeInSec +
|
|
800
|
+
remaining * perActivityTimeInSec;
|
|
801
|
+
const waitTime = (batches - 1) * rateLimitTimeInSec;
|
|
802
|
+
const totalWaitTimeInSec = processingTime + (batches > 0 ? waitTime : 0);
|
|
803
|
+
const hours = Math.floor(totalWaitTimeInSec / 3600);
|
|
804
|
+
const minutes = Math.floor((totalWaitTimeInSec % 3600) / 60);
|
|
805
|
+
const seconds = totalWaitTimeInSec % 60;
|
|
806
|
+
const time = `${String(hours).padStart(2, "0")}h ${String(minutes).padStart(2, "0")}m ${String(seconds).padStart(2, "0")}s`;
|
|
807
|
+
console.log(`\nTotal following: ${followingUserIds.length}\nApproximately ${totalActivities} to like.\nWill take around ${time}`);
|
|
808
|
+
// -------------------
|
|
809
|
+
// Traverse the array and
|
|
810
|
+
// fetch users' activities one by one
|
|
811
|
+
// -------------------
|
|
812
|
+
let userNumber = 0;
|
|
813
|
+
for (const userId of followingUserIds) {
|
|
814
|
+
userNumber++;
|
|
815
|
+
console.log(`\n[${userNumber}]\tID: ${userId}`);
|
|
816
|
+
// Fetch `perPage` activities for the current user
|
|
817
|
+
const activities = yield fetcher(specificUserActivitiesQuery, {
|
|
818
|
+
userId,
|
|
819
|
+
page: 1, // Always fetch from the first page
|
|
820
|
+
perPage,
|
|
821
|
+
});
|
|
822
|
+
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)) {
|
|
823
|
+
console.log(`[${userNumber}] No activities found for User ID: ${userId}`);
|
|
824
|
+
continue;
|
|
825
|
+
}
|
|
826
|
+
const activiti = activities.data.Page.activities;
|
|
827
|
+
for (let i = 0; i < activiti.length; i++) {
|
|
828
|
+
const activ = activiti[i];
|
|
829
|
+
if (!activ.isLiked && activ.id) {
|
|
830
|
+
try {
|
|
831
|
+
const like = yield fetcher(likeActivityMutation, {
|
|
832
|
+
activityId: activ.id,
|
|
833
|
+
});
|
|
834
|
+
responsiveOutput(`${(like === null || like === void 0 ? void 0 : like.data) ? "ā
" : "ā"} ${activityBy(activ, i + 1)}`);
|
|
835
|
+
if (like === null || like === void 0 ? void 0 : like.data) {
|
|
836
|
+
liked++;
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
catch (error) {
|
|
840
|
+
console.error(`Activity possibly deleted. ${error.message}`);
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
else {
|
|
844
|
+
responsiveOutput(`šµ ${activityBy(activ, i + 1)}`);
|
|
845
|
+
}
|
|
846
|
+
// Avoid rate-limiting
|
|
847
|
+
yield new Promise((resolve) => setTimeout(resolve, 1200));
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
console.log(`\nā
All ${liked} activities liked successfully.`);
|
|
851
|
+
}
|
|
852
|
+
catch (error) {
|
|
853
|
+
console.error(`\nError in LikeFollowingActivityV2: ${error.message}`);
|
|
854
|
+
}
|
|
855
|
+
});
|
|
856
|
+
}
|
|
755
857
|
static AutoLike() {
|
|
756
858
|
return __awaiter(this, void 0, void 0, function* () {
|
|
757
859
|
try {
|
|
@@ -765,9 +867,10 @@ Statistics (Manga):
|
|
|
765
867
|
name: "activityType",
|
|
766
868
|
message: "Select activity type:",
|
|
767
869
|
choices: [
|
|
768
|
-
{ name: "Following", value: 1 },
|
|
769
|
-
{ name: "
|
|
770
|
-
{ name: "
|
|
870
|
+
{ name: "Following ⢠v1", value: 1 },
|
|
871
|
+
{ name: "Following ⢠v2", value: 2 },
|
|
872
|
+
{ name: "Global", value: 3 },
|
|
873
|
+
{ name: "Specific User", value: 4 },
|
|
771
874
|
],
|
|
772
875
|
pageSize: 10,
|
|
773
876
|
},
|
|
@@ -776,10 +879,21 @@ Statistics (Manga):
|
|
|
776
879
|
case 1:
|
|
777
880
|
yield this.LikeFollowing();
|
|
778
881
|
break;
|
|
779
|
-
case 2:
|
|
780
|
-
yield
|
|
882
|
+
case 2: {
|
|
883
|
+
const { count } = yield inquirer.prompt([
|
|
884
|
+
{
|
|
885
|
+
type: "number",
|
|
886
|
+
name: "count",
|
|
887
|
+
message: "Likes to give:",
|
|
888
|
+
},
|
|
889
|
+
]);
|
|
890
|
+
yield this.LikeFollowingActivityV2(count);
|
|
781
891
|
break;
|
|
892
|
+
}
|
|
782
893
|
case 3:
|
|
894
|
+
yield this.LikeGlobal();
|
|
895
|
+
break;
|
|
896
|
+
case 4:
|
|
783
897
|
yield this.LikeSpecificUser();
|
|
784
898
|
break;
|
|
785
899
|
default:
|
|
@@ -792,4 +906,124 @@ Statistics (Manga):
|
|
|
792
906
|
});
|
|
793
907
|
}
|
|
794
908
|
}
|
|
795
|
-
|
|
909
|
+
class Social {
|
|
910
|
+
/**
|
|
911
|
+
* Follow the users that follows you
|
|
912
|
+
*/
|
|
913
|
+
static follow() {
|
|
914
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
915
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
|
|
916
|
+
try {
|
|
917
|
+
let pager = 1;
|
|
918
|
+
let hasNextPage = true;
|
|
919
|
+
let allFollowerUsers = [];
|
|
920
|
+
let followedBack = 0;
|
|
921
|
+
spinner.start("Fetching all the followers...");
|
|
922
|
+
while (hasNextPage) {
|
|
923
|
+
const followerUsers = yield fetcher(userFollowersQuery, {
|
|
924
|
+
userId: yield Auth.MyUserId(),
|
|
925
|
+
page: pager,
|
|
926
|
+
});
|
|
927
|
+
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}...`);
|
|
928
|
+
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)) {
|
|
929
|
+
hasNextPage = false;
|
|
930
|
+
}
|
|
931
|
+
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) || []));
|
|
932
|
+
pager++;
|
|
933
|
+
}
|
|
934
|
+
spinner.stop("Fetched all the followers. Starting follow back.");
|
|
935
|
+
// Filter users that do no follow me
|
|
936
|
+
const notFollowing = allFollowerUsers
|
|
937
|
+
.filter(({ isFollowing }) => !isFollowing)
|
|
938
|
+
.map(({ id, name }) => ({ id: id, name: name }));
|
|
939
|
+
console.log(`\nTotal follower ${allFollowerUsers.length}.\nNot followed back ${notFollowing.length}\n`);
|
|
940
|
+
if (notFollowing.length <= 0) {
|
|
941
|
+
console.log(`Probably followed back all the users.`);
|
|
942
|
+
return;
|
|
943
|
+
}
|
|
944
|
+
// Traverse and follow back
|
|
945
|
+
const maxIdLength = Math.max(...notFollowing.map(({ id }) => String(id).length));
|
|
946
|
+
const maxNameLength = Math.max(...notFollowing.map(({ name }) => name.length));
|
|
947
|
+
for (let nf of notFollowing) {
|
|
948
|
+
try {
|
|
949
|
+
const follow = yield fetcher(toggleFollowMutation, { userId: nf.id });
|
|
950
|
+
console.log(`${String(`[${nf.id}]`).padEnd(maxIdLength)}` +
|
|
951
|
+
`\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)}` +
|
|
952
|
+
`\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) ? "ā
" : "šµ"}`);
|
|
953
|
+
// Count the followed back users
|
|
954
|
+
if ((_p = (_o = follow === null || follow === void 0 ? void 0 : follow.data) === null || _o === void 0 ? void 0 : _o.ToggleFollow) === null || _p === void 0 ? void 0 : _p.id) {
|
|
955
|
+
followedBack++;
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
catch (error) {
|
|
959
|
+
console.log(`automate_follow_toggle_follow: ${error.message}`);
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
console.log(`\nā
Followed back ${followedBack} users.`);
|
|
963
|
+
}
|
|
964
|
+
catch (error) {
|
|
965
|
+
console.log(`\nautomate_follow ${error.message}`);
|
|
966
|
+
}
|
|
967
|
+
});
|
|
968
|
+
}
|
|
969
|
+
/**
|
|
970
|
+
* Unfollow the users thats not following you
|
|
971
|
+
*/
|
|
972
|
+
static unfollow() {
|
|
973
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
974
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
|
|
975
|
+
try {
|
|
976
|
+
let pager = 1;
|
|
977
|
+
let hasNextPage = true;
|
|
978
|
+
let allFollowingUsers = [];
|
|
979
|
+
let unfollowedUsers = 0;
|
|
980
|
+
spinner.start("Fetching all following users...");
|
|
981
|
+
while (hasNextPage) {
|
|
982
|
+
const followingUsers = yield fetcher(userFollowingQuery, {
|
|
983
|
+
userId: yield Auth.MyUserId(),
|
|
984
|
+
page: pager,
|
|
985
|
+
});
|
|
986
|
+
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}...`);
|
|
987
|
+
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)) {
|
|
988
|
+
hasNextPage = false;
|
|
989
|
+
}
|
|
990
|
+
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) || []));
|
|
991
|
+
pager++;
|
|
992
|
+
}
|
|
993
|
+
spinner.update(`Fetching complete. Total got ${allFollowingUsers.length} users.`);
|
|
994
|
+
// Filter users that do no follow me
|
|
995
|
+
const notFollowingMe = allFollowingUsers
|
|
996
|
+
.filter((user) => !user.isFollower)
|
|
997
|
+
.map((u3r) => ({ id: u3r.id, name: u3r.name }));
|
|
998
|
+
if (notFollowingMe.length <= 0) {
|
|
999
|
+
spinner.stop(`No users to unfollow. Exiting operation...`);
|
|
1000
|
+
return;
|
|
1001
|
+
}
|
|
1002
|
+
spinner.stop(`Unfollow process activated with ${notFollowingMe.length} users.`);
|
|
1003
|
+
let nfmCount = 0;
|
|
1004
|
+
console.log(`\n`);
|
|
1005
|
+
for (let nfm of notFollowingMe) {
|
|
1006
|
+
nfmCount++;
|
|
1007
|
+
try {
|
|
1008
|
+
const unfollow = yield fetcher(toggleFollowMutation, {
|
|
1009
|
+
userId: nfm.id,
|
|
1010
|
+
});
|
|
1011
|
+
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) ? "ā
" : "šµ"}`);
|
|
1012
|
+
// Count the unfollowed users
|
|
1013
|
+
if ((_p = (_o = unfollow === null || unfollow === void 0 ? void 0 : unfollow.data) === null || _o === void 0 ? void 0 : _o.ToggleFollow) === null || _p === void 0 ? void 0 : _p.id) {
|
|
1014
|
+
unfollowedUsers++;
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
catch (error) {
|
|
1018
|
+
console.log(`unfollow_toggle_follow. ${error.message}`);
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
1021
|
+
console.log(`\nTotal Unfollowed: ${unfollowedUsers} of ${nfmCount} users.`);
|
|
1022
|
+
}
|
|
1023
|
+
catch (error) {
|
|
1024
|
+
console.error(`\nautomate_unfollow: ${error.message}`);
|
|
1025
|
+
}
|
|
1026
|
+
});
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
1029
|
+
export { Auth, Social };
|