Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/wrestleuniverse.py (Python)

Code before:
            raise ExtractorError('pycryptodomex not found. Please install', expected=True)
        private_key = Cryptodome.RSA.generate(2048)
        cipher = Cryptodome.PKCS1_OAEP.new(private_key, hashAlgo=Cryptodome.SHA1)

        def decrypt(data):
            if not data:
                return None
            try:
                return cipher.decrypt(base64.b64decode(data)).decode()
            except (ValueError, binascii.Error) as e:
                raise ExtractorError(f'Could not decrypt data: {e}')

        token = base64.b64encode(private_key.public_key().export_key('DER')).decode()
        api_json = self._call_api(video_id, param, msg, data={
            'deviceId': self._DEVICE_ID,
            'token': token,
            **data,
        }, query=query, fatal=fatal)
        return api_json, decrypt

    def _download_metadata(self, url, video_id, lang, props_keys):
        metadata = self._call_api(video_id, msg='video information', query={'al': lang or 'ja'}, auth=False, fatal=False)
        if not metadata:
            webpage = self._download_webpage(url, video_id)
            nextjs_data = self._search_nextjs_data(webpage, video_id)
            metadata = traverse_obj(nextjs_data, ('props', 'pageProps', *props_keys, {dict})) or {}
        return metadata

    def _get_formats(self, data, path, video_id=None):
        hls_url = traverse_obj(data, path, get_all=False)
        if not hls_url and not data.get('canWatch'):
            self.raise_no_formats(
                'This account does not have access to the requested content', expected=True)
        elif not hls_url:
            self.raise_no_formats('No supported formats found')
        return self._extract_m3u8_formats(hls_url, video_id, 'mp4', m3u8_id='hls', live=True)


class WrestleUniverseVODIE(WrestleUniverseBaseIE):
    _VALID_URL = WrestleUniverseBaseIE._VALID_URL_TMPL % 'videos'
    _TESTS = [{
        'url': 'https://www.wrestle-universe.com/en/videos/dp8mpjmcKfxzUhEHM2uFws',
        'info_dict': {
            'id': 'dp8mpjmcKfxzUhEHM2uFws',
            'ext': 'mp4',
            'title': 'The 3rd “Futari wa Princess” Max Heart Tournament',
            'description': 'md5:318d5061e944797fbbb81d5c7dd00bf5',
            'location': '埼玉・春日部ふれあいキューブ',
            'channel': 'tjpw',
            'duration': 7119,
            'timestamp': 1674979200,

Review comment (suggestion):
```suggestion
            metadata = traverse_obj(nextjs_data, ('props', 'pageProps', *variadic(props_keys), {dict})) or {}
```

Code after:
        if not Cryptodome.RSA:
            raise ExtractorError('pycryptodomex not found. Please install', expected=True)
        private_key = Cryptodome.RSA.generate(2048)
        cipher = Cryptodome.PKCS1_OAEP.new(private_key, hashAlgo=Cryptodome.SHA1)

        def decrypt(data):
            if not data:
                return None
            try:
                return cipher.decrypt(base64.b64decode(data)).decode()
            except (ValueError, binascii.Error) as e:
                raise ExtractorError(f'Could not decrypt data: {e}')

        token = base64.b64encode(private_key.public_key().export_key('DER')).decode()
        api_json = self._call_api(video_id, param, msg, data={
            'deviceId': self._DEVICE_ID,
            'token': token,
            **data,
        }, query=query, fatal=fatal)
        return api_json, decrypt

    def _download_metadata(self, url, video_id, lang, props_keys):
        metadata = self._call_api(video_id, msg='metadata', query={'al': lang or 'ja'}, auth=False, fatal=False)
        if not metadata:
            webpage = self._download_webpage(url, video_id)
            nextjs_data = self._search_nextjs_data(webpage, video_id)
            metadata = traverse_obj(nextjs_data, (
                'props', 'pageProps', *variadic(props_keys, (str, bytes, dict, set)), {dict})) or {}
        return metadata

    def _get_formats(self, data, path, video_id=None):
        hls_url = traverse_obj(data, path, get_all=False)
        if not hls_url and not data.get('canWatch'):
            self.raise_no_formats(
                'This account does not have access to the requested content', expected=True)
        elif not hls_url:
            self.raise_no_formats('No supported formats found')
        return self._extract_m3u8_formats(hls_url, video_id, 'mp4', m3u8_id='hls', live=True)


class WrestleUniverseVODIE(WrestleUniverseBaseIE):
    _VALID_URL = WrestleUniverseBaseIE._VALID_URL_TMPL % 'videos'
    _TESTS = [{
        'url': 'https://www.wrestle-universe.com/en/videos/dp8mpjmcKfxzUhEHM2uFws',
        'info_dict': {
            'id': 'dp8mpjmcKfxzUhEHM2uFws',
            'ext': 'mp4',
            'title': 'The 3rd “Futari wa Princess” Max Heart Tournament',
            'description': 'md5:318d5061e944797fbbb81d5c7dd00bf5',
            'location': '埼玉・春日部ふれあいキューブ',
            'channel': 'tjpw',