-
Notifications
You must be signed in to change notification settings - Fork 0
/
build_hosts.js
executable file
·126 lines (113 loc) · 3.18 KB
/
build_hosts.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#!/usr/bin/env node
const fs = require('fs').promises;
const saveDir = './';
const filename = 'hosts';
let skipHosts = [];
async function main() {
const configObj = JSON.parse(await fs.readFile('config.json', 'utf8'));
if (configObj.skipHosts?.length > 0) {
skipHosts = configObj.skipHosts;
}
let blacks = [];
let whites = [];
for (const url of configObj.blackUrls) {
const data = await fetchData(url);
blacks = [...blacks, ...await getListFromHosts(data, 'Block: ')];
}
for (const url of configObj.whiteUrls) {
const data = await fetchData(url);
whites = [...whites, ...await getListFromHosts(data, 'Allow: ')];
}
let body = '';
if (configObj.defaultHosts?.length > 0) {
body = configObj.defaultHosts.join('\n') + '\n'
}
for (const item of blacks) {
const exists = whites.find(x => x === item);
if (!exists) {
body += appendIP(item) + '\n';
}
}
try {
await fs.mkdir(saveDir, { recursive: true });
await fs.writeFile(saveDir + filename, body);
console.log('Completed!');
} catch (e) {
console.log('Error:', e.stack);
}
}
async function fetchData(url) {
const response = await fetch(url);
if (response.status == 200) {
return await response.text();
} else {
throw new Error(`An error has occured: ${response.status}`);
}
}
async function getListFromHosts(hosts, log = '') {
const list = hosts.split('\n');
const result = [];
for (const item of list) {
let line = item.trim().toLowerCase();
if (isEmpty(line)) {
continue;
}
if (line.startsWith('#')) {
continue;
}
const obj = getHostObj(line);
if (!obj.success) {
continue;
}
if (result.includes(obj.hostname)) {
continue;
}
if (!isEmpty(log)) {
console.log(log + obj.hostname);
}
result.push(obj.hostname);
}
return result;
}
function appendIP(str) {
return `0.0.0.0 ${str.trim()}`;
}
function getHostObj(str) {
str = cleanLine(str);
let flag = false;
const arr = str.split(' ');
// 1 only hostname
// 2 ip and hostname
if (arr.length !== 1 && arr.length !== 2) {
flag = true;
}
if (!flag && skipHosts.find(x => str.endsWith(x))) {
flag = true;
}
if (flag) {
return { success: false, hostname: null };
}
const hostname = hostTrim(arr.at(arr.length === 1 ? 0 : 1));
return { success: true, hostname };
}
function hostTrim(str) {
return str.trim().replace(/^\.|\.$/g, '');
}
function cleanLine(str) {
// remove comment
let line = str.split('#')[0].trim();
// multiple spaces to single space
line = str.replace(/\s\s+/g, ' ');
return line;
}
function isEmpty(str) {
return (!str || str.length === 0);
}
const log = console.log;
console.log = (...strings) => {
const now = (new Date()).toISOString().slice(0, 19).replace(/-/g, '/').replace('T', ' ');
const dateFormat = '[' + now + '] INFO: ' + strings.shift();
strings.unshift(dateFormat);
log(...strings);
};
main();