Configs — Компонент, отвечающий за хранение и загрузку OpenVPN конфигов.
Структура папок.
parse-configs.js — Функция для парсинга конфигов из API.
Пример
Думаю, приглядевшись, вы поймёте, что логика сортировки очевидна.
Cодержимое файла parse-configs.js.
load.js — Функция для обращения к API и создания файлов конфигов.
Cодержимое файла load.js.
get.js — Функция для поиска среди загруженных конфигов.
Cодержимое файла get.js.
index.js — Объект с методами get и load.
Cодержимое файла index.js.
Application
Использование в приложении: /app/Configs.
API
Интерфейс компонента Configs.
Test
Версия для тестирования: /app_test/Configs.
Объект поиска конфигов.
5 часть — Vpn компонент
Структура папок.
configs
¦
¦ configs.json // Хранит метаданные о конфигах
¦ get.js
¦ index.js
¦ load.js
¦ parse-configs.js
¦
L---base // В этой папке хранятся конфиги аки файлы типа ovpn
empty.file // Пустой файл нужен для того чтобы при сборке пустая папка не удалялась
parse-configs.js — Функция для парсинга конфигов из API.
Пример
Думаю, приглядевшись, вы поймёте, что логика сортировки очевидна.
const body = 'Яблоки,Груши,Лук,3,4,6,8,9,6'
const configs = parseConfigs(body)
configs /* [{
"Яблоки": 3,
"Груши": 4,
"Лук": 6
}, {
"Яблоки": 8,
"Груши": 9,
"Лук": 6
}] */
Cодержимое файла parse-configs.js.
Код
module.exports = body =>
body
.replace(/[^#]+/, '')
.replace(/#/, '')
.replace(/\r\n/gi, ',') // Очистка от всякого мусора
.split(',') // Преобразование строки в массив
.reduce((ctx, elem, index) => {
if (index > 14) {
// Черная магия
const key = ctx.name_tmp[ctx.config_name_index]
ctx.config_tmp[key] = elem
ctx.config_name_index++
if (ctx.config_name_index > 14) {
ctx.configs.push(ctx.config_tmp)
ctx.config_tmp = {}
ctx.config_name_index = 0
}
} else {
// Первые 14 позиций это информация о сервере например: ping, страна, etc
ctx.name_tmp.push(elem)
}
return ctx
}, {
name_tmp: [],
config_name_index: 0,
config_tmp: {},
configs: []
}).configs
load.js — Функция для обращения к API и создания файлов конфигов.
Cодержимое файла load.js.
Код
const request = require('request')
, fs = require('fs')
, Base64 = require(`js-base64`).Base64
, parseConfigs = require('./parse-configs')
module.exports = () =>
new Promise((resolve, reject) => {
request(`http://130.158.6.57/api/iphone/`, (err, res, body) => {
if (err || res.statusCode != 200) {
return reject()
}
const configs = parseConfigs(body).map(config => {
// Сам конфиг передается закодированным в base64, его нужно раскодировать
const decode_config = Base64.decode(config.OpenVPN_ConfigData_Base64)
.replace(/dev tun/g, `dev tap`)
, path = `${__dirname}/base/${config.HostName}.ovpn`
fs.writeFileSync(path, decode_config)
delete config.OpenVPN_ConfigData_Base64
config.path = path
return config
})
fs.writeFileSync(`${__dirname}/configs.json`, JSON.stringify(configs))
// Возвращаем общее количество загруженных конфигов
resolve(configs.length)
})
})
get.js — Функция для поиска среди загруженных конфигов.
Cодержимое файла get.js.
Код
const fs = require('fs')
, Base64 = require(`js-base64`).Base64
module.exports = ({
CountryLong = '-'
, Ping = '-'
, NumVpnSessions = '-'
, Score = '-'
, Speed = '-'
, Uptime = '-'
, TotalUsers = '-'
, TotalTraffic = '-'
}) => {
try {
// Загружаем метаданные
const configs = fs.readFileSync(`${__dirname}/configs.json`, {
encoding: 'utf8'
})
// Тут произошел поиск, этот код не такой сложный каким
// может показаться на первый взгляд, тут просто
// конфиги проходят через множество условий
return JSON.parse(configs)
.filter(conf =>
(conf.CountryLong == CountryLong || CountryLong == '-') &&
(parseInt(conf.Ping) < parseInt(Ping) || Ping == '-') &&
(parseInt(conf.NumVpnSessions) > parseInt(NumVpnSessions) || NumVpnSessions == '-') &&
(parseInt(conf.Score) > parseInt(Score) || Score == '-') &&
(parseInt(conf.Speed) > parseInt(Speed) || Speed == '-') &&
(parseInt(conf.Uptime) > parseInt(Uptime) || Uptime == '-') &&
(parseInt(conf.TotalUsers) > parseInt(TotalUsers) || TotalUsers == '-') &&
(parseInt(conf.TotalTraffic) > parseInt(TotalTraffic) || TotalTraffic == '-')
)
} catch (e) {
return []
}
}
index.js — Объект с методами get и load.
Cодержимое файла index.js.
Код
module.exports = {
load: require('./load'),
get: require('./get')
}
Application
Использование в приложении: /app/Configs.
API
Интерфейс компонента Configs.
const Configs = require('./../../app/components/configs')
Configs.load().then(length => {
console.log(`Загружено конфигов: ${length}`)
const search = Configs.get({
CountryLong: 'Japan'
, Ping: 22 // 1-22 ms
, NumVpnSessions: '-' // empty
, Score: '-' // empty
, Speed: 13311 // bit
, Uptime: 3600000 // ms
, TotalUsers: '-' // empty
, TotalTraffic: '-' // empty
})
console.log(`Найдено конфигов: ${search.length}`)
}, () => {
console.log(`Ошибка загрузки конфигов`)
})
Test
Версия для тестирования: /app_test/Configs.
Объект поиска конфигов.
Ключ | Тип | Описание |
---|---|---|
CountryLong | String | Страна VPN сервера |
Ping | Number | Время доставления информации (в миллисекундах) |
NumVpnSessions | Number | Активных сессий |
Score | Number | Качество соединения |
Speed | Number | Скорость соединения (в байтах) |
Uptime | Number | Время бесперебойной работы сервера (в миллисекундах) |
TotalUsers | Number | Всего подключений за время работы |
TotalTraffic | Number | Общий трафик на сервере за время работы (в байтах) |
5 часть — Vpn компонент
Навигация
1 часть — Вводная
2 часть — Разработка
3 часть — OpenVPN компонент
4 часть — Configs компонент
5 часть — Vpn компонент
6 часть — Notify компонент
7 часть — Context компонент
8 часть — Setting компонент
9 часть — Callback компонент
10 часть — Объединение всех компонентов
11 часть — Сборка приложения под Windows
2 часть — Разработка
3 часть — OpenVPN компонент
4 часть — Configs компонент
5 часть — Vpn компонент
6 часть — Notify компонент
7 часть — Context компонент
8 часть — Setting компонент
9 часть — Callback компонент
10 часть — Объединение всех компонентов
11 часть — Сборка приложения под Windows
ThisMan
Складывается ощущение, что вам не стоило разбивать ваш рассказ на маленькие статьи. Лучше было бы все объединить в одну, пусть она была бы больше средней, но так легче искать какую-то определенную часть + полная картинка будет складываться лучше