mirror of
				https://github.com/yt-dlp/yt-dlp.git
				synced 2025-10-31 06:35:12 +00:00 
			
		
		
		
	[jsinterp] Implement splice and general improvement
I still get 403s on YouTube though.
This commit is contained in:
		| @@ -1,5 +1,6 @@ | |||||||
| from __future__ import unicode_literals | from __future__ import unicode_literals | ||||||
|  |  | ||||||
|  | import json | ||||||
| import re | import re | ||||||
|  |  | ||||||
| from .utils import ( | from .utils import ( | ||||||
| @@ -40,8 +41,9 @@ class JSInterpreter(object): | |||||||
|             assign = lambda v: v |             assign = lambda v: v | ||||||
|             expr = stmt[len('return '):] |             expr = stmt[len('return '):] | ||||||
|         else: |         else: | ||||||
|             raise ExtractorError( |             # Try interpreting it as an expression | ||||||
|                 'Cannot determine left side of statement in %r' % stmt) |             expr = stmt | ||||||
|  |             assign = lambda v: v | ||||||
|  |  | ||||||
|         v = self.interpret_expression(expr, local_vars, allow_recursion) |         v = self.interpret_expression(expr, local_vars, allow_recursion) | ||||||
|         return assign(v) |         return assign(v) | ||||||
| @@ -53,35 +55,62 @@ class JSInterpreter(object): | |||||||
|         if expr.isalpha(): |         if expr.isalpha(): | ||||||
|             return local_vars[expr] |             return local_vars[expr] | ||||||
|  |  | ||||||
|         m = re.match(r'^(?P<in>[a-z]+)\.(?P<member>.*)$', expr) |         try: | ||||||
|         if m: |             return json.loads(expr) | ||||||
|             member = m.group('member') |         except ValueError: | ||||||
|             variable = m.group('in') |             pass | ||||||
|  |  | ||||||
|             if variable not in local_vars: |         m = re.match( | ||||||
|  |             r'^(?P<var>[a-z]+)\.(?P<member>[^(]+)(?:\(+(?P<args>[^()]*)\))?$', | ||||||
|  |             expr) | ||||||
|  |         if m: | ||||||
|  |             variable = m.group('var') | ||||||
|  |             member = m.group('member') | ||||||
|  |             arg_str = m.group('args') | ||||||
|  |  | ||||||
|  |             if variable in local_vars: | ||||||
|  |                 obj = local_vars[variable] | ||||||
|  |             else: | ||||||
|                 if variable not in self._objects: |                 if variable not in self._objects: | ||||||
|                     self._objects[variable] = self.extract_object(variable) |                     self._objects[variable] = self.extract_object(variable) | ||||||
|                 obj = self._objects[variable] |                 obj = self._objects[variable] | ||||||
|                 key, args = member.split('(', 1) |  | ||||||
|                 args = args.strip(')') |  | ||||||
|                 argvals = [int(v) if v.isdigit() else local_vars[v] |  | ||||||
|                            for v in args.split(',')] |  | ||||||
|                 return obj[key](argvals) |  | ||||||
|  |  | ||||||
|             val = local_vars[variable] |             if arg_str is None: | ||||||
|             if member == 'split("")': |                 # Member access | ||||||
|                 return list(val) |  | ||||||
|             if member == 'join("")': |  | ||||||
|                 return ''.join(val) |  | ||||||
|                 if member == 'length': |                 if member == 'length': | ||||||
|                 return len(val) |                     return len(obj) | ||||||
|             if member == 'reverse()': |                 return obj[member] | ||||||
|                 return val[::-1] |  | ||||||
|             slice_m = re.match(r'slice\((?P<idx>.*)\)', member) |             assert expr.endswith(')') | ||||||
|             if slice_m: |             # Function call | ||||||
|                 idx = self.interpret_expression( |             if arg_str == '': | ||||||
|                     slice_m.group('idx'), local_vars, allow_recursion - 1) |                 argvals = tuple() | ||||||
|                 return val[idx:] |             else: | ||||||
|  |                 argvals = tuple([ | ||||||
|  |                     self.interpret_expression(v, local_vars, allow_recursion) | ||||||
|  |                     for v in arg_str.split(',')]) | ||||||
|  |  | ||||||
|  |             if member == 'split': | ||||||
|  |                 assert argvals == ('',) | ||||||
|  |                 return list(obj) | ||||||
|  |             if member == 'join': | ||||||
|  |                 assert len(argvals) == 1 | ||||||
|  |                 return argvals[0].join(obj) | ||||||
|  |             if member == 'reverse': | ||||||
|  |                 assert len(argvals) == 0 | ||||||
|  |                 return obj[::-1] | ||||||
|  |             if member == 'slice': | ||||||
|  |                 assert len(argvals) == 1 | ||||||
|  |                 return obj[argvals[0]:] | ||||||
|  |             if member == 'splice': | ||||||
|  |                 assert isinstance(obj, list) | ||||||
|  |                 index, howMany = argvals | ||||||
|  |                 res = [] | ||||||
|  |                 for i in range(index, min(index + howMany, len(obj))): | ||||||
|  |                     res.append(obj.pop(i)) | ||||||
|  |                 return res | ||||||
|  |  | ||||||
|  |             return obj[member](argvals) | ||||||
|  |  | ||||||
|         m = re.match( |         m = re.match( | ||||||
|             r'^(?P<in>[a-z]+)\[(?P<idx>.+)\]$', expr) |             r'^(?P<in>[a-z]+)\[(?P<idx>.+)\]$', expr) | ||||||
| @@ -100,13 +129,14 @@ class JSInterpreter(object): | |||||||
|             return a % b |             return a % b | ||||||
|  |  | ||||||
|         m = re.match( |         m = re.match( | ||||||
|             r'^(?P<func>[a-zA-Z$]+)\((?P<args>[a-z0-9,]+)\)$', expr) |             r'^(?P<func>[.a-zA-Z$]+)\((?P<args>[a-z0-9,]+)\)$', expr) | ||||||
|         if m: |         if m: | ||||||
|             fname = m.group('func') |             fname = m.group('func') | ||||||
|  |             argvals = tuple([ | ||||||
|  |                 int(v) if v.isdigit() else local_vars[v] | ||||||
|  |                 for v in m.group('args').split(',')]) | ||||||
|             if fname not in self._functions: |             if fname not in self._functions: | ||||||
|                 self._functions[fname] = self.extract_function(fname) |                 self._functions[fname] = self.extract_function(fname) | ||||||
|             argvals = [int(v) if v.isdigit() else local_vars[v] |  | ||||||
|                        for v in m.group('args').split(',')] |  | ||||||
|             return self._functions[fname](argvals) |             return self._functions[fname](argvals) | ||||||
|         raise ExtractorError('Unsupported JS expression %r' % expr) |         raise ExtractorError('Unsupported JS expression %r' % expr) | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Philipp Hagemeister
					Philipp Hagemeister