cli_to_api.py 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. #!/usr/bin/env python
  2. # coding: utf-8
  3. from __future__ import unicode_literals
  4. """
  5. This script displays the API parameters corresponding to a yt-dl command line
  6. Example:
  7. $ ./cli_to_api.py -f best
  8. {u'format': 'best'}
  9. $
  10. """
  11. # Allow direct execution
  12. import os
  13. import sys
  14. sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
  15. import youtube_dl
  16. from types import MethodType
  17. def cli_to_api(*opts):
  18. YDL = youtube_dl.YoutubeDL
  19. # to extract the parsed options, break out of YoutubeDL instantiation
  20. # return options via this Exception
  21. class ParseYTDLResult(Exception):
  22. def __init__(self, result):
  23. super(ParseYTDLResult, self).__init__('result')
  24. self.opts = result
  25. # replacement constructor that raises ParseYTDLResult
  26. def ytdl_init(ydl, ydl_opts):
  27. super(YDL, ydl).__init__(ydl_opts)
  28. raise ParseYTDLResult(ydl_opts)
  29. # patch in the constructor
  30. YDL.__init__ = MethodType(ytdl_init, YDL)
  31. # core parser
  32. def parsed_options(argv):
  33. try:
  34. youtube_dl._real_main(list(argv))
  35. except ParseYTDLResult as result:
  36. return result.opts
  37. # from https://github.com/yt-dlp/yt-dlp/issues/5859#issuecomment-1363938900
  38. default = parsed_options([])
  39. def neq_opt(a, b):
  40. if a == b:
  41. return False
  42. if a is None and repr(type(object)).endswith(".utils.DateRange'>"):
  43. return '0001-01-01 - 9999-12-31' != '{0}'.format(b)
  44. return a != b
  45. diff = dict((k, v) for k, v in parsed_options(opts).items() if neq_opt(default[k], v))
  46. if 'postprocessors' in diff:
  47. diff['postprocessors'] = [pp for pp in diff['postprocessors'] if pp not in default['postprocessors']]
  48. return diff
  49. def main():
  50. from pprint import PrettyPrinter
  51. pprint = PrettyPrinter()
  52. super_format = pprint.format
  53. def format(object, context, maxlevels, level):
  54. if repr(type(object)).endswith(".utils.DateRange'>"):
  55. return '{0}: {1}>'.format(repr(object)[:-2], object), True, False
  56. return super_format(object, context, maxlevels, level)
  57. pprint.format = format
  58. pprint.pprint(cli_to_api(*sys.argv))
  59. if __name__ == '__main__':
  60. main()