/
Cooolprogrammers
/
web-nodejs-labs
Обзор
Документация
Войти
/
Cooolprogrammers
/
web-nodejs-labs
Код
Запросы
0
Задачи
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
backend/src/services/lab8/task2/task2.service.js
277 строк
10 KB
darkvoid6@mail.ru
ЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫ
18 дек 2025, 07:59
18 дек 2025, 07:59
f2c4f06
Код
Авторство
О чём код?
import fs from 'fs/promises'; import path from 'path'; import { fileURLToPath } from 'url'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); class Task2Service { constructor() { this.dataDir = path.join(__dirname, '..', '..', '..', '..', 'data', 'lab8', 'task2'); this.rawDataPath = path.join(this.dataDir, 'cup.txt'); this.groupsOutputPath = path.join(this.dataDir, 'groups.json'); this.stadiumsOutputPath = path.join(this.dataDir, 'stadiums.json'); } /** * Проверяет наличие файла с данными */ async checkDataFile() { try { await fs.access(this.rawDataPath); return true; } catch (error) { return false; } } /** * Парсит данные матчей и создает структурированные JSON */ async processData() { try { const fileExists = await this.checkDataFile(); if (!fileExists) { throw new Error(`Файл с данными не найден: ${this.rawDataPath}`); } console.log('Чтение данных из файла...'); const data = await fs.readFile(this.rawDataPath, 'utf8'); const groups = this.parseGroups(data); const stadiums = this.parseStadiums(groups); // Создаем директорию если не существует await fs.mkdir(this.dataDir, { recursive: true }); // Сохраняем результаты await fs.writeFile(this.groupsOutputPath, JSON.stringify(groups, null, 2), 'utf8'); await fs.writeFile(this.stadiumsOutputPath, JSON.stringify(stadiums, null, 2), 'utf8'); console.log('Данные успешно обработаны и сохранены'); return { groups: groups, stadiums: stadiums, message: 'Данные успешно обработаны' }; } catch (error) { console.error('Ошибка при обработке данных:', error); throw error; } } /** * Парсит данные по группам */ parseGroups(data) { const lines = data.split('\n'); const groups = {}; let currentGroup = null; // Сначала собираем команды по группам for (let i = 0; i < lines.length; i++) { const line = lines[i].trim(); if (line.startsWith('Group ')) { const groupMatch = line.match(/Group\s+([A-H])\s*\|\s*(.+)/); if (groupMatch) { const groupName = groupMatch[1]; const teamsStr = groupMatch[2]; const teams = teamsStr.split(/\s{2,}/).map(team => team.trim()).filter(team => team); groups[groupName] = { group: `Group ${groupName}`, teams: teams, matches: [] }; currentGroup = groupName; } } } // Теперь парсим матчи for (let i = 0; i < lines.length; i++) { const line = lines[i].trim(); // Ищем строки с матчами (начинаются с номера в скобках) if (line.match(/^\(\d+\)/)) { const match = this.parseMatchLine(line); if (match && currentGroup) { match.group = `Group ${currentGroup}`; groups[currentGroup].matches.push(match); } } // Обновляем текущую группу при обнаружении новой if (line.startsWith('Group ')) { const groupMatch = line.match(/Group\s+([A-H])/); if (groupMatch) { currentGroup = groupMatch[1]; } } } return Object.values(groups); } /** * Парсит строку с информацией о матче */ parseMatchLine(line) { try { // Пример строки: // (1) Sun Nov/20 19:00 Qatar 0-2 (0-2) Ecuador @ Al Bayt Stadium, Al Khor const matchRegex = /\((\d+)\)\s+(\w+\s+\w+\/\d+)\s+(\d+:\d+)\s+([^-]+)\s+([\d\-]+)\s+\([^)]+\)\s+([^@]+)@\s+([^,]+),\s*(.+)/; const match = line.match(matchRegex); if (!match) { // Попробуем альтернативный формат (без подробного счета в скобках) const altRegex = /\((\d+)\)\s+(\w+\s+\w+\/\d+)\s+(\d+:\d+)\s+([^-]+)\s+([\d\-]+)\s+([^@]+)@\s+([^,]+),\s*(.+)/; const altMatch = line.match(altRegex); if (!altMatch) { console.log('Не удалось распарсить строку:', line); return null; } const [, id, date, time, team1, score, team2, stadium, city] = altMatch; return { id: parseInt(id), date: this.formatDate(date.trim()), time: time.trim(), team1: team1.trim(), team2: team2.trim(), score: score.trim(), stadium: stadium.trim(), city: city.trim() }; } const [, id, date, time, team1, score, team2, stadium, city] = match; return { id: parseInt(id), date: this.formatDate(date.trim()), time: time.trim(), team1: team1.trim(), team2: team2.trim(), score: score.trim(), stadium: stadium.trim(), city: city.trim() }; } catch (error) { console.error('Ошибка парсинга строки матча:', error); console.log('Проблемная строка:', line); return null; } } /** * Форматирует дату в стандартный вид */ formatDate(dateStr) { // Пример: "Sun Nov/20" -> "2022-11-20" const months = { 'Jan': '01', 'Feb': '02', 'Mar': '03', 'Apr': '04', 'May': '05', 'Jun': '06', 'Jul': '07', 'Aug': '08', 'Sep': '09', 'Oct': '10', 'Nov': '11', 'Dec': '12' }; const parts = dateStr.split(' '); if (parts.length >= 2) { const monthDay = parts[1].split('/'); if (monthDay.length === 2) { const month = months[monthDay[0]]; const day = monthDay[1].padStart(2, '0'); return `2022-${month}-${day}`; } } return dateStr; } /** * Парсит данные по стадионам на основе данных групп */ parseStadiums(groups) { const stadiums = {}; groups.forEach(group => { group.matches.forEach(match => { if (match.stadium) { const stadiumName = match.stadium; if (!stadiums[stadiumName]) { stadiums[stadiumName] = { stadium: stadiumName, city: match.city || '', matches: [] }; } stadiums[stadiumName].matches.push({ id: match.id, date: match.date, time: match.time, group: match.group, team1: match.team1, team2: match.team2, score: match.score }); } }); }); return Object.values(stadiums); } /** * Получает обработанные данные групп */ async getGroups() { try { const data = await fs.readFile(this.groupsOutputPath, 'utf8'); return JSON.parse(data); } catch (error) { if (error.code === 'ENOENT') { throw new Error('Данные групп не найдены. Сначала выполните обработку данных.'); } throw error; } } /** * Получает обработанные данные стадионов */ async getStadiums() { try { const data = await fs.readFile(this.stadiumsOutputPath, 'utf8'); return JSON.parse(data); } catch (error) { if (error.code === 'ENOENT') { throw new Error('Данные стадионов не найдены. Сначала выполните обработку данных.'); } throw error; } } /** * Проверяет статус данных */ async getDataStatus() { const rawFileExists = await this.checkDataFile(); const groupsFileExists = await fs.access(this.groupsOutputPath).then(() => true).catch(() => false); const stadiumsFileExists = await fs.access(this.stadiumsOutputPath).then(() => true).catch(() => false); return { rawData: rawFileExists, groupsData: groupsFileExists, stadiumsData: stadiumsFileExists }; } } export default new Task2Service();