Update files

This commit is contained in:
glpshchn 2025-12-01 04:11:27 +03:00
parent 8092d25c0c
commit 04f4bce239
2 changed files with 63 additions and 19 deletions

View File

@ -38,11 +38,20 @@ const interactionLimiter = rateLimit({
message: 'Вы слишком активны, немного подождите',
});
// Мягкий лимит для прокси изображений (больше запросов, так как это медиа)
const proxyLimiter = rateLimit({
windowMs: 15 * 1000, // 15 секунд
max: 200, // 200 запросов (больше для загрузки множества изображений)
message: 'Слишком много запросов изображений',
skipSuccessfulRequests: true, // Не считать успешные запросы
});
module.exports = {
generalLimiter,
postCreationLimiter,
authLimiter,
searchLimiter,
interactionLimiter
interactionLimiter,
proxyLimiter
};

View File

@ -2,6 +2,7 @@ const express = require('express');
const router = express.Router();
const axios = require('axios');
const { authenticate } = require('../middleware/auth');
const { proxyLimiter } = require('../middleware/rateLimiter');
const config = require('../config');
// e621 требует описательный User-Agent с контактами
@ -55,7 +56,8 @@ function createProxyUrl(originalUrl) {
}
// Эндпоинт для проксирования изображений
router.get('/proxy/:encodedUrl', async (req, res) => {
// Используем более мягкий rate limiter для прокси
router.get('/proxy/:encodedUrl', proxyLimiter, async (req, res) => {
try {
const { encodedUrl } = req.params;
@ -156,21 +158,36 @@ router.get('/furry', authenticate, async (req, res) => {
return res.json({ posts: [] });
}
// Проверка на наличие данных
if (!response.data || !response.data.posts || !Array.isArray(response.data.posts)) {
console.warn('⚠️ e621 вернул неверный формат данных');
// Проверка на наличие данных (e621 может возвращать массив напрямую или объект с posts)
let postsData = null;
if (Array.isArray(response.data)) {
postsData = response.data;
} else if (response.data && Array.isArray(response.data.posts)) {
postsData = response.data.posts;
} else if (response.data && Array.isArray(response.data.data)) {
postsData = response.data.data;
} else {
console.warn('⚠️ e621 вернул неверный формат данных для постов:', {
type: typeof response.data,
keys: response.data ? Object.keys(response.data) : null,
hasPosts: !!(response.data && response.data.posts),
isArray: Array.isArray(response.data)
});
return res.json({ posts: [] });
}
const posts = response.data.posts.map(post => ({
id: post.id,
url: createProxyUrl(post.file.url),
preview: createProxyUrl(post.preview.url),
tags: post.tags.general,
rating: post.rating,
score: post.score.total,
source: 'e621'
}));
const posts = postsData
.filter(post => post && post.file && post.file.url) // Фильтруем посты без URL
.map(post => ({
id: post.id,
url: createProxyUrl(post.file.url),
preview: post.preview && post.preview.url ? createProxyUrl(post.preview.url) : null,
tags: post.tags && post.tags.general ? post.tags.general : [],
rating: post.rating || 'q',
score: post.score && post.score.total ? post.score.total : 0,
source: 'e621'
}));
const payload = { posts };
setCache(cacheKey, payload);
@ -312,15 +329,27 @@ router.get('/furry/tags', authenticate, async (req, res) => {
return res.json({ tags: [] });
}
// Проверка на массив
if (!response.data || !Array.isArray(response.data)) {
console.warn('⚠️ e621 вернул не массив:', typeof response.data);
// Проверка на массив (e621 может возвращать массив напрямую или объект с массивом)
let tagsData = null;
if (Array.isArray(response.data)) {
tagsData = response.data;
} else if (response.data && Array.isArray(response.data.tags)) {
tagsData = response.data.tags;
} else if (response.data && Array.isArray(response.data.data)) {
tagsData = response.data.data;
} else {
console.warn('⚠️ e621 вернул неверный формат данных для тегов:', {
type: typeof response.data,
keys: response.data ? Object.keys(response.data) : null,
data: response.data
});
return res.json({ tags: [] });
}
const tags = response.data.map(tag => ({
const tags = tagsData.map(tag => ({
name: tag.name,
count: tag.post_count
count: tag.post_count || tag.count || 0
}));
const payload = { tags };
@ -351,6 +380,12 @@ router.get('/anime/tags', authenticate, async (req, res) => {
return res.json({ tags: [] });
}
const cacheKey = getCacheKey('gelbooru-tags', { query: query.trim().toLowerCase() });
const cached = getFromCache(cacheKey);
if (cached) {
return res.json(cached);
}
try {
const response = await axios.get('https://gelbooru.com/index.php', {
params: {