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.

191 lines
7.0 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. #!/usr/bin/env python2
  2. # -*- coding: utf-8 -*-
  3. """Youtubedlg module responsible for parsing the options. """
  4. from __future__ import unicode_literals
  5. import os.path
  6. from .utils import remove_shortcuts
  7. class OptionHolder(object):
  8. """Simple data structure that holds informations for the given option.
  9. Args:
  10. name (string): Option name. Must be a valid option name
  11. from the optionsmanager.OptionsManager class.
  12. See optionsmanager.OptionsManager load_default() method.
  13. flag (string): The option command line switch.
  14. See https://github.com/rg3/youtube-dl/#options
  15. default_value (any): The option default value. Must be the same type
  16. with the corresponding option from the optionsmanager.OptionsManager
  17. class.
  18. requirements (list): The requirements for the given option. This
  19. argument is a list of strings with the name of all the options
  20. that this specific option needs. For example 'subs_lang' needs the
  21. 'write_subs' option to be enabled.
  22. """
  23. def __init__(self, name, flag, default_value, requirements=None):
  24. self.name = name
  25. self.flag = flag
  26. self.requirements = requirements
  27. self.default_value = default_value
  28. def is_boolean(self):
  29. """Returns True if the option is a boolean switch else False. """
  30. return type(self.default_value) is bool
  31. def check_requirements(self, options_dict):
  32. """Check if the required options are enabled.
  33. Args:
  34. options_dict (dictionary): Dictionary with all the options.
  35. Returns:
  36. True if any of the required options is enabled else False.
  37. """
  38. if self.requirements is None:
  39. return True
  40. return any([options_dict[req] for req in self.requirements])
  41. class OptionsParser(object):
  42. """Parse optionsmanager.OptionsManager options.
  43. This class is responsible for turning some of the youtube-dlg options
  44. to youtube-dl command line options.
  45. """
  46. def __init__(self):
  47. self._ydl_options = [
  48. OptionHolder('playlist_start', '--playlist-start', 1),
  49. OptionHolder('playlist_end', '--playlist-end', 0),
  50. OptionHolder('max_downloads', '--max-downloads', 0),
  51. OptionHolder('username', '-u', ''),
  52. OptionHolder('password', '-p', ''),
  53. OptionHolder('video_password', '--video-password', ''),
  54. OptionHolder('retries', '-R', 10),
  55. OptionHolder('proxy', '--proxy', ''),
  56. OptionHolder('user_agent', '--user-agent', ''),
  57. OptionHolder('referer', '--referer', ''),
  58. OptionHolder('ignore_errors', '-i', False),
  59. OptionHolder('write_description', '--write-description', False),
  60. OptionHolder('write_info', '--write-info-json', False),
  61. OptionHolder('write_thumbnail', '--write-thumbnail', False),
  62. OptionHolder('min_filesize', '--min-filesize', 0),
  63. OptionHolder('max_filesize', '--max-filesize', 0),
  64. OptionHolder('write_all_subs', '--all-subs', False),
  65. OptionHolder('write_auto_subs', '--write-auto-sub', False),
  66. OptionHolder('write_subs', '--write-sub', False),
  67. OptionHolder('keep_video', '-k', False),
  68. OptionHolder('restrict_filenames', '--restrict-filenames', False),
  69. OptionHolder('save_path', '-o', ''),
  70. OptionHolder('embed_subs', '--embed-subs', False, ['write_auto_subs', 'write_subs']),
  71. OptionHolder('to_audio', '-x', False),
  72. OptionHolder('audio_format', '--audio-format', '', ['to_audio']),
  73. OptionHolder('video_format', '-f', '0'),
  74. OptionHolder('subs_lang', '--sub-lang', '', ['write_subs']),
  75. OptionHolder('audio_quality', '--audio-quality', '5', ['to_audio'])
  76. ]
  77. def parse(self, options_dictionary):
  78. """Parse optionsmanager.OptionsManager options.
  79. Parses the given options to youtube-dl command line arguments.
  80. Args:
  81. options_dictionary (dictionary): Dictionary with all the options.
  82. Returns:
  83. List of strings with all the youtube-dl command line options.
  84. """
  85. options_list = ['--newline']
  86. # Create a copy of options_dictionary
  87. # We don't want to edit the original options dictionary
  88. # and change some of the options values like 'save_path' etc..
  89. options_dict = options_dictionary.copy()
  90. self._build_savepath(options_dict)
  91. self._build_videoformat(options_dict)
  92. self._build_filesizes(options_dict)
  93. # Parse basic youtube-dl command line options
  94. for option in self._ydl_options:
  95. if option.check_requirements(options_dict):
  96. value = options_dict[option.name]
  97. if value != option.default_value:
  98. options_list.append(option.flag)
  99. if not option.is_boolean():
  100. options_list.append(unicode(value))
  101. # Parse cmd_args
  102. for option in options_dict['cmd_args'].split():
  103. options_list.append(option)
  104. return options_list
  105. def _build_savepath(self, options_dict):
  106. """Build the save path.
  107. We use this method to build the value of the 'save_path' option and
  108. store it back to the options dictionary.
  109. Args:
  110. options_dict (dictionary): Copy of the original options dictionary.
  111. """
  112. save_path = remove_shortcuts(options_dict['save_path'])
  113. if options_dict['output_format'] == 'id':
  114. save_path = os.path.join(save_path, '%(id)s.%(ext)s')
  115. elif options_dict['output_format'] == 'title':
  116. save_path = os.path.join(save_path, '%(title)s.%(ext)s')
  117. else:
  118. save_path = os.path.join(save_path, options_dict['output_template'])
  119. options_dict['save_path'] = save_path
  120. def _build_videoformat(self, options_dict):
  121. """Build the video format.
  122. We use this method to build the value of the 'video_format' option and
  123. store it back to the options dictionary.
  124. Args:
  125. options_dict (dictionary): Copy of the original options dictionary.
  126. """
  127. if options_dict['video_format'] != '0' and options_dict['second_video_format'] != '0':
  128. options_dict['video_format'] = options_dict['video_format'] + '+' + options_dict['second_video_format']
  129. def _build_filesizes(self, options_dict):
  130. """Build the filesize options values.
  131. We use this method to build the values of 'min_filesize' and
  132. 'max_filesize' options and store them back to options dictionary.
  133. Args:
  134. options_dict (dictionary): Copy of the original options dictionary.
  135. """
  136. if options_dict['min_filesize']:
  137. options_dict['min_filesize'] = unicode(options_dict['min_filesize']) + options_dict['min_filesize_unit']
  138. if options_dict['max_filesize']:
  139. options_dict['max_filesize'] = unicode(options_dict['max_filesize']) + options_dict['max_filesize_unit']