const express = require('express'); const path = require('path'); const fs = require('fs'); const sqlite3 = require('sqlite3').verbose(); const sharp = require('sharp'); require('dotenv').config(); const app = express(); const PORT = process.env.PORT || 3000; const API_KEY = process.env.HOTEL777KEY; if (!API_KEY) { console.error('FATAL: HOTEL777KEY environment variable not set'); process.exit(1); } const imgDir = path.join(__dirname, 'public', 'img'); const supportedFormats = ['.png', '.jpg', '.jpeg', '.gif', '.bmp', '.tiff']; async function convertImagesToWebp() { if (!fs.existsSync(imgDir)) { console.log('Папка img не найдена, пропускаем конвертацию'); return; } const files = fs.readdirSync(imgDir); const toConvert = files.filter(f => { const ext = path.extname(f).toLowerCase(); return supportedFormats.includes(ext) && !f.endsWith('.webp'); }); if (toConvert.length === 0) { console.log('Все изображения уже в формате WebP'); return; } console.log(`Конвертация ${toConvert.length} изображений в WebP...`); for (const file of toConvert) { const inputPath = path.join(imgDir, file); const outputPath = path.join(imgDir, path.basename(file, path.extname(file)) + '.webp'); try { await sharp(inputPath).webp({ quality: 85 }).toFile(outputPath); fs.unlinkSync(inputPath); console.log(` ${file} -> ${path.basename(outputPath)}`); } catch (err) { console.error(` Ошибка конвертации ${file}:`, err.message); } } console.log('Конвертация завершена'); } app.use(express.json()); app.use(express.static(path.join(__dirname, 'public'))); const dataDir = path.join(__dirname, 'data'); if (!fs.existsSync(dataDir)) fs.mkdirSync(dataDir); [ 'equipment_images', 'partner_images', 'license_images', 'activity_images', 'hero_images' ].forEach(dir => { const p = path.join(dataDir, dir); if (!fs.existsSync(p)) fs.mkdirSync(p); app.use('/data/' + dir, express.static(p)); }); const dbPath = path.join(dataDir, 'bookings.db'); const db = new sqlite3.Database(dbPath); const dbModule = require('./modules/database'); const crudModule = require('./modules/database/crud'); const authModule = require('./modules/auth'); const heroModule = require('./modules/hero'); const aboutModule = require('./modules/about'); const servicesModule = require('./modules/services'); const workSchemesModule = require('./modules/workSchemes'); const processStepsModule = require('./modules/processSteps'); const equipmentModule = require('./modules/equipment'); const geographyModule = require('./modules/geography'); const licensesModule = require('./modules/licenses'); const activitiesModule = require('./modules/activities'); const partnersModule = require('./modules/partners'); const settingsModule = require('./modules/settings'); const usersModule = require('./modules/users'); const leadsModule = require('./modules/leads'); const siteDataModule = require('./modules/siteData'); [ crudModule, authModule, heroModule, aboutModule, servicesModule, workSchemesModule, processStepsModule, equipmentModule, geographyModule, licensesModule, activitiesModule, partnersModule, settingsModule, usersModule, leadsModule, siteDataModule ].forEach(m => m.init(db)); const auth = { authenticateToken: authModule.authenticateToken, requireAdmin: authModule.requireAdmin }; authModule.setupRoutes(app); heroModule.setupRoutes(app, auth); aboutModule.setupRoutes(app, auth); servicesModule.setupRoutes(app, auth); workSchemesModule.setupRoutes(app, auth); processStepsModule.setupRoutes(app, auth); equipmentModule.setupRoutes(app, auth); geographyModule.setupRoutes(app, auth); licensesModule.setupRoutes(app, auth); activitiesModule.setupRoutes(app, auth); partnersModule.setupRoutes(app, auth); settingsModule.setupRoutes(app, auth); usersModule.setupRoutes(app, auth); leadsModule.setupRoutes(app, auth); siteDataModule.setupRoutes(app); app.get('/admin', (req, res) => { res.sendFile(path.join(__dirname, 'public', 'admin.html')); }); app.get('/', (req, res) => { const years = new Date().getFullYear() - 2011; const htmlPath = path.join(__dirname, 'public', 'index.html'); const html = fs.readFileSync(htmlPath, 'utf8'); res.send(html.replace(/\{years\}/g, String(years))); }); convertImagesToWebp().then(() => console.log('Images ready')); (async () => { await dbModule.init(db); await authModule.syncAdmin(); console.log('Database initialized, admin synced'); app.listen(PORT, () => { console.log(`Server running on http://localhost:${PORT}`); console.log(`Admin panel: http://localhost:${PORT}/admin`); }); })();