minor fixes and style update

This commit is contained in:
arabcoders 2025-10-26 21:42:48 +03:00
parent 211089bead
commit 24493885aa
6 changed files with 119 additions and 18 deletions

40
API.md
View file

@ -64,6 +64,7 @@ This document describes the available endpoints and their usage. All endpoints r
- [GET /api/notifications](#get-apinotifications) - [GET /api/notifications](#get-apinotifications)
- [PUT /api/notifications](#put-apinotifications) - [PUT /api/notifications](#put-apinotifications)
- [POST /api/yt-dlp/archive\_id/](#post-apiyt-dlparchive_id) - [POST /api/yt-dlp/archive\_id/](#post-apiyt-dlparchive_id)
- [POST /api/yt-dlp/save\_cookies/](#post-apiyt-dlpsave_cookies)
- [POST /api/notifications/test](#post-apinotificationstest) - [POST /api/notifications/test](#post-apinotificationstest)
- [GET /api/yt-dlp/options](#get-apiyt-dlpoptions) - [GET /api/yt-dlp/options](#get-apiyt-dlpoptions)
- [POST /api/system/pause](#post-apisystempause) - [POST /api/system/pause](#post-apisystempause)
@ -1449,6 +1450,45 @@ or an error:
--- ---
### POST /api/yt-dlp/save_cookies/
**Purpose**: Save cookies to a file for use with yt-dlp CLI operations. Requires console to be enabled (`console_enabled` in configuration).
**Body**: JSON object with `cookies` field containing the cookie string.
```json
{
"cookies": "cookie_string_or_netscape_format"
}
```
**Response on Success**:
```json
{
"status": true,
"cookie_file": "/path/to/temp/c_uuid.txt"
}
```
**Response on Error**:
```json
{
"error": "error_message"
}
```
**Status Codes**:
- `200 OK` if cookies were successfully saved.
- `400 Bad Request` if the request body is invalid or missing the `cookies` field.
- `403 Forbidden` if console is disabled.
- `413 Payload Too Large` if cookies exceed 1MB.
- `500 Internal Server Error` if cookie file creation fails.
**Notes**:
- Console must be enabled in configuration (`console_enabled: true`).
- Cookies must be a valid string (≤ 1MB).
- Cookies are stored in the temporary directory with a UUID-based filename.
- Cookie files can be used with subsequent yt-dlp operations.
---
### POST /api/notifications/test ### POST /api/notifications/test
**Purpose**: Triggers a test notification event to all configured targets. **Purpose**: Triggers a test notification event to all configured targets.

View file

@ -21,7 +21,7 @@ from yt_dlp.utils import age_restricted
from .LogWrapper import LogWrapper from .LogWrapper import LogWrapper
from .mini_filter import match_str from .mini_filter import match_str
from .ytdlp import YTDLP from .ytdlp import YTDLP, make_archive_id
LOG: logging.Logger = logging.getLogger("Utils") LOG: logging.Logger = logging.getLogger("Utils")
@ -1242,21 +1242,21 @@ def get_archive_id(url: str) -> dict[str, str | None]:
} }
) )
for key, ie in YTDLP_INFO_CLS._ies.items(): for key, _ie in YTDLP_INFO_CLS._ies.items():
try: try:
if not ie.suitable(url): if not _ie.suitable(url):
continue continue
if not ie.working(): if not _ie.working():
break continue
temp_id = ie.get_temp_id(url) temp_id = _ie.get_temp_id(url)
if not temp_id: if not temp_id:
break continue
idDict["id"] = temp_id idDict["id"] = temp_id
idDict["ie_key"] = key idDict["ie_key"] = key
idDict["archive_id"] = YTDLP_INFO_CLS._make_archive_id(idDict) idDict["archive_id"] = make_archive_id(_ie, temp_id)
break break
except Exception as e: except Exception as e:
LOG.exception(e) LOG.exception(e)

View file

@ -1,8 +1,10 @@
# flake8: noqa: F401
from typing import Any from typing import Any
import yt_dlp import yt_dlp
from yt_dlp.utils import make_archive_id
import app.postprocessors # noqa: F401 import app.postprocessors
class _ArchiveProxy: class _ArchiveProxy:

View file

@ -2,6 +2,7 @@ import json
import logging import logging
import time import time
from collections import OrderedDict from collections import OrderedDict
from pathlib import Path
from typing import Any from typing import Any
from aiohttp import web from aiohttp import web
@ -272,3 +273,60 @@ async def get_archive_ids(request: Request, config: Config) -> Response:
response.append(dct) response.append(dct)
return web.json_response(data=response, status=web.HTTPOk.status_code) return web.json_response(data=response, status=web.HTTPOk.status_code)
@route("POST", "api/yt-dlp/save_cookies/", "save_cookies")
async def save_cookies(request: Request, config: Config) -> Response:
"""
Save cookies for use with CLI.
Returns:
Response: The response object with the yt-dlp CLI options.
"""
if not config.console_enabled:
return web.json_response(
data={"error": "Console is disabled."},
status=web.HTTPForbidden.status_code,
)
data = (await request.json()) if request.body_exists else None
if not data or not isinstance(data, dict):
return web.json_response(
data={"error": "Invalid request. expecting dict with 'cookies' field."},
status=web.HTTPBadRequest.status_code,
)
cookies = data.get("cookies")
if not cookies or not isinstance(cookies, str):
return web.json_response(
data={"error": "Invalid request. 'cookies' field is required and must be a string."},
status=web.HTTPBadRequest.status_code,
)
if len(cookies) > 1_000_000:
return web.json_response(
data={"error": "Cookie size exceeds the maximum limit of 1MB."},
status=web.HTTPBadRequest.status_code,
)
import uuid
from app.library.Utils import load_cookies
cookie_file: Path = Path(config.temp_path) / f"c_{uuid.uuid4()!s}.txt"
try:
cookie_file.write_text(cookies)
file_path = str(cookie_file)
load_cookies(cookie_file)
except Exception as e:
return web.json_response(
data={"error": f"Failed to create cookie file. '{e!s}'."},
status=web.HTTPInternalServerError.status_code,
)
return web.json_response(
data={"status": True, "cookie_file": file_path},
status=web.HTTPOk.status_code,
)

View file

@ -1,15 +1,16 @@
<template> <template>
<Message message_class="p-2 m-2 is-success has-background-warning-90 has-text-dark" v-if="status === 'disconnected'"> <div class="message is-warning" v-if="status === 'disconnected'">
<span class="icon"><i class="fas fa-info-circle" /></span> <div class="message-body">
<span> <span class="icon"><i class="fas fa-info-circle" /></span>
Connection lost, <NuxtLink class="is-bold" @click.prevent="() => $emit('reconnect')">Click here</NuxtLink> <span>
to reconnect. Connection lost, <NuxtLink class="is-bold" @click.prevent="() => $emit('reconnect')">Click here</NuxtLink>
</span> to reconnect.
</Message> </span>
</div>
</div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import Message from '~/components/Message.vue'
import type { connectionStatus } from '~/stores/SocketStore' import type { connectionStatus } from '~/stores/SocketStore'
defineProps<{ 'status': connectionStatus }>() defineProps<{ 'status': connectionStatus }>()
defineEmits<{ (e: "reconnect"): void }>() defineEmits<{ (e: "reconnect"): void }>()

View file

@ -25,7 +25,7 @@ export default withNuxt(
'vue/script-setup-uses-vars': 'off', 'vue/script-setup-uses-vars': 'off',
'vue/html-quotes': ['warn', 'double'], 'vue/html-quotes': ['warn', 'double'],
'vue/mustache-interpolation-spacing': ['warn', 'always'], 'vue/mustache-interpolation-spacing': "off",
'vue/v-bind-style': ['warn', 'shorthand'], 'vue/v-bind-style': ['warn', 'shorthand'],
'vue/v-on-style': ['warn', 'shorthand'], 'vue/v-on-style': ['warn', 'shorthand'],
'vue/attributes-order': 'off', 'vue/attributes-order': 'off',