@irfanshadikrishad/anilist 1.1.0-forbidden.0 ā 1.1.0-forbidden.7
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 -382
- package/LICENSE.md +382 -0
- package/README.md +87 -53
- package/bin/helpers/auth.d.ts +22 -9
- package/bin/helpers/auth.js +562 -312
- package/bin/helpers/fetcher.d.ts +3 -2
- package/bin/helpers/fetcher.js +31 -25
- package/bin/helpers/lists.d.ts +5 -1
- package/bin/helpers/lists.js +516 -405
- package/bin/helpers/mutations.d.ts +7 -4
- package/bin/helpers/mutations.js +9 -10
- package/bin/helpers/queries.d.ts +9 -8
- package/bin/helpers/queries.js +29 -12
- package/bin/helpers/truncate.d.ts +6 -0
- package/bin/helpers/truncate.js +10 -0
- package/bin/helpers/types.d.ts +319 -28
- package/bin/helpers/validation.d.ts +29 -0
- package/bin/helpers/validation.js +117 -0
- package/bin/helpers/workers.d.ts +24 -9
- package/bin/helpers/workers.js +210 -16
- package/bin/index.js +36 -4
- package/package.json +29 -16
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";
|
|
18
|
-
import { deleteActivityMutation, likeActivityMutation, saveTextActivityMutation, } from "./mutations.js";
|
|
19
|
-
import { activityAllQuery, activityAnimeListQuery, activityMangaListQuery, activityMediaList, activityMessageQuery, activityTextQuery, currentUserAnimeList, currentUserMangaList, currentUserQuery,
|
|
20
|
-
import {
|
|
20
|
+
import { AniDB, AniList, MyAnimeList } from "./lists.js";
|
|
21
|
+
import { deleteActivityMutation, deleteMangaEntryMutation, deleteMediaEntryMutation, likeActivityMutation, saveTextActivityMutation, toggleFollowMutation, } from "./mutations.js";
|
|
22
|
+
import { activityAllQuery, activityAnimeListQuery, activityMangaListQuery, activityMediaList, activityMessageQuery, activityTextQuery, currentUserAnimeList, currentUserMangaList, currentUserQuery, followingActivitiesQuery, globalActivitiesQuery, specificUserActivitiesQuery, userActivityQuery, userFollowersQuery, userFollowingQuery, userQuery, } from "./queries.js";
|
|
23
|
+
import { responsiveOutput } from "./truncate.js";
|
|
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;
|
|
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,33 +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: ${(
|
|
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}
|
|
150
179
|
|
|
151
180
|
Statistics (Manga):
|
|
152
|
-
Count: ${(
|
|
153
|
-
|
|
154
|
-
|
|
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}
|
|
155
185
|
`);
|
|
156
186
|
console.log(`\nRecent Activities:`);
|
|
157
187
|
if (activities.length > 0) {
|
|
158
|
-
activities.map(({ status, progress, media }) => {
|
|
159
|
-
|
|
188
|
+
activities.map(({ status, progress, media, createdAt }) => {
|
|
189
|
+
responsiveOutput(`${timestampToTimeAgo(createdAt)}\t${status} ${progress ? `${progress} of ` : ""}${getTitle(media === null || media === void 0 ? void 0 : media.title)}`);
|
|
160
190
|
});
|
|
161
191
|
}
|
|
162
192
|
return user;
|
|
@@ -179,15 +209,12 @@ Statistics (Manga):
|
|
|
179
209
|
static isLoggedIn() {
|
|
180
210
|
return __awaiter(this, void 0, void 0, function* () {
|
|
181
211
|
try {
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
}
|
|
185
|
-
else {
|
|
186
|
-
return false;
|
|
187
|
-
}
|
|
212
|
+
const token = yield Auth.RetriveAccessToken();
|
|
213
|
+
return token !== null;
|
|
188
214
|
}
|
|
189
215
|
catch (error) {
|
|
190
|
-
console.error(
|
|
216
|
+
console.error(`Error checking login status: ${error.message}`);
|
|
217
|
+
return false;
|
|
191
218
|
}
|
|
192
219
|
});
|
|
193
220
|
}
|
|
@@ -201,15 +228,15 @@ Statistics (Manga):
|
|
|
201
228
|
console.log(`\nLogout successful. See you soon, ${username}.`);
|
|
202
229
|
}
|
|
203
230
|
catch (error) {
|
|
204
|
-
console.error("\
|
|
231
|
+
console.error("\nFailed to remove the save file during logout:", error.message);
|
|
205
232
|
}
|
|
206
233
|
}
|
|
207
234
|
else {
|
|
208
|
-
console.
|
|
235
|
+
console.warn("\nNo active session found. You may already be logged out.");
|
|
209
236
|
}
|
|
210
237
|
}
|
|
211
238
|
catch (error) {
|
|
212
|
-
console.error(`\
|
|
239
|
+
console.error(`\nAn error occurred during logout: ${error.message}`);
|
|
213
240
|
}
|
|
214
241
|
});
|
|
215
242
|
}
|
|
@@ -217,23 +244,10 @@ Statistics (Manga):
|
|
|
217
244
|
return __awaiter(this, void 0, void 0, function* () {
|
|
218
245
|
var _a, _b;
|
|
219
246
|
if (!(yield Auth.isLoggedIn())) {
|
|
220
|
-
console.
|
|
247
|
+
console.warn(`\nUser not logged in.`);
|
|
221
248
|
return null;
|
|
222
249
|
}
|
|
223
|
-
const
|
|
224
|
-
const request = yield fetch(aniListEndpoint, {
|
|
225
|
-
method: "POST",
|
|
226
|
-
headers: {
|
|
227
|
-
"Content-Type": "application/json",
|
|
228
|
-
"Authorization": `Bearer ${token}`,
|
|
229
|
-
},
|
|
230
|
-
body: JSON.stringify({ query: currentUserQuery }),
|
|
231
|
-
});
|
|
232
|
-
if (!(request.status === 200)) {
|
|
233
|
-
console.error(`Failed to fetch user data. Status: ${request.status}`);
|
|
234
|
-
return null;
|
|
235
|
-
}
|
|
236
|
-
const { data } = yield request.json();
|
|
250
|
+
const { data } = yield fetcher(currentUserQuery, {});
|
|
237
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;
|
|
238
252
|
});
|
|
239
253
|
}
|
|
@@ -244,20 +258,7 @@ Statistics (Manga):
|
|
|
244
258
|
console.log(`\nUser not logged in.`);
|
|
245
259
|
return null;
|
|
246
260
|
}
|
|
247
|
-
const
|
|
248
|
-
const request = yield fetch(aniListEndpoint, {
|
|
249
|
-
method: "POST",
|
|
250
|
-
headers: {
|
|
251
|
-
"Content-Type": "application/json",
|
|
252
|
-
"Authorization": `Bearer ${token}`,
|
|
253
|
-
},
|
|
254
|
-
body: JSON.stringify({ query: currentUserQuery }),
|
|
255
|
-
});
|
|
256
|
-
if (!request.ok) {
|
|
257
|
-
console.error(`Failed to fetch user data. Status: ${request.status}`);
|
|
258
|
-
return null;
|
|
259
|
-
}
|
|
260
|
-
const { data } = yield request.json();
|
|
261
|
+
const { data } = yield fetcher(currentUserQuery, {});
|
|
261
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;
|
|
262
263
|
});
|
|
263
264
|
}
|
|
@@ -265,72 +266,70 @@ Statistics (Manga):
|
|
|
265
266
|
return __awaiter(this, void 0, void 0, function* () {
|
|
266
267
|
var _a, _b, _c, _d, _e, _f;
|
|
267
268
|
try {
|
|
268
|
-
if (yield Auth.isLoggedIn()) {
|
|
269
|
-
|
|
270
|
-
|
|
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
|
-
for (const act of activities) {
|
|
311
|
-
// Ensure ID is present to avoid unintended errors
|
|
312
|
-
if (act === null || act === void 0 ? void 0 : act.id) {
|
|
313
|
-
const deleteResponse = yield fetcher(deleteActivityMutation, {
|
|
314
|
-
id: act === null || act === void 0 ? void 0 : act.id,
|
|
315
|
-
});
|
|
316
|
-
const isDeleted = (_f = (_e = deleteResponse === null || deleteResponse === void 0 ? void 0 : deleteResponse.data) === null || _e === void 0 ? void 0 : _e.DeleteActivity) === null || _f === void 0 ? void 0 : _f.deleted;
|
|
317
|
-
count++;
|
|
318
|
-
console.log(`[${count}/${activities.length}] ${act === null || act === void 0 ? void 0 : act.id} ${isDeleted ? "ā
" : "ā"}`);
|
|
319
|
-
// Avoiding rate-limit
|
|
320
|
-
yield new Promise((resolve) => setTimeout(resolve, 1100));
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
}
|
|
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;
|
|
324
311
|
}
|
|
325
312
|
else {
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
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
|
+
}
|
|
329
326
|
}
|
|
330
327
|
}
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
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
|
+
}
|
|
334
333
|
}
|
|
335
334
|
}
|
|
336
335
|
catch (error) {
|
|
@@ -341,65 +340,51 @@ Statistics (Manga):
|
|
|
341
340
|
static DeleteMyAnimeList() {
|
|
342
341
|
return __awaiter(this, void 0, void 0, function* () {
|
|
343
342
|
var _a, _b, _c, _d;
|
|
344
|
-
if (yield Auth.isLoggedIn()) {
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
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,
|
|
352
362
|
},
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
})
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
if (lists.length > 0) {
|
|
362
|
-
const { selectedList } = yield inquirer.prompt([
|
|
363
|
-
{
|
|
364
|
-
type: "list",
|
|
365
|
-
name: "selectedList",
|
|
366
|
-
message: "Select an anime list:",
|
|
367
|
-
choices: lists.map((list) => list.name),
|
|
368
|
-
pageSize: 10,
|
|
369
|
-
},
|
|
370
|
-
]);
|
|
371
|
-
const selectedEntries = lists.find((list) => list.name === selectedList);
|
|
372
|
-
if (selectedEntries) {
|
|
373
|
-
console.log(`\nDeleting entries of '${selectedEntries.name}':`);
|
|
374
|
-
for (const [_, entry] of selectedEntries.entries.entries()) {
|
|
375
|
-
if (entry === null || entry === void 0 ? void 0 : entry.id) {
|
|
376
|
-
yield Auth.DeleteAnimeById(entry === null || entry === void 0 ? void 0 : entry.id, (_c = entry === null || entry === void 0 ? void 0 : entry.media) === null || _c === void 0 ? void 0 : _c.title);
|
|
377
|
-
yield new Promise((resolve) => setTimeout(resolve, 1100));
|
|
378
|
-
}
|
|
379
|
-
else {
|
|
380
|
-
console.log(`No id in entry.`);
|
|
381
|
-
console.log(entry);
|
|
382
|
-
}
|
|
383
|
-
}
|
|
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));
|
|
384
371
|
}
|
|
385
372
|
else {
|
|
386
|
-
console.log(
|
|
373
|
+
console.log(`No id in entry.`);
|
|
374
|
+
console.log(entry);
|
|
387
375
|
}
|
|
388
376
|
}
|
|
389
|
-
else {
|
|
390
|
-
console.log(`\nNo anime(s) found in any list.`);
|
|
391
|
-
}
|
|
392
377
|
}
|
|
393
378
|
else {
|
|
394
|
-
console.log(
|
|
379
|
+
console.log("No entries found.");
|
|
395
380
|
}
|
|
396
381
|
}
|
|
397
382
|
else {
|
|
398
|
-
console.log(`\
|
|
383
|
+
console.log(`\nNo anime(s) found in any list.`);
|
|
399
384
|
}
|
|
400
385
|
}
|
|
401
386
|
else {
|
|
402
|
-
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}`);
|
|
403
388
|
}
|
|
404
389
|
});
|
|
405
390
|
}
|
|
@@ -407,19 +392,8 @@ Statistics (Manga):
|
|
|
407
392
|
return __awaiter(this, void 0, void 0, function* () {
|
|
408
393
|
var _a, _b, _c;
|
|
409
394
|
try {
|
|
410
|
-
const
|
|
411
|
-
|
|
412
|
-
headers: {
|
|
413
|
-
"content-type": "application/json",
|
|
414
|
-
"Authorization": `Bearer ${yield Auth.RetriveAccessToken()}`,
|
|
415
|
-
},
|
|
416
|
-
body: JSON.stringify({
|
|
417
|
-
query: deleteMediaEntryMutation,
|
|
418
|
-
variables: { id },
|
|
419
|
-
}),
|
|
420
|
-
});
|
|
421
|
-
const response = yield request.json();
|
|
422
|
-
if (request.status === 200) {
|
|
395
|
+
const response = yield fetcher(deleteMediaEntryMutation, { id: id });
|
|
396
|
+
if (response === null || response === void 0 ? void 0 : response.data) {
|
|
423
397
|
const deleted = (_b = (_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.DeleteMediaListEntry) === null || _b === void 0 ? void 0 : _b.deleted;
|
|
424
398
|
console.log(`del ${title ? getTitle(title) : ""} ${deleted ? "ā
" : "ā"}`);
|
|
425
399
|
}
|
|
@@ -437,95 +411,69 @@ Statistics (Manga):
|
|
|
437
411
|
return __awaiter(this, void 0, void 0, function* () {
|
|
438
412
|
var _a, _b, _c, _d;
|
|
439
413
|
try {
|
|
440
|
-
if (yield Auth.isLoggedIn()) {
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
if (entry === null || entry === void 0 ? void 0 : entry.id) {
|
|
472
|
-
yield Auth.DeleteMangaById(entry === null || entry === void 0 ? void 0 : entry.id, (_c = entry === null || entry === void 0 ? void 0 : entry.media) === null || _c === void 0 ? void 0 : _c.title);
|
|
473
|
-
yield new Promise((resolve) => setTimeout(resolve, 1100));
|
|
474
|
-
}
|
|
475
|
-
else {
|
|
476
|
-
console.log(`No id in entry.`);
|
|
477
|
-
console.log(entry);
|
|
478
|
-
}
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
|
-
else {
|
|
482
|
-
console.error("\nNo entries found.");
|
|
483
|
-
}
|
|
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));
|
|
484
445
|
}
|
|
485
446
|
else {
|
|
486
|
-
console.
|
|
447
|
+
console.log(`No id in entry.`);
|
|
448
|
+
console.log(entry);
|
|
487
449
|
}
|
|
488
450
|
}
|
|
489
|
-
else {
|
|
490
|
-
console.error(`\nSomething went wrong. ${(_d = response === null || response === void 0 ? void 0 : response.errors[0]) === null || _d === void 0 ? void 0 : _d.message}`);
|
|
491
|
-
}
|
|
492
451
|
}
|
|
493
452
|
else {
|
|
494
|
-
console.error(
|
|
453
|
+
console.error("\nNo entries found.");
|
|
495
454
|
}
|
|
496
455
|
}
|
|
497
456
|
else {
|
|
498
|
-
console.error(`\
|
|
457
|
+
console.error(`\nNo manga(s) found in any list.`);
|
|
499
458
|
}
|
|
500
459
|
}
|
|
501
460
|
catch (error) {
|
|
502
|
-
console.error(`\nError deleting manga
|
|
461
|
+
console.error(`\nError deleting manga. ${error.message}`);
|
|
503
462
|
}
|
|
504
463
|
});
|
|
505
464
|
}
|
|
506
465
|
static DeleteMangaById(id, title) {
|
|
507
466
|
return __awaiter(this, void 0, void 0, function* () {
|
|
508
|
-
var _a, _b;
|
|
467
|
+
var _a, _b, _c, _d;
|
|
509
468
|
try {
|
|
510
|
-
const
|
|
511
|
-
method: "POST",
|
|
512
|
-
headers: {
|
|
513
|
-
"Content-Type": "application/json",
|
|
514
|
-
"Authorization": `Bearer ${yield Auth.RetriveAccessToken()}`,
|
|
515
|
-
},
|
|
516
|
-
body: JSON.stringify({
|
|
517
|
-
query: deleteMangaEntryMutation,
|
|
518
|
-
variables: { id },
|
|
519
|
-
}),
|
|
520
|
-
});
|
|
521
|
-
const { data, errors } = yield request.json();
|
|
469
|
+
const response = yield fetcher(deleteMangaEntryMutation, { id });
|
|
522
470
|
const statusMessage = title ? getTitle(title) : "";
|
|
523
|
-
if (
|
|
524
|
-
const deleted = (_a =
|
|
471
|
+
if (response === null || response === void 0 ? void 0 : response.data) {
|
|
472
|
+
const deleted = (_b = (_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.DeleteMediaListEntry) === null || _b === void 0 ? void 0 : _b.deleted;
|
|
525
473
|
console.log(`del ${statusMessage} ${deleted ? "ā
" : "ā"}`);
|
|
526
474
|
}
|
|
527
475
|
else {
|
|
528
|
-
console.error(`Error deleting manga. ${(
|
|
476
|
+
console.error(`Error deleting manga. ${(_d = (_c = response === null || response === void 0 ? void 0 : response.errors) === null || _c === void 0 ? void 0 : _c[0]) === null || _d === void 0 ? void 0 : _d.message}`);
|
|
529
477
|
}
|
|
530
478
|
}
|
|
531
479
|
catch (error) {
|
|
@@ -535,25 +483,20 @@ Statistics (Manga):
|
|
|
535
483
|
}
|
|
536
484
|
static Write(status) {
|
|
537
485
|
return __awaiter(this, void 0, void 0, function* () {
|
|
538
|
-
var _a;
|
|
539
486
|
try {
|
|
540
487
|
if (!(yield Auth.isLoggedIn())) {
|
|
541
488
|
console.error(`\nPlease login to use this feature.`);
|
|
542
489
|
return;
|
|
543
490
|
}
|
|
544
|
-
const
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
`<br><br><br><br>*Written using [@irfanshadikrishad/anilist](https://www.npmjs.com/package/@irfanshadikrishad/anilist).*`,
|
|
548
|
-
};
|
|
549
|
-
const data = yield fetcher(query, variables);
|
|
491
|
+
const { data } = yield fetcher(saveTextActivityMutation, {
|
|
492
|
+
status: status,
|
|
493
|
+
});
|
|
550
494
|
if (!data) {
|
|
551
495
|
console.error(`\nSomething went wrong. ${data}.`);
|
|
552
496
|
return;
|
|
553
497
|
}
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
console.log(`\n[${savedActivity.id}] status saved successfully!`);
|
|
498
|
+
if (data.SaveTextActivity.id) {
|
|
499
|
+
console.log(`\n[${data.SaveTextActivity.id}] status saved successfully!`);
|
|
557
500
|
}
|
|
558
501
|
}
|
|
559
502
|
catch (error) {
|
|
@@ -572,6 +515,7 @@ Statistics (Manga):
|
|
|
572
515
|
choices: [
|
|
573
516
|
{ name: "Exported JSON file.", value: 1 },
|
|
574
517
|
{ name: "MyAnimeList (XML)", value: 2 },
|
|
518
|
+
{ name: "AniDB (json-large)", value: 3 },
|
|
575
519
|
],
|
|
576
520
|
pageSize: 10,
|
|
577
521
|
},
|
|
@@ -583,6 +527,9 @@ Statistics (Manga):
|
|
|
583
527
|
case 2:
|
|
584
528
|
yield MyAnimeList.importAnime();
|
|
585
529
|
break;
|
|
530
|
+
case 3:
|
|
531
|
+
yield AniDB.importAnime();
|
|
532
|
+
break;
|
|
586
533
|
default:
|
|
587
534
|
console.log(`\nInvalid Choice.`);
|
|
588
535
|
break;
|
|
@@ -625,24 +572,84 @@ Statistics (Manga):
|
|
|
625
572
|
}
|
|
626
573
|
});
|
|
627
574
|
}
|
|
628
|
-
static
|
|
575
|
+
static LikeFollowing() {
|
|
629
576
|
return __awaiter(this, void 0, void 0, function* () {
|
|
630
|
-
var _a, _b, _c, _d;
|
|
577
|
+
var _a, _b, _c, _d, _e, _f;
|
|
631
578
|
try {
|
|
632
579
|
let page = 1;
|
|
633
580
|
let hasMoreActivities = true;
|
|
634
|
-
let
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
? globalActivitiesQuery
|
|
638
|
-
: followingActivitiesQuery;
|
|
581
|
+
let retryCount = 0;
|
|
582
|
+
const maxRetries = 5;
|
|
583
|
+
let likedCount = 0;
|
|
639
584
|
while (hasMoreActivities) {
|
|
640
|
-
const activities = yield fetcher(
|
|
585
|
+
const activities = yield fetcher(followingActivitiesQuery, {
|
|
586
|
+
page,
|
|
587
|
+
perPage: 50,
|
|
588
|
+
});
|
|
589
|
+
if (activities && ((_b = (_a = activities === null || activities === void 0 ? void 0 : activities.data) === null || _a === void 0 ? void 0 : _a.Page) === null || _b === void 0 ? void 0 : _b.activities.length) > 0) {
|
|
590
|
+
spinner.success(`Got ${(_d = (_c = activities === null || activities === void 0 ? void 0 : activities.data) === null || _c === void 0 ? void 0 : _c.Page) === null || _d === void 0 ? void 0 : _d.activities.length} activities..`);
|
|
591
|
+
retryCount = 0; // Reset retry count on successful fetch
|
|
592
|
+
const activiti = (_f = (_e = activities === null || activities === void 0 ? void 0 : activities.data) === null || _e === void 0 ? void 0 : _e.Page) === null || _f === void 0 ? void 0 : _f.activities;
|
|
593
|
+
for (let activ of activiti) {
|
|
594
|
+
if (!activ.isLiked && activ.id) {
|
|
595
|
+
try {
|
|
596
|
+
const like = yield fetcher(likeActivityMutation, {
|
|
597
|
+
activityId: activ.id,
|
|
598
|
+
});
|
|
599
|
+
if (like === null || like === void 0 ? void 0 : like.data) {
|
|
600
|
+
likedCount++;
|
|
601
|
+
}
|
|
602
|
+
responsiveOutput(`${(like === null || like === void 0 ? void 0 : like.data) ? "ā
" : "ā"} ${activityBy(activ, likedCount)}`);
|
|
603
|
+
}
|
|
604
|
+
catch (error) {
|
|
605
|
+
console.error(`Activity possibly deleted. ${error.message}`);
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
else {
|
|
609
|
+
responsiveOutput(`"šµ" ${activityBy(activ, likedCount)}`);
|
|
610
|
+
}
|
|
611
|
+
// avoiding rate-limit
|
|
612
|
+
yield new Promise((resolve) => {
|
|
613
|
+
setTimeout(resolve, 2000);
|
|
614
|
+
});
|
|
615
|
+
}
|
|
616
|
+
page++;
|
|
617
|
+
}
|
|
618
|
+
else {
|
|
619
|
+
if (retryCount < maxRetries) {
|
|
620
|
+
spinner.start("Getting activities...");
|
|
621
|
+
retryCount++;
|
|
622
|
+
spinner.update(`Empty activities returned. Retrying... (${retryCount}/${maxRetries})`);
|
|
623
|
+
yield new Promise((resolve) => setTimeout(resolve, 2000));
|
|
624
|
+
}
|
|
625
|
+
else {
|
|
626
|
+
spinner.error(`Probably the end of activities after ${maxRetries} retries.`);
|
|
627
|
+
hasMoreActivities = false;
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
catch (error) {
|
|
633
|
+
console.error(`\nError from likeFollowing. ${error.message}`);
|
|
634
|
+
}
|
|
635
|
+
});
|
|
636
|
+
}
|
|
637
|
+
static LikeGlobal() {
|
|
638
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
639
|
+
var _a, _b, _c, _d, _e, _f;
|
|
640
|
+
try {
|
|
641
|
+
let page = 1;
|
|
642
|
+
let hasMoreActivities = true;
|
|
643
|
+
let likedCount = 0;
|
|
644
|
+
spinner.start(`Getting global activities...`);
|
|
645
|
+
while (hasMoreActivities) {
|
|
646
|
+
const activities = yield fetcher(globalActivitiesQuery, {
|
|
641
647
|
page,
|
|
642
648
|
perPage: 50,
|
|
643
649
|
});
|
|
644
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) {
|
|
645
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...`);
|
|
646
653
|
for (let activ of activiti) {
|
|
647
654
|
if (!activ.isLiked && activ.id) {
|
|
648
655
|
try {
|
|
@@ -650,26 +657,26 @@ Statistics (Manga):
|
|
|
650
657
|
activityId: activ.id,
|
|
651
658
|
});
|
|
652
659
|
// const ToggleLike = like?.data?.ToggleLike
|
|
653
|
-
|
|
660
|
+
likedCount++;
|
|
661
|
+
responsiveOutput(`${(like === null || like === void 0 ? void 0 : like.data) ? "ā
" : "ā"} ${activityBy(activ, likedCount)}`);
|
|
654
662
|
}
|
|
655
663
|
catch (error) {
|
|
656
|
-
console.error(`Activity possibly deleted
|
|
664
|
+
console.error(`Activity possibly deleted. ${error.message}`);
|
|
657
665
|
}
|
|
658
666
|
}
|
|
659
667
|
else {
|
|
660
|
-
|
|
668
|
+
responsiveOutput(`šµ ${activityBy(activ, likedCount)}`);
|
|
661
669
|
}
|
|
662
670
|
// avoiding rate-limit
|
|
663
671
|
yield new Promise((resolve) => {
|
|
664
|
-
setTimeout(resolve,
|
|
672
|
+
setTimeout(resolve, 1500);
|
|
665
673
|
});
|
|
666
674
|
}
|
|
667
675
|
page++;
|
|
668
676
|
}
|
|
669
677
|
else {
|
|
670
678
|
// No more activities to like
|
|
671
|
-
|
|
672
|
-
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}`);
|
|
673
680
|
hasMoreActivities = false;
|
|
674
681
|
}
|
|
675
682
|
}
|
|
@@ -681,7 +688,7 @@ Statistics (Manga):
|
|
|
681
688
|
}
|
|
682
689
|
static LikeSpecificUser() {
|
|
683
690
|
return __awaiter(this, void 0, void 0, function* () {
|
|
684
|
-
var _a, _b, _c, _d
|
|
691
|
+
var _a, _b, _c, _d;
|
|
685
692
|
try {
|
|
686
693
|
const { username } = yield inquirer.prompt([
|
|
687
694
|
{
|
|
@@ -690,55 +697,166 @@ Statistics (Manga):
|
|
|
690
697
|
message: "Username of the user:",
|
|
691
698
|
},
|
|
692
699
|
]);
|
|
700
|
+
const { toLikeAmount } = yield inquirer.prompt([
|
|
701
|
+
{
|
|
702
|
+
type: "number",
|
|
703
|
+
name: "toLikeAmount",
|
|
704
|
+
message: "Likes to give:",
|
|
705
|
+
},
|
|
706
|
+
]);
|
|
693
707
|
const userDetails = yield fetcher(userQuery, { username: username });
|
|
694
|
-
|
|
708
|
+
spinner.start(`Getting activities by ${username}`);
|
|
709
|
+
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) {
|
|
695
710
|
let page = 1;
|
|
696
711
|
const perPage = 50;
|
|
697
|
-
const userId =
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
}
|
|
719
|
-
|
|
720
|
-
|
|
712
|
+
const userId = userDetails.data.User.id;
|
|
713
|
+
let likedCount = 0;
|
|
714
|
+
while (likedCount < toLikeAmount) {
|
|
715
|
+
const activities = yield fetcher(specificUserActivitiesQuery, {
|
|
716
|
+
page,
|
|
717
|
+
perPage,
|
|
718
|
+
userId,
|
|
719
|
+
});
|
|
720
|
+
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;
|
|
721
|
+
if (!activiti || activiti.length === 0) {
|
|
722
|
+
spinner.error("No more activities found.");
|
|
723
|
+
break;
|
|
724
|
+
}
|
|
725
|
+
spinner.success(`Got ${activiti.length} activities...`);
|
|
726
|
+
for (let activ of activiti) {
|
|
727
|
+
if (!activ.isLiked && activ.id) {
|
|
728
|
+
try {
|
|
729
|
+
const like = yield fetcher(likeActivityMutation, {
|
|
730
|
+
activityId: activ.id,
|
|
731
|
+
});
|
|
732
|
+
likedCount++;
|
|
733
|
+
responsiveOutput(`${(like === null || like === void 0 ? void 0 : like.data) ? "ā
" : "ā"} ${activityBy(activ, likedCount)}`);
|
|
734
|
+
if (likedCount >= toLikeAmount) {
|
|
735
|
+
spinner.success(`Finished liking ${likedCount} activities of ${username}.`);
|
|
736
|
+
return;
|
|
721
737
|
}
|
|
722
738
|
}
|
|
723
|
-
|
|
724
|
-
console.
|
|
739
|
+
catch (error) {
|
|
740
|
+
console.error(`Activity possibly deleted. ${error.message}`);
|
|
725
741
|
}
|
|
726
|
-
// Avoiding rate limit
|
|
727
|
-
yield new Promise((resolve) => {
|
|
728
|
-
setTimeout(resolve, 2000);
|
|
729
|
-
});
|
|
730
742
|
}
|
|
731
|
-
|
|
732
|
-
|
|
743
|
+
else {
|
|
744
|
+
responsiveOutput(`šµ ${activityBy(activ, likedCount)}`);
|
|
745
|
+
}
|
|
733
746
|
}
|
|
747
|
+
page += 1;
|
|
734
748
|
}
|
|
735
749
|
}
|
|
750
|
+
else {
|
|
751
|
+
spinner.error(`User ${username} does not exist.`);
|
|
752
|
+
exit(1);
|
|
753
|
+
}
|
|
736
754
|
}
|
|
737
755
|
catch (error) {
|
|
738
756
|
console.error(`\nError from LikeSpecificUser. ${error.message}`);
|
|
739
757
|
}
|
|
740
758
|
});
|
|
741
759
|
}
|
|
760
|
+
static LikeFollowingActivityV2(perPage) {
|
|
761
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
762
|
+
var _a, _b, _c, _d, _e;
|
|
763
|
+
try {
|
|
764
|
+
if (!(yield Auth.isLoggedIn())) {
|
|
765
|
+
console.error(`\nPlease log in to use this feature.`);
|
|
766
|
+
return;
|
|
767
|
+
}
|
|
768
|
+
const allFollowingUsers = [];
|
|
769
|
+
let hasNextPage = true;
|
|
770
|
+
let page = 1;
|
|
771
|
+
let liked = 0;
|
|
772
|
+
// ------------------------
|
|
773
|
+
// Fetch all following users
|
|
774
|
+
// ------------------------
|
|
775
|
+
spinner.start(`Gathering following information...`);
|
|
776
|
+
while (hasNextPage) {
|
|
777
|
+
spinner.update(`Fetched page ${page}...`);
|
|
778
|
+
const followingUsers = yield fetcher(userFollowingQuery, {
|
|
779
|
+
userId: yield Auth.MyUserId(),
|
|
780
|
+
page,
|
|
781
|
+
});
|
|
782
|
+
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)) {
|
|
783
|
+
console.error(`\nFailed to fetch following users.`);
|
|
784
|
+
return;
|
|
785
|
+
}
|
|
786
|
+
allFollowingUsers.push(...followingUsers.data.Page.following);
|
|
787
|
+
hasNextPage = followingUsers.data.Page.pageInfo.hasNextPage;
|
|
788
|
+
page++;
|
|
789
|
+
}
|
|
790
|
+
spinner.stop(`Got ${allFollowingUsers.length} following user.`);
|
|
791
|
+
// Extract the IDs of all following users
|
|
792
|
+
const followingUserIds = allFollowingUsers.map((user) => user.id);
|
|
793
|
+
// --------------------
|
|
794
|
+
// APPROXIMATE TIME
|
|
795
|
+
// --------------------
|
|
796
|
+
const totalActivities = followingUserIds.length * perPage;
|
|
797
|
+
const perActivityTimeInSec = 1;
|
|
798
|
+
const rateLimitTimeInSec = 60;
|
|
799
|
+
const batchSize = 29;
|
|
800
|
+
const batches = Math.floor(totalActivities / batchSize);
|
|
801
|
+
const remaining = totalActivities % batchSize;
|
|
802
|
+
const processingTime = batches * batchSize * perActivityTimeInSec +
|
|
803
|
+
remaining * perActivityTimeInSec;
|
|
804
|
+
const waitTime = (batches - 1) * rateLimitTimeInSec;
|
|
805
|
+
const totalWaitTimeInSec = processingTime + (batches > 0 ? waitTime : 0);
|
|
806
|
+
const hours = Math.floor(totalWaitTimeInSec / 3600);
|
|
807
|
+
const minutes = Math.floor((totalWaitTimeInSec % 3600) / 60);
|
|
808
|
+
const seconds = totalWaitTimeInSec % 60;
|
|
809
|
+
const time = `${String(hours).padStart(2, "0")}h ${String(minutes).padStart(2, "0")}m ${String(seconds).padStart(2, "0")}s`;
|
|
810
|
+
console.log(`\nTotal following: ${followingUserIds.length}\nApproximately ${totalActivities} to like.\nWill take around ${time}`);
|
|
811
|
+
// -------------------
|
|
812
|
+
// Traverse the array and
|
|
813
|
+
// fetch users' activities one by one
|
|
814
|
+
// -------------------
|
|
815
|
+
let userNumber = 0;
|
|
816
|
+
for (const userId of followingUserIds) {
|
|
817
|
+
userNumber++;
|
|
818
|
+
console.log(`\n[${userNumber}]\tID: ${userId}`);
|
|
819
|
+
// Fetch `perPage` activities for the current user
|
|
820
|
+
const activities = yield fetcher(specificUserActivitiesQuery, {
|
|
821
|
+
userId,
|
|
822
|
+
page: 1, // Always fetch from the first page
|
|
823
|
+
perPage,
|
|
824
|
+
});
|
|
825
|
+
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)) {
|
|
826
|
+
console.log(`[${userNumber}] No activities found for User ID: ${userId}`);
|
|
827
|
+
continue;
|
|
828
|
+
}
|
|
829
|
+
const activiti = activities.data.Page.activities;
|
|
830
|
+
for (let i = 0; i < activiti.length; i++) {
|
|
831
|
+
const activ = activiti[i];
|
|
832
|
+
if (!activ.isLiked && activ.id) {
|
|
833
|
+
try {
|
|
834
|
+
const like = yield fetcher(likeActivityMutation, {
|
|
835
|
+
activityId: activ.id,
|
|
836
|
+
});
|
|
837
|
+
responsiveOutput(`${(like === null || like === void 0 ? void 0 : like.data) ? "ā
" : "ā"} ${activityBy(activ, i + 1)}`);
|
|
838
|
+
if (like === null || like === void 0 ? void 0 : like.data) {
|
|
839
|
+
liked++;
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
catch (error) {
|
|
843
|
+
console.error(`Activity possibly deleted. ${error.message}`);
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
else {
|
|
847
|
+
responsiveOutput(`šµ ${activityBy(activ, i + 1)}`);
|
|
848
|
+
}
|
|
849
|
+
// Avoid rate-limiting
|
|
850
|
+
yield new Promise((resolve) => setTimeout(resolve, 1200));
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
console.log(`\nā
All ${liked} activities liked successfully.`);
|
|
854
|
+
}
|
|
855
|
+
catch (error) {
|
|
856
|
+
console.error(`\nError in LikeFollowingActivityV2: ${error.message}`);
|
|
857
|
+
}
|
|
858
|
+
});
|
|
859
|
+
}
|
|
742
860
|
static AutoLike() {
|
|
743
861
|
return __awaiter(this, void 0, void 0, function* () {
|
|
744
862
|
try {
|
|
@@ -752,21 +870,33 @@ Statistics (Manga):
|
|
|
752
870
|
name: "activityType",
|
|
753
871
|
message: "Select activity type:",
|
|
754
872
|
choices: [
|
|
755
|
-
{ name: "Following", value: 1 },
|
|
756
|
-
{ name: "
|
|
757
|
-
{ name: "
|
|
873
|
+
{ name: "Following ⢠v1", value: 1 },
|
|
874
|
+
{ name: "Following ⢠v2", value: 2 },
|
|
875
|
+
{ name: "Global", value: 3 },
|
|
876
|
+
{ name: "Specific User", value: 4 },
|
|
758
877
|
],
|
|
759
878
|
pageSize: 10,
|
|
760
879
|
},
|
|
761
880
|
]);
|
|
762
881
|
switch (activityType) {
|
|
763
882
|
case 1:
|
|
764
|
-
yield this.
|
|
883
|
+
yield this.LikeFollowing();
|
|
765
884
|
break;
|
|
766
|
-
case 2:
|
|
767
|
-
yield
|
|
885
|
+
case 2: {
|
|
886
|
+
const { count } = yield inquirer.prompt([
|
|
887
|
+
{
|
|
888
|
+
type: "number",
|
|
889
|
+
name: "count",
|
|
890
|
+
message: "Likes to give:",
|
|
891
|
+
},
|
|
892
|
+
]);
|
|
893
|
+
yield this.LikeFollowingActivityV2(count);
|
|
768
894
|
break;
|
|
895
|
+
}
|
|
769
896
|
case 3:
|
|
897
|
+
yield this.LikeGlobal();
|
|
898
|
+
break;
|
|
899
|
+
case 4:
|
|
770
900
|
yield this.LikeSpecificUser();
|
|
771
901
|
break;
|
|
772
902
|
default:
|
|
@@ -779,4 +909,124 @@ Statistics (Manga):
|
|
|
779
909
|
});
|
|
780
910
|
}
|
|
781
911
|
}
|
|
782
|
-
|
|
912
|
+
class Social {
|
|
913
|
+
/**
|
|
914
|
+
* Follow the users that follows you
|
|
915
|
+
*/
|
|
916
|
+
static follow() {
|
|
917
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
918
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
|
|
919
|
+
try {
|
|
920
|
+
let pager = 1;
|
|
921
|
+
let hasNextPage = true;
|
|
922
|
+
let allFollowerUsers = [];
|
|
923
|
+
let followedBack = 0;
|
|
924
|
+
spinner.start("Fetching all the followers...");
|
|
925
|
+
while (hasNextPage) {
|
|
926
|
+
const followerUsers = yield fetcher(userFollowersQuery, {
|
|
927
|
+
userId: yield Auth.MyUserId(),
|
|
928
|
+
page: pager,
|
|
929
|
+
});
|
|
930
|
+
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}...`);
|
|
931
|
+
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)) {
|
|
932
|
+
hasNextPage = false;
|
|
933
|
+
}
|
|
934
|
+
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) || []));
|
|
935
|
+
pager++;
|
|
936
|
+
}
|
|
937
|
+
spinner.stop("Fetched all the followers. Starting follow back.");
|
|
938
|
+
// Filter users that do no follow me
|
|
939
|
+
const notFollowing = allFollowerUsers
|
|
940
|
+
.filter(({ isFollowing }) => !isFollowing)
|
|
941
|
+
.map(({ id, name }) => ({ id: id, name: name }));
|
|
942
|
+
console.log(`\nTotal follower ${allFollowerUsers.length}.\nNot followed back ${notFollowing.length}\n`);
|
|
943
|
+
if (notFollowing.length <= 0) {
|
|
944
|
+
console.log(`Probably followed back all the users.`);
|
|
945
|
+
return;
|
|
946
|
+
}
|
|
947
|
+
// Traverse and follow back
|
|
948
|
+
const maxIdLength = Math.max(...notFollowing.map(({ id }) => String(id).length));
|
|
949
|
+
const maxNameLength = Math.max(...notFollowing.map(({ name }) => name.length));
|
|
950
|
+
for (let nf of notFollowing) {
|
|
951
|
+
try {
|
|
952
|
+
const follow = yield fetcher(toggleFollowMutation, { userId: nf.id });
|
|
953
|
+
console.log(`${String(`[${nf.id}]`).padEnd(maxIdLength)}` +
|
|
954
|
+
`\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)}` +
|
|
955
|
+
`\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) ? "ā
" : "šµ"}`);
|
|
956
|
+
// Count the followed back users
|
|
957
|
+
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) {
|
|
958
|
+
followedBack++;
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
catch (error) {
|
|
962
|
+
console.log(`automate_follow_toggle_follow: ${error.message}`);
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
console.log(`\nā
Followed back ${followedBack} users.`);
|
|
966
|
+
}
|
|
967
|
+
catch (error) {
|
|
968
|
+
console.log(`\nautomate_follow ${error.message}`);
|
|
969
|
+
}
|
|
970
|
+
});
|
|
971
|
+
}
|
|
972
|
+
/**
|
|
973
|
+
* Unfollow the users thats not following you
|
|
974
|
+
*/
|
|
975
|
+
static unfollow() {
|
|
976
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
977
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
|
|
978
|
+
try {
|
|
979
|
+
let pager = 1;
|
|
980
|
+
let hasNextPage = true;
|
|
981
|
+
let allFollowingUsers = [];
|
|
982
|
+
let unfollowedUsers = 0;
|
|
983
|
+
spinner.start("Fetching all following users...");
|
|
984
|
+
while (hasNextPage) {
|
|
985
|
+
const followingUsers = yield fetcher(userFollowingQuery, {
|
|
986
|
+
userId: yield Auth.MyUserId(),
|
|
987
|
+
page: pager,
|
|
988
|
+
});
|
|
989
|
+
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}...`);
|
|
990
|
+
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)) {
|
|
991
|
+
hasNextPage = false;
|
|
992
|
+
}
|
|
993
|
+
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) || []));
|
|
994
|
+
pager++;
|
|
995
|
+
}
|
|
996
|
+
spinner.update(`Fetching complete. Total got ${allFollowingUsers.length} users.`);
|
|
997
|
+
// Filter users that do no follow me
|
|
998
|
+
const notFollowingMe = allFollowingUsers
|
|
999
|
+
.filter((user) => !user.isFollower)
|
|
1000
|
+
.map((u3r) => ({ id: u3r.id, name: u3r.name }));
|
|
1001
|
+
if (notFollowingMe.length <= 0) {
|
|
1002
|
+
spinner.stop(`No users to unfollow. Exiting operation...`);
|
|
1003
|
+
return;
|
|
1004
|
+
}
|
|
1005
|
+
spinner.stop(`Unfollow process activated with ${notFollowingMe.length} users.`);
|
|
1006
|
+
let nfmCount = 0;
|
|
1007
|
+
console.log(`\n`);
|
|
1008
|
+
for (let nfm of notFollowingMe) {
|
|
1009
|
+
nfmCount++;
|
|
1010
|
+
try {
|
|
1011
|
+
const unfollow = yield fetcher(toggleFollowMutation, {
|
|
1012
|
+
userId: nfm.id,
|
|
1013
|
+
});
|
|
1014
|
+
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) ? "ā
" : "šµ"}`);
|
|
1015
|
+
// Count the unfollowed users
|
|
1016
|
+
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) {
|
|
1017
|
+
unfollowedUsers++;
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
catch (error) {
|
|
1021
|
+
console.log(`unfollow_toggle_follow. ${error.message}`);
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
console.log(`\nTotal Unfollowed: ${unfollowedUsers} of ${nfmCount} users.`);
|
|
1025
|
+
}
|
|
1026
|
+
catch (error) {
|
|
1027
|
+
console.error(`\nautomate_unfollow: ${error.message}`);
|
|
1028
|
+
}
|
|
1029
|
+
});
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1032
|
+
export { Auth, Social };
|