minor fixes and style update
This commit is contained in:
parent
211089bead
commit
24493885aa
6 changed files with 119 additions and 18 deletions
40
API.md
40
API.md
|
|
@ -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.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
)
|
||||||
|
|
|
||||||
|
|
@ -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 }>()
|
||||||
|
|
|
||||||
|
|
@ -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',
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue