youtube-dl-gui/youtube_dl_gui/optionsmanager.py

418 lines
15 KiB
Python
Raw Normal View History

2014-05-22 08:43:36 -07:00
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
2014-03-01 09:12:37 -08:00
2014-12-22 08:21:47 -08:00
"""Youtubedlg module to handle settings. """
2014-07-20 08:47:07 -07:00
from __future__ import unicode_literals
import os
import json
2015-03-12 16:17:37 -07:00
from .utils import (
os_path_expanduser,
os_path_exists,
2015-03-12 16:17:37 -07:00
encode_tuple,
decode_tuple,
check_path,
get_default_lang
2015-03-12 16:17:37 -07:00
)
2014-03-01 09:12:37 -08:00
from .formats import (
OUTPUT_FORMATS,
2016-10-15 10:03:54 -07:00
FORMATS
)
2016-10-15 02:41:00 -07:00
2014-04-30 03:38:56 -07:00
2014-07-20 08:47:07 -07:00
class OptionsManager(object):
2014-12-22 08:21:47 -08:00
"""Handles youtubedlg options.
2014-12-22 08:21:47 -08:00
This class is responsible for storing and retrieving the options.
2014-07-20 08:47:07 -07:00
2014-12-22 08:21:47 -08:00
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).
2014-12-22 08:21:47 -08:00
Args:
config_path (string): Absolute path where OptionsManager
should store the settings file.
2014-07-20 08:47:07 -07:00
2014-12-22 08:21:47 -08:00
Note:
See load_default() method for available options.
2014-12-22 08:21:47 -08:00
Example:
Access the options using the 'options' variable.
2014-12-22 08:21:47 -08:00
opt_manager = OptionsManager('.')
opt_manager.options['save_path'] = '~/Downloads'
2014-12-22 08:21:47 -08:00
"""
2014-04-30 03:38:56 -07:00
SETTINGS_FILENAME = 'settings.json'
SENSITIVE_KEYS = ('sudo_password', 'password', 'video_password')
2014-04-30 03:38:56 -07:00
def __init__(self, config_path):
self.config_path = config_path
2014-12-03 09:56:38 -08:00
self.settings_file = os.path.join(config_path, self.SETTINGS_FILENAME)
self.options = dict()
self.load_default()
self.load_from_file()
2014-04-30 03:38:56 -07:00
def load_default(self):
2014-12-22 08:21:47 -08:00
"""Load the default options.
2014-12-22 08:21:47 -08:00
Note:
This method is automatically called by the constructor.
2014-12-22 08:21:47 -08:00
Options Description:
save_path (string): Path where youtube-dl should store the
2014-12-22 08:21:47 -08:00
downloaded file. Default is $HOME.
video_format (string): Video format to download.
When this options is set to '0' youtube-dl will choose
2014-12-22 08:21:47 -08:00
the best video format available for the given URL.
2014-12-22 08:21:47 -08:00
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
2014-12-22 08:21:47 -08:00
video file.
2014-12-22 08:21:47 -08:00
keep_video (boolen): If True youtube-dl will keep the video file
after post processing it.
2014-12-22 08:21:47 -08:00
audio_format (string): Audio format of the post processed file.
2017-10-09 06:38:54 -07:00
Available values are "mp3", "wav", "aac", "m4a", "vorbis",
"opus" & "flac".
2014-12-22 08:21:47 -08:00
audio_quality (string): Audio quality of the post processed file.
Available values are "9", "5", "0". The lowest the value the
better the quality.
2014-12-22 08:21:47 -08:00
restrict_filenames (boolean): If True youtube-dl will restrict
the downloaded file filename to ASCII characters only.
2016-10-15 02:54:05 -07:00
output_format (int): This option sets the downloaded file
2016-10-15 02:38:13 -07:00
output template. See formats.OUTPUT_FORMATS for more info.
2014-12-22 08:21:47 -08:00
output_template (string): Can be any output template supported
by youtube-dl.
2014-12-22 08:21:47 -08:00
playlist_start (int): Playlist index to start downloading.
2014-12-22 08:21:47 -08:00
playlist_end (int): Playlist index to stop downloading.
2014-12-22 08:21:47 -08:00
max_downloads (int): Maximum number of video files to download
from the given playlist.
2014-12-22 08:21:47 -08:00
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.
2014-12-22 08:21:47 -08:00
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.
2014-12-22 08:21:47 -08:00
min_filesize_unit (string): Minimum file size unit.
Available values: '', 'k', 'm', 'g', 'y', 'p', 'e', 'z', 'y'.
2014-12-22 08:21:47 -08:00
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
2014-12-22 08:21:47 -08:00
the subtitles file for the given URL.
write_all_subs (boolean): If True youtube-dl will try to download
2014-12-22 08:21:47 -08:00
all the available subtitles files for the given URL.
write_auto_subs (boolean): If True youtube-dl will try to download
2014-12-22 08:21:47 -08:00
the automatic subtitles file for the given URL.
2014-12-22 08:21:47 -08:00
embed_subs (boolean): If True youtube-dl will merge the subtitles
file with the video. (ONLY mp4 files).
2014-12-22 08:21:47 -08:00
subs_lang (string): Language of the subtitles file to download.
Needs 'write_subs' option.
2014-12-22 08:21:47 -08:00
ignore_errors (boolean): If True youtube-dl will ignore the errors
and continue the download process.
2014-12-22 08:21:47 -08:00
open_dl_dir (boolean): If True youtube-dlg will open the
destination folder after download process has been completed.
2014-12-22 08:21:47 -08:00
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
2014-12-22 08:21:47 -08:00
metadata to a .info.json file.
2014-12-22 08:21:47 -08:00
write_thumbnail (boolean): If True youtube-dl will write
thumbnail image to disk.
2014-12-22 08:21:47 -08:00
retries (int): Number of youtube-dl retries.
2014-12-22 08:21:47 -08:00
user_agent (string): Specify a custom user agent for youtube-dl.
referer (string): Specify a custom referer to use if the video
2014-12-22 08:21:47 -08:00
access is restricted to one domain.
2014-12-22 08:21:47 -08:00
proxy (string): Use the specified HTTP/HTTPS proxy.
2014-12-22 08:21:47 -08:00
shutdown (boolean): If True youtube-dlg will turn the computer
off after the download process has been completed.
2014-12-22 08:21:47 -08:00
sudo_password (string): SUDO password for the shutdown process if
2015-01-10 07:36:27 -08:00
the user does not have elevated privileges.
2014-12-22 08:21:47 -08:00
username (string): Username to login with.
2014-12-22 08:21:47 -08:00
password (string): Password to login with.
2014-12-22 08:21:47 -08:00
video_password (string): Video password for the given URL.
2014-12-22 08:21:47 -08:00
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
2014-12-22 08:21:47 -08:00
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.
2014-12-22 08:21:47 -08:00
cmd_args (string): String that contains extra youtube-dl options
seperated by spaces.
enable_log (boolean): If True youtube-dlg will enable
2014-12-22 08:21:47 -08:00
the LogManager. See main() function under __init__().
2014-12-22 08:21:47 -08:00
log_time (boolean): See logmanager.LogManager add_time attribute.
2015-03-04 09:26:32 -08:00
2015-01-24 06:01:36 -08:00
workers_number (int): Number of download workers that download manager
will spawn. Must be greater than zero.
2015-03-04 09:26:32 -08:00
locale_name (string): Locale name (e.g. ru_RU).
2015-03-25 08:09:55 -07:00
main_win_size (tuple): Main window size (width, height).
If window becomes to small the program will reset its size.
See _settings_are_valid method MIN_FRAME_SIZE.
opts_win_size (tuple): Options window size (width, height).
If window becomes to small the program will reset its size.
See _settings_are_valid method MIN_FRAME_SIZE.
save_path_dirs (list): List that contains temporary save paths.
selected_video_formats (list): List that contains the selected
video formats to display on the main window.
2016-10-15 05:49:08 -07:00
selected_audio_formats (list): List that contains the selected
audio formats to display on the main window.
2016-10-15 10:05:48 -07:00
selected_format (string): Current format selected on the main window.
youtube_dl_debug (boolean): When True will pass '-v' flag to youtube-dl.
ignore_config (boolean): When True will ignore youtube-dl config file options.
confirm_exit (boolean): When True create popup to confirm exiting youtube-dl-gui.
native_hls (boolean): When True youtube-dl will use the native HLS implementation.
show_completion_popup (boolean): When True youtube-dl-gui will create a popup
to inform the user for the download completion.
2016-11-16 04:26:23 -08:00
confirm_deletion (boolean): When True ask user before item removal.
2016-11-23 04:10:09 -08:00
nomtime (boolean): When True will not use the Last-modified header to
set the file modification time.
embed_thumbnail (boolean): When True will embed the thumbnail in
the audio file as cover art.
2016-11-23 05:39:56 -08:00
add_metadata (boolean): When True will write metadata to file.
2018-01-14 05:56:04 -08:00
disable_update (boolean): When True the update process will be disabled.
2014-12-22 08:21:47 -08:00
"""
2016-12-10 12:20:15 -08:00
#REFACTOR Remove old options & check options validation
self.options = {
'save_path': os_path_expanduser('~'),
2016-11-09 07:30:32 -08:00
'save_path_dirs': [
os_path_expanduser('~'),
os.path.join(os_path_expanduser('~'), "Downloads"),
os.path.join(os_path_expanduser('~'), "Desktop"),
os.path.join(os_path_expanduser('~'), "Videos"),
os.path.join(os_path_expanduser('~'), "Music"),
],
'video_format': '0',
'second_video_format': '0',
'to_audio': False,
'keep_video': False,
2016-10-23 08:02:40 -07:00
'audio_format': '',
'audio_quality': '5',
'restrict_filenames': False,
2016-10-15 02:38:13 -07:00
'output_format': 1,
'output_template': os.path.join('%(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,
2016-11-03 07:00:07 -07:00
'open_dl_dir': False,
'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,
2016-11-03 07:00:07 -07:00
'log_time': True,
'workers_number': 3,
'locale_name': get_default_lang(),
'main_win_size': (740, 490),
'opts_win_size': (640, 490),
2016-11-05 08:42:22 -07:00
'selected_video_formats': ['webm', 'mp4'],
2016-11-09 07:00:31 -08:00
'selected_audio_formats': ['mp3', 'm4a', 'vorbis'],
'selected_format': '0',
'youtube_dl_debug': False,
'ignore_config': True,
'confirm_exit': True,
'native_hls': True,
2016-11-16 04:26:23 -08:00
'show_completion_popup': True,
2016-11-23 04:10:09 -08:00
'confirm_deletion': True,
'nomtime': False,
2016-11-23 05:39:56 -08:00
'embed_thumbnail': False,
2018-01-14 05:56:04 -08:00
'add_metadata': False,
'disable_update': False
}
2014-04-30 03:38:56 -07:00
# Set the youtubedl_path again if the disable_update option is set
new_path = '/usr/bin'
if self.options['disable_update'] and os.name != 'nt' and os_path_exists(new_path):
self.options['youtubedl_path'] = new_path
2014-04-30 03:38:56 -07:00
def load_from_file(self):
2014-12-22 08:21:47 -08:00
"""Load options from settings file. """
if not os_path_exists(self.settings_file):
return
2014-07-20 08:47:07 -07:00
with open(self.settings_file, 'rb') as settings_file:
2014-04-30 03:38:56 -07:00
try:
2014-07-20 08:47:07 -07:00
options = json.load(settings_file)
2015-03-04 09:26:32 -08:00
2015-01-24 06:01:36 -08:00
if self._settings_are_valid(options):
self.options = options
2014-04-30 03:38:56 -07:00
except:
self.load_default()
def save_to_file(self):
2014-12-22 08:21:47 -08:00
"""Save options to settings file. """
check_path(self.config_path)
2014-07-20 08:47:07 -07:00
with open(self.settings_file, 'wb') as settings_file:
options = self._get_options()
2014-07-20 08:47:07 -07:00
json.dump(options,
settings_file,
indent=4,
separators=(',', ': '))
def _settings_are_valid(self, settings_dictionary):
2014-12-22 08:21:47 -08:00
"""Check settings.json dictionary.
2014-12-22 08:21:47 -08:00
Args:
2015-10-12 06:19:23 -07:00
settings_dictionary (dict): Options dictionary loaded
2014-12-22 08:21:47 -08:00
from the settings file. See load_from_file() method.
2014-12-22 08:21:47 -08:00
Returns:
True if settings.json dictionary is valid, else False.
2014-12-22 08:21:47 -08:00
"""
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')
2017-10-09 06:38:54 -07:00
VALID_AUDIO_FORMAT = ('mp3', 'wav', 'aac', 'm4a', 'vorbis', 'opus', 'flac', '')
VALID_AUDIO_QUALITY = ('0', '5', '9')
VALID_FILESIZE_UNIT = ('', 'k', 'm', 'g', 't', 'p', 'e', 'z', 'y')
VALID_SUB_LANGUAGE = ('en', 'el', 'pt', 'fr', 'it', 'ru', 'es', 'de', 'he', 'sv', 'tr')
2015-03-04 09:26:32 -08:00
2015-03-12 16:17:37 -07:00
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:
2014-07-20 08:47:07 -07:00
return False
2015-03-04 09:26:32 -08:00
if type(self.options[key]) != type(settings_dictionary[key]):
return False
# Check if each key has a valid value
rules_dict = {
2016-10-15 10:03:54 -07:00
'video_format': FORMATS.keys(),
'second_video_format': VALID_VIDEO_FORMAT,
'audio_format': VALID_AUDIO_FORMAT,
'audio_quality': VALID_AUDIO_QUALITY,
2016-10-15 02:41:00 -07:00
'output_format': OUTPUT_FORMATS.keys(),
'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
2015-03-04 09:26:32 -08:00
# Check workers number value
2015-01-24 06:01:36 -08:00
if settings_dictionary['workers_number'] < 1:
return False
2014-07-20 08:47:07 -07:00
2015-03-12 16:17:37 -07:00
# 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
2014-07-20 08:47:07 -07:00
return True
def _get_options(self):
2014-12-22 08:21:47 -08:00
"""Return options dictionary without SENSITIVE_KEYS. """
2014-12-03 09:56:38 -08:00
temp_options = self.options.copy()
2014-12-03 09:56:38 -08:00
for key in self.SENSITIVE_KEYS:
temp_options[key] = ''
2015-03-12 16:17:37 -07:00
# 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
2015-03-12 16:17:37 -07:00