|
|
#!/usr/bin/env python2 # -*- coding: utf-8 -*-
"""Youtubedlg module to handle settings. """
from __future__ import unicode_literals
import json import os.path
from .utils import ( encode_tuple, decode_tuple, check_path )
class OptionsManager(object):
"""Handles youtubedlg options.
This class is responsible for storing and retrieving the options.
Attributes: SETTINGS_FILENAME (string): Filename of the settings file. SENSITIVE_KEYS (tuple): Contains the keys that we don't want to store on the settings file. (SECURITY ISSUES).
Args: config_path (string): Absolute path where OptionsManager should store the settings file.
Note: See load_default() method for available options.
Example: Access the options using the 'options' variable.
opt_manager = OptionsManager('.') opt_manager.options['save_path'] = '~/Downloads'
"""
SETTINGS_FILENAME = 'settings.json' SENSITIVE_KEYS = ('sudo_password', 'password', 'video_password')
def __init__(self, config_path): self.config_path = config_path self.settings_file = os.path.join(config_path, self.SETTINGS_FILENAME) self.options = dict() self.load_default() self.load_from_file()
def load_default(self): """Load the default options.
Note: This method is automatically called by the constructor.
Options Description:
save_path (string): Path where youtube-dl should store the downloaded file. Default is $HOME.
video_format (string): Video format to download. When this options is set to '0' youtube-dl will choose the best video format available for the given URL.
second_video_format (string): Video format to mix with the first one (-f 18+17).
to_audio (boolean): If True youtube-dl will post process the video file.
keep_video (boolen): If True youtube-dl will keep the video file after post processing it.
audio_format (string): Audio format of the post processed file. Available values are "mp3", "wav", "aac", "m4a", "vorbis".
audio_quality (string): Audio quality of the post processed file. Available values are "9", "5", "0". The lowest the value the better the quality.
restrict_filenames (boolean): If True youtube-dl will restrict the downloaded file filename to ASCII characters only.
output_format (string): This option sets the downloaded file output template. Available values are 'id', 'title', 'custom'
'id' -> '%(id)s.%(ext)s' 'title' -> '%(title)s.%(ext)s' 'custom' -> Use 'output_template' as output template.
output_template (string): Can be any output template supported by youtube-dl.
playlist_start (int): Playlist index to start downloading.
playlist_end (int): Playlist index to stop downloading.
max_downloads (int): Maximum number of video files to download from the given playlist.
min_filesize (float): Minimum file size of the video file. If the video file is smaller than the given size then youtube-dl will abort the download process.
max_filesize (float): Maximum file size of the video file. If the video file is larger than the given size then youtube-dl will abort the download process.
min_filesize_unit (string): Minimum file size unit. Available values: '', 'k', 'm', 'g', 'y', 'p', 'e', 'z', 'y'.
max_filesize_unit (string): Maximum file size unit. See 'min_filesize_unit' option for available values.
write_subs (boolean): If True youtube-dl will try to download the subtitles file for the given URL.
write_all_subs (boolean): If True youtube-dl will try to download all the available subtitles files for the given URL.
write_auto_subs (boolean): If True youtube-dl will try to download the automatic subtitles file for the given URL.
embed_subs (boolean): If True youtube-dl will merge the subtitles file with the video. (ONLY mp4 files).
subs_lang (string): Language of the subtitles file to download. Needs 'write_subs' option.
ignore_errors (boolean): If True youtube-dl will ignore the errors and continue the download process.
open_dl_dir (boolean): If True youtube-dlg will open the destination folder after download process has been completed.
write_description (boolean): If True youtube-dl will write video description to a .description file.
write_info (boolean): If True youtube-dl will write video metadata to a .info.json file.
write_thumbnail (boolean): If True youtube-dl will write thumbnail image to disk.
retries (int): Number of youtube-dl retries.
user_agent (string): Specify a custom user agent for youtube-dl.
referer (string): Specify a custom referer to use if the video access is restricted to one domain.
proxy (string): Use the specified HTTP/HTTPS proxy.
shutdown (boolean): If True youtube-dlg will turn the computer off after the download process has been completed.
sudo_password (string): SUDO password for the shutdown process if the user does not have elevated privileges.
username (string): Username to login with.
password (string): Password to login with.
video_password (string): Video password for the given URL.
youtubedl_path (string): Absolute path to the youtube-dl binary. Default is the self.config_path. You can change this option to point on /usr/local/bin etc.. if you want to use the youtube-dl binary on your system. This is also the directory where youtube-dlg will auto download the youtube-dl if not exists so you should make sure you have write access if you want to update the youtube-dl binary from within youtube-dlg.
cmd_args (string): String that contains extra youtube-dl options seperated by spaces.
enable_log (boolean): If True youtube-dlg will enable the LogManager. See main() function under __init__().
log_time (boolean): See logmanager.LogManager add_time attribute.
workers_number (int): Number of download workers that download manager will spawn. Must be greater than zero.
locale_name (string): Locale name (e.g. ru_RU).
"""
self.options = { 'save_path': os.path.expanduser('~'), 'video_format': '0', 'second_video_format': '0', 'to_audio': False, 'keep_video': False, 'audio_format': 'mp3', 'audio_quality': '5', 'restrict_filenames': False, 'output_format': 'title', 'output_template': '%(uploader)s/%(title)s.%(ext)s', 'playlist_start': 1, 'playlist_end': 0, 'max_downloads': 0, 'min_filesize': 0, 'max_filesize': 0, 'min_filesize_unit': '', 'max_filesize_unit': '', 'write_subs': False, 'write_all_subs': False, 'write_auto_subs': False, 'embed_subs': False, 'subs_lang': 'en', 'ignore_errors': True, 'open_dl_dir': True, 'write_description': False, 'write_info': False, 'write_thumbnail': False, 'retries': 10, 'user_agent': '', 'referer': '', 'proxy': '', 'shutdown': False, 'sudo_password': '', 'username': '', 'password': '', 'video_password': '', 'youtubedl_path': self.config_path, 'cmd_args': '', 'enable_log': True, 'log_time': False, 'workers_number': 3, 'locale_name': 'en_US', 'main_win_size': (700, 490), 'opts_win_size': (640, 270) }
def load_from_file(self): """Load options from settings file. """ if not os.path.exists(self.settings_file): return
with open(self.settings_file, 'rb') as settings_file: try: options = json.load(settings_file)
if self._settings_are_valid(options): self.options = options except: self.load_default()
def save_to_file(self): """Save options to settings file. """ check_path(self.config_path)
with open(self.settings_file, 'wb') as settings_file: options = self._get_options() json.dump(options, settings_file, indent=4, separators=(',', ': '))
def _settings_are_valid(self, settings_dictionary): """Check settings.json dictionary.
Args: settings_dictionary (dictionary): Options dictionary loaded from the settings file. See load_from_file() method.
Returns: True if settings.json dictionary is valid, else False.
"""
VALID_VIDEO_FORMAT = ('0', '17', '36', '5', '34', '35', '43', '44', '45', '46', '18', '22', '37', '38', '160', '133', '134', '135', '136','137', '264', '138', '242', '243', '244', '247', '248', '271', '272', '82', '83', '84', '85', '100', '101', '102', '139', '140', '141', '171', '172')
VALID_AUDIO_FORMAT = ('mp3', 'wav', 'aac', 'm4a', 'vorbis')
VALID_AUDIO_QUALITY = ('0', '5', '9')
VALID_OUTPUT_FORMAT = ('title', 'id', 'custom')
VALID_FILESIZE_UNIT = ('', 'k', 'm', 'g', 't', 'p', 'e', 'z', 'y')
VALID_SUB_LANGUAGE = ('en', 'gr', 'pt', 'fr', 'it', 'ru', 'es', 'de')
MIN_FRAME_SIZE = 100
# Decode string formatted tuples back to normal tuples settings_dictionary['main_win_size'] = decode_tuple(settings_dictionary['main_win_size']) settings_dictionary['opts_win_size'] = decode_tuple(settings_dictionary['opts_win_size'])
for key in self.options: if key not in settings_dictionary: return False
if type(self.options[key]) != type(settings_dictionary[key]): return False
# Check if each key has a valid value rules_dict = { 'video_format': VALID_VIDEO_FORMAT, 'second_video_format': VALID_VIDEO_FORMAT, 'audio_format': VALID_AUDIO_FORMAT, 'audio_quality': VALID_AUDIO_QUALITY, 'output_format': VALID_OUTPUT_FORMAT, 'min_filesize_unit': VALID_FILESIZE_UNIT, 'max_filesize_unit': VALID_FILESIZE_UNIT, 'subs_lang': VALID_SUB_LANGUAGE }
for key, valid_list in rules_dict.items(): if settings_dictionary[key] not in valid_list: return False
# Check workers number value if settings_dictionary['workers_number'] < 1: return False
# Check main-options frame size for size in settings_dictionary['main_win_size']: if size < MIN_FRAME_SIZE: return False
for size in settings_dictionary['opts_win_size']: if size < MIN_FRAME_SIZE: return False
return True
def _get_options(self): """Return options dictionary without SENSITIVE_KEYS. """ temp_options = self.options.copy()
for key in self.SENSITIVE_KEYS: temp_options[key] = ''
# Encode normal tuples to string formatted tuples temp_options['main_win_size'] = encode_tuple(temp_options['main_win_size']) temp_options['opts_win_size'] = encode_tuple(temp_options['opts_win_size'])
return temp_options
|