Allow plugin extractors to replace the built-in ones

This allows easier plugin chaining; e.g.
- https://gist.github.com/pukkandan/24f13ff1ed385c5a390c1d7bd130d8f7
- https://gist.github.com/pukkandan/fcf5ca1785c80f64e471f0ee14f990fb
pull/5004/head
pukkandan 2 months ago
parent 1060f82f89
commit 2314b4d89f
No known key found for this signature in database
GPG Key ID: 7EEE9E1E817D0A39
  1. 13
      yt_dlp/extractor/common.py
  2. 7
      yt_dlp/extractor/extractors.py

@ -5,6 +5,7 @@ import hashlib
import http.client
import http.cookiejar
import http.cookies
import inspect
import itertools
import json
import math
@ -3900,6 +3901,18 @@ class InfoExtractor:
"""Only for compatibility with some older extractors"""
return next(iter(cls._extract_embed_urls(None, webpage) or []), None)
@classmethod
def __init_subclass__(cls, *, plugin_name=None, **kwargs):
if plugin_name:
mro = inspect.getmro(cls)
super_class = cls.__wrapped__ = mro[mro.index(cls) + 1]
cls.IE_NAME, cls.ie_key = f'{super_class.IE_NAME}+{plugin_name}', super_class.ie_key
while getattr(super_class, '__wrapped__', None):
super_class = super_class.__wrapped__
setattr(sys.modules[super_class.__module__], super_class.__name__, cls)
return super().__init_subclass__(**kwargs)
class SearchInfoExtractor(InfoExtractor):
"""

@ -3,6 +3,9 @@ import os
from ..utils import load_plugins
# NB: Must be before other imports so that plugins can be correctly injected
_PLUGIN_CLASSES = load_plugins('extractor', 'IE', {})
_LAZY_LOADER = False
if not os.environ.get('YTDLP_NO_LAZY_EXTRACTORS'):
with contextlib.suppress(ImportError):
@ -19,5 +22,5 @@ if not _LAZY_LOADER:
]
_ALL_CLASSES.append(GenericIE) # noqa: F405
_PLUGIN_CLASSES = load_plugins('extractor', 'IE', globals())
_ALL_CLASSES = list(_PLUGIN_CLASSES.values()) + _ALL_CLASSES
globals().update(_PLUGIN_CLASSES)
_ALL_CLASSES[:0] = _PLUGIN_CLASSES.values()

Loading…
Cancel
Save