stack-analyze 1.1.7 → 1.2.0
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/CHANGELOG.md +33 -3
- package/about.js +97 -45
- package/cli.js +313 -109
- package/functions/animeInfo.js +12 -15
- package/functions/bitly.js +3 -4
- package/functions/cryptoList.js +16 -13
- package/functions/gitUser.js +14 -14
- package/functions/hardware.js +195 -243
- package/functions/moviesInfo.js +5 -10
- package/functions/multipleStack.js +13 -8
- package/functions/pageSpeed.js +1 -1
- package/functions/password.js +25 -0
- package/functions/scraping.js +153 -0
- package/functions/singleStack.js +14 -9
- package/functions/twitch.js +5 -7
- package/index.cjs +177 -139
- package/index.mjs +179 -140
- package/package.json +18 -18
- package/readme.md +38 -7
- package/utils.js +15 -0
- package/env/bitly.env.js +0 -1
- package/env/movie.env.js +0 -1
- package/env/twitchID.env.js +0 -1
- package/hash/aboutOpts.js +0 -53
- package/hash/hardwareTools.js +0 -47
- package/hash/infoTools.js +0 -112
- package/hash/mainTools.js +0 -67
- package/models/aboutTables.js +0 -40
- package/models/animeTable.js +0 -33
- package/models/cryptoTables.js +0 -32
- package/models/hardwareTables.js +0 -87
- package/models/movieTables.js +0 -33
- package/models/stackTables.js +0 -23
- package/models/twitchTables.js +0 -28
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { default as axios } from "axios";
|
|
2
|
+
import { load } from "cheerio";
|
|
3
|
+
import colors from "colors";
|
|
4
|
+
import { printTable } from "console-table-printer";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @typedef {Object} options
|
|
8
|
+
* @property {function(): Promise<void>} options.title
|
|
9
|
+
* @property {function(): Promise<void>} options.images
|
|
10
|
+
* @property {function(): Promise<void>} options.metadata
|
|
11
|
+
* @property {function(): Promise<void>} options.headings
|
|
12
|
+
* @property {function(): Promise<void>} options.table_heading
|
|
13
|
+
* @property {function(): Promise<void>} options.table_data
|
|
14
|
+
* @property {function(): Promise<void>} options.links
|
|
15
|
+
* @property {function(): Promise<void>} options.cites
|
|
16
|
+
*
|
|
17
|
+
* @param {string} url
|
|
18
|
+
* @returns {options}
|
|
19
|
+
*/
|
|
20
|
+
export default function scrape(url) {
|
|
21
|
+
let $;
|
|
22
|
+
|
|
23
|
+
const scraping = axios.create({
|
|
24
|
+
baseURL: url
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
const title = async () => {
|
|
28
|
+
try {
|
|
29
|
+
const { data } = await scraping.get("");
|
|
30
|
+
$ = load(data);
|
|
31
|
+
|
|
32
|
+
console.info("title page:", $("title").text());
|
|
33
|
+
} catch (err) { console.error(colors.red(err.message)); }
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const images = async () => {
|
|
37
|
+
try {
|
|
38
|
+
const { data } = await scraping.get("");
|
|
39
|
+
$ = load(data);
|
|
40
|
+
|
|
41
|
+
const imgs = $("img").map((i, el) => ({
|
|
42
|
+
imagePath: $(el).attr("src"),
|
|
43
|
+
imageTitle: $(el).attr("alt")
|
|
44
|
+
})).toArray();
|
|
45
|
+
|
|
46
|
+
imgs.length === 0
|
|
47
|
+
? console.info("no found images")
|
|
48
|
+
: printTable(imgs);
|
|
49
|
+
} catch (err) { console.error(colors.red(err.message)); }
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const metadata = async () => {
|
|
53
|
+
try {
|
|
54
|
+
const { data } = await scraping.get("");
|
|
55
|
+
$ = load(data);
|
|
56
|
+
|
|
57
|
+
const metadataList = $("meta").map((i, el) => ({
|
|
58
|
+
metaInfo: $(el).attr("name"),
|
|
59
|
+
metaContent: $(el).attr("content")
|
|
60
|
+
})).toArray()
|
|
61
|
+
.filter(({ metaInfo }) => metaInfo !== undefined);
|
|
62
|
+
|
|
63
|
+
printTable(metadataList);
|
|
64
|
+
} catch (err) { console.error(colors.red(err.message)); }
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const headings = async () => {
|
|
68
|
+
try {
|
|
69
|
+
const { data } = await scraping.get("");
|
|
70
|
+
$ = load(data);
|
|
71
|
+
|
|
72
|
+
const headingList = $("h1, h2, h3, h4, h5, h6").map((i, el) => ({
|
|
73
|
+
headingTag: $(el).prop("tagName"),
|
|
74
|
+
headingText: $(el).text()
|
|
75
|
+
})).toArray();
|
|
76
|
+
|
|
77
|
+
printTable(headingList);
|
|
78
|
+
} catch (err) { console.error(colors.red(err.message)); }
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const table_heading = async () => {
|
|
82
|
+
try {
|
|
83
|
+
const { data } = await scraping.get("");
|
|
84
|
+
$ = load(data);
|
|
85
|
+
|
|
86
|
+
const tableHeadList = $("th").map((i, el) => ({
|
|
87
|
+
headingRow: i,
|
|
88
|
+
text: $(el).text()
|
|
89
|
+
})).toArray();
|
|
90
|
+
|
|
91
|
+
tableHeadList.length === 0
|
|
92
|
+
? console.info("no found th tags")
|
|
93
|
+
: printTable(tableHeadList);
|
|
94
|
+
} catch (err) { console.error(colors.red(err.message)); }
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
const table_data = async () => {
|
|
98
|
+
try {
|
|
99
|
+
const { data } = await scraping.get("");
|
|
100
|
+
$ = load(data);
|
|
101
|
+
|
|
102
|
+
const tableColumnList = $("td").map((i, el) => $(el).text()).toArray();
|
|
103
|
+
|
|
104
|
+
tableColumnList.length === 0
|
|
105
|
+
? console.info("no found td tags")
|
|
106
|
+
: printTable(tableColumnList);
|
|
107
|
+
} catch (err) { console.error(colors.red(err.message)); }
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
const links = async () => {
|
|
112
|
+
try {
|
|
113
|
+
const { data } = await scraping.get("");
|
|
114
|
+
$ = load(data);
|
|
115
|
+
|
|
116
|
+
const linkList = $("a").map((i, el) => ({
|
|
117
|
+
url: $(el).attr("href"),
|
|
118
|
+
text: $(el).text()
|
|
119
|
+
})).toArray()
|
|
120
|
+
.filter(({ url }) => url.indexOf("#") !== 0);
|
|
121
|
+
|
|
122
|
+
printTable(linkList);
|
|
123
|
+
} catch (err) { console.error(colors.red(err.message)); }
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
const cites = async () => {
|
|
127
|
+
try {
|
|
128
|
+
const { data } = await scraping.get("");
|
|
129
|
+
$ = load(data);
|
|
130
|
+
|
|
131
|
+
const citeList = $("q, blockquote").map((i, el) => ({
|
|
132
|
+
citeTag: $(el).prop("tagName"),
|
|
133
|
+
citeLink: $(el).attr("cite"),
|
|
134
|
+
citeText: $(el).text()
|
|
135
|
+
})).toArray();
|
|
136
|
+
|
|
137
|
+
citeList.length === 0
|
|
138
|
+
? console.info("no found q and/or blockquote tags")
|
|
139
|
+
: printTable(citeList);
|
|
140
|
+
} catch (err) { console.error(colors.red(err.message)); }
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
return {
|
|
144
|
+
title,
|
|
145
|
+
images,
|
|
146
|
+
metadata,
|
|
147
|
+
headings,
|
|
148
|
+
table_heading,
|
|
149
|
+
table_data,
|
|
150
|
+
links,
|
|
151
|
+
cites
|
|
152
|
+
};
|
|
153
|
+
}
|
package/functions/singleStack.js
CHANGED
|
@@ -2,7 +2,10 @@
|
|
|
2
2
|
import Wappalyzer from "wappalyzer";
|
|
3
3
|
import figlet from "figlet";
|
|
4
4
|
import colors from "colors";
|
|
5
|
-
import
|
|
5
|
+
import { printTable } from "console-table-printer";
|
|
6
|
+
|
|
7
|
+
// list format
|
|
8
|
+
import { listFormat } from "../utils.js";
|
|
6
9
|
|
|
7
10
|
/**
|
|
8
11
|
*
|
|
@@ -23,17 +26,19 @@ export default async function singleStack(url) {
|
|
|
23
26
|
name,
|
|
24
27
|
website,
|
|
25
28
|
categories
|
|
26
|
-
}) =>
|
|
27
|
-
|
|
28
|
-
techWebsite: website,
|
|
29
|
-
techCategories: categories.map(({ name }) => name).join(", ")
|
|
30
|
-
}));
|
|
29
|
+
}) => {
|
|
30
|
+
const stackCategories = categories.map(({ name }) => name);
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
return {
|
|
33
|
+
techName: name,
|
|
34
|
+
techWebsite: website,
|
|
35
|
+
techCategories: listFormat.format(stackCategories)
|
|
36
|
+
};
|
|
37
|
+
});
|
|
33
38
|
|
|
34
|
-
|
|
39
|
+
console.info(colors.green(figlet.textSync(url)));
|
|
35
40
|
|
|
36
|
-
|
|
41
|
+
printTable(stackResult);
|
|
37
42
|
} catch (err) {
|
|
38
43
|
console.error(colors.red(err.message));
|
|
39
44
|
}
|
package/functions/twitch.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
// modules
|
|
2
|
-
import "
|
|
3
|
-
import axios from "axios";
|
|
2
|
+
import { default as axios } from "axios";
|
|
4
3
|
import { format } from "timeago.js";
|
|
5
4
|
import colors from "colors";
|
|
6
5
|
|
|
7
6
|
// table
|
|
8
|
-
import
|
|
7
|
+
import { printTable } from "console-table-printer";
|
|
9
8
|
|
|
10
9
|
/**
|
|
11
10
|
*
|
|
@@ -14,13 +13,13 @@ import twitchTable from "../models/twitchTables.js";
|
|
|
14
13
|
* @param {string} apiToken - twitch api token
|
|
15
14
|
* @returns { Promise<void> } - return twitch results
|
|
16
15
|
*/
|
|
17
|
-
const twitchInfo = async (twitchUser, apiToken) => {
|
|
16
|
+
const twitchInfo = async (twitchUser, twitchClient, apiToken) => {
|
|
18
17
|
|
|
19
18
|
try {
|
|
20
19
|
const { data: twitchData } = await axios.get(`https://api.twitch.tv/helix/users?login=${twitchUser}`, {
|
|
21
20
|
headers: {
|
|
22
21
|
Authorization: `Bearer ${apiToken}`,
|
|
23
|
-
"Client-Id":
|
|
22
|
+
"Client-Id": twitchClient
|
|
24
23
|
}
|
|
25
24
|
});
|
|
26
25
|
|
|
@@ -36,8 +35,7 @@ const twitchInfo = async (twitchUser, apiToken) => {
|
|
|
36
35
|
createdTime: format(created_at)
|
|
37
36
|
}));
|
|
38
37
|
|
|
39
|
-
|
|
40
|
-
twitchTable.printTable();
|
|
38
|
+
printTable(result);
|
|
41
39
|
} catch (err) {
|
|
42
40
|
console.error(colors.red(err));
|
|
43
41
|
}
|
package/index.cjs
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
// modules
|
|
2
2
|
const axios = require("axios").default;
|
|
3
|
-
const CoinGecko = require("coingecko-api");
|
|
4
3
|
const {
|
|
5
4
|
cpu,
|
|
6
5
|
mem,
|
|
@@ -10,53 +9,13 @@ const {
|
|
|
10
9
|
bios
|
|
11
10
|
} = require("systeminformation");
|
|
12
11
|
const Wappalyzer = require("wappalyzer");
|
|
12
|
+
const cheerio = require("cheerio");
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
const CoinGeckoClient = new CoinGecko();
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* @typedef {Object} anime
|
|
19
|
-
* @property {string} anime.query
|
|
20
|
-
* @property {function(data): void} anime.results
|
|
21
|
-
*
|
|
22
|
-
* @typedef {Object} bitly
|
|
23
|
-
* @property {string} bitly.link
|
|
24
|
-
* @property {string} bitly.token
|
|
25
|
-
* @property {function(data): void} bitly.results
|
|
26
|
-
*
|
|
27
|
-
* @typedef {Object} github
|
|
28
|
-
* @property {string} github.user
|
|
29
|
-
* @property {string} github.results
|
|
30
|
-
*
|
|
31
|
-
* @typedef {Object} movie
|
|
32
|
-
* @property {string} movie.api_key
|
|
33
|
-
* @property {string} movie.query
|
|
34
|
-
* @property {function(data): void} movie.results
|
|
35
|
-
*
|
|
36
|
-
* @typedef {Object} multiple
|
|
37
|
-
* @property {string[]} multiple.urls
|
|
38
|
-
* @property {function(data): void} multiple.results
|
|
39
|
-
*
|
|
40
|
-
* @typedef {Object} stack
|
|
41
|
-
* @property {string} stack.urls
|
|
42
|
-
* @property {function(data): void} stack.results
|
|
43
|
-
*
|
|
44
|
-
* @typedef {Object} twitch
|
|
45
|
-
* @property {string} twitch.query
|
|
46
|
-
* @property {string} twitch.token
|
|
47
|
-
* @property {string} twitch.clientID
|
|
48
|
-
* @property {function(data): void} twitch.results
|
|
49
|
-
*/
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* @param {anime} {query, results}
|
|
53
|
-
* @returns {Promise<void>}
|
|
54
|
-
*/
|
|
55
|
-
const animeSearch = async ({ query, results }) => {
|
|
14
|
+
const animeSearch = async ({ query, results, failed }) => {
|
|
56
15
|
/* error manager */
|
|
57
16
|
try {
|
|
58
17
|
// call api
|
|
59
|
-
const { data } = await axios.get("https://api.jikan.moe/
|
|
18
|
+
const { data } = await axios.get("https://api.jikan.moe/v/anime", {
|
|
60
19
|
params: {
|
|
61
20
|
q: query,
|
|
62
21
|
limit: 10
|
|
@@ -65,14 +24,10 @@ const animeSearch = async ({ query, results }) => {
|
|
|
65
24
|
|
|
66
25
|
results(data.results);
|
|
67
26
|
|
|
68
|
-
} catch (err) {
|
|
27
|
+
} catch (err) { failed(err); }
|
|
69
28
|
};
|
|
70
29
|
|
|
71
|
-
|
|
72
|
-
* @param {bitly} {link, token, results}
|
|
73
|
-
* @returns {Promise<void>}
|
|
74
|
-
*/
|
|
75
|
-
const bitlyInfo = async ({ link, token, results }) => {
|
|
30
|
+
const bitlyInfo = async ({ link, token, results, failed }) => {
|
|
76
31
|
try {
|
|
77
32
|
const { data } = await axios.post(
|
|
78
33
|
"https://api-ssl.bitly.com/v4/expand",
|
|
@@ -88,45 +43,34 @@ const bitlyInfo = async ({ link, token, results }) => {
|
|
|
88
43
|
);
|
|
89
44
|
|
|
90
45
|
results(data);
|
|
91
|
-
} catch (err) {
|
|
46
|
+
} catch (err) { failed(err); }
|
|
92
47
|
};
|
|
93
48
|
|
|
94
|
-
|
|
95
|
-
*
|
|
96
|
-
* @descripiton call the crypto market list
|
|
97
|
-
* @param {function(data): void} callback
|
|
98
|
-
* @returns { Promise<void> } - return results search
|
|
99
|
-
*/
|
|
100
|
-
const cryptoMarket = async (callback) => {
|
|
49
|
+
const cryptoMarket = async ({results, failed}) => {
|
|
101
50
|
try {
|
|
102
51
|
// start crypto
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
-
|
|
52
|
+
const { data } = await axios.get(
|
|
53
|
+
"https://api.coingecko.com/api/v3/coins/markets", {
|
|
54
|
+
params: {
|
|
55
|
+
vs_currency: "usd",
|
|
56
|
+
per_page: 10
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
);
|
|
106
60
|
|
|
107
61
|
// map coinData
|
|
108
|
-
|
|
109
|
-
} catch (err) {
|
|
62
|
+
results(data);
|
|
63
|
+
} catch (err) { failed(err); }
|
|
110
64
|
};
|
|
111
65
|
|
|
112
|
-
|
|
113
|
-
*
|
|
114
|
-
* @param {github} {user, results}
|
|
115
|
-
* @returns {Promise<void>}
|
|
116
|
-
*/
|
|
117
|
-
async function githubInfo({ user, results }) {
|
|
66
|
+
async function githubInfo({ user, results, failed }) {
|
|
118
67
|
try {
|
|
119
68
|
const { data } = await axios.get(`https://api.github.com/users/${user}`);
|
|
120
69
|
|
|
121
70
|
results(data);
|
|
122
|
-
} catch (err) {
|
|
71
|
+
} catch (err) { failed(err); }
|
|
123
72
|
}
|
|
124
73
|
|
|
125
|
-
/**
|
|
126
|
-
*
|
|
127
|
-
* @param {function(data): void} callback
|
|
128
|
-
* @returns {Promise<void>}
|
|
129
|
-
*/
|
|
130
74
|
async function cpuInfo(callback) {
|
|
131
75
|
try {
|
|
132
76
|
const {
|
|
@@ -156,11 +100,6 @@ async function cpuInfo(callback) {
|
|
|
156
100
|
} catch (err) { callback(err); }
|
|
157
101
|
}
|
|
158
102
|
|
|
159
|
-
/**
|
|
160
|
-
*
|
|
161
|
-
* @param {function(data): void} callback
|
|
162
|
-
* @returns {Promise<void>}
|
|
163
|
-
*/
|
|
164
103
|
async function ramMemInfo(callback) {
|
|
165
104
|
try {
|
|
166
105
|
const {
|
|
@@ -182,11 +121,6 @@ async function ramMemInfo(callback) {
|
|
|
182
121
|
} catch (err) { callback(err); }
|
|
183
122
|
}
|
|
184
123
|
|
|
185
|
-
/**
|
|
186
|
-
*
|
|
187
|
-
* @param {function(data): void} callback
|
|
188
|
-
* @returns {Promise<void>}
|
|
189
|
-
*/
|
|
190
124
|
async function osDetail(callback) {
|
|
191
125
|
try {
|
|
192
126
|
const {
|
|
@@ -214,11 +148,6 @@ async function osDetail(callback) {
|
|
|
214
148
|
} catch (err) { callback(err); }
|
|
215
149
|
}
|
|
216
150
|
|
|
217
|
-
/**
|
|
218
|
-
*
|
|
219
|
-
* @param {function(data): void} callback
|
|
220
|
-
* @returns {Promise<void>}
|
|
221
|
-
*/
|
|
222
151
|
async function diskInfo(callback) {
|
|
223
152
|
try {
|
|
224
153
|
const disks = await diskLayout();
|
|
@@ -242,11 +171,6 @@ async function diskInfo(callback) {
|
|
|
242
171
|
} catch (err) { callback(err); }
|
|
243
172
|
}
|
|
244
173
|
|
|
245
|
-
/**
|
|
246
|
-
*
|
|
247
|
-
* @param {function(data): void} callback
|
|
248
|
-
* @returns {Promise<void>}
|
|
249
|
-
*/
|
|
250
174
|
async function controllerInfo(callback) {
|
|
251
175
|
try {
|
|
252
176
|
const { controllers } = await graphics();
|
|
@@ -267,11 +191,6 @@ async function controllerInfo(callback) {
|
|
|
267
191
|
} catch (err) { callback(err); }
|
|
268
192
|
}
|
|
269
193
|
|
|
270
|
-
/**
|
|
271
|
-
*
|
|
272
|
-
* @param {function(data): void} callback
|
|
273
|
-
* @returns {Promise<void>}
|
|
274
|
-
*/
|
|
275
194
|
async function displayInfo(callback) {
|
|
276
195
|
try {
|
|
277
196
|
const { displays } = await graphics();
|
|
@@ -294,11 +213,6 @@ async function displayInfo(callback) {
|
|
|
294
213
|
} catch (err) { callback(err); }
|
|
295
214
|
}
|
|
296
215
|
|
|
297
|
-
/**
|
|
298
|
-
*
|
|
299
|
-
* @param {function(data): void} callback
|
|
300
|
-
* @returns {Promise<void>}
|
|
301
|
-
*/
|
|
302
216
|
async function biosInfo(callback) {
|
|
303
217
|
try {
|
|
304
218
|
const {
|
|
@@ -312,11 +226,7 @@ async function biosInfo(callback) {
|
|
|
312
226
|
} catch (err) { callback(err); }
|
|
313
227
|
}
|
|
314
228
|
|
|
315
|
-
|
|
316
|
-
* @param {movie} {api_key, query, results}
|
|
317
|
-
* @returns {Promise<void>} void results
|
|
318
|
-
*/
|
|
319
|
-
const movieDB = async ({ api_key, query, results }) => {
|
|
229
|
+
const movieDB = async ({ api_key, query, results, failed }) => {
|
|
320
230
|
try {
|
|
321
231
|
const { data } = await axios.get("https://api.themoviedb.org/3/search/movie", {
|
|
322
232
|
params: {
|
|
@@ -350,14 +260,10 @@ const movieDB = async ({ api_key, query, results }) => {
|
|
|
350
260
|
.filter(({ release_date }) => release_date !== undefined && release_date !== "");
|
|
351
261
|
|
|
352
262
|
results(movieData);
|
|
353
|
-
} catch (err) {
|
|
263
|
+
} catch (err) { failed(err); }
|
|
354
264
|
};
|
|
355
265
|
|
|
356
|
-
|
|
357
|
-
* @param {multiple} {urls, results}
|
|
358
|
-
* @returns {Promise<void>}
|
|
359
|
-
*/
|
|
360
|
-
async function multipleStack({ urls, results }) {
|
|
266
|
+
async function multipleStack({ urls, results, failed }) {
|
|
361
267
|
let result;
|
|
362
268
|
const wappalyzer = new Wappalyzer();
|
|
363
269
|
try {
|
|
@@ -371,16 +277,12 @@ async function multipleStack({ urls, results }) {
|
|
|
371
277
|
};
|
|
372
278
|
})
|
|
373
279
|
);
|
|
374
|
-
|
|
280
|
+
results(result);
|
|
281
|
+
} catch (err) { failed(err); }
|
|
375
282
|
await wappalyzer.destroy();
|
|
376
|
-
results(result);
|
|
377
283
|
}
|
|
378
284
|
|
|
379
|
-
|
|
380
|
-
* @param {stack} {url, results}
|
|
381
|
-
* @returns {Promise<void>}
|
|
382
|
-
*/
|
|
383
|
-
const pageSpeed = async ({ url, results }) => {
|
|
285
|
+
const pageSpeed = async ({ url, results, failed }) => {
|
|
384
286
|
try {
|
|
385
287
|
const resMobile = await axios.get("https://www.googleapis.com/pagespeedonline/v5/runPagespeed", {
|
|
386
288
|
params: {
|
|
@@ -403,14 +305,10 @@ const pageSpeed = async ({ url, results }) => {
|
|
|
403
305
|
const desktop = Math.round(resDesktop.data.lighthouseResult.categories.performance.score * 100);
|
|
404
306
|
|
|
405
307
|
results({ mobile, desktop });
|
|
406
|
-
} catch (err) {
|
|
308
|
+
} catch (err) { failed(err); }
|
|
407
309
|
};
|
|
408
310
|
|
|
409
|
-
|
|
410
|
-
* @param {stack} {url, results}
|
|
411
|
-
* @returns {Promise<void>}
|
|
412
|
-
*/
|
|
413
|
-
async function singleStack({ url, results }) {
|
|
311
|
+
async function singleStack({ url, results, failed }) {
|
|
414
312
|
const wappalyzer = await new Wappalyzer;
|
|
415
313
|
|
|
416
314
|
let result;
|
|
@@ -428,18 +326,13 @@ async function singleStack({ url, results }) {
|
|
|
428
326
|
techWebsite: website,
|
|
429
327
|
techCategories: categories.map(({ name }) => name).join(", ")
|
|
430
328
|
}));
|
|
431
|
-
|
|
329
|
+
results(result);
|
|
330
|
+
} catch (err) { failed(err); }
|
|
432
331
|
|
|
433
332
|
await wappalyzer.destroy();
|
|
434
|
-
results(result);
|
|
435
333
|
}
|
|
436
334
|
|
|
437
|
-
|
|
438
|
-
*
|
|
439
|
-
* @param {twitch} { query, token, clientID, results }
|
|
440
|
-
* @returns {Promise<void>}
|
|
441
|
-
*/
|
|
442
|
-
async function twitchInfo({ query, token, clientID, results }) {
|
|
335
|
+
async function twitchInfo({ query, token, clientID, results, failed }) {
|
|
443
336
|
try {
|
|
444
337
|
const { data: twitchData } = await axios.get(`https://api.twitch.tv/helix/users?login=${query}`,
|
|
445
338
|
{
|
|
@@ -450,9 +343,152 @@ async function twitchInfo({ query, token, clientID, results }) {
|
|
|
450
343
|
});
|
|
451
344
|
|
|
452
345
|
results(twitchData.data);
|
|
453
|
-
} catch (err) {
|
|
346
|
+
} catch (err) { failed(err); }
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
function scrape(url) {
|
|
350
|
+
let $;
|
|
351
|
+
|
|
352
|
+
const scraping = axios.create({
|
|
353
|
+
baseURL: url
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
const title = async ({results, failed}) => {
|
|
357
|
+
try {
|
|
358
|
+
const { data } = await scraping.get(url);
|
|
359
|
+
$ = cheerio.load(data);
|
|
360
|
+
|
|
361
|
+
results($("title").text());
|
|
362
|
+
} catch (err) { failed(err); }
|
|
363
|
+
};
|
|
364
|
+
|
|
365
|
+
const images = async ({results, failed}) => {
|
|
366
|
+
try {
|
|
367
|
+
const { data } = await scraping.get(url);
|
|
368
|
+
$ = cheerio.load(data);
|
|
369
|
+
|
|
370
|
+
const imgs = $("img").map((i, el) => ({
|
|
371
|
+
imagePath: $(el).attr("src"),
|
|
372
|
+
imageTitle: $(el).attr("alt")
|
|
373
|
+
})).toArray();
|
|
374
|
+
|
|
375
|
+
results(imgs);
|
|
376
|
+
} catch (err) { failed(err); }
|
|
377
|
+
};
|
|
378
|
+
|
|
379
|
+
const metadata = async ({results, failed}) => {
|
|
380
|
+
try {
|
|
381
|
+
const { data } = await scraping.get(url);
|
|
382
|
+
$ = cheerio.load(data);
|
|
383
|
+
|
|
384
|
+
const metadataList = $("meta").map((i, el) => ({
|
|
385
|
+
metaInfo: $(el).attr("name"),
|
|
386
|
+
metaContent: $(el).attr("content")
|
|
387
|
+
})).toArray()
|
|
388
|
+
.filter(({ metaInfo }) => metaInfo !== undefined);
|
|
389
|
+
|
|
390
|
+
results(metadataList);
|
|
391
|
+
} catch (err) { failed(err); }
|
|
392
|
+
};
|
|
393
|
+
|
|
394
|
+
const headings = async ({results, failed}) => {
|
|
395
|
+
try {
|
|
396
|
+
const { data } = await scraping.get(url);
|
|
397
|
+
$ = cheerio.load(data);
|
|
398
|
+
|
|
399
|
+
const headingList = $("h1, h2, h3, h4, h5, h6").map((i, el) => ({
|
|
400
|
+
headingTag: $(el).prop("tagName"),
|
|
401
|
+
headingText: $(el).text()
|
|
402
|
+
})).toArray();
|
|
403
|
+
|
|
404
|
+
results(headingList);
|
|
405
|
+
} catch (err) { failed(err); }
|
|
406
|
+
};
|
|
407
|
+
|
|
408
|
+
const table_heading = async ({results, failed}) => {
|
|
409
|
+
try {
|
|
410
|
+
const { data } = await scraping.get(url);
|
|
411
|
+
$ = cheerio.load(data);
|
|
412
|
+
|
|
413
|
+
const tableHeadList = $("th").map((i, el) => ({
|
|
414
|
+
headingRow: i,
|
|
415
|
+
text: $(el).text()
|
|
416
|
+
})).toArray();
|
|
417
|
+
|
|
418
|
+
results(tableHeadList);
|
|
419
|
+
} catch (err) { failed(err); }
|
|
420
|
+
};
|
|
421
|
+
|
|
422
|
+
const table_data = async ({results, failed}) => {
|
|
423
|
+
try {
|
|
424
|
+
const { data } = await scraping.get(url);
|
|
425
|
+
$ = cheerio.load(data);
|
|
426
|
+
|
|
427
|
+
const tableColumnList = $("td").map((i, el) => $(el).text()).toArray();
|
|
428
|
+
|
|
429
|
+
results(tableColumnList);
|
|
430
|
+
} catch (err) { failed(err); }
|
|
431
|
+
};
|
|
432
|
+
|
|
433
|
+
|
|
434
|
+
const links = async ({results, failed}) => {
|
|
435
|
+
try {
|
|
436
|
+
const { data } = await scraping.get(url);
|
|
437
|
+
$ = cheerio.load(data);
|
|
438
|
+
|
|
439
|
+
const linkList = $("a").map((i, el) => ({
|
|
440
|
+
url: $(el).attr("href"),
|
|
441
|
+
text: $(el).text()
|
|
442
|
+
})).toArray()
|
|
443
|
+
.filter(({ url }) => url.indexOf("#") !== 0);
|
|
444
|
+
|
|
445
|
+
results(linkList);
|
|
446
|
+
} catch (err) { failed(err); }
|
|
447
|
+
};
|
|
448
|
+
|
|
449
|
+
const cites = async ({results, failed}) => {
|
|
450
|
+
try {
|
|
451
|
+
const { data } = await scraping.get(url);
|
|
452
|
+
$ = cheerio.load(data);
|
|
453
|
+
|
|
454
|
+
const citeList = $("q, blockquote").map((i, el) => ({
|
|
455
|
+
citeTag: $(el).prop("tagName"),
|
|
456
|
+
citeLink: $(el).attr("cite"),
|
|
457
|
+
citeText: $(el).text()
|
|
458
|
+
})).toArray();
|
|
459
|
+
|
|
460
|
+
results(citeList);
|
|
461
|
+
} catch (err) { failed(err); }
|
|
462
|
+
};
|
|
463
|
+
|
|
464
|
+
return {
|
|
465
|
+
title,
|
|
466
|
+
images,
|
|
467
|
+
metadata,
|
|
468
|
+
headings,
|
|
469
|
+
table_heading,
|
|
470
|
+
table_data,
|
|
471
|
+
links,
|
|
472
|
+
cites
|
|
473
|
+
};
|
|
454
474
|
}
|
|
455
475
|
|
|
476
|
+
const password = () => {
|
|
477
|
+
const chars = "0123456789abcdefghijklmnopqrstuvwxyz!@#$%^&*()ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
478
|
+
|
|
479
|
+
// blank password var
|
|
480
|
+
let password = "";
|
|
481
|
+
|
|
482
|
+
// loop generate chars
|
|
483
|
+
for(let i = 0; i < 12; i++) {
|
|
484
|
+
const randomNumber = Math.floor(Math.random() * chars.length);
|
|
485
|
+
|
|
486
|
+
password += chars.substring(randomNumber, randomNumber + 1);
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
return password;
|
|
490
|
+
};
|
|
491
|
+
|
|
456
492
|
// exports
|
|
457
493
|
module.exports = {
|
|
458
494
|
animeSearch,
|
|
@@ -470,5 +506,7 @@ module.exports = {
|
|
|
470
506
|
multipleStack,
|
|
471
507
|
pageSpeed,
|
|
472
508
|
singleStack,
|
|
473
|
-
twitchInfo
|
|
509
|
+
twitchInfo,
|
|
510
|
+
scrape,
|
|
511
|
+
password
|
|
474
512
|
};
|