feat(anime): turkanime bölüm listesi çekme özelliği ekle

Turkanime anime URL'lerini destekleyerek bölüm listelerini çekme
özelliği eklendi. Kullanıcılar turkanime.tv anime sayfa URL'lerini
girerek bölüm linklerini alabilirler.

- Yeni TURKANIME_DEBUG çevre değişkeni eklendi
- /api/turkanime/episodes API uç noktası eklendi
- İstemci tarafında URL normalizasyonu ve işlemesi eklendi
- HTML'den bölüm linklerini çıkarma mantığı eklendi
This commit is contained in:
2026-01-22 13:32:19 +03:00
parent 1bad4f7256
commit 511a8cbba0
3 changed files with 155 additions and 2 deletions

View File

@@ -91,6 +91,7 @@ const YT_ALLOWED_RESOLUTIONS = new Set([
]);
const YT_EXTRACTOR_ARGS =
process.env.YT_DLP_EXTRACTOR_ARGS || null;
const TURKANIME_DEBUG = String(process.env.TURKANIME_DEBUG || "").toLowerCase() === "1";
let resolvedYtDlpBinary = null;
const TMDB_API_KEY = process.env.TMDB_API_KEY;
const TMDB_BASE_URL = "https://api.themoviedb.org/3";
@@ -728,6 +729,52 @@ function normalizeYoutubeWatchUrl(value) {
}
}
function normalizeTurkanimeUrl(value) {
if (!value || typeof value !== "string") return null;
try {
const urlObj = new URL(value.trim());
if (urlObj.protocol !== "https:") return null;
const host = urlObj.hostname.toLowerCase();
if (!host.endsWith("turkanime.tv")) return null;
if (!urlObj.pathname.startsWith("/anime/")) return null;
urlObj.hash = "";
return urlObj.toString();
} catch (err) {
return null;
}
}
function extractTurkanimeEpisodeLinks(html) {
if (!html) return [];
const listMatch = html.match(
/<ul[^>]*class=["'][^"']*list[^"']*menum[^"']*["'][^>]*>([\s\S]*?)<\/ul>/i
);
if (!listMatch) return [];
const listHtml = listMatch[1];
const hrefs = [];
const hrefRegex = /href=["']([^"']+)["']/gi;
let match;
while ((match = hrefRegex.exec(listHtml))) {
hrefs.push(match[1]);
}
const links = hrefs
.filter((href) => href.includes("/video/"))
.map((href) => {
if (href.startsWith("//")) return `https:${href}`;
if (href.startsWith("/")) return `https://www.turkanime.tv${href}`;
return href;
})
.filter((href) => {
try {
const urlObj = new URL(href);
return urlObj.hostname.toLowerCase().endsWith("turkanime.tv");
} catch {
return false;
}
});
return Array.from(new Set(links));
}
function startYoutubeDownload(url) {
const normalized = normalizeYoutubeWatchUrl(url);
if (!normalized) return null;
@@ -6234,6 +6281,77 @@ app.post("/api/youtube/download", requireAuth, async (req, res) => {
}
});
app.post("/api/turkanime/episodes", requireAuth, async (req, res) => {
try {
const rawUrl = req.body?.url;
const normalized = normalizeTurkanimeUrl(rawUrl);
if (!normalized) {
return res.status(400).json({
ok: false,
error: "Geçerli bir turkanime.tv anime URL'si gerekli."
});
}
if (TURKANIME_DEBUG) {
console.log("🧪 Turkanime fetch başlıyor:", normalized);
}
const resp = await fetch(normalized, {
headers: {
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36",
Accept: "text/html"
}
});
if (!resp.ok) {
if (TURKANIME_DEBUG) {
console.warn("🧪 Turkanime HTTP hata:", resp.status, resp.statusText);
}
return res.status(502).json({
ok: false,
error: `Turkanime sayfası alınamadı (HTTP ${resp.status}).`
});
}
const html = await resp.text();
if (TURKANIME_DEBUG) {
console.log("🧪 Turkanime HTML uzunluğu:", html.length);
}
const links = extractTurkanimeEpisodeLinks(html);
if (!links.length) {
if (TURKANIME_DEBUG) {
const hasBolumler = html.includes("bolumler");
const hasList = /class=["'][^"']*list[^"']*menum/i.test(html);
const bolumIndex = html.indexOf("bolumler");
const snippetStart = bolumIndex > 200 ? bolumIndex - 200 : 0;
const snippet =
bolumIndex >= 0
? html.slice(snippetStart, bolumIndex + 400)
: html.slice(0, 400);
console.warn("🧪 Turkanime bölüm listesi bulunamadı.", {
hasBolumler,
hasList,
bolumIndex,
snippet
});
}
return res.status(404).json({
ok: false,
error: "Bölüm listesi bulunamadı."
});
}
if (TURKANIME_DEBUG) {
console.log("🧪 Turkanime bölüm link sayısı:", links.length);
}
res.json({ ok: true, links });
} catch (err) {
if (TURKANIME_DEBUG) {
console.error("🧪 Turkanime hata:", err?.message || err);
}
res.status(500).json({
ok: false,
error: err?.message || "Turkanime verisi alınamadı."
});
}
});
// --- 🎫 YouTube cookies yönetimi ---
app.get("/api/youtube/cookies", requireAuth, (req, res) => {
try {