]>
Raphaël G. Git Repositories - youtubedl/blob - test/test_YoutubeDL.py
75945e38f837fc11496856180336fc2828121cca
   4 from __future__ 
import unicode_literals
 
   6 # Allow direct execution 
  10 sys
.path
.insert(0, os
.path
.dirname(os
.path
.dirname(os
.path
.abspath(__file__
)))) 
  14 from test
.helper 
import FakeYDL
, assertRegexpMatches
 
  15 from youtube_dl 
import YoutubeDL
 
  16 from youtube_dl
.compat 
import compat_str
, compat_urllib_error
 
  17 from youtube_dl
.extractor 
import YoutubeIE
 
  18 from youtube_dl
.extractor
.common 
import InfoExtractor
 
  19 from youtube_dl
.postprocessor
.common 
import PostProcessor
 
  20 from youtube_dl
.utils 
import ExtractorError
, match_filter_func
 
  22 TEST_URL 
= 'http://localhost/sample.mp4' 
  26     def __init__(self
, *args
, **kwargs
): 
  27         super(YDL
, self
).__init
__(*args
, **kwargs
) 
  28         self
.downloaded_info_dicts 
= [] 
  31     def process_info(self
, info_dict
): 
  32         self
.downloaded_info_dicts
.append(info_dict
) 
  34     def to_screen(self
, msg
): 
  38 def _make_result(formats
, **kwargs
): 
  42         'title': 'testttitle', 
  43         'extractor': 'testex', 
  49 class TestFormatSelection(unittest
.TestCase
): 
  50     def test_prefer_free_formats(self
): 
  51         # Same resolution => download webm 
  53         ydl
.params
['prefer_free_formats'] = True 
  55             {'ext': 'webm', 'height': 460, 'url': TEST_URL
}, 
  56             {'ext': 'mp4', 'height': 460, 'url': TEST_URL
}, 
  58         info_dict 
= _make_result(formats
) 
  60         yie
._sort
_formats
(info_dict
['formats']) 
  61         ydl
.process_ie_result(info_dict
) 
  62         downloaded 
= ydl
.downloaded_info_dicts
[0] 
  63         self
.assertEqual(downloaded
['ext'], 'webm') 
  65         # Different resolution => download best quality (mp4) 
  67         ydl
.params
['prefer_free_formats'] = True 
  69             {'ext': 'webm', 'height': 720, 'url': TEST_URL
}, 
  70             {'ext': 'mp4', 'height': 1080, 'url': TEST_URL
}, 
  72         info_dict
['formats'] = formats
 
  74         yie
._sort
_formats
(info_dict
['formats']) 
  75         ydl
.process_ie_result(info_dict
) 
  76         downloaded 
= ydl
.downloaded_info_dicts
[0] 
  77         self
.assertEqual(downloaded
['ext'], 'mp4') 
  79         # No prefer_free_formats => prefer mp4 and flv for greater compatibility 
  81         ydl
.params
['prefer_free_formats'] = False 
  83             {'ext': 'webm', 'height': 720, 'url': TEST_URL
}, 
  84             {'ext': 'mp4', 'height': 720, 'url': TEST_URL
}, 
  85             {'ext': 'flv', 'height': 720, 'url': TEST_URL
}, 
  87         info_dict
['formats'] = formats
 
  89         yie
._sort
_formats
(info_dict
['formats']) 
  90         ydl
.process_ie_result(info_dict
) 
  91         downloaded 
= ydl
.downloaded_info_dicts
[0] 
  92         self
.assertEqual(downloaded
['ext'], 'mp4') 
  95         ydl
.params
['prefer_free_formats'] = False 
  97             {'ext': 'flv', 'height': 720, 'url': TEST_URL
}, 
  98             {'ext': 'webm', 'height': 720, 'url': TEST_URL
}, 
 100         info_dict
['formats'] = formats
 
 102         yie
._sort
_formats
(info_dict
['formats']) 
 103         ydl
.process_ie_result(info_dict
) 
 104         downloaded 
= ydl
.downloaded_info_dicts
[0] 
 105         self
.assertEqual(downloaded
['ext'], 'flv') 
 107     def test_format_selection(self
): 
 109             {'format_id': '35', 'ext': 'mp4', 'preference': 1, 'url': TEST_URL
}, 
 110             {'format_id': 'example-with-dashes', 'ext': 'webm', 'preference': 1, 'url': TEST_URL
}, 
 111             {'format_id': '45', 'ext': 'webm', 'preference': 2, 'url': TEST_URL
}, 
 112             {'format_id': '47', 'ext': 'webm', 'preference': 3, 'url': TEST_URL
}, 
 113             {'format_id': '2', 'ext': 'flv', 'preference': 4, 'url': TEST_URL
}, 
 115         info_dict 
= _make_result(formats
) 
 117         ydl 
= YDL({'format': '20/47'}) 
 118         ydl
.process_ie_result(info_dict
.copy()) 
 119         downloaded 
= ydl
.downloaded_info_dicts
[0] 
 120         self
.assertEqual(downloaded
['format_id'], '47') 
 122         ydl 
= YDL({'format': '20/71/worst'}) 
 123         ydl
.process_ie_result(info_dict
.copy()) 
 124         downloaded 
= ydl
.downloaded_info_dicts
[0] 
 125         self
.assertEqual(downloaded
['format_id'], '35') 
 128         ydl
.process_ie_result(info_dict
.copy()) 
 129         downloaded 
= ydl
.downloaded_info_dicts
[0] 
 130         self
.assertEqual(downloaded
['format_id'], '2') 
 132         ydl 
= YDL({'format': 'webm/mp4'}) 
 133         ydl
.process_ie_result(info_dict
.copy()) 
 134         downloaded 
= ydl
.downloaded_info_dicts
[0] 
 135         self
.assertEqual(downloaded
['format_id'], '47') 
 137         ydl 
= YDL({'format': '3gp/40/mp4'}) 
 138         ydl
.process_ie_result(info_dict
.copy()) 
 139         downloaded 
= ydl
.downloaded_info_dicts
[0] 
 140         self
.assertEqual(downloaded
['format_id'], '35') 
 142         ydl 
= YDL({'format': 'example-with-dashes'}) 
 143         ydl
.process_ie_result(info_dict
.copy()) 
 144         downloaded 
= ydl
.downloaded_info_dicts
[0] 
 145         self
.assertEqual(downloaded
['format_id'], 'example-with-dashes') 
 147     def test_format_selection_audio(self
): 
 149             {'format_id': 'audio-low', 'ext': 'webm', 'preference': 1, 'vcodec': 'none', 'url': TEST_URL
}, 
 150             {'format_id': 'audio-mid', 'ext': 'webm', 'preference': 2, 'vcodec': 'none', 'url': TEST_URL
}, 
 151             {'format_id': 'audio-high', 'ext': 'flv', 'preference': 3, 'vcodec': 'none', 'url': TEST_URL
}, 
 152             {'format_id': 'vid', 'ext': 'mp4', 'preference': 4, 'url': TEST_URL
}, 
 154         info_dict 
= _make_result(formats
) 
 156         ydl 
= YDL({'format': 'bestaudio'}) 
 157         ydl
.process_ie_result(info_dict
.copy()) 
 158         downloaded 
= ydl
.downloaded_info_dicts
[0] 
 159         self
.assertEqual(downloaded
['format_id'], 'audio-high') 
 161         ydl 
= YDL({'format': 'worstaudio'}) 
 162         ydl
.process_ie_result(info_dict
.copy()) 
 163         downloaded 
= ydl
.downloaded_info_dicts
[0] 
 164         self
.assertEqual(downloaded
['format_id'], 'audio-low') 
 167             {'format_id': 'vid-low', 'ext': 'mp4', 'preference': 1, 'url': TEST_URL
}, 
 168             {'format_id': 'vid-high', 'ext': 'mp4', 'preference': 2, 'url': TEST_URL
}, 
 170         info_dict 
= _make_result(formats
) 
 172         ydl 
= YDL({'format': 'bestaudio/worstaudio/best'}) 
 173         ydl
.process_ie_result(info_dict
.copy()) 
 174         downloaded 
= ydl
.downloaded_info_dicts
[0] 
 175         self
.assertEqual(downloaded
['format_id'], 'vid-high') 
 177     def test_format_selection_audio_exts(self
): 
 179             {'format_id': 'mp3-64', 'ext': 'mp3', 'abr': 64, 'url': 'http://_', 'vcodec': 'none'}, 
 180             {'format_id': 'ogg-64', 'ext': 'ogg', 'abr': 64, 'url': 'http://_', 'vcodec': 'none'}, 
 181             {'format_id': 'aac-64', 'ext': 'aac', 'abr': 64, 'url': 'http://_', 'vcodec': 'none'}, 
 182             {'format_id': 'mp3-32', 'ext': 'mp3', 'abr': 32, 'url': 'http://_', 'vcodec': 'none'}, 
 183             {'format_id': 'aac-32', 'ext': 'aac', 'abr': 32, 'url': 'http://_', 'vcodec': 'none'}, 
 186         info_dict 
= _make_result(formats
) 
 187         ydl 
= YDL({'format': 'best'}) 
 189         ie
._sort
_formats
(info_dict
['formats']) 
 190         ydl
.process_ie_result(copy
.deepcopy(info_dict
)) 
 191         downloaded 
= ydl
.downloaded_info_dicts
[0] 
 192         self
.assertEqual(downloaded
['format_id'], 'aac-64') 
 194         ydl 
= YDL({'format': 'mp3'}) 
 196         ie
._sort
_formats
(info_dict
['formats']) 
 197         ydl
.process_ie_result(copy
.deepcopy(info_dict
)) 
 198         downloaded 
= ydl
.downloaded_info_dicts
[0] 
 199         self
.assertEqual(downloaded
['format_id'], 'mp3-64') 
 201         ydl 
= YDL({'prefer_free_formats': True}) 
 203         ie
._sort
_formats
(info_dict
['formats']) 
 204         ydl
.process_ie_result(copy
.deepcopy(info_dict
)) 
 205         downloaded 
= ydl
.downloaded_info_dicts
[0] 
 206         self
.assertEqual(downloaded
['format_id'], 'ogg-64') 
 208     def test_format_selection_video(self
): 
 210             {'format_id': 'dash-video-low', 'ext': 'mp4', 'preference': 1, 'acodec': 'none', 'url': TEST_URL
}, 
 211             {'format_id': 'dash-video-high', 'ext': 'mp4', 'preference': 2, 'acodec': 'none', 'url': TEST_URL
}, 
 212             {'format_id': 'vid', 'ext': 'mp4', 'preference': 3, 'url': TEST_URL
}, 
 214         info_dict 
= _make_result(formats
) 
 216         ydl 
= YDL({'format': 'bestvideo'}) 
 217         ydl
.process_ie_result(info_dict
.copy()) 
 218         downloaded 
= ydl
.downloaded_info_dicts
[0] 
 219         self
.assertEqual(downloaded
['format_id'], 'dash-video-high') 
 221         ydl 
= YDL({'format': 'worstvideo'}) 
 222         ydl
.process_ie_result(info_dict
.copy()) 
 223         downloaded 
= ydl
.downloaded_info_dicts
[0] 
 224         self
.assertEqual(downloaded
['format_id'], 'dash-video-low') 
 226         ydl 
= YDL({'format': 'bestvideo[format_id^=dash][format_id$=low]'}) 
 227         ydl
.process_ie_result(info_dict
.copy()) 
 228         downloaded 
= ydl
.downloaded_info_dicts
[0] 
 229         self
.assertEqual(downloaded
['format_id'], 'dash-video-low') 
 232             {'format_id': 'vid-vcodec-dot', 'ext': 'mp4', 'preference': 1, 'vcodec': 'avc1.123456', 'acodec': 'none', 'url': TEST_URL
}, 
 234         info_dict 
= _make_result(formats
) 
 236         ydl 
= YDL({'format': 'bestvideo[vcodec=avc1.123456]'}) 
 237         ydl
.process_ie_result(info_dict
.copy()) 
 238         downloaded 
= ydl
.downloaded_info_dicts
[0] 
 239         self
.assertEqual(downloaded
['format_id'], 'vid-vcodec-dot') 
 241     def test_youtube_format_selection(self
): 
 243             '38', '37', '46', '22', '45', '35', '44', '18', '34', '43', '6', '5', '17', '36', '13', 
 244             # Apple HTTP Live Streaming 
 245             '96', '95', '94', '93', '92', '132', '151', 
 247             '85', '84', '102', '83', '101', '82', '100', 
 249             '137', '248', '136', '247', '135', '246', 
 250             '245', '244', '134', '243', '133', '242', '160', 
 252             '141', '172', '140', '171', '139', 
 255         def format_info(f_id
): 
 256             info 
= YoutubeIE
._formats
[f_id
].copy() 
 258             # XXX: In real cases InfoExtractor._parse_mpd_formats() fills up 'acodec' 
 259             # and 'vcodec', while in tests such information is incomplete since 
 260             # commit a6c2c24479e5f4827ceb06f64d855329c0a6f593 
 261             # test_YoutubeDL.test_youtube_format_selection is broken without 
 263             if 'acodec' in info 
and 'vcodec' not in info
: 
 264                 info
['vcodec'] = 'none' 
 265             elif 'vcodec' in info 
and 'acodec' not in info
: 
 266                 info
['acodec'] = 'none' 
 268             info
['format_id'] = f_id
 
 269             info
['url'] = 'url:' + f_id
 
 271         formats_order 
= [format_info(f_id
) for f_id 
in order
] 
 273         info_dict 
= _make_result(list(formats_order
), extractor
='youtube') 
 274         ydl 
= YDL({'format': 'bestvideo+bestaudio'}) 
 276         yie
._sort
_formats
(info_dict
['formats']) 
 277         ydl
.process_ie_result(info_dict
) 
 278         downloaded 
= ydl
.downloaded_info_dicts
[0] 
 279         self
.assertEqual(downloaded
['format_id'], '137+141') 
 280         self
.assertEqual(downloaded
['ext'], 'mp4') 
 282         info_dict 
= _make_result(list(formats_order
), extractor
='youtube') 
 283         ydl 
= YDL({'format': 'bestvideo[height>=999999]+bestaudio/best'}) 
 285         yie
._sort
_formats
(info_dict
['formats']) 
 286         ydl
.process_ie_result(info_dict
) 
 287         downloaded 
= ydl
.downloaded_info_dicts
[0] 
 288         self
.assertEqual(downloaded
['format_id'], '38') 
 290         info_dict 
= _make_result(list(formats_order
), extractor
='youtube') 
 291         ydl 
= YDL({'format': 'bestvideo/best,bestaudio'}) 
 293         yie
._sort
_formats
(info_dict
['formats']) 
 294         ydl
.process_ie_result(info_dict
) 
 295         downloaded_ids 
= [info
['format_id'] for info 
in ydl
.downloaded_info_dicts
] 
 296         self
.assertEqual(downloaded_ids
, ['137', '141']) 
 298         info_dict 
= _make_result(list(formats_order
), extractor
='youtube') 
 299         ydl 
= YDL({'format': '(bestvideo[ext=mp4],bestvideo[ext=webm])+bestaudio'}) 
 301         yie
._sort
_formats
(info_dict
['formats']) 
 302         ydl
.process_ie_result(info_dict
) 
 303         downloaded_ids 
= [info
['format_id'] for info 
in ydl
.downloaded_info_dicts
] 
 304         self
.assertEqual(downloaded_ids
, ['137+141', '248+141']) 
 306         info_dict 
= _make_result(list(formats_order
), extractor
='youtube') 
 307         ydl 
= YDL({'format': '(bestvideo[ext=mp4],bestvideo[ext=webm])[height<=720]+bestaudio'}) 
 309         yie
._sort
_formats
(info_dict
['formats']) 
 310         ydl
.process_ie_result(info_dict
) 
 311         downloaded_ids 
= [info
['format_id'] for info 
in ydl
.downloaded_info_dicts
] 
 312         self
.assertEqual(downloaded_ids
, ['136+141', '247+141']) 
 314         info_dict 
= _make_result(list(formats_order
), extractor
='youtube') 
 315         ydl 
= YDL({'format': '(bestvideo[ext=none]/bestvideo[ext=webm])+bestaudio'}) 
 317         yie
._sort
_formats
(info_dict
['formats']) 
 318         ydl
.process_ie_result(info_dict
) 
 319         downloaded_ids 
= [info
['format_id'] for info 
in ydl
.downloaded_info_dicts
] 
 320         self
.assertEqual(downloaded_ids
, ['248+141']) 
 322         for f1
, f2 
in zip(formats_order
, formats_order
[1:]): 
 323             info_dict 
= _make_result([f1
, f2
], extractor
='youtube') 
 324             ydl 
= YDL({'format': 'best/bestvideo'}) 
 326             yie
._sort
_formats
(info_dict
['formats']) 
 327             ydl
.process_ie_result(info_dict
) 
 328             downloaded 
= ydl
.downloaded_info_dicts
[0] 
 329             self
.assertEqual(downloaded
['format_id'], f1
['format_id']) 
 331             info_dict 
= _make_result([f2
, f1
], extractor
='youtube') 
 332             ydl 
= YDL({'format': 'best/bestvideo'}) 
 334             yie
._sort
_formats
(info_dict
['formats']) 
 335             ydl
.process_ie_result(info_dict
) 
 336             downloaded 
= ydl
.downloaded_info_dicts
[0] 
 337             self
.assertEqual(downloaded
['format_id'], f1
['format_id']) 
 339     def test_audio_only_extractor_format_selection(self
): 
 340         # For extractors with incomplete formats (all formats are audio-only or 
 341         # video-only) best and worst should fallback to corresponding best/worst 
 342         # video-only or audio-only formats (as per 
 343         # https://github.com/rg3/youtube-dl/pull/5556) 
 345             {'format_id': 'low', 'ext': 'mp3', 'preference': 1, 'vcodec': 'none', 'url': TEST_URL
}, 
 346             {'format_id': 'high', 'ext': 'mp3', 'preference': 2, 'vcodec': 'none', 'url': TEST_URL
}, 
 348         info_dict 
= _make_result(formats
) 
 350         ydl 
= YDL({'format': 'best'}) 
 351         ydl
.process_ie_result(info_dict
.copy()) 
 352         downloaded 
= ydl
.downloaded_info_dicts
[0] 
 353         self
.assertEqual(downloaded
['format_id'], 'high') 
 355         ydl 
= YDL({'format': 'worst'}) 
 356         ydl
.process_ie_result(info_dict
.copy()) 
 357         downloaded 
= ydl
.downloaded_info_dicts
[0] 
 358         self
.assertEqual(downloaded
['format_id'], 'low') 
 360     def test_format_not_available(self
): 
 362             {'format_id': 'regular', 'ext': 'mp4', 'height': 360, 'url': TEST_URL
}, 
 363             {'format_id': 'video', 'ext': 'mp4', 'height': 720, 'acodec': 'none', 'url': TEST_URL
}, 
 365         info_dict 
= _make_result(formats
) 
 367         # This must fail since complete video-audio format does not match filter 
 368         # and extractor does not provide incomplete only formats (i.e. only 
 369         # video-only or audio-only). 
 370         ydl 
= YDL({'format': 'best[height>360]'}) 
 371         self
.assertRaises(ExtractorError
, ydl
.process_ie_result
, info_dict
.copy()) 
 373     def test_invalid_format_specs(self
): 
 374         def assert_syntax_error(format_spec
): 
 375             ydl 
= YDL({'format': format_spec
}) 
 376             info_dict 
= _make_result([{'format_id': 'foo', 'url': TEST_URL
}]) 
 377             self
.assertRaises(SyntaxError, ydl
.process_ie_result
, info_dict
) 
 379         assert_syntax_error('bestvideo,,best') 
 380         assert_syntax_error('+bestaudio') 
 381         assert_syntax_error('bestvideo+') 
 382         assert_syntax_error('/') 
 384     def test_format_filtering(self
): 
 386             {'format_id': 'A', 'filesize': 500, 'width': 1000}, 
 387             {'format_id': 'B', 'filesize': 1000, 'width': 500}, 
 388             {'format_id': 'C', 'filesize': 1000, 'width': 400}, 
 389             {'format_id': 'D', 'filesize': 2000, 'width': 600}, 
 390             {'format_id': 'E', 'filesize': 3000}, 
 392             {'format_id': 'G', 'filesize': 1000000}, 
 395             f
['url'] = 'http://_/' 
 397         info_dict 
= _make_result(formats
) 
 399         ydl 
= YDL({'format': 'best[filesize<3000]'}) 
 400         ydl
.process_ie_result(info_dict
) 
 401         downloaded 
= ydl
.downloaded_info_dicts
[0] 
 402         self
.assertEqual(downloaded
['format_id'], 'D') 
 404         ydl 
= YDL({'format': 'best[filesize<=3000]'}) 
 405         ydl
.process_ie_result(info_dict
) 
 406         downloaded 
= ydl
.downloaded_info_dicts
[0] 
 407         self
.assertEqual(downloaded
['format_id'], 'E') 
 409         ydl 
= YDL({'format': 'best[filesize <= ? 3000]'}) 
 410         ydl
.process_ie_result(info_dict
) 
 411         downloaded 
= ydl
.downloaded_info_dicts
[0] 
 412         self
.assertEqual(downloaded
['format_id'], 'F') 
 414         ydl 
= YDL({'format': 'best [filesize = 1000] [width>450]'}) 
 415         ydl
.process_ie_result(info_dict
) 
 416         downloaded 
= ydl
.downloaded_info_dicts
[0] 
 417         self
.assertEqual(downloaded
['format_id'], 'B') 
 419         ydl 
= YDL({'format': 'best [filesize = 1000] [width!=450]'}) 
 420         ydl
.process_ie_result(info_dict
) 
 421         downloaded 
= ydl
.downloaded_info_dicts
[0] 
 422         self
.assertEqual(downloaded
['format_id'], 'C') 
 424         ydl 
= YDL({'format': '[filesize>?1]'}) 
 425         ydl
.process_ie_result(info_dict
) 
 426         downloaded 
= ydl
.downloaded_info_dicts
[0] 
 427         self
.assertEqual(downloaded
['format_id'], 'G') 
 429         ydl 
= YDL({'format': '[filesize<1M]'}) 
 430         ydl
.process_ie_result(info_dict
) 
 431         downloaded 
= ydl
.downloaded_info_dicts
[0] 
 432         self
.assertEqual(downloaded
['format_id'], 'E') 
 434         ydl 
= YDL({'format': '[filesize<1MiB]'}) 
 435         ydl
.process_ie_result(info_dict
) 
 436         downloaded 
= ydl
.downloaded_info_dicts
[0] 
 437         self
.assertEqual(downloaded
['format_id'], 'G') 
 439         ydl 
= YDL({'format': 'all[width>=400][width<=600]'}) 
 440         ydl
.process_ie_result(info_dict
) 
 441         downloaded_ids 
= [info
['format_id'] for info 
in ydl
.downloaded_info_dicts
] 
 442         self
.assertEqual(downloaded_ids
, ['B', 'C', 'D']) 
 444         ydl 
= YDL({'format': 'best[height<40]'}) 
 446             ydl
.process_ie_result(info_dict
) 
 447         except ExtractorError
: 
 449         self
.assertEqual(ydl
.downloaded_info_dicts
, []) 
 452 class TestYoutubeDL(unittest
.TestCase
): 
 453     def test_subtitles(self
): 
 454         def s_formats(lang
, autocaption
=False): 
 457                 'url': 'http://localhost/video.%s.%s' % (lang
, ext
), 
 458                 '_auto': autocaption
, 
 459             } for ext 
in ['vtt', 'srt', 'ass']] 
 460         subtitles 
= dict((l
, s_formats(l
)) for l 
in ['en', 'fr', 'es']) 
 461         auto_captions 
= dict((l
, s_formats(l
, True)) for l 
in ['it', 'pt', 'es']) 
 465             'url': 'http://localhost/video.mp4', 
 466             'subtitles': subtitles
, 
 467             'automatic_captions': auto_captions
, 
 471         def get_info(params
={}): 
 472             params
.setdefault('simulate', True) 
 474             ydl
.report_warning 
= lambda *args
, **kargs
: None 
 475             return ydl
.process_video_result(info_dict
, download
=False) 
 478         self
.assertFalse(result
.get('requested_subtitles')) 
 479         self
.assertEqual(result
['subtitles'], subtitles
) 
 480         self
.assertEqual(result
['automatic_captions'], auto_captions
) 
 482         result 
= get_info({'writesubtitles': True}) 
 483         subs 
= result
['requested_subtitles'] 
 484         self
.assertTrue(subs
) 
 485         self
.assertEqual(set(subs
.keys()), set(['en'])) 
 486         self
.assertTrue(subs
['en'].get('data') is None) 
 487         self
.assertEqual(subs
['en']['ext'], 'ass') 
 489         result 
= get_info({'writesubtitles': True, 'subtitlesformat': 'foo/srt'}) 
 490         subs 
= result
['requested_subtitles'] 
 491         self
.assertEqual(subs
['en']['ext'], 'srt') 
 493         result 
= get_info({'writesubtitles': True, 'subtitleslangs': ['es', 'fr', 'it']}) 
 494         subs 
= result
['requested_subtitles'] 
 495         self
.assertTrue(subs
) 
 496         self
.assertEqual(set(subs
.keys()), set(['es', 'fr'])) 
 498         result 
= get_info({'writesubtitles': True, 'writeautomaticsub': True, 'subtitleslangs': ['es', 'pt']}) 
 499         subs 
= result
['requested_subtitles'] 
 500         self
.assertTrue(subs
) 
 501         self
.assertEqual(set(subs
.keys()), set(['es', 'pt'])) 
 502         self
.assertFalse(subs
['es']['_auto']) 
 503         self
.assertTrue(subs
['pt']['_auto']) 
 505         result 
= get_info({'writeautomaticsub': True, 'subtitleslangs': ['es', 'pt']}) 
 506         subs 
= result
['requested_subtitles'] 
 507         self
.assertTrue(subs
) 
 508         self
.assertEqual(set(subs
.keys()), set(['es', 'pt'])) 
 509         self
.assertTrue(subs
['es']['_auto']) 
 510         self
.assertTrue(subs
['pt']['_auto']) 
 512     def test_add_extra_info(self
): 
 518             'playlist': 'funny videos', 
 520         YDL
.add_extra_info(test_dict
, extra_info
) 
 521         self
.assertEqual(test_dict
['extractor'], 'Foo') 
 522         self
.assertEqual(test_dict
['playlist'], 'funny videos') 
 524     def test_prepare_filename(self
): 
 533             ydl 
= YoutubeDL({'outtmpl': templ
}) 
 534             return ydl
.prepare_filename(info
) 
 535         self
.assertEqual(fname('%(id)s.%(ext)s'), '1234.mp4') 
 536         self
.assertEqual(fname('%(id)s-%(width)s.%(ext)s'), '1234-NA.mp4') 
 537         # Replace missing fields with 'NA' 
 538         self
.assertEqual(fname('%(uploader_date)s-%(id)s.%(ext)s'), 'NA-1234.mp4') 
 539         self
.assertEqual(fname('%(height)d.%(ext)s'), '1080.mp4') 
 540         self
.assertEqual(fname('%(height)6d.%(ext)s'), '  1080.mp4') 
 541         self
.assertEqual(fname('%(height)-6d.%(ext)s'), '1080  .mp4') 
 542         self
.assertEqual(fname('%(height)06d.%(ext)s'), '001080.mp4') 
 543         self
.assertEqual(fname('%(height) 06d.%(ext)s'), ' 01080.mp4') 
 544         self
.assertEqual(fname('%(height)   06d.%(ext)s'), ' 01080.mp4') 
 545         self
.assertEqual(fname('%(height)0 6d.%(ext)s'), ' 01080.mp4') 
 546         self
.assertEqual(fname('%(height)0   6d.%(ext)s'), ' 01080.mp4') 
 547         self
.assertEqual(fname('%(height)   0   6d.%(ext)s'), ' 01080.mp4') 
 548         self
.assertEqual(fname('%%(height)06d.%(ext)s'), '%(height)06d.mp4') 
 549         self
.assertEqual(fname('%(width)06d.%(ext)s'), 'NA.mp4') 
 550         self
.assertEqual(fname('%(width)06d.%%(ext)s'), 'NA.%(ext)s') 
 551         self
.assertEqual(fname('%%(width)06d.%(ext)s'), '%(width)06d.mp4') 
 553     def test_format_note(self
): 
 555         self
.assertEqual(ydl
._format
_note
({}), '') 
 556         assertRegexpMatches(self
, ydl
._format
_note
({ 
 559         assertRegexpMatches(self
, ydl
._format
_note
({ 
 563     def test_postprocessors(self
): 
 564         filename 
= 'post-processor-testfile.mp4' 
 565         audiofile 
= filename 
+ '.mp3' 
 567         class SimplePP(PostProcessor
): 
 569                 with open(audiofile
, 'wt') as f
: 
 571                 return [info
['filepath']], info
 
 573         def run_pp(params
, PP
): 
 574             with open(filename
, 'wt') as f
: 
 576             ydl 
= YoutubeDL(params
) 
 577             ydl
.add_post_processor(PP()) 
 578             ydl
.post_process(filename
, {'filepath': filename
}) 
 580         run_pp({'keepvideo': True}, SimplePP
) 
 581         self
.assertTrue(os
.path
.exists(filename
), '%s doesn\'t exist' % filename
) 
 582         self
.assertTrue(os
.path
.exists(audiofile
), '%s doesn\'t exist' % audiofile
) 
 586         run_pp({'keepvideo': False}, SimplePP
) 
 587         self
.assertFalse(os
.path
.exists(filename
), '%s exists' % filename
) 
 588         self
.assertTrue(os
.path
.exists(audiofile
), '%s doesn\'t exist' % audiofile
) 
 591         class ModifierPP(PostProcessor
): 
 593                 with open(info
['filepath'], 'wt') as f
: 
 597         run_pp({'keepvideo': False}, ModifierPP
) 
 598         self
.assertTrue(os
.path
.exists(filename
), '%s doesn\'t exist' % filename
) 
 601     def test_match_filter(self
): 
 602         class FilterYDL(YDL
): 
 603             def __init__(self
, *args
, **kwargs
): 
 604                 super(FilterYDL
, self
).__init
__(*args
, **kwargs
) 
 605                 self
.params
['simulate'] = True 
 607             def process_info(self
, info_dict
): 
 608                 super(YDL
, self
).process_info(info_dict
) 
 610             def _match_entry(self
, info_dict
, incomplete
): 
 611                 res 
= super(FilterYDL
, self
)._match
_entry
(info_dict
, incomplete
) 
 613                     self
.downloaded_info_dicts
.append(info_dict
) 
 622             'filesize': 10 * 1024, 
 624             'uploader': "變態妍字幕版 太妍 тест", 
 625             'creator': "тест ' 123 ' тест--", 
 633             'description': 'foo', 
 634             'filesize': 5 * 1024, 
 636             'uploader': "тест 123", 
 638         videos 
= [first
, second
] 
 640         def get_videos(filter_
=None): 
 641             ydl 
= FilterYDL({'match_filter': filter_
}) 
 643                 ydl
.process_ie_result(v
, download
=True) 
 644             return [v
['id'] for v 
in ydl
.downloaded_info_dicts
] 
 647         self
.assertEqual(res
, ['1', '2']) 
 653                 return 'Video id is not 1' 
 655         self
.assertEqual(res
, ['1']) 
 657         f 
= match_filter_func('duration < 30') 
 659         self
.assertEqual(res
, ['2']) 
 661         f 
= match_filter_func('description = foo') 
 663         self
.assertEqual(res
, ['2']) 
 665         f 
= match_filter_func('description =? foo') 
 667         self
.assertEqual(res
, ['1', '2']) 
 669         f 
= match_filter_func('filesize > 5KiB') 
 671         self
.assertEqual(res
, ['1']) 
 673         f 
= match_filter_func('playlist_id = 42') 
 675         self
.assertEqual(res
, ['1']) 
 677         f 
= match_filter_func('uploader = "變態妍字幕版 太妍 тест"') 
 679         self
.assertEqual(res
, ['1']) 
 681         f 
= match_filter_func('uploader != "變態妍字幕版 太妍 тест"') 
 683         self
.assertEqual(res
, ['2']) 
 685         f 
= match_filter_func('creator = "тест \' 123 \' тест--"') 
 687         self
.assertEqual(res
, ['1']) 
 689         f 
= match_filter_func("creator = 'тест \\' 123 \\' тест--'") 
 691         self
.assertEqual(res
, ['1']) 
 693         f 
= match_filter_func(r
"creator = 'тест \' 123 \' тест--' & duration > 30") 
 695         self
.assertEqual(res
, []) 
 697     def test_playlist_items_selection(self
): 
 700             'title': compat_str(i
), 
 702         } for i 
in range(1, 5)] 
 707             'extractor': 'test:playlist', 
 708             'extractor_key': 'test:playlist', 
 709             'webpage_url': 'http://example.com', 
 714             # make a copy because the dictionary can be modified 
 715             ydl
.process_ie_result(playlist
.copy()) 
 716             return [int(v
['id']) for v 
in ydl
.downloaded_info_dicts
] 
 719         self
.assertEqual(result
, [1, 2, 3, 4]) 
 721         result 
= get_ids({'playlistend': 10}) 
 722         self
.assertEqual(result
, [1, 2, 3, 4]) 
 724         result 
= get_ids({'playlistend': 2}) 
 725         self
.assertEqual(result
, [1, 2]) 
 727         result 
= get_ids({'playliststart': 10}) 
 728         self
.assertEqual(result
, []) 
 730         result 
= get_ids({'playliststart': 2}) 
 731         self
.assertEqual(result
, [2, 3, 4]) 
 733         result 
= get_ids({'playlist_items': '2-4'}) 
 734         self
.assertEqual(result
, [2, 3, 4]) 
 736         result 
= get_ids({'playlist_items': '2,4'}) 
 737         self
.assertEqual(result
, [2, 4]) 
 739         result 
= get_ids({'playlist_items': '10'}) 
 740         self
.assertEqual(result
, []) 
 742     def test_urlopen_no_file_protocol(self
): 
 743         # see https://github.com/rg3/youtube-dl/issues/8227 
 745         self
.assertRaises(compat_urllib_error
.URLError
, ydl
.urlopen
, 'file:///etc/passwd') 
 747     def test_do_not_override_ie_key_in_url_transparent(self
): 
 750         class Foo1IE(InfoExtractor
): 
 751             _VALID_URL 
= r
'foo1:' 
 753             def _real_extract(self
, url
): 
 755                     '_type': 'url_transparent', 
 758                     'title': 'foo1 title' 
 761         class Foo2IE(InfoExtractor
): 
 762             _VALID_URL 
= r
'foo2:' 
 764             def _real_extract(self
, url
): 
 771         class Foo3IE(InfoExtractor
): 
 772             _VALID_URL 
= r
'foo3:' 
 774             def _real_extract(self
, url
): 
 775                 return _make_result([{'url': TEST_URL
}], title
='foo3 title') 
 777         ydl
.add_info_extractor(Foo1IE(ydl
)) 
 778         ydl
.add_info_extractor(Foo2IE(ydl
)) 
 779         ydl
.add_info_extractor(Foo3IE(ydl
)) 
 780         ydl
.extract_info('foo1:') 
 781         downloaded 
= ydl
.downloaded_info_dicts
[0] 
 782         self
.assertEqual(downloaded
['url'], TEST_URL
) 
 783         self
.assertEqual(downloaded
['title'], 'foo1 title') 
 786 if __name__ 
== '__main__':