]> jfr.im git - yt-dlp.git/blame - youtube_dl/__init__.py
added the --no-post-overwrites argument
[yt-dlp.git] / youtube_dl / __init__.py
CommitLineData
235b3ba4
PH
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3
02b324a2 4from __future__ import with_statement
9e8056d5 5from __future__ import absolute_import
02b324a2 6
3906e6ce 7__authors__ = (
59ae15a5
PH
8 'Ricardo Garcia Gonzalez',
9 'Danny Colligan',
10 'Benjamin Johnson',
11 'Vasyl\' Vavrychuk',
12 'Witold Baryluk',
13 'Paweł Paprota',
14 'Gergely Imreh',
15 'Rogério Brito',
16 'Philipp Hagemeister',
17 'Sören Schulze',
18 'Kevin Ngo',
19 'Ori Avtalion',
20 'shizeeg',
21 'Filippo Valsorda',
22 'Christian Albrecht',
88f6c78b 23 'Dave Vasilevsky',
59ae15a5 24 )
235b3ba4
PH
25
26__license__ = 'Public Domain'
235b3ba4 27
c9ed14e6 28import getpass
c9ed14e6 29import optparse
235b3ba4 30import os
235b3ba4 31import re
c9ed14e6 32import shlex
235b3ba4 33import socket
235b3ba4
PH
34import subprocess
35import sys
235b3ba4 36import warnings
235b3ba4 37
9e8056d5 38from .utils import *
cc51a7d4 39from .version import __version__
9e8056d5
PH
40from .FileDownloader import *
41from .InfoExtractors import *
42from .PostProcessor import *
235b3ba4
PH
43
44def updateSelf(downloader, filename):
5a304a76 45 """Update the program file with the latest version from the repository"""
59ae15a5 46
5a304a76 47 # TODO: at least, check https certificates
59ae15a5 48
5a304a76 49 from zipimport import zipimporter
59ae15a5 50
5a304a76
FV
51 API_URL = "https://api.github.com/repos/rg3/youtube-dl/downloads"
52 BIN_URL = "https://github.com/downloads/rg3/youtube-dl/youtube-dl"
53 EXE_URL = "https://github.com/downloads/rg3/youtube-dl/youtube-dl.exe"
54
55 if hasattr(sys, "frozen"): # PY2EXE
56 if not os.access(filename, os.W_OK):
57 sys.exit('ERROR: no write permissions on %s' % filename)
58
59 downloader.to_screen(u'Updating to latest version...')
60
61 urla = compat_urllib_request.urlopen(API_URL)
62 download = filter(lambda x: x["name"] == "youtube-dl.exe", json.loads(urla.read()))
63 if not download:
64 downloader.to_screen(u'ERROR: can\'t find the current version. Please try again later.')
65 return
66 newversion = download[0]["description"].strip()
67 if newversion == __version__:
68 downloader.to_screen(u'youtube-dl is up-to-date (' + __version__ + ')')
69 return
70 urla.close()
59ae15a5 71
59ae15a5
PH
72 exe = os.path.abspath(filename)
73 directory = os.path.dirname(exe)
74 if not os.access(directory, os.W_OK):
75 sys.exit('ERROR: no write permissions on %s' % directory)
76
77 try:
5a304a76 78 urlh = compat_urllib_request.urlopen(EXE_URL)
59ae15a5
PH
79 newcontent = urlh.read()
80 urlh.close()
81 with open(exe + '.new', 'wb') as outf:
82 outf.write(newcontent)
83 except (IOError, OSError) as err:
84 sys.exit('ERROR: unable to download latest version')
85
86 try:
87 bat = os.path.join(directory, 'youtube-dl-updater.bat')
88 b = open(bat, 'w')
89 b.write("""
f36cd076 90echo Updating youtube-dl...
bcfde70d 91ping 127.0.0.1 -n 5 -w 1000 > NUL
53e89361
FV
92move /Y "%s.new" "%s"
93del "%s"
59ae15a5
PH
94 \n""" %(exe, exe, bat))
95 b.close()
51937c08 96
59ae15a5
PH
97 os.startfile(bat)
98 except (IOError, OSError) as err:
99 sys.exit('ERROR: unable to overwrite current version')
53e89361 100
5a304a76
FV
101 elif isinstance(globals().get('__loader__'), zipimporter): # UNIX ZIP
102 if not os.access(filename, os.W_OK):
103 sys.exit('ERROR: no write permissions on %s' % filename)
104
105 downloader.to_screen(u'Updating to latest version...')
106
107 urla = compat_urllib_request.urlopen(API_URL)
108 download = [x for x in json.loads(urla.read().decode('utf8')) if x["name"] == "youtube-dl"]
109 if not download:
110 downloader.to_screen(u'ERROR: can\'t find the current version. Please try again later.')
111 return
112 newversion = download[0]["description"].strip()
113 if newversion == __version__:
114 downloader.to_screen(u'youtube-dl is up-to-date (' + __version__ + ')')
115 return
116 urla.close()
117
59ae15a5 118 try:
5a304a76 119 urlh = compat_urllib_request.urlopen(BIN_URL)
59ae15a5
PH
120 newcontent = urlh.read()
121 urlh.close()
122 except (IOError, OSError) as err:
123 sys.exit('ERROR: unable to download latest version')
235b3ba4 124
59ae15a5
PH
125 try:
126 with open(filename, 'wb') as outf:
127 outf.write(newcontent)
128 except (IOError, OSError) as err:
129 sys.exit('ERROR: unable to overwrite current version')
235b3ba4 130
5a304a76
FV
131 else:
132 downloader.to_screen(u'It looks like you installed youtube-dl with pip or setup.py. Please use that to update.')
133 return
134
59ae15a5 135 downloader.to_screen(u'Updated youtube-dl. Restart youtube-dl to use the new version.')
235b3ba4
PH
136
137def parseOpts():
59ae15a5
PH
138 def _readOptions(filename_bytes):
139 try:
140 optionf = open(filename_bytes)
141 except IOError:
142 return [] # silently skip if file is not present
143 try:
144 res = []
145 for l in optionf:
146 res += shlex.split(l, comments=True)
147 finally:
148 optionf.close()
149 return res
150
151 def _format_option_string(option):
152 ''' ('-o', '--option') -> -o, --format METAVAR'''
153
154 opts = []
155
156 if option._short_opts:
157 opts.append(option._short_opts[0])
158 if option._long_opts:
159 opts.append(option._long_opts[0])
160 if len(opts) > 1:
161 opts.insert(1, ', ')
162
163 if option.takes_value(): opts.append(' %s' % option.metavar)
164
165 return "".join(opts)
166
167 def _find_term_columns():
168 columns = os.environ.get('COLUMNS', None)
169 if columns:
170 return int(columns)
171
172 try:
173 sp = subprocess.Popen(['stty', 'size'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
174 out,err = sp.communicate()
175 return int(out.split()[1])
176 except:
177 pass
178 return None
179
180 max_width = 80
181 max_help_position = 80
182
183 # No need to wrap help messages if we're on a wide console
184 columns = _find_term_columns()
185 if columns: max_width = columns
186
187 fmt = optparse.IndentedHelpFormatter(width=max_width, max_help_position=max_help_position)
188 fmt.format_option_strings = _format_option_string
189
190 kw = {
191 'version' : __version__,
192 'formatter' : fmt,
193 'usage' : '%prog [options] url [url...]',
194 'conflict_handler' : 'resolve',
195 }
196
197 parser = optparse.OptionParser(**kw)
198
199 # option groups
200 general = optparse.OptionGroup(parser, 'General Options')
201 selection = optparse.OptionGroup(parser, 'Video Selection')
202 authentication = optparse.OptionGroup(parser, 'Authentication Options')
203 video_format = optparse.OptionGroup(parser, 'Video Format Options')
204 postproc = optparse.OptionGroup(parser, 'Post-processing Options')
205 filesystem = optparse.OptionGroup(parser, 'Filesystem Options')
206 verbosity = optparse.OptionGroup(parser, 'Verbosity / Simulation Options')
207
208 general.add_option('-h', '--help',
209 action='help', help='print this help text and exit')
210 general.add_option('-v', '--version',
211 action='version', help='print program version and exit')
212 general.add_option('-U', '--update',
213 action='store_true', dest='update_self', help='update this program to latest version')
214 general.add_option('-i', '--ignore-errors',
215 action='store_true', dest='ignoreerrors', help='continue on download errors', default=False)
216 general.add_option('-r', '--rate-limit',
217 dest='ratelimit', metavar='LIMIT', help='download rate limit (e.g. 50k or 44.6m)')
218 general.add_option('-R', '--retries',
219 dest='retries', metavar='RETRIES', help='number of retries (default is %default)', default=10)
220 general.add_option('--buffer-size',
221 dest='buffersize', metavar='SIZE', help='size of download buffer (e.g. 1024 or 16k) (default is %default)', default="1024")
222 general.add_option('--no-resize-buffer',
223 action='store_true', dest='noresizebuffer',
224 help='do not automatically adjust the buffer size. By default, the buffer size is automatically resized from an initial value of SIZE.', default=False)
225 general.add_option('--dump-user-agent',
226 action='store_true', dest='dump_user_agent',
227 help='display the current browser identification', default=False)
228 general.add_option('--user-agent',
229 dest='user_agent', help='specify a custom user agent', metavar='UA')
230 general.add_option('--list-extractors',
231 action='store_true', dest='list_extractors',
232 help='List all supported extractors and the URLs they would handle', default=False)
8d5d3a5d 233 general.add_option('--test', action='store_true', dest='test', default=False, help=optparse.SUPPRESS_HELP)
59ae15a5
PH
234
235 selection.add_option('--playlist-start',
236 dest='playliststart', metavar='NUMBER', help='playlist video to start at (default is %default)', default=1)
237 selection.add_option('--playlist-end',
238 dest='playlistend', metavar='NUMBER', help='playlist video to end at (default is last)', default=-1)
239 selection.add_option('--match-title', dest='matchtitle', metavar='REGEX',help='download only matching titles (regex or caseless sub-string)')
240 selection.add_option('--reject-title', dest='rejecttitle', metavar='REGEX',help='skip download for matching titles (regex or caseless sub-string)')
241 selection.add_option('--max-downloads', metavar='NUMBER', dest='max_downloads', help='Abort after downloading NUMBER files', default=None)
242
243 authentication.add_option('-u', '--username',
244 dest='username', metavar='USERNAME', help='account username')
245 authentication.add_option('-p', '--password',
246 dest='password', metavar='PASSWORD', help='account password')
247 authentication.add_option('-n', '--netrc',
248 action='store_true', dest='usenetrc', help='use .netrc authentication data', default=False)
249
250
251 video_format.add_option('-f', '--format',
252 action='store', dest='format', metavar='FORMAT', help='video format code')
253 video_format.add_option('--all-formats',
254 action='store_const', dest='format', help='download all available video formats', const='all')
255 video_format.add_option('--prefer-free-formats',
256 action='store_true', dest='prefer_free_formats', default=False, help='prefer free video formats unless a specific one is requested')
257 video_format.add_option('--max-quality',
258 action='store', dest='format_limit', metavar='FORMAT', help='highest quality format to download')
259 video_format.add_option('-F', '--list-formats',
260 action='store_true', dest='listformats', help='list all available formats (currently youtube only)')
261 video_format.add_option('--write-srt',
262 action='store_true', dest='writesubtitles',
263 help='write video closed captions to a .srt file (currently youtube only)', default=False)
264 video_format.add_option('--srt-lang',
265 action='store', dest='subtitleslang', metavar='LANG',
266 help='language of the closed captions to download (optional) use IETF language tags like \'en\'')
267
268
269 verbosity.add_option('-q', '--quiet',
270 action='store_true', dest='quiet', help='activates quiet mode', default=False)
271 verbosity.add_option('-s', '--simulate',
272 action='store_true', dest='simulate', help='do not download the video and do not write anything to disk', default=False)
273 verbosity.add_option('--skip-download',
274 action='store_true', dest='skip_download', help='do not download the video', default=False)
275 verbosity.add_option('-g', '--get-url',
276 action='store_true', dest='geturl', help='simulate, quiet but print URL', default=False)
277 verbosity.add_option('-e', '--get-title',
278 action='store_true', dest='gettitle', help='simulate, quiet but print title', default=False)
279 verbosity.add_option('--get-thumbnail',
280 action='store_true', dest='getthumbnail',
281 help='simulate, quiet but print thumbnail URL', default=False)
282 verbosity.add_option('--get-description',
283 action='store_true', dest='getdescription',
284 help='simulate, quiet but print video description', default=False)
285 verbosity.add_option('--get-filename',
286 action='store_true', dest='getfilename',
287 help='simulate, quiet but print output filename', default=False)
288 verbosity.add_option('--get-format',
289 action='store_true', dest='getformat',
290 help='simulate, quiet but print output format', default=False)
291 verbosity.add_option('--no-progress',
292 action='store_true', dest='noprogress', help='do not print progress bar', default=False)
293 verbosity.add_option('--console-title',
294 action='store_true', dest='consoletitle',
295 help='display progress in console titlebar', default=False)
296 verbosity.add_option('-v', '--verbose',
297 action='store_true', dest='verbose', help='print various debugging information', default=False)
298
299
300 filesystem.add_option('-t', '--title',
301 action='store_true', dest='usetitle', help='use title in file name', default=False)
302 filesystem.add_option('--id',
303 action='store_true', dest='useid', help='use video ID in file name', default=False)
304 filesystem.add_option('-l', '--literal',
305 action='store_true', dest='usetitle', help='[deprecated] alias of --title', default=False)
306 filesystem.add_option('-A', '--auto-number',
307 action='store_true', dest='autonumber',
308 help='number downloaded files starting from 00000', default=False)
309 filesystem.add_option('-o', '--output',
77c4beab 310 dest='outtmpl', metavar='TEMPLATE', help='output filename template. Use %(title)s to get the title, %(uploader)s for the uploader name, %(uploader_id)s for the uploader nickname if different, %(autonumber)s to get an automatically incremented number, %(ext)s for the filename extension, %(upload_date)s for the upload date (YYYYMMDD), %(extractor)s for the provider (youtube, metacafe, etc), %(id)s for the video id and %% for a literal percent. Use - to output to stdout. Can also be used to download to a different directory, for example with -o \'/my/downloads/%(uploader)s/%(title)s-%(id)s.%(ext)s\' .')
59ae15a5
PH
311 filesystem.add_option('--restrict-filenames',
312 action='store_true', dest='restrictfilenames',
313 help='Restrict filenames to only ASCII characters, and avoid "&" and spaces in filenames', default=False)
314 filesystem.add_option('-a', '--batch-file',
315 dest='batchfile', metavar='FILE', help='file containing URLs to download (\'-\' for stdin)')
316 filesystem.add_option('-w', '--no-overwrites',
317 action='store_true', dest='nooverwrites', help='do not overwrite files', default=False)
318 filesystem.add_option('-c', '--continue',
319 action='store_true', dest='continue_dl', help='resume partially downloaded files', default=True)
320 filesystem.add_option('--no-continue',
321 action='store_false', dest='continue_dl',
322 help='do not resume partially downloaded files (restart from beginning)')
323 filesystem.add_option('--cookies',
324 dest='cookiefile', metavar='FILE', help='file to read cookies from and dump cookie jar in')
325 filesystem.add_option('--no-part',
326 action='store_true', dest='nopart', help='do not use .part files', default=False)
327 filesystem.add_option('--no-mtime',
328 action='store_false', dest='updatetime',
329 help='do not use the Last-modified header to set the file modification time', default=True)
330 filesystem.add_option('--write-description',
331 action='store_true', dest='writedescription',
332 help='write video description to a .description file', default=False)
333 filesystem.add_option('--write-info-json',
334 action='store_true', dest='writeinfojson',
335 help='write video metadata to a .info.json file', default=False)
336
337
338 postproc.add_option('-x', '--extract-audio', action='store_true', dest='extractaudio', default=False,
339 help='convert video files to audio-only files (requires ffmpeg or avconv and ffprobe or avprobe)')
340 postproc.add_option('--audio-format', metavar='FORMAT', dest='audioformat', default='best',
341 help='"best", "aac", "vorbis", "mp3", "m4a", or "wav"; best by default')
342 postproc.add_option('--audio-quality', metavar='QUALITY', dest='audioquality', default='5',
343 help='ffmpeg/avconv audio quality specification, insert a value between 0 (better) and 9 (worse) for VBR or a specific bitrate like 128K (default 5)')
344 postproc.add_option('-k', '--keep-video', action='store_true', dest='keepvideo', default=False,
345 help='keeps the video file on disk after the post-processing; the video is erased by default')
f0648fc1
BPG
346 postproc.add_option('--no-post-overwrites', action='store_true', dest='nopostoverwrites', default=False,
347 help='do not overwrite post-processed files; the post-processed files are overwritten by default')
59ae15a5
PH
348
349
350 parser.add_option_group(general)
351 parser.add_option_group(selection)
352 parser.add_option_group(filesystem)
353 parser.add_option_group(verbosity)
354 parser.add_option_group(video_format)
355 parser.add_option_group(authentication)
356 parser.add_option_group(postproc)
357
358 xdg_config_home = os.environ.get('XDG_CONFIG_HOME')
359 if xdg_config_home:
360 userConf = os.path.join(xdg_config_home, 'youtube-dl.conf')
361 else:
362 userConf = os.path.join(os.path.expanduser('~'), '.config', 'youtube-dl.conf')
363 argv = _readOptions('/etc/youtube-dl.conf') + _readOptions(userConf) + sys.argv[1:]
364 opts, args = parser.parse_args(argv)
365
366 return parser, opts, args
235b3ba4
PH
367
368def gen_extractors():
59ae15a5
PH
369 """ Return a list of an instance of every supported extractor.
370 The order does matter; the first extractor matched is the one handling the URL.
371 """
372 return [
373 YoutubePlaylistIE(),
374 YoutubeChannelIE(),
375 YoutubeUserIE(),
376 YoutubeSearchIE(),
377 YoutubeIE(),
378 MetacafeIE(),
379 DailymotionIE(),
59ae15a5
PH
380 GoogleSearchIE(),
381 PhotobucketIE(),
382 YahooIE(),
383 YahooSearchIE(),
384 DepositFilesIE(),
385 FacebookIE(),
386 BlipTVUserIE(),
387 BlipTVIE(),
388 VimeoIE(),
389 MyVideoIE(),
390 ComedyCentralIE(),
391 EscapistIE(),
392 CollegeHumorIE(),
393 XVideosIE(),
394 SoundcloudIE(),
395 InfoQIE(),
396 MixcloudIE(),
397 StanfordOpenClassroomIE(),
398 MTVIE(),
399 YoukuIE(),
400 XNXXIE(),
401 GooglePlusIE(),
402 ArteTvIE(),
4cc3d074 403 NBAIE(),
0b40544f 404 JustinTVIE(),
21a9c6aa 405 FunnyOrDieIE(),
59ae15a5
PH
406 GenericIE()
407 ]
235b3ba4
PH
408
409def _real_main():
59ae15a5
PH
410 parser, opts, args = parseOpts()
411
412 # Open appropriate CookieJar
413 if opts.cookiefile is None:
414 jar = compat_cookiejar.CookieJar()
415 else:
416 try:
417 jar = compat_cookiejar.MozillaCookieJar(opts.cookiefile)
418 if os.path.isfile(opts.cookiefile) and os.access(opts.cookiefile, os.R_OK):
419 jar.load()
420 except (IOError, OSError) as err:
421 sys.exit(u'ERROR: unable to open cookie file')
422 # Set user agent
423 if opts.user_agent is not None:
424 std_headers['User-Agent'] = opts.user_agent
425
426 # Dump user agent
427 if opts.dump_user_agent:
428 print(std_headers['User-Agent'])
429 sys.exit(0)
430
431 # Batch file verification
432 batchurls = []
433 if opts.batchfile is not None:
434 try:
435 if opts.batchfile == '-':
436 batchfd = sys.stdin
437 else:
438 batchfd = open(opts.batchfile, 'r')
439 batchurls = batchfd.readlines()
440 batchurls = [x.strip() for x in batchurls]
441 batchurls = [x for x in batchurls if len(x) > 0 and not re.search(r'^[#/;]', x)]
442 except IOError:
443 sys.exit(u'ERROR: batch file could not be read')
444 all_urls = batchurls + args
445 all_urls = [url.strip() for url in all_urls]
446
447 # General configuration
448 cookie_processor = compat_urllib_request.HTTPCookieProcessor(jar)
449 proxy_handler = compat_urllib_request.ProxyHandler()
450 opener = compat_urllib_request.build_opener(proxy_handler, cookie_processor, YoutubeDLHandler())
451 compat_urllib_request.install_opener(opener)
452 socket.setdefaulttimeout(300) # 5 minutes should be enough (famous last words)
453
454 extractors = gen_extractors()
455
456 if opts.list_extractors:
457 for ie in extractors:
b08e09c3 458 print(ie.IE_NAME + (' (CURRENTLY BROKEN)' if not ie._WORKING else ''))
1a2c3c0f
FV
459 matchedUrls = [url for url in all_urls if ie.suitable(url)]
460 all_urls = [url for url in all_urls if url not in matchedUrls]
59ae15a5
PH
461 for mu in matchedUrls:
462 print(u' ' + mu)
463 sys.exit(0)
464
465 # Conflicting, missing and erroneous options
466 if opts.usenetrc and (opts.username is not None or opts.password is not None):
467 parser.error(u'using .netrc conflicts with giving username/password')
468 if opts.password is not None and opts.username is None:
469 parser.error(u'account username missing')
470 if opts.outtmpl is not None and (opts.usetitle or opts.autonumber or opts.useid):
471 parser.error(u'using output template conflicts with using title, video ID or auto number')
472 if opts.usetitle and opts.useid:
473 parser.error(u'using title conflicts with using video ID')
474 if opts.username is not None and opts.password is None:
475 opts.password = getpass.getpass(u'Type account password and press return:')
476 if opts.ratelimit is not None:
477 numeric_limit = FileDownloader.parse_bytes(opts.ratelimit)
478 if numeric_limit is None:
479 parser.error(u'invalid rate limit specified')
480 opts.ratelimit = numeric_limit
481 if opts.retries is not None:
482 try:
483 opts.retries = int(opts.retries)
484 except (TypeError, ValueError) as err:
485 parser.error(u'invalid retry count specified')
486 if opts.buffersize is not None:
487 numeric_buffersize = FileDownloader.parse_bytes(opts.buffersize)
488 if numeric_buffersize is None:
489 parser.error(u'invalid buffer size specified')
490 opts.buffersize = numeric_buffersize
491 try:
492 opts.playliststart = int(opts.playliststart)
493 if opts.playliststart <= 0:
494 raise ValueError(u'Playlist start must be positive')
495 except (TypeError, ValueError) as err:
496 parser.error(u'invalid playlist start number specified')
497 try:
498 opts.playlistend = int(opts.playlistend)
499 if opts.playlistend != -1 and (opts.playlistend <= 0 or opts.playlistend < opts.playliststart):
500 raise ValueError(u'Playlist end must be greater than playlist start')
501 except (TypeError, ValueError) as err:
502 parser.error(u'invalid playlist end number specified')
503 if opts.extractaudio:
504 if opts.audioformat not in ['best', 'aac', 'mp3', 'vorbis', 'm4a', 'wav']:
505 parser.error(u'invalid audio format specified')
506 if opts.audioquality:
507 opts.audioquality = opts.audioquality.strip('k').strip('K')
508 if not opts.audioquality.isdigit():
509 parser.error(u'invalid audio quality specified')
510
5cb9c312
PH
511 if sys.version_info < (3,):
512 # In Python 2, sys.argv is a bytestring (also note http://bugs.python.org/issue2128 for Windows systems)
0be41ec2
PH
513 if opts.outtmpl is not None:
514 opts.outtmpl = opts.outtmpl.decode(preferredencoding())
5cb9c312
PH
515 outtmpl =((opts.outtmpl is not None and opts.outtmpl)
516 or (opts.format == '-1' and opts.usetitle and u'%(title)s-%(id)s-%(format)s.%(ext)s')
517 or (opts.format == '-1' and u'%(id)s-%(format)s.%(ext)s')
518 or (opts.usetitle and opts.autonumber and u'%(autonumber)s-%(title)s-%(id)s.%(ext)s')
519 or (opts.usetitle and u'%(title)s-%(id)s.%(ext)s')
520 or (opts.useid and u'%(id)s.%(ext)s')
521 or (opts.autonumber and u'%(autonumber)s-%(id)s.%(ext)s')
522 or u'%(id)s.%(ext)s')
59ae15a5
PH
523 # File downloader
524 fd = FileDownloader({
525 'usenetrc': opts.usenetrc,
526 'username': opts.username,
527 'password': opts.password,
528 'quiet': (opts.quiet or opts.geturl or opts.gettitle or opts.getthumbnail or opts.getdescription or opts.getfilename or opts.getformat),
529 'forceurl': opts.geturl,
530 'forcetitle': opts.gettitle,
531 'forcethumbnail': opts.getthumbnail,
532 'forcedescription': opts.getdescription,
533 'forcefilename': opts.getfilename,
534 'forceformat': opts.getformat,
535 'simulate': opts.simulate,
536 'skip_download': (opts.skip_download or opts.simulate or opts.geturl or opts.gettitle or opts.getthumbnail or opts.getdescription or opts.getfilename or opts.getformat),
537 'format': opts.format,
538 'format_limit': opts.format_limit,
539 'listformats': opts.listformats,
5cb9c312 540 'outtmpl': outtmpl,
59ae15a5
PH
541 'restrictfilenames': opts.restrictfilenames,
542 'ignoreerrors': opts.ignoreerrors,
543 'ratelimit': opts.ratelimit,
544 'nooverwrites': opts.nooverwrites,
545 'retries': opts.retries,
546 'buffersize': opts.buffersize,
547 'noresizebuffer': opts.noresizebuffer,
548 'continuedl': opts.continue_dl,
549 'noprogress': opts.noprogress,
550 'playliststart': opts.playliststart,
551 'playlistend': opts.playlistend,
552 'logtostderr': opts.outtmpl == '-',
553 'consoletitle': opts.consoletitle,
554 'nopart': opts.nopart,
555 'updatetime': opts.updatetime,
556 'writedescription': opts.writedescription,
557 'writeinfojson': opts.writeinfojson,
558 'writesubtitles': opts.writesubtitles,
559 'subtitleslang': opts.subtitleslang,
560 'matchtitle': opts.matchtitle,
561 'rejecttitle': opts.rejecttitle,
562 'max_downloads': opts.max_downloads,
563 'prefer_free_formats': opts.prefer_free_formats,
564 'verbose': opts.verbose,
8d5d3a5d 565 'test': opts.test,
59ae15a5
PH
566 })
567
568 if opts.verbose:
569 fd.to_screen(u'[debug] Proxy map: ' + str(proxy_handler.proxies))
570
571 for extractor in extractors:
572 fd.add_info_extractor(extractor)
573
574 # PostProcessors
575 if opts.extractaudio:
f0648fc1 576 fd.add_post_processor(FFmpegExtractAudioPP(preferredcodec=opts.audioformat, preferredquality=opts.audioquality, keepvideo=opts.keepvideo, nopostoverwrites=opts.nopostoverwrites))
59ae15a5
PH
577
578 # Update version
579 if opts.update_self:
580 updateSelf(fd, sys.argv[0])
581
582 # Maybe do nothing
583 if len(all_urls) < 1:
584 if not opts.update_self:
585 parser.error(u'you must provide at least one URL')
586 else:
587 sys.exit()
588
589 try:
590 retcode = fd.download(all_urls)
591 except MaxDownloadsReached:
592 fd.to_screen(u'--max-download limit reached, aborting.')
593 retcode = 101
594
595 # Dump cookie jar if requested
596 if opts.cookiefile is not None:
597 try:
598 jar.save()
599 except (IOError, OSError) as err:
600 sys.exit(u'ERROR: unable to save cookie jar')
601
602 sys.exit(retcode)
235b3ba4
PH
603
604def main():
59ae15a5
PH
605 try:
606 _real_main()
607 except DownloadError:
608 sys.exit(1)
609 except SameFileError:
610 sys.exit(u'ERROR: fixed output name but more than one file to download')
611 except KeyboardInterrupt:
612 sys.exit(u'\nERROR: Interrupted by user')