Merge pull request #481 from arabcoders/dev
Strip out comment lines when creating yt-dlp command
This commit is contained in:
commit
d1a20b3972
6 changed files with 103 additions and 16 deletions
|
|
@ -262,8 +262,8 @@ class HttpAPI:
|
||||||
|
|
||||||
response: Response = await handler(request)
|
response: Response = await handler(request)
|
||||||
|
|
||||||
contentType: str | None = response.headers.get("content-type", None)
|
contentType: str = response.headers.get("content-type", "")
|
||||||
if contentType and contentType.startswith("text/html"):
|
if contentType.startswith("text/html") and getattr(response, "_path", None):
|
||||||
rewrite_path: str = base_path.rstrip("/")
|
rewrite_path: str = base_path.rstrip("/")
|
||||||
async with await anyio.open_file(response._path, "rb") as f:
|
async with await anyio.open_file(response._path, "rb") as f:
|
||||||
content = await f.read()
|
content = await f.read()
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,11 @@ class ARGSMerger:
|
||||||
if not args or not isinstance(args, str) or len(args) < 2:
|
if not args or not isinstance(args, str) or len(args) < 2:
|
||||||
return self
|
return self
|
||||||
|
|
||||||
_args: list[str] = shlex.split(args)
|
_args: list[str] = shlex.split(
|
||||||
|
# Filter out comment lines.
|
||||||
|
"\n".join([line for line in args.split("\n") if not line.lstrip().startswith("#")])
|
||||||
|
)
|
||||||
|
|
||||||
if len(_args) > 0:
|
if len(_args) > 0:
|
||||||
self.args.extend(_args)
|
self.args.extend(_args)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -527,6 +527,80 @@ class TestARGSMerger:
|
||||||
assert result is merger # Returns self for chaining
|
assert result is merger # Returns self for chaining
|
||||||
assert merger.args == ["--format", "best"]
|
assert merger.args == ["--format", "best"]
|
||||||
|
|
||||||
|
def test_add_filters_comment_lines(self):
|
||||||
|
"""Test that comment lines (starting with #) are filtered out."""
|
||||||
|
from app.library.YTDLPOpts import ARGSMerger
|
||||||
|
|
||||||
|
merger = ARGSMerger()
|
||||||
|
cli_with_comments = """--format best
|
||||||
|
# This is a comment
|
||||||
|
--output test.mp4
|
||||||
|
#Another comment without space
|
||||||
|
--no-playlist"""
|
||||||
|
|
||||||
|
merger.add(cli_with_comments)
|
||||||
|
|
||||||
|
# Comments should be filtered out
|
||||||
|
assert "#" not in merger.as_string()
|
||||||
|
assert "This is a comment" not in merger.as_string()
|
||||||
|
assert "Another comment" not in merger.as_string()
|
||||||
|
|
||||||
|
# Valid options should remain
|
||||||
|
assert "--format" in merger.args
|
||||||
|
assert "best" in merger.args
|
||||||
|
assert "--output" in merger.args
|
||||||
|
assert "test.mp4" in merger.args
|
||||||
|
assert "--no-playlist" in merger.args
|
||||||
|
|
||||||
|
def test_add_filters_indented_comment_lines(self):
|
||||||
|
"""Test that indented comment lines are filtered out."""
|
||||||
|
from app.library.YTDLPOpts import ARGSMerger
|
||||||
|
|
||||||
|
merger = ARGSMerger()
|
||||||
|
cli_with_indented_comments = """--format best
|
||||||
|
# Indented comment with spaces
|
||||||
|
# Indented comment with tabs
|
||||||
|
--output test.mp4
|
||||||
|
# Another indented comment
|
||||||
|
--socket-timeout 30"""
|
||||||
|
|
||||||
|
merger.add(cli_with_indented_comments)
|
||||||
|
|
||||||
|
# Comments should be filtered out
|
||||||
|
result = merger.as_string()
|
||||||
|
assert "# Indented comment with spaces" not in result
|
||||||
|
assert "# Indented comment with tabs" not in result
|
||||||
|
assert "# Another indented comment" not in result
|
||||||
|
|
||||||
|
# Valid options should remain
|
||||||
|
assert "--format" in merger.args
|
||||||
|
assert "--output" in merger.args
|
||||||
|
assert "--socket-timeout" in merger.args
|
||||||
|
|
||||||
|
def test_add_filters_complex_commented_extractor_args(self):
|
||||||
|
"""Test filtering of complex real-world commented extractor-args."""
|
||||||
|
from app.library.YTDLPOpts import ARGSMerger
|
||||||
|
|
||||||
|
merger = ARGSMerger()
|
||||||
|
cli_with_complex_comments = """--extractor-args "youtube:player-client=default,tv,mweb,-web_safari;formats=incomplete"
|
||||||
|
#--extractor-args "youtube:player-client=default,tv,mweb;-formats=incomplete;player_js_version=actual"
|
||||||
|
#--extractor-args "youtube:player-client=default,tv,mweb,web_safari;formats=incomplete"
|
||||||
|
--socket-timeout 60"""
|
||||||
|
|
||||||
|
merger.add(cli_with_complex_comments)
|
||||||
|
|
||||||
|
result = merger.as_string()
|
||||||
|
|
||||||
|
# Commented lines should be filtered out completely
|
||||||
|
assert "player_js_version=actual" not in result
|
||||||
|
# Check the specific commented variant (with comma before web_safari, not dash)
|
||||||
|
assert "mweb,web_safari;formats=incomplete" not in result
|
||||||
|
|
||||||
|
# Valid extractor-args should remain (with -web_safari, note the dash)
|
||||||
|
assert "youtube:player-client=default,tv,mweb,-web_safari;formats=incomplete" in result
|
||||||
|
assert "--socket-timeout" in merger.args
|
||||||
|
assert "60" in merger.args
|
||||||
|
|
||||||
def test_add_multiple_args_with_chaining(self):
|
def test_add_multiple_args_with_chaining(self):
|
||||||
"""Test adding multiple arguments using method chaining."""
|
"""Test adding multiple arguments using method chaining."""
|
||||||
from app.library.YTDLPOpts import ARGSMerger
|
from app.library.YTDLPOpts import ARGSMerger
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ const props = defineProps<{
|
||||||
code_classes?: string
|
code_classes?: string
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const isLoading = ref<boolean>(false)
|
const isLoading = ref<boolean>(true)
|
||||||
const data = ref<any>({})
|
const data = ref<any>({})
|
||||||
|
|
||||||
onMounted(async (): Promise<void> => {
|
onMounted(async (): Promise<void> => {
|
||||||
|
|
@ -35,7 +35,6 @@ onMounted(async (): Promise<void> => {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
isLoading.value = true
|
|
||||||
const response = await request(url)
|
const response = await request(url)
|
||||||
const body = await response.text()
|
const body = await response.text()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,14 +31,19 @@ code {
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-content-max" style="height: 80vh;" v-else>
|
<div class="modal-content-max" style="height: 80vh;" v-else>
|
||||||
<div class="content p-0 m-0" style="position: relative">
|
<div class="content p-0 m-0" style="position: relative">
|
||||||
<pre :class="[code_classes, custom_classes]"><code class="p-4 is-block" v-text="data" /></pre>
|
<div style="font-size:30vh; width: 99%" class="has-text-centered" v-if="isLoading">
|
||||||
<div class="m-4 is-flex" style="position: absolute; top:0; right:0;">
|
<i class="fas fa-circle-notch fa-spin" />
|
||||||
<button class="button is-small is-purple mr-3" @click="() => toggleClass('is-pre-wrap-force')">
|
</div>
|
||||||
<span class="icon"><i class="fas fa-text-width" /></span>
|
<div v-else>
|
||||||
</button>
|
<pre :class="[code_classes, custom_classes]"><code class="p-4 is-block" v-text="data" /></pre>
|
||||||
<button class="button is-info is-small" @click="() => copyText(JSON.stringify(data, null, 2))">
|
<div class="m-4 is-flex" style="position: absolute; top:0; right:0;">
|
||||||
<span class="icon"><i class="fas fa-copy" /></span>
|
<button class="button is-small is-purple mr-3" @click="() => toggleClass('is-pre-wrap-force')">
|
||||||
</button>
|
<span class="icon"><i class="fas fa-text-width" /></span>
|
||||||
|
</button>
|
||||||
|
<button class="button is-info is-small" @click="() => copyText(JSON.stringify(data, null, 2))">
|
||||||
|
<span class="icon"><i class="fas fa-copy" /></span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@
|
||||||
|
|
||||||
<div class="navbar-brand pl-5">
|
<div class="navbar-brand pl-5">
|
||||||
<NuxtLink class="navbar-item is-text-overflow" to="/" @click.prevent="(e: MouseEvent) => changeRoute(e)"
|
<NuxtLink class="navbar-item is-text-overflow" to="/" @click.prevent="(e: MouseEvent) => changeRoute(e)"
|
||||||
v-tooltip="socket.isConnected ? 'Connected' : 'Connecting'">
|
v-tooltip="socket.isConnected ? 'Connected' : 'Connecting'" id="top">
|
||||||
<span class="is-text-overflow">
|
<span class="is-text-overflow">
|
||||||
<span class="icon">
|
<span class="icon">
|
||||||
<i v-if="'connecting' === socket.connectionStatus" class="fas fa-arrows-rotate fa-spin" />
|
<i v-if="'connecting' === socket.connectionStatus" class="fas fa-arrows-rotate fa-spin" />
|
||||||
|
|
@ -172,15 +172,19 @@
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<div class="has-text-left" v-if="config.app?.app_version">
|
<div class="has-text-left" v-if="config.app?.app_version">
|
||||||
© {{ Year }} - <NuxtLink href="https://github.com/ArabCoders/ytptube" target="_blank">YTPTube</NuxtLink>
|
© {{ Year }} - <NuxtLink href="https://github.com/ArabCoders/ytptube" target="_blank">YTPTube</NuxtLink>
|
||||||
<span class="has-tooltip"
|
(<span class="has-tooltip"
|
||||||
v-tooltip="`Build Date: ${config.app?.app_build_date}, Branch: ${config.app?.app_branch}, commit: ${config.app?.app_commit_sha}`">
|
v-tooltip="`Build Date: ${config.app?.app_build_date}, Branch: ${config.app?.app_branch}, commit: ${config.app?.app_commit_sha}`">
|
||||||
({{ config?.app?.app_version || 'unknown' }})</span>
|
{{ config?.app?.app_version || 'unknown' }}</span>)
|
||||||
- <NuxtLink target="_blank" href="https://github.com/yt-dlp/yt-dlp">yt-dlp</NuxtLink>
|
- <NuxtLink target="_blank" href="https://github.com/yt-dlp/yt-dlp">yt-dlp</NuxtLink>
|
||||||
<span> ({{ config?.app?.ytdlp_version || 'unknown' }})</span>
|
<span> ({{ config?.app?.ytdlp_version || 'unknown' }})</span>
|
||||||
- <NuxtLink to="/changelog">CHANGELOG</NuxtLink>
|
- <NuxtLink to="/changelog">CHANGELOG</NuxtLink>
|
||||||
- <NuxtLink @click="doc.file = '/api/docs/FAQ.md'">FAQ</NuxtLink>
|
- <NuxtLink @click="doc.file = '/api/docs/FAQ.md'">FAQ</NuxtLink>
|
||||||
- <NuxtLink @click="doc.file = '/api/docs/README.md'">README</NuxtLink>
|
- <NuxtLink @click="doc.file = '/api/docs/README.md'">README</NuxtLink>
|
||||||
- <NuxtLink @click="doc.file = '/api/docs/API.md'">API</NuxtLink>
|
- <NuxtLink @click="doc.file = '/api/docs/API.md'">API</NuxtLink>
|
||||||
|
- <NuxtLink @click="scrollToTop">
|
||||||
|
<span class="icon"><i class="fas fa-arrow-up" /></span>
|
||||||
|
<span>Top</span>
|
||||||
|
</NuxtLink>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="column is-narrow" v-if="config.app?.started">
|
<div class="column is-narrow" v-if="config.app?.started">
|
||||||
|
|
@ -507,4 +511,5 @@ const connectionStatusColor = computed(() => {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const scrollToTop = () => document.getElementById('top')?.scrollIntoView({ behavior: 'smooth' });
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue