we no longer use json cookies, instead rely on netescape cookies and recommend what yt-dlp recommend as well.

This commit is contained in:
ArabCoders 2025-02-27 00:39:18 +03:00
parent 1934815a41
commit 96260301be
6 changed files with 56 additions and 42 deletions

View file

@ -1,6 +1,5 @@
import asyncio
import hashlib
import json
import logging
import multiprocessing
import os
@ -15,7 +14,7 @@ from .config import Config
from .Emitter import Emitter
from .ffprobe import ffprobe
from .ItemDTO import ItemDTO
from .Utils import get_opts, json_cookie, merge_config
from .Utils import get_opts, merge_config
LOG = logging.getLogger("download")
@ -138,17 +137,11 @@ class Download:
if self.info.cookies:
try:
data = json_cookie(json.loads(self.info.cookies))
if not data:
LOG.warning(
f"The cookie string that was provided for {self.info.title} is empty or not in expected spec."
)
with open(os.path.join(self.temp_path, f"cookie_{self.info._id}.txt"), "w") as f:
f.write(data)
params["cookiefile"] = f.name
f.write(self.info.cookies)
params["cookiefile"] = f.name
except ValueError as e:
LOG.error(f"Invalid cookies: was provided for '{self.info.title}'. '{e!s}'.")
LOG.error(f"Failed to create cookie file for '{self.info.id}: {self.info.title}'. '{e!s}'.")
if self.is_live or self.is_manifestless:
hasDeletedOptions = False

View file

@ -3,10 +3,12 @@ import json
import logging
import os
import time
import uuid
from datetime import UTC, datetime
from email.utils import formatdate
from sqlite3 import Connection
import anyio
import yt_dlp
from aiohttp import web
@ -354,9 +356,11 @@ class DownloadQueue(metaclass=Singleton):
folder = str(folder) if folder else ""
filePath = calc_download_path(base_path=self.config.download_path, folder=folder)
yt_conf = {}
cookie_file = os.path.join(self.config.temp_path, f"c_{uuid.uuid4().hex}.txt")
LOG.info(
f"Adding 'URL: {url}' to 'Folder: {filePath}' with 'Preset: {preset}' 'Naming: {template}', 'Cookies: {cookies}' 'YTConfig: {config}'."
f"Adding 'URL: {url}' to 'Folder: {filePath}' with 'Preset: {preset}' 'Naming: {template}', 'Cookies: {len(cookies)}/chars' 'YTConfig: {config}'."
)
if isinstance(config, str):
@ -384,19 +388,33 @@ class DownloadQueue(metaclass=Singleton):
started = time.perf_counter()
LOG.debug(f"extract_info: checking {url=}")
logs = []
yt_conf = {
"callback": {
"func": lambda _, msg: logs.append(msg),
"level": logging.WARNING,
},
**merge_config(self.config.ytdl_options, config),
}
if cookies:
try:
async with await anyio.open_file(cookie_file, "w") as f:
await f.write(cookies)
yt_conf["cookiefile"] = f.name
except ValueError as e:
LOG.error(f"Failed to create cookie file for '{self.info.id}: {self.info.title}'. '{e!s}'.")
entry = await asyncio.wait_for(
fut=asyncio.get_running_loop().run_in_executor(
None,
extract_info,
get_opts(preset, merge_config(self.config.ytdl_options, config)),
url,
bool(self.config.ytdl_debug),
None, extract_info, get_opts(preset, yt_conf), url, bool(self.config.ytdl_debug)
),
timeout=self.config.extract_info_timeout,
)
if not entry:
return {"status": "error", "msg": "Unable to extract info check logs."}
return {"status": "error", "msg": "Unable to extract info." + "\n".join(logs)}
LOG.debug(
f"extract_info: for 'URL: {url}' is done in '{time.perf_counter() - started}'. Length: '{len(entry)}'."
@ -413,6 +431,13 @@ class DownloadQueue(metaclass=Singleton):
"status": "error",
"msg": f"TimeoutError: {self.config.extract_info_timeout}s reached Unable to extract info.",
}
finally:
if cookie_file and os.path.exists(cookie_file):
try:
os.remove(yt_conf["cookiefile"])
del yt_conf["cookiefile"]
except Exception as e:
LOG.error(f"Failed to remove cookie file '{yt_conf['cookiefile']}'. {e!s}")
return await self.__add_entry(
entry=entry,

View file

@ -17,7 +17,7 @@ from .encoder import Encoder
from .EventsSubscriber import Event, Events, EventsSubscriber
from .Singleton import Singleton
LOG = logging.getLogger("notifications")
LOG = logging.getLogger("tasks")
@dataclass(kw_only=True)

View file

@ -100,7 +100,7 @@
</div>
<div class="column is-6-tablet is-12-mobile">
<div class="field">
<label class="label is-inline" for="ytdlpCookies" v-tooltip="'JSON exported cookies for downloading.'">
<label class="label is-inline" for="ytdlpCookies" v-tooltip="'Netscape HTTP Cookie format'">
Cookies
</label>
<div class="control">
@ -109,8 +109,10 @@
</div>
<span class="help">
<span class="icon"><i class="fa-solid fa-info" /></span>
<span>Use <NuxtLink target="_blank" to="https://github.com/jrie/flagCookies">
flagCookies</NuxtLink> to extract cookies as JSON string.</span>
<span>Use the <NuxtLink target="_blank"
to="https://github.com/yt-dlp/yt-dlp/wiki/FAQ#how-do-i-pass-cookies-to-yt-dlp">
Recommended addon</NuxtLink> by yt-dlp to export cookies. The cookies MUST be in Netscape HTTP
Cookie format.</span>
</span>
</div>
</div>

View file

@ -127,7 +127,8 @@
<div class="column is-6-tablet is-12-mobile">
<div class="field">
<label class="label is-inline" for="config" v-tooltip="'Extends current global yt-dlp config. (JSON)'">
JSON yt-dlp config or CLI options. <NuxtLink v-if="form.config && !form.config.trim().startsWith('{')"
JSON yt-dlp config or CLI options. <NuxtLink
v-if="form.config && (typeof form.config === 'string') && !form.config.trim().startsWith('{')"
@click="convertOptions()">Convert to JSON</NuxtLink>
</label>
<div class="control">
@ -145,17 +146,16 @@
<div class="column is-6-tablet is-12-mobile">
<div class="field">
<label class="label is-inline" for="cookies" v-tooltip="'JSON exported cookies for downloading.'">
JSON Cookies
</label>
<label class="label is-inline" for="cookies" v-tooltip="'Netscape HTTP Cookie format.'">Cookies</label>
<div class="control">
<textarea class="textarea" id="cookies" v-model="form.cookies" :disabled="addInProgress"></textarea>
</div>
<span class="help">
<span class="icon"><i class="fa-solid fa-info" /></span>
<span>Use <NuxtLink target="_blank" to="https://github.com/jrie/flagCookies">flagCookies</NuxtLink> to
extract cookies as JSON string.
</span>
<span>Use the <NuxtLink target="_blank"
to="https://github.com/yt-dlp/yt-dlp/wiki/FAQ#how-do-i-pass-cookies-to-yt-dlp">
Recommended addon</NuxtLink> by yt-dlp to export cookies. The cookies MUST be in Netscape HTTP
Cookie format.</span>
</span>
</div>
</div>
@ -217,7 +217,6 @@ const props = defineProps({
const form = reactive(props.task);
onMounted(() => {
if (props.task?.config && (typeof props.task.config === 'object')) {
form.config = JSON.stringify(props.task.config, null, 4);
}
@ -252,7 +251,11 @@ const checkInfo = async () => {
return;
}
if (form.config && !form.config.trim().startsWith('{')) {
if (typeof form.config === 'object') {
form.config = JSON.stringify(form.config, null, 4);
}
if (form.config && form.config && !form.config.trim().startsWith('{')) {
await convertOptions();
}
@ -265,15 +268,6 @@ const checkInfo = async () => {
}
}
if (form.cookies) {
try {
JSON.parse(form.cookies);
} catch (e) {
toast.error(`Invalid JSON yt-dlp cookies. ${e.message}`)
return;
}
}
emitter('submit', { reference: toRaw(props.reference), task: toRaw(form) });
}

View file

@ -269,10 +269,10 @@ const editItem = item => {
}
const calcPath = path => {
let loc = config.app.download_path
const loc = config.app.download_path || '/downloads'
if (path) {
let loc = loc + '/' + sTrim(path, '/')
return loc + '/' + sTrim(path, '/')
}
return loc