Add support for loading a config file with different parameters for each site
On Unix it look for ~/.config/youtube-dl/config.ini or ~/.config/youtube-dl.ini, Windows support is currently missing. The new config file is in the INI format, the options are given in the long form without the leading dashes. Parameters for an specific extractor are written in their own section. When a video is contained in a playlist, it inherits the parameters from the playlist extractor. Example: write-thumbnail= [youtube:playlist] output=%(playlist)s/%(id)s.%(ext)s [youtube] format=webm All the videos use '--write-thumbnail', videos inside a YouTube playlist use the specified output template and YouTube videos are downloaded in the webm format.
This commit is contained in:
parent
fa5bda9053
commit
e6f20cd142
@ -42,6 +42,7 @@ from .downloader import (
|
|||||||
)
|
)
|
||||||
from .extractor import gen_extractors, list_extractors
|
from .extractor import gen_extractors, list_extractors
|
||||||
from .YoutubeDL import YoutubeDL
|
from .YoutubeDL import YoutubeDL
|
||||||
|
from .params import Params, ParamsSection
|
||||||
|
|
||||||
|
|
||||||
def _build_ydl_opts(opts, parser):
|
def _build_ydl_opts(opts, parser):
|
||||||
@ -311,6 +312,30 @@ def _build_ydl_opts(opts, parser):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class CLIParams(Params):
|
||||||
|
def __init__(self, opts, build_section_args, parser):
|
||||||
|
super(CLIParams, self).__init__(_build_ydl_opts(opts, parser))
|
||||||
|
self.build_section_args = build_section_args
|
||||||
|
self.parser = parser
|
||||||
|
|
||||||
|
def section(self, section):
|
||||||
|
return CLIParamsSection([section], self.build_section_args, self.parser)
|
||||||
|
|
||||||
|
|
||||||
|
# TODO: investigate if it's worth to cache this
|
||||||
|
class CLIParamsSection(ParamsSection):
|
||||||
|
def __init__(self, sections, build_section_args, parser):
|
||||||
|
section_args = build_section_args(*sections)
|
||||||
|
section_opts = parser.parse_args(section_args)[0]
|
||||||
|
super(CLIParamsSection, self).__init__(_build_ydl_opts(section_opts, parser), {})
|
||||||
|
self.section_names = sections
|
||||||
|
self.build_section_args = build_section_args
|
||||||
|
self.parser = parser
|
||||||
|
|
||||||
|
def section(self, section):
|
||||||
|
return CLIParamsSection(self.section_names + [section], self.build_section_args, self.parser)
|
||||||
|
|
||||||
|
|
||||||
def _real_main(argv=None):
|
def _real_main(argv=None):
|
||||||
# Compatibility fixes for Windows
|
# Compatibility fixes for Windows
|
||||||
if sys.platform == 'win32':
|
if sys.platform == 'win32':
|
||||||
@ -321,7 +346,7 @@ def _real_main(argv=None):
|
|||||||
|
|
||||||
setproctitle('youtube-dl')
|
setproctitle('youtube-dl')
|
||||||
|
|
||||||
parser, opts, args = parseOpts(argv)
|
parser, opts, build_section_args, args = parseOpts(argv)
|
||||||
|
|
||||||
# Set user agent
|
# Set user agent
|
||||||
if opts.user_agent is not None:
|
if opts.user_agent is not None:
|
||||||
@ -385,7 +410,7 @@ def _real_main(argv=None):
|
|||||||
compat_print(desc)
|
compat_print(desc)
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
ydl_opts = _build_ydl_opts(opts, parser)
|
ydl_opts = CLIParams(opts, build_section_args, parser)
|
||||||
|
|
||||||
with YoutubeDL(ydl_opts) as ydl:
|
with YoutubeDL(ydl_opts) as ydl:
|
||||||
# Update version
|
# Update version
|
||||||
|
@ -582,11 +582,17 @@ if sys.version_info >= (3, 0):
|
|||||||
else:
|
else:
|
||||||
from tokenize import generate_tokens as compat_tokenize_tokenize
|
from tokenize import generate_tokens as compat_tokenize_tokenize
|
||||||
|
|
||||||
|
try:
|
||||||
|
import configparser as compat_configparser
|
||||||
|
except ImportError:
|
||||||
|
import ConfigParser as compat_configparser
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
'compat_HTMLParser',
|
'compat_HTMLParser',
|
||||||
'compat_HTTPError',
|
'compat_HTTPError',
|
||||||
'compat_basestring',
|
'compat_basestring',
|
||||||
'compat_chr',
|
'compat_chr',
|
||||||
|
'compat_configparser',
|
||||||
'compat_cookiejar',
|
'compat_cookiejar',
|
||||||
'compat_cookies',
|
'compat_cookies',
|
||||||
'compat_etree_fromstring',
|
'compat_etree_fromstring',
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import io
|
||||||
import os.path
|
import os.path
|
||||||
import optparse
|
import optparse
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from .downloader.external import list_external_downloaders
|
from .downloader.external import list_external_downloaders
|
||||||
from .compat import (
|
from .compat import (
|
||||||
|
compat_configparser,
|
||||||
compat_expanduser,
|
compat_expanduser,
|
||||||
compat_get_terminal_size,
|
compat_get_terminal_size,
|
||||||
compat_getenv,
|
compat_getenv,
|
||||||
@ -743,17 +745,41 @@ def parseOpts(overrideArguments=None):
|
|||||||
optionf.close()
|
optionf.close()
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
def _readIni(filename_bytes, default=([], {})):
|
||||||
|
try:
|
||||||
|
ini = open(filename_bytes)
|
||||||
|
except IOError:
|
||||||
|
return default # silently skip if file is not present
|
||||||
|
parser = compat_configparser.RawConfigParser()
|
||||||
|
ini = io.StringIO('[@GLOBAL@]\n' + ini.read())
|
||||||
|
parser.readfp(ini)
|
||||||
|
|
||||||
|
def convert_opts(opts):
|
||||||
|
return [
|
||||||
|
'--' + opt + ('' if not arg else ('=' + arg))
|
||||||
|
for opt, arg in opts]
|
||||||
|
global_opts = convert_opts(parser.items('@GLOBAL@'))
|
||||||
|
section_opts = dict((section, convert_opts(parser.items(section))) for section in parser.sections() if section != '@GLOBAL@')
|
||||||
|
return global_opts, section_opts
|
||||||
|
|
||||||
def _readUserConf():
|
def _readUserConf():
|
||||||
xdg_config_home = compat_getenv('XDG_CONFIG_HOME')
|
xdg_config_home = compat_getenv('XDG_CONFIG_HOME')
|
||||||
if xdg_config_home:
|
if xdg_config_home:
|
||||||
userConfFile = os.path.join(xdg_config_home, 'youtube-dl', 'config')
|
userConfFile = os.path.join(xdg_config_home, 'youtube-dl', 'config')
|
||||||
|
userIniFile = os.path.join(xdg_config_home, 'youtube-dl', 'config.ini')
|
||||||
if not os.path.isfile(userConfFile):
|
if not os.path.isfile(userConfFile):
|
||||||
userConfFile = os.path.join(xdg_config_home, 'youtube-dl.conf')
|
userConfFile = os.path.join(xdg_config_home, 'youtube-dl.conf')
|
||||||
|
if not os.path.isfile(userIniFile):
|
||||||
|
userIniFile = os.path.join(xdg_config_home, 'youtube-dl.ini')
|
||||||
else:
|
else:
|
||||||
userConfFile = os.path.join(compat_expanduser('~'), '.config', 'youtube-dl', 'config')
|
userConfFile = os.path.join(compat_expanduser('~'), '.config', 'youtube-dl', 'config')
|
||||||
|
userIniFile = os.path.join(compat_expanduser('~'), '.config', 'youtube-dl', 'config.ini')
|
||||||
if not os.path.isfile(userConfFile):
|
if not os.path.isfile(userConfFile):
|
||||||
userConfFile = os.path.join(compat_expanduser('~'), '.config', 'youtube-dl.conf')
|
userConfFile = os.path.join(compat_expanduser('~'), '.config', 'youtube-dl.conf')
|
||||||
|
if not os.path.isfile(userIniFile):
|
||||||
|
userIniFile = os.path.join(compat_expanduser('~'), '.config', 'youtube-dl.ini')
|
||||||
userConf = _readOptions(userConfFile, None)
|
userConf = _readOptions(userConfFile, None)
|
||||||
|
userIni = _readIni(userIniFile, None)
|
||||||
|
|
||||||
if userConf is None:
|
if userConf is None:
|
||||||
appdata_dir = compat_getenv('appdata')
|
appdata_dir = compat_getenv('appdata')
|
||||||
@ -778,7 +804,11 @@ def parseOpts(overrideArguments=None):
|
|||||||
if userConf is None:
|
if userConf is None:
|
||||||
userConf = []
|
userConf = []
|
||||||
|
|
||||||
return userConf
|
if userIni is None:
|
||||||
|
userIni = [], {}
|
||||||
|
iniGlobal, iniSections = userIni
|
||||||
|
|
||||||
|
return userConf + iniGlobal, iniSections
|
||||||
|
|
||||||
def _hide_login_info(opts):
|
def _hide_login_info(opts):
|
||||||
opts = list(opts)
|
opts = list(opts)
|
||||||
@ -807,18 +837,30 @@ def parseOpts(overrideArguments=None):
|
|||||||
if '--ignore-config' in command_line_conf:
|
if '--ignore-config' in command_line_conf:
|
||||||
system_conf = []
|
system_conf = []
|
||||||
user_conf = []
|
user_conf = []
|
||||||
|
user_sections = {}
|
||||||
else:
|
else:
|
||||||
system_conf = compat_conf(_readOptions('/etc/youtube-dl.conf'))
|
system_conf = compat_conf(_readOptions('/etc/youtube-dl.conf'))
|
||||||
if '--ignore-config' in system_conf:
|
if '--ignore-config' in system_conf:
|
||||||
user_conf = []
|
user_conf = []
|
||||||
|
user_sections = {}
|
||||||
else:
|
else:
|
||||||
user_conf = compat_conf(_readUserConf())
|
user_conf, user_sections = _readUserConf()
|
||||||
|
user_conf = compat_conf(user_conf)
|
||||||
argv = system_conf + user_conf + command_line_conf
|
argv = system_conf + user_conf + command_line_conf
|
||||||
|
|
||||||
opts, args = parser.parse_args(argv)
|
opts, args = parser.parse_args(argv)
|
||||||
if opts.verbose:
|
if opts.verbose:
|
||||||
write_string('[debug] System config: ' + repr(_hide_login_info(system_conf)) + '\n')
|
write_string('[debug] System config: ' + repr(_hide_login_info(system_conf)) + '\n')
|
||||||
write_string('[debug] User config: ' + repr(_hide_login_info(user_conf)) + '\n')
|
write_string('[debug] User config: ' + repr(_hide_login_info(user_conf)) + '\n')
|
||||||
|
for section, section_args in user_sections.items():
|
||||||
|
write_string('[debug] User config for "' + section + '": ' + repr(_hide_login_info(section_args)) + '\n')
|
||||||
write_string('[debug] Command-line args: ' + repr(_hide_login_info(command_line_conf)) + '\n')
|
write_string('[debug] Command-line args: ' + repr(_hide_login_info(command_line_conf)) + '\n')
|
||||||
|
|
||||||
return parser, opts, args
|
def build_section_args(*sections):
|
||||||
|
res = system_conf + user_conf
|
||||||
|
for section in sections:
|
||||||
|
res.extend(user_sections.get(section, []))
|
||||||
|
res.extend(command_line_conf)
|
||||||
|
return res
|
||||||
|
|
||||||
|
return parser, opts, build_section_args, args
|
||||||
|
Loading…
x
Reference in New Issue
Block a user