mullvad-servers-ping-tester
Version:
Инструмент для тестирования пинга серверов Mullvad VPN с расширенной аналитикой
174 lines • 8.61 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
require("reflect-metadata");
const commander_1 = require("commander");
const chalk_1 = __importDefault(require("chalk"));
const inversify_config_1 = require("@/config/inversify.config");
const types_1 = require("@/config/types");
const config_1 = __importDefault(require("@/config/config"));
const logger_1 = require("@/utils/logger");
/**
* Основной класс приложения
* Отвечает за инициализацию и запуск приложения
*/
class Application {
/**
* Создает экземпляр приложения
* Инициализирует все необходимые сервисы
*/
constructor() {
this.logger = new logger_1.Logger(Application.name);
this.isVerboseMode = false;
// Получаем сервисы из контейнера DI
this.serverFetcherService = inversify_config_1.container.get(types_1.TYPES.ServerFetcherService);
this.pingService = inversify_config_1.container.get(types_1.TYPES.PingService);
this.outputGeneratorService = inversify_config_1.container.get(types_1.TYPES.OutputGeneratorService);
this.historyAnalyzerService = inversify_config_1.container.get(types_1.TYPES.HistoryAnalyzerService);
this.webServerService = inversify_config_1.container.get(types_1.TYPES.WebServerService);
}
/**
* Запускает приложение
* @returns {Promise<void>}
*/
async run() {
try {
this.setupCommandLineInterface();
}
catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error);
this.logger.error('Application error:', errorMessage);
process.exit(1);
}
}
/**
* Настраивает интерфейс командной строки
*/
setupCommandLineInterface() {
const program = new commander_1.Command();
program
.name('mullvad-ping-tester')
.description('Advanced tool for testing ping to Mullvad VPN servers with detailed analytics')
.version('1.0.0');
program
.option('-c, --country <codes>', 'Filter servers by country code (comma-separated)')
.option('-C, --city <names>', 'Filter servers by city name (comma-separated)')
.option('-t, --timeout <ms>', 'Ping timeout in milliseconds')
.option('-r, --retries <number>', 'Number of ping retries')
.option('-p, --parallel <number>', 'Number of parallel pings')
.option('-f, --format <formats>', 'Output formats (comma-separated: json,html,csv)')
.option('-o, --output <path>', 'Path to save results')
.option('-w, --web', 'Start web server for interactive results')
.option('-v, --verbose', 'Enable verbose logging')
.option('-q, --quiet', 'Disable all logging except errors');
program.action(async (options) => {
// Настраиваем уровень логирования
if (options.verbose) {
logger_1.Logger.setLogLevel(logger_1.ELogLevel.DEBUG);
this.isVerboseMode = true;
this.logger.info('Verbose logging enabled');
}
else if (options.quiet) {
logger_1.Logger.setLogLevel(logger_1.ELogLevel.ERROR);
}
// Применяем опции командной строки к конфигурации
if (options.country)
config_1.default.COUNTRY_FILTER = options.country;
if (options.city)
config_1.default.CITY_FILTER = options.city;
if (options.timeout)
config_1.default.PING_TIMEOUT = parseInt(options.timeout, 10);
if (options.retries)
config_1.default.PING_RETRIES = parseInt(options.retries, 10);
if (options.parallel)
config_1.default.CONCURRENT_PINGS = parseInt(options.parallel, 10);
if (options.output)
config_1.default.SAVE_PATH = options.output;
if (options.format) {
config_1.default.SAVE_FORMATS = options.format.split(',');
}
if (options.web)
config_1.default.WEB_SERVER.ENABLED = true;
await this.startApplication();
});
program.parse();
}
/**
* Запускает основную логику приложения
* @returns {Promise<void>}
*/
async startApplication() {
try {
this.logger.info(chalk_1.default.bold.green('Starting Mullvad Server Ping Tester...'));
// Получаем список серверов
this.logger.info('Fetching server list...');
const servers = await this.serverFetcherService.fetchServers();
if (servers.length === 0) {
this.logger.error('No servers found. Exiting...');
process.exit(1);
}
this.logger.info(`Found ${servers.length} servers matching criteria`);
// Пингуем серверы
this.logger.info('Pinging servers...');
const pingResults = await this.pingService.pingAllServers(servers);
// Генерируем статистику
this.logger.info('Generating statistics...');
const stats = this.outputGeneratorService.generateStatistics(pingResults);
// Выводим результаты
this.outputGeneratorService.printResults(pingResults, stats, {
format: 'console',
topCount: config_1.default.TOP_SERVERS_COUNT,
verbose: this.isVerboseMode
});
// Сохраняем результаты
this.logger.info('Saving results...');
await this.outputGeneratorService.saveResults(pingResults, stats, {
format: config_1.default.SAVE_FORMATS[0],
outputPath: config_1.default.SAVE_PATH,
topCount: config_1.default.TOP_SERVERS_COUNT
});
// Анализируем историю, если доступна
let historicalData = [];
try {
this.logger.info('Analyzing historical data...');
historicalData = await this.historyAnalyzerService.loadHistory();
if (historicalData.length > 0) {
const trends = this.historyAnalyzerService.analyzePerformanceTrends(historicalData);
const stableServers = this.historyAnalyzerService.findMostStableServers(historicalData);
this.logger.info('Historical analysis complete');
}
}
catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error);
this.logger.warn('Could not analyze historical data:', errorMessage);
}
// Запускаем веб-сервер, если включен
if (config_1.default.WEB_SERVER.ENABLED) {
this.logger.info(`Starting web server on ${config_1.default.WEB_SERVER.HOST}:${config_1.default.WEB_SERVER.PORT}...`);
await this.webServerService.start(config_1.default.WEB_SERVER.PORT);
// Обновляем данные на веб-сервере
this.webServerService.updateData(pingResults, stats, historicalData);
this.logger.info(chalk_1.default.green(`Web server running at http://${config_1.default.WEB_SERVER.HOST}:${config_1.default.WEB_SERVER.PORT}`));
this.logger.info('Press Ctrl+C to stop');
}
else {
this.logger.info(chalk_1.default.green('All done!'));
}
}
catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error);
this.logger.error('Error during application execution:', errorMessage);
process.exit(1);
}
}
}
// Запускаем приложение
const app = new Application();
app.run().catch(error => {
console.error('Unhandled error:', error);
process.exit(1);
});
//# sourceMappingURL=index.js.map