denisgay/server.js
2025-11-12 19:51:06 +07:00

201 lines
7.1 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const express = require('express');
const cors = require('cors');
const cron = require('node-cron');
const fs = require('fs').promises;
const path = require('path');
require('dotenv').config();
const app = express();
const PORT = process.env.PORT || 3000;
// Middleware
app.use(cors());
app.use(express.json());
app.use(express.static('.'));
// Файл для хранения цитат
const QUOTES_FILE = path.join(__dirname, 'quotes.json');
// Загрузка цитат из файла
async function loadQuotes() {
try {
const data = await fs.readFile(QUOTES_FILE, 'utf8');
return JSON.parse(data);
} catch (error) {
return [];
}
}
// Сохранение цитат в файл
async function saveQuotes(quotes) {
await fs.writeFile(QUOTES_FILE, JSON.stringify(quotes, null, 2));
}
// Генерация цитаты через OpenRouter
async function generateQuote() {
const prompt = `Generate a gay pride quote in Russian on behalf of Denis Shulepov.
The quote should be:
- Short and concise (1-3 sentences)
- Bold, confident and unapologetic about being gay
- Celebrate gay culture, freedom and pride
- Witty, sarcastic and clever
- Support LGBTQ+ community and gay lifestyle
- Elegant but with attitude
Topics: gay pride, gay culture, fashion, style, relationships, love, freedom, celebrating being gay, self-expression, beauty.
Use gay slang, humor and vivid imagery. Be bold and confident. The quote should celebrate gay culture and pride with style and elegance. Never use crude street language or insults.
Answer only with the text of the quote, without additional explanations. Answer in Russian!`;
try {
const requestBody = JSON.stringify({
model: process.env.OPENROUTER_MODEL || 'google/gemini-2.5-flash-lite-preview-09-2025',
messages: [
{
role: 'user',
content: prompt
}
],
max_tokens: 200,
temperature: 0.9
});
const response = await fetch('https://openrouter.ai/api/v1/chat/completions', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.OPENROUTER_API_KEY}`,
'Content-Type': 'application/json; charset=utf-8',
'HTTP-Referer': 'http://localhost:3000',
'X-Title': 'Gay Quotes App'
},
body: requestBody
});
if (!response.ok) {
const errorText = await response.text();
throw new Error(`HTTP error! status: ${response.status}, message: ${errorText}`);
}
const data = await response.json();
return data.choices[0].message.content.trim();
} catch (error) {
console.error('Ошибка при генерации цитаты:', error);
throw error;
}
}
// Автоматическая публикация цитаты
async function autoPublishQuote() {
try {
console.log('Автоматическая генерация цитаты...');
const quotes = await loadQuotes();
const quoteText = await generateQuote();
const newQuote = {
id: Date.now().toString(),
text: quoteText,
author: 'Денис Шулепов',
date: new Date().toISOString()
};
quotes.unshift(newQuote);
// Ограничиваем количество цитат до 100
if (quotes.length > 100) {
quotes.splice(100);
}
await saveQuotes(quotes);
console.log('Новая цитата опубликована:', quoteText);
return newQuote;
} catch (error) {
console.error('Ошибка при автоматической публикации цитаты:', error);
throw error;
}
}
// API Routes
app.get('/api/quotes', async (req, res) => {
try {
const quotes = await loadQuotes();
res.json(quotes);
} catch (error) {
res.status(500).json({ error: 'Ошибка при загрузке цитат' });
}
});
app.post('/api/quotes', async (req, res) => {
try {
const newQuote = await autoPublishQuote();
res.json(newQuote);
} catch (error) {
res.status(500).json({ error: 'Ошибка при генерации цитаты' });
}
});
app.delete('/api/quotes/:id', async (req, res) => {
try {
const quotes = await loadQuotes();
const filteredQuotes = quotes.filter(q => q.id !== req.params.id);
await saveQuotes(filteredQuotes);
res.json({ success: true });
} catch (error) {
res.status(500).json({ error: 'Ошибка при удалении цитаты' });
}
});
// Запуск автопубликации каждый час
cron.schedule('0 * * * *', async () => {
console.log('Запланированная публикация цитаты...');
await autoPublishQuote();
});
// Инициализация при старте сервера
async function initializeServer() {
try {
// Создаем файл с цитатами если его нет
try {
await fs.access(QUOTES_FILE);
} catch {
const initialQuotes = [
{
id: '1',
text: 'Если жизнь подкидывает лимоны, сделай не лимонад, а шикарный коктейль с водкой и танцуй на барной стойке!',
author: 'Денис Шулепов',
date: new Date(Date.now() - 86400000).toISOString()
},
{
id: '2',
text: 'Быть собой — это самый эпатажный coming out в мире, дорогие. И я уже на подиуме!',
author: 'Денис Шулепов',
date: new Date(Date.now() - 172800000).toISOString()
},
{
id: '3',
text: 'Драма — это когда ты не нашёл туфли 42 размера. Трагедия — когда они есть, но не в твоём цвете.',
author: 'Денис Шулепов',
date: new Date(Date.now() - 259200000).toISOString()
}
];
await saveQuotes(initialQuotes);
console.log('Создан начальный файл с цитатами');
}
// Публикуем первую цитату при старте
await autoPublishQuote();
} catch (error) {
console.error('Ошибка при инициализации сервера:', error);
}
}
// Запуск сервера
app.listen(PORT, () => {
console.log(`Сервер запущен на порту ${PORT}`);
console.log(`Гейский цитатник доступен по адресу: http://localhost:${PORT}`);
initializeServer();
});