Allow passing different options to each extractor

Currently it can only be done through python and only affects the extractors, not YoutubeDL.
This commit is contained in:
Jaime Marquínez Ferrándiz 2016-03-18 19:02:09 +01:00
parent 75f86b2a66
commit b67e4daddb
4 changed files with 71 additions and 4 deletions

View File

@ -17,6 +17,7 @@ from youtube_dl.extractor import YoutubeIE
from youtube_dl.extractor.common import InfoExtractor from youtube_dl.extractor.common import InfoExtractor
from youtube_dl.postprocessor.common import PostProcessor from youtube_dl.postprocessor.common import PostProcessor
from youtube_dl.utils import ExtractorError, match_filter_func from youtube_dl.utils import ExtractorError, match_filter_func
from youtube_dl.params import Params
TEST_URL = 'http://localhost/sample.mp4' TEST_URL = 'http://localhost/sample.mp4'
@ -702,6 +703,22 @@ class TestYoutubeDL(unittest.TestCase):
downloaded = ydl.downloaded_info_dicts[0] downloaded = ydl.downloaded_info_dicts[0]
self.assertEqual(downloaded['url'], TEST_URL) self.assertEqual(downloaded['url'], TEST_URL)
def test_subparams(self):
example_params = {'foo': 'example'}
params = Params({'foo': 'base', 'blah': 'base'}, {'example.com': example_params})
ydl = YoutubeDL(params)
class ExampleIE(InfoExtractor):
IE_NAME = 'example.com'
ie = ExampleIE()
ydl.add_info_extractor(ie)
pars = ie.params
self.assertEqual(pars['foo'], 'example')
self.assertEqual(pars['blah'], 'base')
self.assertEqual(pars.get('blah'), 'base')
self.assertEqual(pars.get('nonexistant'), None)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View File

@ -94,6 +94,7 @@ from .postprocessor import (
get_postprocessor, get_postprocessor,
) )
from .version import __version__ from .version import __version__
from .params import Params
if compat_os_name == 'nt': if compat_os_name == 'nt':
import ctypes import ctypes
@ -122,7 +123,9 @@ class YoutubeDL(object):
options instead. These options are available through the params options instead. These options are available through the params
attribute for the InfoExtractors to use. The YoutubeDL also attribute for the InfoExtractors to use. The YoutubeDL also
registers itself as the downloader in charge for the InfoExtractors registers itself as the downloader in charge for the InfoExtractors
that are added to it, so this is a "mutual registration". that are added to it, so this is a "mutual registration". To use different
parameters in an extractor, the youtube_dl.params.Params class must be
used.
Available options: Available options:
@ -294,11 +297,14 @@ class YoutubeDL(object):
self._num_downloads = 0 self._num_downloads = 0
self._screen_file = [sys.stdout, sys.stderr][params.get('logtostderr', False)] self._screen_file = [sys.stdout, sys.stderr][params.get('logtostderr', False)]
self._err_file = sys.stderr self._err_file = sys.stderr
self.params = { if not isinstance(params, Params):
params = Params(params)
self.params = params
default_params = {
# Default parameters # Default parameters
'nocheckcertificate': False, 'nocheckcertificate': False,
} }
self.params.update(params) self.add_extra_info(self.params, default_params)
self.cache = Cache(self) self.cache = Cache(self)
if params.get('bidi_workaround', False): if params.get('bidi_workaround', False):

View File

@ -53,6 +53,7 @@ from ..utils import (
update_Request, update_Request,
update_url_query, update_url_query,
) )
from ..params import ParamsSection
class InfoExtractor(object): class InfoExtractor(object):
@ -331,7 +332,7 @@ class InfoExtractor(object):
def set_downloader(self, downloader): def set_downloader(self, downloader):
"""Sets the downloader for this IE.""" """Sets the downloader for this IE."""
self._downloader = downloader self._downloader = downloader
self.params = downloader.params if downloader else {} self.params = downloader.params.section(self.IE_NAME) if downloader else ParamsSection()
def _real_initialize(self): def _real_initialize(self):
"""Real initialization process. Redefine in subclasses.""" """Real initialization process. Redefine in subclasses."""

43
youtube_dl/params.py Normal file
View File

@ -0,0 +1,43 @@
from __future__ import unicode_literals
class Params(dict):
"""Params class
The params class holds the parameters for YoutubeDL objects, in its
simplest form it's initialized with a dictionary with the parameters. To
override some parameter in an info extractor a dictionary can be passed as
the second argument, its keys must match the IE_NAME properties of the
extractors.
"""
def __init__(self, params, sections=None):
super(Params, self).__init__(params)
if sections is None:
sections = {}
self.sections = sections
def section(self, section):
"""Return the params for the specified section"""
return ParamsSection(self.sections.get(section, {}), self)
class ParamsSection(object):
def __init__(self, main=None, parent=None):
if main is None:
main = {}
if parent is None:
parent = Params({})
self.main = main
self.parent = parent
def __getitem__(self, key):
if key in self.main:
return self.main[key]
else:
return self.parent[key]
def get(self, key, default=None):
try:
return self[key]
except KeyError:
return default