update newDownload template

This commit is contained in:
arabcoders 2025-04-01 20:34:14 +03:00
parent fa9c084397
commit 4730583510
5 changed files with 62 additions and 30 deletions

View file

@ -21,7 +21,7 @@ from .Events import EventBus, Events
from .ItemDTO import ItemDTO from .ItemDTO import ItemDTO
from .Presets import Presets from .Presets import Presets
from .Singleton import Singleton from .Singleton import Singleton
from .Utils import arg_converter, calc_download_path, extract_info, is_downloaded from .Utils import arg_converter, calc_download_path, extract_info, is_downloaded, strip_newline
from .YTDLPOpts import YTDLPOpts from .YTDLPOpts import YTDLPOpts
LOG = logging.getLogger("DownloadQueue") LOG = logging.getLogger("DownloadQueue")
@ -421,7 +421,7 @@ class DownloadQueue(metaclass=Singleton):
cookie_file = os.path.join(self.config.temp_path, f"c_{uuid.uuid4().hex}.txt") cookie_file = os.path.join(self.config.temp_path, f"c_{uuid.uuid4().hex}.txt")
LOG.info( LOG.info(
f"Adding 'URL: {url}' to 'Folder: {filePath}' with 'Preset: {preset}' 'Naming: {template}', 'Cookies: {len(cookies)}/chars' 'CLI: {cli}' 'Extras: {extras}'." f"Adding 'URL: {url}' to 'Folder: {filePath}' with 'Preset: {preset}' 'Naming: {template}', 'Cookies: {len(cookies)}/chars' 'CLI: {strip_newline(cli)}' 'Extras: {extras}'."
) )
if isinstance(config, str): if isinstance(config, str):

View file

@ -475,7 +475,8 @@ class HttpAPI(Common):
err = err.split("\n")[-1] if "\n" in err else err err = err.split("\n")[-1] if "\n" in err else err
err = err.replace("main.py: error: ", "").strip().capitalize() err = err.replace("main.py: error: ", "").strip().capitalize()
return web.json_response( return web.json_response(
data={"error": f"Failed to command line arguments for yt-dlp. '{err}'."}, status=web.HTTPBadRequest.status_code data={"error": f"Failed to parse command arguments for yt-dlp. '{err}'."},
status=web.HTTPBadRequest.status_code,
) )
@route("GET", "api/yt-dlp/url/info") @route("GET", "api/yt-dlp/url/info")

View file

@ -925,3 +925,22 @@ def clean_item(item: dict, keys: list | tuple) -> tuple[dict, bool]:
item.pop(key) item.pop(key)
return item, status return item, status
def strip_newline(string: str) -> str:
"""
Remove newlines from a string.
Args:
string (str): The string to process.
Returns:
str: The string without newlines.
"""
if not string:
return ""
res = re.sub(r"(\r\n|\r|\n)", " ", string)
return res.strip() if res else ""

View file

@ -5,31 +5,39 @@
<div class="box"> <div class="box">
<div class="columns is-multiline is-mobile"> <div class="columns is-multiline is-mobile">
<div class="column is-12"> <div class="column is-12">
<div class="control has-icons-left"> <label class="label is-inline is-unselectable" for="url">
<span class="icon"><i class="fa-solid fa-link" /></span>
URLs
</label>
<div class="control">
<input type="text" class="input" id="url" placeholder="Video or playlist link" <input type="text" class="input" id="url" placeholder="Video or playlist link"
:disabled="!socket.isConnected || addInProgress" v-model="url"> :disabled="!socket.isConnected || addInProgress" v-model="url">
<span class="icon is-small is-left">
<i class="fa-solid fa-link" />
</span>
</div> </div>
<span class="help">
<span class="icon"><i class="fa-solid fa-info" /></span>
<span>You can add multiple URLs separated by a comma <code>,</code>.</span>
</span>
</div> </div>
<div class="column is-4-tablet is-12-mobile" v-if="!config.app.basic_mode"> <div class="column is-4-tablet is-12-mobile" v-if="!config.app.basic_mode">
<div class="field has-addons"> <div class="field has-addons">
<div class="control"> <div class="control">
<a href="#" class="button is-static">Preset</a> <a href="#" class="button is-static">
<span class="icon"><i class="fa-solid fa-sliders" /></span>
<span>Preset</span>
</a>
</div> </div>
<div class="control is-expanded"> <div class="control is-expanded">
<div class="select is-fullwidth"> <div class="select is-fullwidth">
<select id="preset" class="is-fullwidth" <select id="preset" class="is-fullwidth"
:disabled="!socket.isConnected || addInProgress || hasFormatInConfig" v-model="selectedPreset" :disabled="!socket.isConnected || addInProgress || hasFormatInConfig" v-model="selectedPreset"
v-tooltip.bottom="hasFormatInConfig ? 'Presets are disabled. Format key is present in the Command arguments for yt-dlp.' : ''"> v-tooltip.bottom="hasFormatInConfig ? 'Presets are disabled. Format key is present in the Command arguments for yt-dlp.' : ''">
<optgroup label="Default presets"> <optgroup label="Custom presets" v-if="config?.presets.filter(p => !p?.default).length > 0">
<option v-for="item in filter_presets(true)" :key="item.name" :value="item.name"> <option v-for="item in filter_presets(false)" :key="item.name" :value="item.name">
{{ item.name }} {{ item.name }}
</option> </option>
</optgroup> </optgroup>
<optgroup label="Custom presets" v-if="config?.presets.filter(p => !p?.default).length > 0"> <optgroup label="Default presets">
<option v-for="item in filter_presets(false)" :key="item.name" :value="item.name"> <option v-for="item in filter_presets(true)" :key="item.name" :value="item.name">
{{ item.name }} {{ item.name }}
</option> </option>
</optgroup> </optgroup>
@ -41,7 +49,10 @@
<div class="column is-6-tablet is-12-mobile" v-if="!config.app.basic_mode"> <div class="column is-6-tablet is-12-mobile" v-if="!config.app.basic_mode">
<div class="field has-addons" v-tooltip="'Folder relative to ' + config.app.download_path"> <div class="field has-addons" v-tooltip="'Folder relative to ' + config.app.download_path">
<div class="control"> <div class="control">
<a href="#" class="button is-static">Save in</a> <a href="#" class="button is-static">
<span class="icon"><i class="fa-solid fa-folder" /></span>
<span>Save in</span>
</a>
</div> </div>
<div class="control is-expanded"> <div class="control is-expanded">
<input type="text" class="input is-fullwidth" id="path" v-model="downloadPath" placeholder="Default" <input type="text" class="input is-fullwidth" id="path" v-model="downloadPath" placeholder="Default"
@ -67,17 +78,17 @@
</div> </div>
<div class="columns is-multiline is-mobile" v-if="showAdvanced && !config.app.basic_mode"> <div class="columns is-multiline is-mobile" v-if="showAdvanced && !config.app.basic_mode">
<div class="column is-6-tablet is-12-mobile"> <div class="column is-12">
<div class="field"> <div class="field">
<label class="label is-inline" for="output_format" <label class="label is-inline is-unselectable" for="output_format"
v-tooltip="'Default Format: ' + config.app.output_template"> v-tooltip="'Default: ' + config.app.output_template">
<span class="icon"><i class="fa-solid fa-file" /></span>
Output Template Output Template
</label> </label>
<div class="control has-icons-left"> <div class="control">
<input type="text" class="input" v-model="output_template" id="output_format" <input type="text" class="input" v-model="output_template" id="output_format"
:disabled="!socket.isConnected || addInProgress" :disabled="!socket.isConnected || addInProgress"
placeholder="Uses default output template naming if empty."> placeholder="Uses default output template naming if empty.">
<span class="icon is-small is-left"><i class="fa-solid fa-file" /></span>
</div> </div>
<span class="help"> <span class="help">
<span class="icon"><i class="fa-solid fa-info" /></span> <span class="icon"><i class="fa-solid fa-info" /></span>
@ -87,16 +98,16 @@
</div> </div>
</div> </div>
<div class="column is-6-tablet is-12-mobile"> <div class="column is-6-tablet is-4-mobile">
<div class="field"> <div class="field">
<label class="label is-inline" for="cli_options"> <label class="label is-inline is-unselectable" for="cli_options">
<span class="icon"><i class="fa-solid fa-terminal" /></span>
Command arguments for yt-dlp Command arguments for yt-dlp
</label> </label>
<div class="control has-icons-left"> <div class="control">
<input type="text" class="input" v-model="ytdlp_cli" id="cli_options" <textarea class="textarea is-pre" v-model="ytdlp_cli" id="cli_options"
:disabled="!socket.isConnected || addInProgress" :disabled="!socket.isConnected || addInProgress"
placeholder="command options to use, e.g. --no-embed-metadata --no-embed-thumbnail"> placeholder="command options to use, e.g. --no-embed-metadata --no-embed-thumbnail" />
<span class="icon is-small is-left"><i class="fa-solid fa-terminal" /></span>
</div> </div>
<span class="help"> <span class="help">
@ -110,9 +121,10 @@
</div> </div>
</div> </div>
<div class="column is-12"> <div class="column is-6-tablet is-4-mobile">
<div class="field"> <div class="field">
<label class="label is-inline" for="ytdlpCookies" v-tooltip="'Netscape HTTP Cookie format'"> <label class="label is-inline is-unselectable" for="ytdlpCookies">
<span class="icon"><i class="fa-solid fa-cookie" /></span>
Cookies Cookies
</label> </label>
<div class="control"> <div class="control">
@ -206,8 +218,9 @@ const resetConfig = () => {
return return
} }
selectedPreset.value = config.app.default_preset.value selectedPreset.value = config.app.default_preset
ytdlpCookies.value = '' ytdlpCookies.value = ''
ytdlp_cli.value = ''
output_template.value = null output_template.value = null
url.value = null url.value = null
downloadPath.value = null downloadPath.value = null
@ -277,9 +290,8 @@ const hasFormatInConfig = computed(() => {
return false return false
} }
return /(?<!\w)(-f|--format)(=|:)?(?!\w)/.test(ytdlp_cli.value) return /(?<!\S)(-f|--format)(=|\s)(\S+)/.test(ytdlp_cli.value)
}) })
const filter_presets = (flag = true) => config.presets.filter(item => item.default === flag) const filter_presets = (flag = true) => config.presets.filter(item => item.default === flag)
</script> </script>

View file

@ -389,7 +389,7 @@ const hasFormatInConfig = computed(() => {
return false return false
} }
return /(?<!\w)(-f|--format)(=|:)?(?!\w)/.test(form.cli) return /(?<!\S)(-f|--format)(=|\s)(\S+)/.test(form.cli)
}) })
const filter_presets = (flag = true) => config.presets.filter(item => item.default === flag) const filter_presets = (flag = true) => config.presets.filter(item => item.default === flag)