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 .YoutubeDL import YoutubeDL
|
||||
from .params import Params, ParamsSection
|
||||
|
||||
|
||||
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):
|
||||
# Compatibility fixes for Windows
|
||||
if sys.platform == 'win32':
|
||||
@ -321,7 +346,7 @@ def _real_main(argv=None):
|
||||
|
||||
setproctitle('youtube-dl')
|
||||
|
||||
parser, opts, args = parseOpts(argv)
|
||||
parser, opts, build_section_args, args = parseOpts(argv)
|
||||
|
||||
# Set user agent
|
||||
if opts.user_agent is not None:
|
||||
@ -385,7 +410,7 @@ def _real_main(argv=None):
|
||||
compat_print(desc)
|
||||
sys.exit(0)
|
||||
|
||||
ydl_opts = _build_ydl_opts(opts, parser)
|
||||
ydl_opts = CLIParams(opts, build_section_args, parser)
|
||||
|
||||
with YoutubeDL(ydl_opts) as ydl:
|
||||
# Update version
|
||||
|
@ -582,11 +582,17 @@ if sys.version_info >= (3, 0):
|
||||
else:
|
||||
from tokenize import generate_tokens as compat_tokenize_tokenize
|
||||
|
||||
try:
|
||||
import configparser as compat_configparser
|
||||
except ImportError:
|
||||
import ConfigParser as compat_configparser
|
||||
|
||||
__all__ = [
|
||||
'compat_HTMLParser',
|
||||
'compat_HTTPError',
|
||||
'compat_basestring',
|
||||
'compat_chr',
|
||||
'compat_configparser',
|
||||
'compat_cookiejar',
|
||||
'compat_cookies',
|
||||
'compat_etree_fromstring',
|
||||
|
@ -1,11 +1,13 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import io
|
||||
import os.path
|
||||
import optparse
|
||||
import sys
|
||||
|
||||
from .downloader.external import list_external_downloaders
|
||||
from .compat import (
|
||||
compat_configparser,
|
||||
compat_expanduser,
|
||||
compat_get_terminal_size,
|
||||
compat_getenv,
|
||||
@ -743,17 +745,41 @@ def parseOpts(overrideArguments=None):
|
||||
optionf.close()
|
||||
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():
|
||||
xdg_config_home = compat_getenv('XDG_CONFIG_HOME')
|
||||
if xdg_config_home:
|
||||
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):
|
||||
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:
|
||||
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):
|
||||
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)
|
||||
userIni = _readIni(userIniFile, None)
|
||||
|
||||
if userConf is None:
|
||||
appdata_dir = compat_getenv('appdata')
|
||||
@ -778,7 +804,11 @@ def parseOpts(overrideArguments=None):
|
||||
if userConf is None:
|
||||
userConf = []
|
||||
|
||||
return userConf
|
||||
if userIni is None:
|
||||
userIni = [], {}
|
||||
iniGlobal, iniSections = userIni
|
||||
|
||||
return userConf + iniGlobal, iniSections
|
||||
|
||||
def _hide_login_info(opts):
|
||||
opts = list(opts)
|
||||
@ -807,18 +837,30 @@ def parseOpts(overrideArguments=None):
|
||||
if '--ignore-config' in command_line_conf:
|
||||
system_conf = []
|
||||
user_conf = []
|
||||
user_sections = {}
|
||||
else:
|
||||
system_conf = compat_conf(_readOptions('/etc/youtube-dl.conf'))
|
||||
if '--ignore-config' in system_conf:
|
||||
user_conf = []
|
||||
user_sections = {}
|
||||
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
|
||||
|
||||
opts, args = parser.parse_args(argv)
|
||||
if opts.verbose:
|
||||
write_string('[debug] System config: ' + repr(_hide_login_info(system_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')
|
||||
|
||||
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