support preset in yt-dlp/url/info endpoint.
This commit is contained in:
parent
ebb7299053
commit
4f7da0b125
7 changed files with 97 additions and 49 deletions
|
|
@ -77,13 +77,14 @@ async def convert(request: Request) -> Response:
|
|||
|
||||
|
||||
@route("GET", "api/yt-dlp/url/info/", "get_info")
|
||||
async def get_info(request: Request, cache: Cache) -> Response:
|
||||
async def get_info(request: Request, cache: Cache, config: Config) -> Response:
|
||||
"""
|
||||
Get the video info.
|
||||
|
||||
Args:
|
||||
request (Request): The request object.
|
||||
cache (Cache): The cache instance.
|
||||
config (Config): The config instance.
|
||||
|
||||
Returns:
|
||||
Response: The response object
|
||||
|
|
@ -91,25 +92,27 @@ async def get_info(request: Request, cache: Cache) -> Response:
|
|||
"""
|
||||
url: str | None = request.query.get("url")
|
||||
if not url:
|
||||
return web.json_response(data={"error": "URL is required."}, status=web.HTTPBadRequest.status_code)
|
||||
return web.json_response(
|
||||
data={"status": False, "message": "URL is required.", "error": "URL is required."},
|
||||
status=web.HTTPBadRequest.status_code,
|
||||
)
|
||||
|
||||
try:
|
||||
validate_url(url)
|
||||
except ValueError as e:
|
||||
return web.json_response(data={"error": str(e)}, status=web.HTTPBadRequest.status_code)
|
||||
return web.json_response(
|
||||
data={"status": False, "message": str(e), "error": str(e)},
|
||||
status=web.HTTPBadRequest.status_code,
|
||||
)
|
||||
|
||||
config = Config.get_instance()
|
||||
|
||||
preset = request.query.get("preset")
|
||||
if preset:
|
||||
exists: Preset | None = Presets.get_instance().get(preset)
|
||||
if not exists:
|
||||
return web.json_response(
|
||||
data={"status": False, "message": f"Preset '{preset}' does not exist."},
|
||||
status=web.HTTPBadRequest.status_code,
|
||||
)
|
||||
else:
|
||||
preset: str = config.default_preset
|
||||
preset: str = request.query.get("preset", config.default_preset)
|
||||
exists: Preset | None = Presets.get_instance().get(preset)
|
||||
if not exists:
|
||||
msg: str = f"Preset '{preset}' does not exist."
|
||||
return web.json_response(
|
||||
data={"status": False, "message": msg, "error": msg},
|
||||
status=web.HTTPBadRequest.status_code,
|
||||
)
|
||||
|
||||
try:
|
||||
key: str = cache.hash(f"{preset}:{url}")
|
||||
|
|
@ -118,6 +121,7 @@ async def get_info(request: Request, cache: Cache) -> Response:
|
|||
data: Any | None = cache.get(key)
|
||||
data["_cached"] = {
|
||||
"status": "hit",
|
||||
"preset": preset,
|
||||
"key": key,
|
||||
"ttl": data.get("_cached", {}).get("ttl", 300),
|
||||
"ttl_left": data.get("_cached", {}).get("expires", time.time() + 300) - time.time(),
|
||||
|
|
@ -130,7 +134,7 @@ async def get_info(request: Request, cache: Cache) -> Response:
|
|||
if ytdlp_proxy := config.get_ytdlp_args().get("proxy", None):
|
||||
opts["proxy"] = ytdlp_proxy
|
||||
|
||||
ytdlp_opts = YTDLPOpts.get_instance().preset(name=preset).add(opts).get_all()
|
||||
ytdlp_opts: dict = YTDLPOpts.get_instance().preset(name=preset).add(opts).get_all()
|
||||
|
||||
data = extract_info(
|
||||
config=ytdlp_opts,
|
||||
|
|
@ -153,6 +157,7 @@ async def get_info(request: Request, cache: Cache) -> Response:
|
|||
|
||||
data["_cached"] = {
|
||||
"status": "miss",
|
||||
"preset": preset,
|
||||
"key": key,
|
||||
"ttl": 300,
|
||||
"ttl_left": 300,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div class="dropdown" :class="{ 'is-active': isOpen, 'drop-up': dropUp }" ref="dropdown">
|
||||
<div class="dropdown-trigger">
|
||||
<button class="button is-fullwidth is-justify-content-space-between" aria-haspopup="true"
|
||||
<button class="button is-fullwidth is-justify-content-space-between" aria-haspopup="true" type="button"
|
||||
aria-controls="dropdown-menu" @click="toggle" :class="button_classes">
|
||||
<span class="icon" v-if="icons"><i :class="icons" /></span>
|
||||
<span>{{ label }}</span>
|
||||
|
|
|
|||
|
|
@ -51,6 +51,11 @@ const props = defineProps({
|
|||
default: '',
|
||||
required: false,
|
||||
},
|
||||
preset: {
|
||||
type: String,
|
||||
default: '',
|
||||
required: false,
|
||||
},
|
||||
useUrl: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
|
|
@ -73,7 +78,16 @@ const handle_event = (e: KeyboardEvent) => {
|
|||
onMounted(async () => {
|
||||
document.addEventListener('keydown', handle_event)
|
||||
|
||||
const url = props.useUrl ? props.link : '/api/yt-dlp/url/info?url=' + encodePath(props.link)
|
||||
let url = props.useUrl ? props.link : '/api/yt-dlp/url/info';
|
||||
|
||||
if (!props.useUrl) {
|
||||
let params = new URLSearchParams();
|
||||
if (props.preset) {
|
||||
params.append('preset', props.preset);
|
||||
}
|
||||
params.append('url', props.link);
|
||||
url += '?' + params.toString();
|
||||
}
|
||||
|
||||
try {
|
||||
isLoading.value = true
|
||||
|
|
|
|||
|
|
@ -188,7 +188,7 @@
|
|||
</NuxtLink>
|
||||
<hr class="dropdown-divider" />
|
||||
</template>
|
||||
<NuxtLink class="dropdown-item" @click="emitter('getInfo', item.url)">
|
||||
<NuxtLink class="dropdown-item" @click="emitter('getInfo', item.url, item.preset)">
|
||||
<span class="icon"><i class="fa-solid fa-info" /></span>
|
||||
<span>yt-dlp Information</span>
|
||||
</NuxtLink>
|
||||
|
|
@ -357,7 +357,8 @@
|
|||
<hr class="dropdown-divider" />
|
||||
</template>
|
||||
|
||||
<NuxtLink class="dropdown-item" @click="emitter('getInfo', item.url)" v-if="!config.app.basic_mode">
|
||||
<NuxtLink class="dropdown-item" @click="emitter('getInfo', item.url, item.preset)"
|
||||
v-if="!config.app.basic_mode">
|
||||
<span class="icon"><i class="fa-solid fa-info" /></span>
|
||||
<span>yt-dlp Information</span>
|
||||
</NuxtLink>
|
||||
|
|
|
|||
|
|
@ -172,11 +172,29 @@
|
|||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column is-12">
|
||||
<div class="field is-grouped is-justify-self-end">
|
||||
<div class="column is-12 is-hidden-tablet">
|
||||
<Dropdown icons="fa-solid fa-cogs" label="Actions">
|
||||
<NuxtLink class="dropdown-item" @click="emitter('getInfo', form.url, form.preset)">
|
||||
<span class="icon has-text-info"><i class="fa-solid fa-info" /></span>
|
||||
<span>yt-dlp Information</span>
|
||||
</NuxtLink>
|
||||
|
||||
<NuxtLink class="dropdown-item" @click="removeFromArchive(form.url)">
|
||||
<span class="icon has-text-warning"><i class="fa-solid fa-box-archive" /></span>
|
||||
<span>Remove from archive</span>
|
||||
</NuxtLink>
|
||||
|
||||
<hr class="dropdown-divider" />
|
||||
<NuxtLink class="dropdown-item" @click="resetConfig">
|
||||
<span class="icon has-text-danger"><i class="fa-solid fa-rotate-left" /></span>
|
||||
<span>Reset local settings</span>
|
||||
</NuxtLink>
|
||||
</Dropdown>
|
||||
</div>
|
||||
<div class="column is-12">
|
||||
<div class="field is-grouped is-justify-self-end is-hidden-mobile">
|
||||
<div class="control">
|
||||
<button type="button" class="button is-info" @click="emitter('getInfo', form.url)"
|
||||
<button type="button" class="button is-info" @click="emitter('getInfo', form.url, form.preset)"
|
||||
:class="{ 'is-loading': !socket.isConnected }"
|
||||
:disabled="!socket.isConnected || addInProgress || !form?.url">
|
||||
<span class="icon"><i class="fa-solid fa-info" /></span>
|
||||
|
|
@ -200,6 +218,7 @@
|
|||
<span>Reset</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -120,18 +120,19 @@
|
|||
<span>Cancel Item</span>
|
||||
</NuxtLink>
|
||||
|
||||
<hr class="dropdown-divider" v-if="!config.app.basic_mode" />
|
||||
<template v-if="!config.app.basic_mode">
|
||||
<hr class="dropdown-divider" />
|
||||
|
||||
<NuxtLink class="dropdown-item" @click="emitter('getInfo', item.url)" v-if="!config.app.basic_mode">
|
||||
<span class="icon"><i class="fa-solid fa-info" /></span>
|
||||
<span>yt-dlp Information</span>
|
||||
</NuxtLink>
|
||||
<NuxtLink class="dropdown-item" @click="emitter('getInfo', item.url, item.preset)">
|
||||
<span class="icon"><i class="fa-solid fa-info" /></span>
|
||||
<span>yt-dlp Information</span>
|
||||
</NuxtLink>
|
||||
|
||||
<NuxtLink class="dropdown-item" @click="emitter('getItemInfo', item._id)"
|
||||
v-if="!config.app.basic_mode">
|
||||
<span class="icon"><i class="fa-solid fa-info-circle" /></span>
|
||||
<span>Local Information</span>
|
||||
</NuxtLink>
|
||||
<NuxtLink class="dropdown-item" @click="emitter('getItemInfo', item._id)">
|
||||
<span class="icon"><i class="fa-solid fa-info-circle" /></span>
|
||||
<span>Local Information</span>
|
||||
</NuxtLink>
|
||||
</template>
|
||||
</Dropdown>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
@ -227,10 +228,11 @@
|
|||
<span class="icon"><i class="fa-solid fa-play" /></span>
|
||||
<span>Play video</span>
|
||||
</NuxtLink>
|
||||
<hr class="dropdown-divider" />
|
||||
<hr class="dropdown-divider" v-if="!config.app.basic_mode"/>
|
||||
</template>
|
||||
|
||||
<NuxtLink class="dropdown-item" @click="emitter('getInfo', item.url)" v-if="!config.app.basic_mode">
|
||||
<NuxtLink class="dropdown-item" @click="emitter('getInfo', item.url, item.preset)"
|
||||
v-if="!config.app.basic_mode">
|
||||
<span class="icon"><i class="fa-solid fa-info" /></span>
|
||||
<span>yt-dlp Information</span>
|
||||
</NuxtLink>
|
||||
|
|
|
|||
|
|
@ -60,14 +60,16 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<NewDownload v-if="config.showForm || config.app.basic_mode" @getInfo="url => get_info = url" :item="item_form"
|
||||
<NewDownload v-if="config.showForm || config.app.basic_mode"
|
||||
@getInfo="(url: string, preset: string = '') => view_info(url, false, preset)" :item="item_form"
|
||||
@clear_form="item_form = {}" @remove_archive="" />
|
||||
<Queue @getInfo="(url: string) => view_info(url, false)" :thumbnails="show_thumbnail" :query="query"
|
||||
<Queue @getInfo="(url: string, preset: string = '') => view_info(url, false, preset)" :thumbnails="show_thumbnail"
|
||||
:query="query" @getItemInfo="(id: string) => view_info(`/api/history/${id}`, true)" @clear_search="query = ''" />
|
||||
<History @getInfo="(url: string, preset: string = '') => view_info(url, false, preset)"
|
||||
@add_new="item => toNewDownload(item)" :query="query" :thumbnails="show_thumbnail"
|
||||
@getItemInfo="(id: string) => view_info(`/api/history/${id}`, true)" @clear_search="query = ''" />
|
||||
<History @getInfo="(url: string) => view_info(url, false)" @add_new="item => toNewDownload(item)" :query="query"
|
||||
:thumbnails="show_thumbnail" @getItemInfo="(id: string) => view_info(`/api/history/${id}`, true)"
|
||||
@clear_search="query = ''" />
|
||||
<GetInfo v-if="get_info" :link="get_info" :useUrl="get_info_use_url" @closeModel="close_info()" />
|
||||
<GetInfo v-if="info_view.url" :link="info_view.url" :preset="info_view.preset" :useUrl="info_view.useUrl"
|
||||
@closeModel="close_info()" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
@ -83,8 +85,11 @@ const bg_opacity = useStorage<number>('random_bg_opacity', 0.85)
|
|||
const display_style = useStorage<string>('display_style', 'cards')
|
||||
const show_thumbnail = useStorage<boolean>('show_thumbnail', true)
|
||||
|
||||
const get_info = ref<string>('')
|
||||
const get_info_use_url = ref<boolean>(false)
|
||||
const info_view = ref({
|
||||
url: '',
|
||||
preset: '',
|
||||
useUrl: false,
|
||||
}) as Ref<{ url: string, preset: string, useUrl: boolean }>
|
||||
const item_form = ref({})
|
||||
const query = ref()
|
||||
const toggleFilter = ref(false)
|
||||
|
|
@ -126,16 +131,18 @@ const pauseDownload = () => {
|
|||
}
|
||||
|
||||
const close_info = () => {
|
||||
get_info.value = ''
|
||||
get_info_use_url.value = false
|
||||
info_view.value.url = ''
|
||||
info_view.value.preset = ''
|
||||
info_view.value.useUrl = false
|
||||
}
|
||||
|
||||
const view_info = (url: string, useUrl: boolean = false) => {
|
||||
get_info.value = url
|
||||
get_info_use_url.value = useUrl
|
||||
const view_info = (url: string, useUrl: boolean = false, preset: string = '') => {
|
||||
info_view.value.url = url
|
||||
info_view.value.useUrl = useUrl
|
||||
info_view.value.preset = preset
|
||||
}
|
||||
|
||||
watch(get_info, v => {
|
||||
watch(() => info_view.value.url, v => {
|
||||
if (!bg_enable.value) {
|
||||
return
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue