dptxa-proxy / src /pages /api /movies.js
TXAVLOG
Deploy DPTXA to Hugging Face Spaces
4bea261
Raw
History Blame Contribute Delete
5.05 kB
import {
getNewestMovies,
getSeriesMovies,
getSingleMovies,
getCartoonMovies,
getMoviesByCategory,
getMoviesByCountry,
getMoviesByTopic
} from '../../lib/api.js';
const fetchWithTimeout = async (url, options = {}) => {
const { timeout = 5000 } = options;
const controller = new AbortController();
const id = setTimeout(() => controller.abort(), timeout);
try {
const response = await fetch(url, { ...options, signal: controller.signal });
clearTimeout(id);
return response;
} catch (e) {
clearTimeout(id);
throw e;
}
};
export const GET = async ({ url }) => {
const type = url.searchParams.get('type') || '';
const category = url.searchParams.get('category') || '';
const country = url.searchParams.get('country') || '';
const topic = url.searchParams.get('topic') || '';
const keyword = url.searchParams.get('keyword') || url.searchParams.get('q') || '';
const page = parseInt(url.searchParams.get('page') || '1');
try {
let result = { items: [] };
if (keyword) {
result = await import('../../lib/api.js').then(m => m.searchMovies(keyword, page));
} else if (topic) {
result = await getMoviesByTopic(topic, page);
} else if (country) {
result = await getMoviesByCountry(country, page);
} else if (category) {
if (category === 'phim-moi-cap-nhat') {
result = await getNewestMovies(page);
} else {
result = await getMoviesByCategory(category, page);
}
} else if (type === 'newest') {
result = await getNewestMovies(page);
} else if (type === 'series') {
result = await getSeriesMovies(page);
} else if (type === 'single') {
result = await getSingleMovies(page);
} else if (type === 'cartoon') {
result = await getCartoonMovies(page);
}
// FALLBACK SYSTEM: If less than 4 movies in local DB, fetch from public KKPhim API!
if (!result.items || result.items.length < 4) {
try {
let fallbackUrl = '';
if (country) {
fallbackUrl = `https://phimapi.com/v1/api/quoc-gia/${country}?page=${page}`;
} else if (category) {
const defaultTypes = {
'phim-bo': 'phim-bo',
'phim-le': 'phim-le',
'hoat-hinh': 'hoat-hinh',
'tv-shows': 'tv-shows'
};
if (defaultTypes[category]) {
fallbackUrl = `https://phimapi.com/v1/api/danh-sach/${defaultTypes[category]}?page=${page}`;
} else if (category === 'phim-chieu-rap') {
fallbackUrl = `https://phimapi.com/v1/api/the-loai/hanh-dong?page=${page}`;
} else {
fallbackUrl = `https://phimapi.com/v1/api/the-loai/${category}?page=${page}`;
}
} else if (type === 'newest') {
fallbackUrl = `https://phimapi.com/danh-sach/phim-moi-cap-nhat?page=${page}`;
} else if (type === 'series') {
fallbackUrl = `https://phimapi.com/v1/api/danh-sach/phim-bo?page=${page}`;
} else if (type === 'single') {
fallbackUrl = `https://phimapi.com/v1/api/danh-sach/phim-le?page=${page}`;
} else if (type === 'cartoon') {
fallbackUrl = `https://phimapi.com/v1/api/danh-sach/hoat-hinh?page=${page}`;
}
if (fallbackUrl) {
const res = await fetchWithTimeout(fallbackUrl);
if (res.ok) {
const data = await res.json();
let items = [];
if (fallbackUrl.includes('danh-sach/phim-moi-cap-nhat')) {
items = data.items || [];
} else if (data.data && data.data.items) {
items = data.data.items || [];
}
const mapped = items.map(item => ({
_id: item._id,
name: item.name,
slug: item.slug,
origin_name: item.origin_name,
thumb_url: item.thumb_url,
poster_url: item.poster_url,
year: item.year,
quality: item.quality || 'FHD',
lang: item.lang || 'Vietsub',
episode_current: item.episode_current || 'Tập 1',
type: item.type || 'single',
isLocal: false
}));
const localItems = result.items || [];
const mergedItems = [...localItems];
for (const item of mapped) {
if (!mergedItems.some(x => x.slug === item.slug)) {
mergedItems.push(item);
}
}
result.items = mergedItems.slice(0, 12);
}
}
} catch (err) {
console.error('[API FALLBACK ERROR]', err);
}
}
return new Response(JSON.stringify(result), {
status: 200,
headers: { 'Content-Type': 'application/json' }
});
} catch (err) {
console.error('Error fetching movies API:', err);
return new Response(JSON.stringify({ error: err.message, items: [] }), {
status: 500,
headers: { 'Content-Type': 'application/json' }
});
}
};