The little things give you away... A collection of various small helper stuff
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 

97 lignes
3.2 KiB

  1. #!/usr/bin/env python3
  2. import itertools
  3. import os.path
  4. import subprocess
  5. def test(input, lines):
  6. p = subprocess.Popen([os.path.join(os.path.dirname(__file__), '.make-and-exec-binaries', 'youtube-extract-rapid'], text = False, stdin = subprocess.PIPE, stdout = subprocess.PIPE)
  7. stdout, stderr = p.communicate(input)
  8. assert not stderr
  9. stdout = stdout.split(b'\n')
  10. assert stdout[-1] == b'' and stdout[:-1] == lines, f'Got {stdout!r} instead of {lines!r} from {input!r}'
  11. def is_id_char(c):
  12. return b'0' <= c <= b'9' or b'a' <= c <= b'z' or b'A' <= c <= b'Z' or c == b'_' or c == b'-'
  13. def bytes_range(a, b):
  14. # Yields every char between a and b (inclusive) as a bytes object
  15. return map(lambda x: bytes([x]), range(ord(a), ord(b) + 1))
  16. test(b'', [])
  17. test(b'short\n', [])
  18. test(b'01234567890', [b'v 01234567890'])
  19. test(b'01234567890\n', [b'v 01234567890'])
  20. # Videos
  21. input = []
  22. for a in map(lambda x: bytes.fromhex(f'{x:02x}'), range(256)):
  23. if is_id_char(a):
  24. continue
  25. for b in map(lambda x: bytes.fromhex(f'{x:02x}'), range(256)):
  26. if is_id_char(b):
  27. continue
  28. input.append(a + b'0aA_-1bB_-2' + b)
  29. test(b''.join(input), [b'v 0aA_-1bB_-2'] * len(input))
  30. # Channels
  31. test(b'0123456789abcdeFGHIJ_-', [b'c 0123456789abcdeFGHIJ_-'])
  32. test(b'UC0123456789abcdeFGHIJ_-', [b'c UC0123456789abcdeFGHIJ_-'])
  33. # Pure playlists
  34. playlists = [
  35. b'0123456789ABCDEF',
  36. b'PL0123456789ABCDEF',
  37. b'0123456789abcdefghijABCDEFGHIJ_-',
  38. b'PL0123456789abcdefghijABCDEFGHIJ_-',
  39. b'RDAMVM0123456789abcdeFGHIJ_-',
  40. b'RDGMEM0123456789abcdeFGHIJ_-',
  41. b'RDAO0123456789abcdeFGHIJ_-',
  42. b'RDEM0123456789abcdeFGHIJ_-',
  43. b'RDKM0123456789abcdeFGHIJ_-',
  44. ]
  45. for playlist in playlists:
  46. test(playlist, [b'p ' + playlist])
  47. # Music playlist madness
  48. for prefix in (b'RDCLAK5uy_', b'RDTMAK5uy_', b'OLAK5uy_'):
  49. for c in bytes_range(b'k', b'n'):
  50. test(prefix + c + b'0123456789abcdefghijABCDEFGHIJ_-', [b'p ' + prefix + c + b'0123456789abcdefghijABCDEFGHIJ_-'])
  51. # Playlists with video IDs
  52. for prefix in (b'RD', b'UL', b'EL', b'CL', b'SL', b'LP', b'RDMM', b'RDQM', b'RDEM', b'RDLV', b'RDHC'):
  53. test(prefix + b'0aA_-1bB_-2', [b'p ' + prefix + b'0aA_-1bB_-2', b'v 0aA_-1bB_-2'])
  54. for a, b in itertools.product(bytes_range(b'0', b'4'), bytes_range(b'0', b'9')):
  55. playlist = b'RD' + a + b + b'0aA_-1bB_-2'
  56. test(playlist, [b'p ' + playlist, b'v 0aA_-1bB_-2'])
  57. playlist = b'RDGMEM' + b'0123456789abcdeFGHIJ_-' + b'VM0aA_-1bB_-2'
  58. test(playlist, [b'p ' + playlist, b'v 0aA_-1bB_-2'])
  59. # Playlists with channel IDs
  60. for prefix in (b'UU', b'LL', b'FL', b'PU', b'UUSH'):
  61. test(prefix + b'0123456789abcdeFGHIJ_-', [b'p ' + prefix + b'0123456789abcdeFGHIJ_-', b'c 0123456789abcdeFGHIJ_-'])
  62. test(b'RDCMUC0123456789abcdeFGHIJ_-', [b'p RDCMUC0123456789abcdeFGHIJ_-', b'c UC0123456789abcdeFGHIJ_-'])
  63. # Some particular unrecognised IDs
  64. ids = [
  65. b'0123456789ABCDEG',
  66. b'PL0123456789ABCDEG',
  67. b'RDCLAK5uy_j0123456789abcdefghijABCDEFGHIJ_-',
  68. b'RDCLAK5uy_o0123456789abcdefghijABCDEFGHIJ_-',
  69. ]
  70. for id_ in ids:
  71. test(id_, [b'? ' + id_])
  72. # Buffer rollover
  73. BUFFER_SIZE = 1024 * 1024
  74. for offset in range(-11, 1):
  75. test(b'?' * (BUFFER_SIZE + offset) + b'0aA_-1bB_-2', [b'v 0aA_-1bB_-2'])
  76. # Max length exceedance
  77. MAX_RESULT_SIZE = 1024
  78. for length in range(MAX_RESULT_SIZE + 1, MAX_RESULT_SIZE + 15):
  79. test(b'0' * length, [])