You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
304 lines
10 KiB
304 lines
10 KiB
#!/usr/bin/env python2
|
|
|
|
"""Youtubedlg module to parse the options.
|
|
|
|
Note:
|
|
If you want to add new values on the module attributes
|
|
e.g. (SUBS_LANG, VIDEO_FORMATS, etc..) you also need to add the
|
|
values on the optionsframe module in order for them to be
|
|
visible from the GUI.
|
|
|
|
"""
|
|
|
|
import os.path
|
|
|
|
from .utils import remove_shortcuts
|
|
|
|
SUBS_LANG = {
|
|
"English": "en",
|
|
"Greek": "gr",
|
|
"Portuguese": "pt",
|
|
"French": "fr",
|
|
"Italian": "it",
|
|
"Russian": "ru",
|
|
"Spanish": "es",
|
|
"German": "de"
|
|
}
|
|
|
|
VIDEO_FORMATS = {
|
|
"default": "0",
|
|
"none": "0",
|
|
"3gp [176x144]": "17",
|
|
"3gp [320x240]": "36",
|
|
"flv [400x240]": "5",
|
|
"flv [640x360]": "34",
|
|
"flv [854x480]": "35",
|
|
"webm [640x360]": "43",
|
|
"webm [854x480]": "44",
|
|
"webm [1280x720]": "45",
|
|
"webm [1920x1080]": "46",
|
|
"mp4 [640x360]": "18",
|
|
"mp4 [1280x720]": "22",
|
|
"mp4 [1920x1080]": "37",
|
|
"mp4 [4096x3072]": "38",
|
|
"mp4 144p (DASH)": "160",
|
|
"mp4 240p (DASH)": "133",
|
|
"mp4 360p (DASH)": "134",
|
|
"mp4 480p (DASH)": "135",
|
|
"mp4 720p (DASH)": "136",
|
|
"mp4 1080p (DASH)": "137",
|
|
"mp4 1440p (DASH)": "264",
|
|
"mp4 2160p (DASH)": "138",
|
|
"webm 240p (DASH)": "242",
|
|
"webm 360p (DASH)": "243",
|
|
"webm 480p (DASH)": "244",
|
|
"webm 720p (DASH)": "247",
|
|
"webm 1080p (DASH)": "248",
|
|
"webm 1440p (DASH)": "271",
|
|
"webm 2160p (DASH)": "272",
|
|
"mp4 360p (3D)": "82",
|
|
"mp4 480p (3D)": "83",
|
|
"mp4 720p (3D)": "84",
|
|
"mp4 1080p (3D)": "85",
|
|
"webm 360p (3D)": "100",
|
|
"webm 480p (3D)": "101",
|
|
"webm 720p (3D)": "102",
|
|
"m4a 48k (DASH AUDIO)": "139",
|
|
"m4a 128k (DASH AUDIO)": "140",
|
|
"m4a 256k (DASH AUDIO)": "141",
|
|
"webm 48k (DASH AUDIO)": "171",
|
|
"webm 256k (DASH AUDIO)": "172"
|
|
}
|
|
|
|
AUDIO_QUALITY = {
|
|
"high": "0",
|
|
"mid": "5",
|
|
"low": "9"
|
|
}
|
|
|
|
FILESIZE_UNITS = {
|
|
'Bytes': '',
|
|
'Kilobytes': 'k',
|
|
'Megabytes': 'm',
|
|
'Gigabytes': 'g',
|
|
'Terabytes': 't',
|
|
'Petabytes': 'p',
|
|
'Exabytes': 'e',
|
|
'Zettabytes': 'z',
|
|
'Yottabytes': 'y'
|
|
}
|
|
|
|
class OptionHolder():
|
|
|
|
"""Simple data structure that holds informations for the given option.
|
|
|
|
Args:
|
|
name (string): Option name. Must be a valid option name
|
|
from the optionsmanager.OptionsManager class.
|
|
See optionsmanager.OptionsManager load_default() method.
|
|
|
|
flag (string): The option command line switch.
|
|
See https://github.com/rg3/youtube-dl/#options
|
|
|
|
default_value (any): The option default value. Must be the same type
|
|
with the corresponding option from the optionsmanager.OptionsManager
|
|
class.
|
|
|
|
requirements (list): The requirements for the given option. This
|
|
argument is a list of strings with the name of all the options
|
|
that this specific option needs. For example 'subs_lang' needs the
|
|
'write_subs' option to be enabled.
|
|
|
|
"""
|
|
|
|
def __init__(self, name, flag, default_value, requirements=[]):
|
|
self.name = name
|
|
self.flag = flag
|
|
self.requirements = requirements
|
|
self.default_value = default_value
|
|
|
|
def is_boolean(self):
|
|
"""Returns True if the option is a boolean switch else False. """
|
|
return type(self.default_value) is bool
|
|
|
|
def check_requirements(self, options_dict):
|
|
"""Check if the required options are enabled.
|
|
|
|
Args:
|
|
options_dict (dictionary): Dictionary with all the options.
|
|
|
|
Returns:
|
|
True if any of the required options is enabled else False.
|
|
|
|
"""
|
|
if not self.requirements:
|
|
return True
|
|
|
|
return any(map(lambda x: options_dict[x], self.requirements))
|
|
|
|
class OptionsParser():
|
|
|
|
"""Parse optionsmanager.OptionsManager options.
|
|
|
|
This class is responsible for turning some of the youtube-dlg options
|
|
to youtube-dl command line options.
|
|
|
|
"""
|
|
|
|
def __init__(self):
|
|
self._ydl_options = [
|
|
OptionHolder('playlist_start', '--playlist-start', 1),
|
|
OptionHolder('playlist_end', '--playlist-end', 0),
|
|
OptionHolder('max_downloads', '--max-downloads', 0),
|
|
OptionHolder('username', '-u', ''),
|
|
OptionHolder('password', '-p', ''),
|
|
OptionHolder('video_password', '--video-password', ''),
|
|
OptionHolder('retries', '-R', 10),
|
|
OptionHolder('proxy', '--proxy', ''),
|
|
OptionHolder('user_agent', '--user-agent', ''),
|
|
OptionHolder('referer', '--referer', ''),
|
|
OptionHolder('ignore_errors', '-i', False),
|
|
OptionHolder('write_description', '--write-description', False),
|
|
OptionHolder('write_info', '--write-info-json', False),
|
|
OptionHolder('write_thumbnail', '--write-thumbnail', False),
|
|
OptionHolder('min_filesize', '--min-filesize', 0),
|
|
OptionHolder('max_filesize', '--max-filesize', 0),
|
|
OptionHolder('write_all_subs', '--all-subs', False),
|
|
OptionHolder('write_auto_subs', '--write-auto-sub', False),
|
|
OptionHolder('write_subs', '--write-sub', False),
|
|
OptionHolder('keep_video', '-k', False),
|
|
OptionHolder('restrict_filenames', '--restrict-filenames', False),
|
|
OptionHolder('save_path', '-o', ''),
|
|
OptionHolder('embed_subs', '--embed-subs', False, ['write_auto_subs', 'write_subs']),
|
|
OptionHolder('to_audio', '-x', False),
|
|
OptionHolder('audio_format', '--audio-format', '', ['to_audio']),
|
|
OptionHolder('video_format', '-f', ''),
|
|
OptionHolder('subs_lang', '--sub-lang', '', ['write_subs']),
|
|
OptionHolder('audio_quality', '--audio-quality', '5', ['to_audio'])
|
|
]
|
|
|
|
def parse(self, options_dictionary):
|
|
"""Parse optionsmanager.OptionsHandler options.
|
|
|
|
Parses the given options to youtube-dl command line arguments.
|
|
|
|
Args:
|
|
options_dictionary (dictionary): Dictionary with all the options.
|
|
|
|
Returns:
|
|
List of strings with all the youtube-dl command line options.
|
|
|
|
"""
|
|
options_list = ['--newline']
|
|
|
|
# Create a copy of options_dictionary
|
|
# We don't want to edit the original options dictionary
|
|
# and change some of the options values like 'save_path' etc..
|
|
options_dict = options_dictionary.copy()
|
|
|
|
self._build_savepath(options_dict)
|
|
self._build_subslang(options_dict)
|
|
self._build_videoformat(options_dict)
|
|
self._build_audioquality(options_dict)
|
|
self._build_filesizes(options_dict)
|
|
|
|
# Parse basic youtube-dl command line options
|
|
for option in self._ydl_options:
|
|
if option.check_requirements(options_dict):
|
|
value = options_dict[option.name]
|
|
|
|
if value != option.default_value:
|
|
options_list.append(option.flag)
|
|
|
|
if not option.is_boolean():
|
|
options_list.append(str(value))
|
|
|
|
# Parse cmd_args
|
|
for option in options_dict['cmd_args'].split():
|
|
options_list.append(option)
|
|
|
|
return options_list
|
|
|
|
def _build_savepath(self, options_dict):
|
|
"""Build the save path.
|
|
|
|
We use this method to build the value of the 'save_path' option and
|
|
store it back to the options dictionary.
|
|
|
|
Args:
|
|
options_dict (dictionary): Copy of the original options dictionary.
|
|
|
|
"""
|
|
save_path = remove_shortcuts(options_dict['save_path'])
|
|
|
|
if options_dict['output_format'] == 'id':
|
|
save_path = os.path.join(save_path, '%(id)s.%(ext)s')
|
|
elif options_dict['output_format'] == 'title':
|
|
save_path = os.path.join(save_path, '%(title)s.%(ext)s')
|
|
else:
|
|
save_path = os.path.join(save_path, options_dict['output_template'])
|
|
|
|
options_dict['save_path'] = save_path
|
|
|
|
def _build_videoformat(self, options_dict):
|
|
"""Build the video format.
|
|
|
|
We use this method to build the value of the 'video_format' option and
|
|
store it back to the options dictionary.
|
|
|
|
Args:
|
|
options_dict (dictionary): Copy of the original options dictionary.
|
|
|
|
"""
|
|
first_vf = VIDEO_FORMATS[options_dict['video_format']]
|
|
second_vf = VIDEO_FORMATS[options_dict['second_video_format']]
|
|
|
|
if first_vf != '0' and second_vf != '0':
|
|
options_dict['video_format'] = first_vf + '+' + second_vf
|
|
elif first_vf != '0' and second_vf == '0':
|
|
options_dict['video_format'] = first_vf
|
|
else:
|
|
options_dict['video_format'] = ''
|
|
|
|
def _build_subslang(self, options_dict):
|
|
"""Build the subtitles language option value.
|
|
|
|
We use this method to build the value of the 'subs_lang' option and
|
|
store it back to the options dictionary.
|
|
|
|
Args:
|
|
options_dict (dictionary): Copy of the original options dictionary.
|
|
|
|
"""
|
|
options_dict['subs_lang'] = SUBS_LANG[options_dict['subs_lang']]
|
|
|
|
def _build_audioquality(self, options_dict):
|
|
"""Build the audio quality option value.
|
|
|
|
We use this method to build the value of the 'audio_quality' option and
|
|
store it back to the options dictionary.
|
|
|
|
Args:
|
|
options_dict (dictionary): Copy of the original options dictionary.
|
|
|
|
"""
|
|
options_dict['audio_quality'] = AUDIO_QUALITY[options_dict['audio_quality']]
|
|
|
|
def _build_filesizes(self, options_dict):
|
|
"""Build the filesize options values.
|
|
|
|
We use this method to build the values of 'min_filesize' and
|
|
'max_filesize' options and store them back to options dictionary.
|
|
|
|
Args:
|
|
options_dict (dictionary): Copy of the original options dictionary.
|
|
|
|
"""
|
|
if options_dict['min_filesize']:
|
|
size_unit = FILESIZE_UNITS[options_dict['min_filesize_unit']]
|
|
options_dict['min_filesize'] = str(options_dict['min_filesize']) + size_unit
|
|
|
|
if options_dict['max_filesize']:
|
|
size_unit = FILESIZE_UNITS[options_dict['max_filesize_unit']]
|
|
options_dict['max_filesize'] = str(options_dict['max_filesize']) + size_unit
|
|
|