feat(ph): pornhub için cookie yönetimi ekle

Pornhub video indirmelerinde yetkilendirme için cookie dosyası yönetimi
eklendi. Kullanıcılar arayüz üzerinden Netscape formatındaki cookies.txt
içeriğini kaydedebilir ve yönetebilir.

- Backend API /api/pornhub/cookies endpointleri eklendi
- Ayarlar sayfasına Pornhub sekmesi eklendi
- Cookie dosyası kontrolü ve yt-dlp entegrasyonu sağlandı
- Rabbit ikonu yenilendi ve boyutu artırıldı
- Docker portu 3005 olarak değiştirildi
This commit is contained in:
2025-12-27 20:02:35 +03:00
parent b63bd41973
commit 8bf08880fd
6 changed files with 193 additions and 14 deletions

View File

@@ -5,6 +5,7 @@
const tabs = [
{ id: "general", label: "General", icon: "fa-solid fa-sliders" },
{ id: "youtube", label: "YouTube", icon: "fa-brands fa-youtube" },
{ id: "pornhub", label: "Pornhub", icon: "fa-solid fa-lock" },
{ id: "advanced", label: "Advanced", icon: "fa-solid fa-gear" }
];
@@ -13,6 +14,10 @@
let cookiesUpdatedAt = null;
let loadingCookies = false;
let savingCookies = false;
let pornhubCookies = "";
let phCookiesUpdatedAt = null;
let loadingPhCookies = false;
let savingPhCookies = false;
let loadingYtSettings = false;
let savingYtSettings = false;
let selectedResolution = "1080p";
@@ -69,6 +74,54 @@
}
}
async function loadPornhubCookies() {
loadingPhCookies = true;
error = null;
success = null;
try {
const resp = await apiFetch("/api/pornhub/cookies");
if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
const data = await resp.json();
pornhubCookies = data?.cookies || "";
phCookiesUpdatedAt = data?.updatedAt || null;
} catch (err) {
error = err?.message || "Cookies alınamadı.";
} finally {
loadingPhCookies = false;
}
}
async function savePornhubCookies() {
if (savingPhCookies) return;
error = null;
success = null;
savingPhCookies = true;
try {
const payload = {
cookies: pornhubCookies
.split("\n")
.map((line) => line.trim())
.filter(Boolean)
.join("\n")
};
const resp = await apiFetch("/api/pornhub/cookies", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(payload)
});
const data = await resp.json().catch(() => ({}));
if (!resp.ok || !data?.ok) {
throw new Error(data?.error || `HTTP ${resp.status}`);
}
phCookiesUpdatedAt = data.updatedAt || Date.now();
success = "Cookies kaydedildi.";
} catch (err) {
error = err?.message || "Cookies kaydedilemedi.";
} finally {
savingPhCookies = false;
}
}
async function loadYoutubeSettings() {
loadingYtSettings = true;
error = null;
@@ -114,6 +167,7 @@
onMount(() => {
loadCookies();
loadYoutubeSettings();
loadPornhubCookies();
});
function formatDate(ts) {
@@ -221,6 +275,54 @@
</button>
</div>
{#if error}
<div class="alert error">
<i class="fa-solid fa-circle-exclamation"></i>
{error}
</div>
{/if}
{#if success}
<div class="alert success">
<i class="fa-solid fa-circle-check"></i>
{success}
</div>
{/if}
</div>
{:else if activeTab === "pornhub"}
<div class="card">
<div class="card-header">
<div class="title">
<i class="fa-solid fa-lock"></i>
<span>Pornhub Cookies</span>
</div>
{#if phCookiesUpdatedAt}
<div class="meta">Son güncelleme: {formatDate(phCookiesUpdatedAt)}</div>
{/if}
</div>
<div class="field">
<label for="ph-cookies">cookies.txt içeriği</label>
<textarea
id="ph-cookies"
spellcheck="false"
placeholder="Netscape HTTP Cookie formatında (cookies.txt) içerik girin"
bind:value={pornhubCookies}
></textarea>
<small>
Zararlı komut çalıştırılamaz; yalnızca düz metin cookie satırları yazılır.
Maksimum 20KB. Engellenen karakterler otomatik reddedilir.
</small>
</div>
<div class="actions">
<button class="btn" on:click={loadPornhubCookies} disabled={loadingPhCookies || savingPhCookies}>
<i class="fa-solid fa-rotate"></i> Yenile
</button>
<button class="btn primary" on:click={savePornhubCookies} disabled={loadingPhCookies || savingPhCookies}>
<i class="fa-solid fa-floppy-disk"></i> Kaydet
</button>
</div>
{#if error}
<div class="alert error">
<i class="fa-solid fa-circle-exclamation"></i>