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.

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