Fix the 'utils.build_command' function

Wrap the option with double quotes if it contains
any special characters (spaces, parentheses, etc..) instead
of wrapping it only when it contains spaces.

This patch fixes the issue with the parentheses inside
the youtube-dl output template when running Youtube-dlg
on Linux.

Related to #173
This commit is contained in:
MrS0m30n3 2017-06-18 21:36:18 +03:00
parent 9d86eafde0
commit 279ca6b527
2 changed files with 44 additions and 30 deletions

View File

@ -67,43 +67,47 @@ class TestBuildCommand(unittest.TestCase):
"""Test case for the build_command method."""
def test_build_command_linux(self):
result = "youtube-dl -o \"/home/user/downloads/%(upload_date)s/%(id)" \
"s_%(playlist_id)s - %(format)s.%(ext)s\" -f mp4 --ignore-config " \
"\"https://www.youtube.com/watch?v=aaaaaaaaaaa&list=AAAAAAAAAAA\""
def setUp(self):
self.url = "https://www.youtube.com/watch?v=aaaaaaaaaaa&list=AAAAAAAAAAA"
options = [
"-o",
"/home/user/downloads/%(upload_date)s/%(id)s_%(playlist_id)s - %(format)s.%(ext)s",
"-f",
"mp4",
"--ignore-config"
]
self.options = ["-o", None, "-f", "mp4", "--ignore-config"]
url = "https://www.youtube.com/watch?v=aaaaaaaaaaa&list=AAAAAAAAAAA"
self.result = "{{ydl_bin}} -o \"{{tmpl}}\" -f mp4 --ignore-config \"{url}\"".format(url=self.url)
utils.YOUTUBEDL_BIN = "youtube-dl"
def run_tests(self, ydl_bin, tmpl):
"""Run the main test.
self.assertEqual(utils.build_command(options, url), result)
Args:
ydl_bin (str): Name of the youtube-dl binary
tmpl (str): Youtube-dl output template
def test_build_command_windows(self):
result = "youtube-dl.exe -o \"C:\\downloads\\%(upload_date)s\\%(id)" \
"s_%(playlist_id)s - %(format)s.%(ext)s\" -f mp4 --ignore-config " \
"\"https://www.youtube.com/watch?v=aaaaaaaaaaa&list=AAAAAAAAAAA\""
"""
utils.YOUTUBEDL_BIN = ydl_bin
self.options[1] = tmpl # Plug the template in our options
options = [
"-o",
"C:\\downloads\\%(upload_date)s\\%(id)s_%(playlist_id)s - %(format)s.%(ext)s",
"-f",
"mp4",
"--ignore-config"
]
result = self.result.format(ydl_bin=ydl_bin, tmpl=tmpl)
url = "https://www.youtube.com/watch?v=aaaaaaaaaaa&list=AAAAAAAAAAA"
self.assertEqual(utils.build_command(self.options, self.url), result)
utils.YOUTUBEDL_BIN = "youtube-dl.exe"
def test_build_command_with_spaces_linux(self):
tmpl = "/home/user/downloads/%(upload_date)s/%(id)s_%(playlist_id)s - %(format)s.%(ext)s"
self.assertEqual(utils.build_command(options, url), result)
self.run_tests("youtube-dl", tmpl)
def test_build_command_without_spaces_linux(self):
tmpl = "/home/user/downloads/%(id)s.%(ext)s"
self.run_tests("youtube-dl", tmpl)
def test_build_command_with_spaces_windows(self):
tmpl = "C:\\downloads\\%(upload_date)s\\%(id)s_%(playlist_id)s - %(format)s.%(ext)s"
self.run_tests("youtube-dl.exe", tmpl)
def test_build_command_without_spaces_windows(self):
tmpl = "C:\\downloads\\%(id)s.%(ext)s"
self.run_tests("youtube-dl.exe", tmpl)
def main():

View File

@ -356,10 +356,20 @@ def format_bytes(bytes):
def build_command(options_list, url):
"""Build the youtube-dl command line string."""
# If option has spaces wrap it with double quotes
def escape(option):
"""Wrap option with double quotes if it contains special symbols."""
special_symbols = [" ", "(", ")"]
for symbol in special_symbols:
if symbol in option:
return "\"{}\"".format(option)
return option
# If option has special symbols wrap it with double quotes
# Probably not the best solution since if the option already contains
# double quotes it will be a mess, see issue #173
options = ["\"{}\"".format(option) if " " in option else option for option in options_list]
options = [escape(option) for option in options_list]
# Always wrap the url with double quotes
url = "\"{}\"".format(url)