From 48af4b55b31e9ada065e1ca54dec0a4a5cf2c783 Mon Sep 17 00:00:00 2001 From: marcwebbie Date: Fri, 27 Sep 2013 17:32:52 -0300 Subject: [PATCH 1/2] Add code to write info.json output to stdout when option -output is used with a dash: -o - --- test/test_write_info_json.py | 20 ++++++++++++++++++++ youtube_dl/utils.py | 17 ++++++++++++----- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/test/test_write_info_json.py b/test/test_write_info_json.py index de6d5180f..84a885d61 100644 --- a/test/test_write_info_json.py +++ b/test/test_write_info_json.py @@ -67,6 +67,26 @@ class TestInfoJSON(unittest.TestCase): descr = descf.read() self.assertEqual(descr, EXPECTED_DESCRIPTION) + def test_info_json_with_stdout_as_output_returns_good_json(self): + from unittest.mock import patch + from io import StringIO + params['writedescription'] = False + params['quiet'] = True + params['outtmpl'] = '-' + with patch('sys.stdout', new_callable=StringIO) as mock_stdout: + ie = youtube_dl.extractor.YoutubeIE() + ydl = YoutubeDL(params) + ydl.add_info_extractor(ie) + ydl.download([TEST_ID]) + output = mock_stdout.getvalue() + jd = json.loads(output) + self.assertEqual(jd['upload_date'], u'20121002') + self.assertEqual(jd['description'], EXPECTED_DESCRIPTION) + self.assertEqual(jd['id'], TEST_ID) + self.assertEqual(jd['extractor'], 'youtube') + self.assertEqual(jd['title'], u'''youtube-dl test video "'/\ä↭𝕐''') + self.assertEqual(jd['uploader'], 'Philipp Hagemeister') + def tearDown(self): if os.path.exists(INFO_JSON_FILE): os.remove(INFO_JSON_FILE) diff --git a/youtube_dl/utils.py b/youtube_dl/utils.py index 814a9b6be..3db3eb006 100644 --- a/youtube_dl/utils.py +++ b/youtube_dl/utils.py @@ -200,14 +200,21 @@ else: # In Python 2.x, json.dump expects a bytestream. # In Python 3.x, it writes to a character stream -if sys.version_info < (3,0): +# if user passed '-' as outputname, redirect output to stdout +if sys.version_info < (3, 0): def write_json_file(obj, fn): - with open(fn, 'wb') as f: - json.dump(obj, f) + if fn.rstrip('.info.json') == u'-': + json.dump(obj, sys.stdout) + else: + with open(fn, 'wb') as f: + json.dump(obj, f) else: def write_json_file(obj, fn): - with open(fn, 'w', encoding='utf-8') as f: - json.dump(obj, f) + if fn.rstrip('.info.json') == u'-': + json.dump(obj, sys.stdout) + else: + with open(fn, 'w', encoding='utf-8') as f: + json.dump(obj, f) if sys.version_info >= (2,7): def find_xpath_attr(node, xpath, key, val): From b13cab0b7ac2c66dcd7703d783457b7c8fbd1c39 Mon Sep 17 00:00:00 2001 From: marcwebbie Date: Fri, 27 Sep 2013 22:03:34 -0300 Subject: [PATCH 2/2] Added python2 test for writing json-info to stdout --- test/test_write_info_json.py | 39 +++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/test/test_write_info_json.py b/test/test_write_info_json.py index 84a885d61..1c4d94d03 100644 --- a/test/test_write_info_json.py +++ b/test/test_write_info_json.py @@ -13,16 +13,20 @@ import youtube_dl.YoutubeDL import youtube_dl.extractor from youtube_dl.utils import * -PARAMETERS_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), "parameters.json") +PARAMETERS_FILE = os.path.join( + os.path.dirname(os.path.abspath(__file__)), "parameters.json") # General configuration (from __init__, not very elegant...) jar = compat_cookiejar.CookieJar() cookie_processor = compat_urllib_request.HTTPCookieProcessor(jar) proxy_handler = compat_urllib_request.ProxyHandler() -opener = compat_urllib_request.build_opener(proxy_handler, cookie_processor, YoutubeDLHandler()) +opener = compat_urllib_request.build_opener( + proxy_handler, cookie_processor, YoutubeDLHandler()) compat_urllib_request.install_opener(opener) + class YoutubeDL(youtube_dl.YoutubeDL): + def __init__(self, *args, **kwargs): super(YoutubeDL, self).__init__(*args, **kwargs) self.to_stderr = self.to_screen @@ -42,7 +46,9 @@ This is a test video for youtube-dl. For more information, contact phihag@phihag.de .''' + class TestInfoJSON(unittest.TestCase): + def setUp(self): # Clear old files self.tearDown() @@ -68,18 +74,31 @@ class TestInfoJSON(unittest.TestCase): self.assertEqual(descr, EXPECTED_DESCRIPTION) def test_info_json_with_stdout_as_output_returns_good_json(self): - from unittest.mock import patch - from io import StringIO params['writedescription'] = False params['quiet'] = True params['outtmpl'] = '-' - with patch('sys.stdout', new_callable=StringIO) as mock_stdout: - ie = youtube_dl.extractor.YoutubeIE() - ydl = YoutubeDL(params) - ydl.add_info_extractor(ie) - ydl.download([TEST_ID]) - output = mock_stdout.getvalue() + + jd = None + if sys.version_info < (3, 0): + from subprocess import Popen, PIPE + import shlex + tests_dir = os.path.dirname(os.path.realpath(__file__)) + repo_dir = os.path.dirname(tests_dir) + os.chdir(repo_dir) + cmd = "youtube_dl/__main__.py --skip-download --write-info-json -quite BaW_jenozKc -o -" + output = Popen(shlex.split(cmd), stdout=PIPE).communicate()[0] jd = json.loads(output) + else: + from unittest.mock import patch + from io import StringIO + with patch('sys.stdout', new_callable=StringIO) as mock_stdout: + ie = youtube_dl.extractor.YoutubeIE() + ydl = YoutubeDL(params) + ydl.add_info_extractor(ie) + ydl.download([TEST_ID]) + output = mock_stdout.getvalue() + jd = json.loads(output) + self.assertEqual(jd['upload_date'], u'20121002') self.assertEqual(jd['description'], EXPECTED_DESCRIPTION) self.assertEqual(jd['id'], TEST_ID)