ronantakizawa/codereview-bench huggingface dataset:
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/ina.py (Python)

Code before:
        'url': 'https://www.ina.fr/ina-eclaire-actu/video/cpb8205116303/les-jeux-electroniques',
        'md5': '4b8284a9a3a184fdc7e744225b8251e7',
        'info_dict': {
            'id': 'CPB8205116303',
            'ext': 'mp4',
            'title': 'Les jeux électroniques',
            'description': 'md5:e09f7683dad1cc60b74950490127d233',
            'date': 're:1982-12-04T.*',
            'duration': 657,
            'thumbnail': 'https://cdn-hub.ina.fr/notice/690x517/203/CPB8205116303.jpeg',
        }
    }]

    def _real_extract(self, url):
        video_id = self._match_id(url).upper()
        webpage = self._download_webpage(url, video_id)

        api_url = self._html_search_regex(r'asset-details-url=["\'](?P<api_url>[^"\']+)', webpage, 'api_url')
        api_url = api_url.replace(video_id, f'{video_id}.json')

        api_response = self._download_json(api_url, video_id)

        return {
            'id': video_id,
            'url': api_response['resourceUrl'],
            'ext': "mp4" if api_response['type'] == "video" else "mp3",
            'title': api_response['title'],
            'description': api_response.get('description'),
            'date': api_response.get('dateOfBroadcast'),
            'duration': api_response.get('duration'),
            'thumbnail': api_response.get('resourceThumbnail'),
        }


Review comment (suggestion):
```suggestion
            'ext': {'video': 'mp4', 'audio': 'mp3'}.get(api_response.get('type')),
```

Code after:
    }, {
        'url': 'https://www.ina.fr/ina-eclaire-actu/video/cpb8205116303/les-jeux-electroniques',
        'md5': '4b8284a9a3a184fdc7e744225b8251e7',
        'info_dict': {
            'id': 'CPB8205116303',
            'ext': 'mp4',
            'title': 'Les jeux électroniques',
            'description': 'md5:e09f7683dad1cc60b74950490127d233',
            'upload_date': '19821204',
            'duration': 657,
            'thumbnail': 'https://cdn-hub.ina.fr/notice/690x517/203/CPB8205116303.jpeg',
        }
    }]

    def _real_extract(self, url):
        video_id = self._match_id(url).upper()
        webpage = self._download_webpage(url, video_id)

        api_url = self._html_search_regex(
            r'asset-details-url\s*=\s*["\'](?P<api_url>[^"\']+)',
            webpage, 'api_url').replace(video_id, f'{video_id}.json')

        api_response = self._download_json(api_url, video_id)

        return {
            'id': video_id,
            'url': api_response['resourceUrl'],
            'ext': {'video': 'mp4', 'audio': 'mp3'}.get(api_response.get('type')),
            'title': api_response.get('title'),
            'description': api_response.get('description'),
            'upload_date': unified_strdate(api_response.get('dateOfBroadcast')),
            'duration': api_response.get('duration'),
            'thumbnail': api_response.get('resourceThumbnail'),
        }
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/ina.py (Python)

Code before:
        'info_dict': {
            'id': 'CPB8205116303',
            'ext': 'mp4',
            'title': 'Les jeux électroniques',
            'description': 'md5:e09f7683dad1cc60b74950490127d233',
            'upload_date': '19821204',
            'duration': 657,
            'thumbnail': 'https://cdn-hub.ina.fr/notice/690x517/203/CPB8205116303.jpeg',
        }
    }]

    def _real_extract(self, url):
        video_id = self._match_id(url).upper()
        webpage = self._download_webpage(url, video_id)

        api_url = self._html_search_regex(
            r'asset-details-url\s*=\s*["\'](?P<api_url>[^"\']+)',
            webpage, 'api_url').replace(video_id, f'{video_id}.json')

        api_response = self._download_json(api_url, video_id)

        return {
            'id': video_id,
            'url': api_response['resourceUrl'],
            'ext': {'video': 'mp4', 'audio': 'mp3'}.get(api_response.get('type')),
            'title': api_response['title'],
            'description': api_response.get('description'),
            'upload_date': unified_strdate(api_response.get('dateOfBroadcast')),
            'duration': api_response.get('duration'),
            'thumbnail': api_response.get('resourceThumbnail'),
        }


Review comment (suggestion):
```suggestion
            'title': api_response.get('title'),
```

Code after:
        'info_dict': {
            'id': 'CPB8205116303',
            'ext': 'mp4',
            'title': 'Les jeux électroniques',
            'description': 'md5:e09f7683dad1cc60b74950490127d233',
            'upload_date': '19821204',
            'duration': 657,
            'thumbnail': 'https://cdn-hub.ina.fr/notice/690x517/203/CPB8205116303.jpeg',
        }
    }]

    def _real_extract(self, url):
        video_id = self._match_id(url).upper()
        webpage = self._download_webpage(url, video_id)

        api_url = self._html_search_regex(
            r'asset-details-url\s*=\s*["\'](?P<api_url>[^"\']+)',
            webpage, 'api_url').replace(video_id, f'{video_id}.json')

        api_response = self._download_json(api_url, video_id)

        return {
            'id': video_id,
            'url': api_response['resourceUrl'],
            'ext': {'video': 'mp4', 'audio': 'mp3'}.get(api_response.get('type')),
            'title': api_response.get('title'),
            'description': api_response.get('description'),
            'upload_date': unified_strdate(api_response.get('dateOfBroadcast')),
            'duration': api_response.get('duration'),
            'thumbnail': api_response.get('resourceThumbnail'),
        }
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/netverse.py (Python)

Code before:
from .common import InfoExtractor
from ..utils import (
    traverse_obj,
    ExtractorError,
    # GeoRestrictedError,
)


class NetverseBaseIE(InfoExtractor):
    def get_required_json(self, url, data=None):
        match = self._match_valid_url(url).groupdict()
        display_id, sites_type = match['display_id'], match['type']

        if sites_type == 'watch' or sites_type == 'video':
            media_api_url = f'https://api.netverse.id/medias/api/v2/watchvideo/{display_id}'
        elif sites_type == 'webseries':
            media_api_url = f'https://api.netverse.id/medias/api/v2/webseries/{display_id}'

        json_data = self._download_json(media_api_url, display_id, data=data)

        if json_data.get('error'):
            raise ExtractorError(json_data.get('message'))

        return json_data

    def get_access_id(self, dailymotion_url):
        return dailymotion_url.split('/')[-1]

    def _call_metadata_api_from_video_url(self, dailymotion_url):
        access_id = self.get_access_id(dailymotion_url)
        metadata_json = self._call_metadata_api(access_id)
        return access_id, metadata_json

    def _call_metadata_api(self, access_id, req_file_type='video', query=None):
        video_metadata_api_url = f'https://www.dailymotion.com/player/metadata/{req_file_type}/{access_id}'

        if query is None:

Review comment (suggestion):
```suggestion
        display_id, sites_type = self._match_valid_url(url).group('display_id', 'type')
```

Code after:
from .common import InfoExtractor
from .dailymotion import DailymotionIE
from ..utils import smuggle_url, traverse_obj


class NetverseBaseIE(InfoExtractor):
    _ENDPOINTS = {
        'watch': 'watchvideo',
        'video': 'watchvideo',
        'webseries': 'webseries',
        'season': 'webseason_videos',
    }

    def _call_api(self, slug, endpoint, query={}, season_id='', display_id=None):
        return self._download_json(
            f'https://api.netverse.id/medias/api/v2/{self._ENDPOINTS[endpoint]}/{slug}/{season_id}',
            display_id or slug, query=query)


class NetverseIE(NetverseBaseIE):
    _VALID_URL = r'https?://(?:\w+\.)?netverse\.id/(?P<type>watch|video)/(?P<display_id>[^/?#&]+)'
    _TESTS = [{
        # Watch video
        'url': 'https://www.netverse.id/watch/waktu-indonesia-bercanda-edisi-spesial-lebaran-2016',
        'info_dict': {
            'id': 'k4yhqUwINAGtmHx3NkL',
            'title': 'Waktu Indonesia Bercanda - Edisi Spesial Lebaran 2016',
            'ext': 'mp4',
            'season': 'Season 2016',
            'description': 'md5:d41d8cd98f00b204e9800998ecf8427e',
            'thumbnail': r're:https?://s\d+\.dmcdn\.net/v/T7aV31Y0eGRWBbwkK/x1080',
            'episode_number': 22,
            'episode': 'Episode 22',
            'uploader_id': 'x2ir3vq',
            'age_limit': 0,
            'tags': [],
            'view_count': int,
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/netverse.py (Python)

Code before:
            'series': traverse_obj(videos, ('program_detail', 'title')),
        }


class NetversePlaylistIE(NetverseBaseIE):
    _VALID_URL = r'https?://(?:\w+\.)?netverse\.id/(?P<type>webseries)/(?P<display_id>[^/?#&]+)'
    _TEST = {
        'url': 'https://netverse.id/webseries/tetangga-masa-gitu',
        'info_dict': {
            'id': 'tetangga-masa-gitu',
            'title': 'Tetangga Masa Gitu',
        },
        'playlist_count': 46,
    }

    def parse_playlist(self, url, page_num):
        _, playlist_json = self._call_api(url, query={'page': page_num})
        for slug in traverse_obj(playlist_json, ('response', 'related', 'data', ..., 'slug')):
            yield self.url_result(f'https://www.netverse.id/video/{slug}', NetverseIE)

    def _real_extract(self, url):
        _, playlist_data = self._call_api(url)

        # TODO: get video from other season
        # The season has id and the next season video is located at api_url/<season_id>?page=<page>
        # still not not sure about number in OnDemandPagedList
        return self.playlist_result(
            OnDemandPagedList(functools.partial(self.parse_playlist, url), 8),
            traverse_obj(playlist_data, ('response', 'webseries_info', 'slug')),
            traverse_obj(playlist_data, ('response', 'webseries_info', 'title')))


Review comment (suggestion):
will you be addressing this todo now? or should I merge without it?

```suggestion
        # FIXME: get video from other season from api_url/<season_id>?page=<page>
```

Code after:
        'playlist_count': 519,
    }, {
        # single season
        'url': 'https://netverse.id/webseries/kelas-internasional',
        'info_dict': {
            'id': 'kelas-internasional',
            'title': 'Kelas Internasional',
        },
        'playlist_count': 203,
    }]

    def parse_playlist(self, json_data, playlist_id):
        slug_sample = traverse_obj(json_data, ('related', 'data', ..., 'slug'))[0]
        for season in traverse_obj(json_data, ('seasons', ..., 'id')):
            playlist_json = self._call_api(
                slug_sample, 'season', display_id=playlist_id, season_id=season)

            for current_page in range(playlist_json['response']['season_list']['last_page']):
                playlist_json = self._call_api(slug_sample, 'season', query={'page': current_page + 1},
                                               season_id=season, display_id=playlist_id)
                for slug in traverse_obj(playlist_json, ('response', ..., 'data', ..., 'slug')):
                    yield self.url_result(f'https://www.netverse.id/video/{slug}', NetverseIE)

    def _real_extract(self, url):
        playlist_id, sites_type = self._match_valid_url(url).group('display_id', 'type')
        playlist_data = self._call_api(playlist_id, sites_type)

        return self.playlist_result(
            self.parse_playlist(playlist_data['response'], playlist_id),
            traverse_obj(playlist_data, ('response', 'webseries_info', 'slug')),
            traverse_obj(playlist_data, ('response', 'webseries_info', 'title')))
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/netverse.py (Python)

Code before:
import functools

from .common import InfoExtractor
from .dailymotion import DailymotionIE
from ..utils import (
    InAdvancePagedList,
    smuggle_url,
    traverse_obj,
)


class NetverseBaseIE(InfoExtractor):
    _ENDPOINTS = {
        'watch': 'watchvideo',
        'video': 'watchvideo',
        'webseries': 'webseries',
        'season': 'webseason_videos',
    }

    def _call_api(self, input_data, query={}, season='',
                  custom_id=None, force_endpoint_type='auto', input_type='url'):

        slug = None
        if input_type == 'url':
            display_id, sites_type = self._match_valid_url(input_data).group('display_id', 'type')
        elif input_type == 'slug':
            slug = input_data
        display_id = display_id if slug is None else slug
        endpoint = self._ENDPOINTS[sites_type] if force_endpoint_type == 'auto' else self._ENDPOINTS[force_endpoint_type]

        json_data = self._download_json(
            f'https://api.netverse.id/medias/api/v2/{endpoint}/{display_id}/{season}',
            custom_id or display_id, query=query)
        return display_id, json_data

Review comment (suggestion):
```suggestion
from ..utils import InAdvancePagedList, smuggle_url, traverse_obj
```

Code after:
from .common import InfoExtractor
from .dailymotion import DailymotionIE
from ..utils import smuggle_url, traverse_obj


class NetverseBaseIE(InfoExtractor):
    _ENDPOINTS = {
        'watch': 'watchvideo',
        'video': 'watchvideo',
        'webseries': 'webseries',
        'season': 'webseason_videos',
    }

    def _call_api(self, slug, endpoint, query={}, season_id='', display_id=None):
        return self._download_json(
            f'https://api.netverse.id/medias/api/v2/{self._ENDPOINTS[endpoint]}/{slug}/{season_id}',
            display_id or slug, query=query)


class NetverseIE(NetverseBaseIE):
    _VALID_URL = r'https?://(?:\w+\.)?netverse\.id/(?P<type>watch|video)/(?P<display_id>[^/?#&]+)'
    _TESTS = [{
        # Watch video
        'url': 'https://www.netverse.id/watch/waktu-indonesia-bercanda-edisi-spesial-lebaran-2016',
        'info_dict': {
            'id': 'k4yhqUwINAGtmHx3NkL',
            'title': 'Waktu Indonesia Bercanda - Edisi Spesial Lebaran 2016',
            'ext': 'mp4',
            'season': 'Season 2016',
            'description': 'md5:d41d8cd98f00b204e9800998ecf8427e',
            'thumbnail': r're:https?://s\d+\.dmcdn\.net/v/T7aV31Y0eGRWBbwkK/x1080',
            'episode_number': 22,
            'episode': 'Episode 22',
            'uploader_id': 'x2ir3vq',
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/ixigua.py (Python)

Code before:
from .common import InfoExtractor
from ..utils import (
    ExtractorError,
    get_element_by_id,
    int_or_none,
    js_to_json,
    str_or_none,
    traverse_obj,
)
import base64


class IxiguaIE(InfoExtractor):
    _VALID_URL = r'https?://(?:\w+\.)?ixigua\.com/(?:video/)?(?P<id>[0-9]+).+'
    _TEST = {
        'url': 'https://www.ixigua.com/6996881461559165471',
        'info_dict': {
            'id': '6996881461559165471',
            'ext': 'mp4',
            'title': '盲目涉水风险大，亲身示范高水位行车注意事项',
            'description': '本期《懂车帝评测》，我们将尝试验证一个夏日大家可能会遇到的关键性问题：如果突发暴雨，我们不得不涉水行车，如何做才能更好保障生命安全。',
            'tag': 'video_car',
            'like_count': int,
            'dislike_count': int,
            'view_count': int,
            'uploader': '懂车帝原创',
            'uploader_id': '6480145787',
            'thumbnail': r're:^https?://.*\.(avif|webp)(?:\?.+)',  # still not sure for regex
            'timestamp': 1629088414,
            'duration': 1030,
        },
        'skip': 'This Extractor need cookies',
    }

    def _get_json_data(self, webpage, video_id):

Review comment (refactor):
```suggestion
import base64

from .common import InfoExtractor
from ..utils import (
    ExtractorError,
    get_element_by_id,
    int_or_none,
    js_to_json,
    str_or_none,
    traverse_obj,
)
```

Code after:
import base64

from .common import InfoExtractor
from ..utils import (
    ExtractorError,
    get_element_by_id,
    int_or_none,
    js_to_json,
    str_or_none,
    traverse_obj,
)


class IxiguaIE(InfoExtractor):
    _VALID_URL = r'https?://(?:\w+\.)?ixigua\.com/(?:video/)?(?P<id>\d+).+'
    _TESTS = [{
        'url': 'https://www.ixigua.com/6996881461559165471',
        'info_dict': {
            'id': '6996881461559165471',
            'ext': 'mp4',
            'title': '盲目涉水风险大，亲身示范高水位行车注意事项',
            'description': 'md5:8c82f46186299add4a1c455430740229',
            'tags': ['video_car'],
            'like_count': int,
            'dislike_count': int,
            'view_count': int,
            'uploader': '懂车帝原创',
            'uploader_id': '6480145787',
            'thumbnail': r're:^https?://.+\.(avif|webp)',
            'timestamp': 1629088414,
            'duration': 1030,
        }
    }]

    def _get_json_data(self, webpage, video_id):
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/ixigua.py (Python)

Code before:
from .common import InfoExtractor
from ..utils import (
    ExtractorError,
    get_element_by_id,
    int_or_none,
    js_to_json,
    str_or_none,
    traverse_obj,
)
import base64


class IxiguaIE(InfoExtractor):
    _VALID_URL = r'https?://(?:\w+\.)?ixigua\.com/(?:video/)?(?P<id>[0-9]+).+'
    _TEST = {
        'url': 'https://www.ixigua.com/6996881461559165471',
        'info_dict': {
            'id': '6996881461559165471',
            'ext': 'mp4',
            'title': '盲目涉水风险大，亲身示范高水位行车注意事项',
            'description': '本期《懂车帝评测》，我们将尝试验证一个夏日大家可能会遇到的关键性问题：如果突发暴雨，我们不得不涉水行车，如何做才能更好保障生命安全。',
            'tag': 'video_car',
            'like_count': int,
            'dislike_count': int,
            'view_count': int,
            'uploader': '懂车帝原创',
            'uploader_id': '6480145787',
            'thumbnail': r're:^https?://.*\.(avif|webp)(?:\?.+)',  # still not sure for regex
            'timestamp': 1629088414,
            'duration': 1030,
        },
        'skip': 'This Extractor need cookies',
    }

    def _get_json_data(self, webpage, video_id):
        js_data = get_element_by_id('SSR_HYDRATED_DATA', webpage)
        if not js_data:
            raise ExtractorError('Failed to get SSR_HYDRATED_DATA',)


Review comment (suggestion):
```suggestion
    _VALID_URL = r'https?://(?:\w+\.)?ixigua\.com/(?:video/)?(?P<id>\d+)'
```

Code after:
import base64

from .common import InfoExtractor
from ..utils import (
    ExtractorError,
    get_element_by_id,
    int_or_none,
    js_to_json,
    str_or_none,
    traverse_obj,
)


class IxiguaIE(InfoExtractor):
    _VALID_URL = r'https?://(?:\w+\.)?ixigua\.com/(?:video/)?(?P<id>\d+).+'
    _TESTS = [{
        'url': 'https://www.ixigua.com/6996881461559165471',
        'info_dict': {
            'id': '6996881461559165471',
            'ext': 'mp4',
            'title': '盲目涉水风险大，亲身示范高水位行车注意事项',
            'description': 'md5:8c82f46186299add4a1c455430740229',
            'tags': ['video_car'],
            'like_count': int,
            'dislike_count': int,
            'view_count': int,
            'uploader': '懂车帝原创',
            'uploader_id': '6480145787',
            'thumbnail': r're:^https?://.+\.(avif|webp)',
            'timestamp': 1629088414,
            'duration': 1030,
        }
    }]

    def _get_json_data(self, webpage, video_id):
        js_data = get_element_by_id('SSR_HYDRATED_DATA', webpage)
        if not js_data:
            if self._cookies_passed:
                raise ExtractorError('Failed to get SSR_HYDRATED_DATA')
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/fourzerostudio.py (Python)

Code before:
            'title': 'わたベーさんからイラスト差し入れいただきました。ありがとうございました！',
            'timestamp': 1652109105,
            'like_count': 1,
            'uploader': 'ソエジマケイタ',
            'uploader_id': 'soeji',
        }
    }]

    def _real_extract(self, url):
        video_id, uploader_id = self._match_valid_url(url).group('id', 'uploader_id')
        webpage = self._download_webpage(url, video_id)
        nuxt_data = self._search_nuxt_data(webpage, video_id, full_data=True)

        clip_info = traverse_obj(nuxt_data, ('ssrRefs', lambda _, v: v['__typename'] == 'PublicCreatorArchivedClip'), get_all=False)

        for m in self._parse_html5_media_entries(url, webpage, video_id):
            if 'mp4' in traverse_obj(m, ('formats', ..., 'ext')):
                info = m
                break
        else:
            self.report_warning('Failed to find a desired media element. Falling back to using NUXT data.')
            info = {
                'formats': [{
                    'ext': 'mp4',
                    'url': url,
                } for url in clip_info.get('mediaFiles') if url],
            }
        info.update({
            'id': video_id,
            'title': clip_info.get('clipComment'),
            'timestamp': unified_timestamp(clip_info.get('createdAt')),
            'like_count': clip_info.get('likeCount'),
            'uploader_id': uploader_id,
            **self._extract_uploader_info(nuxt_data),
        })
        return info


Review comment (suggestion):
```suggestion
                } for url in clip_info.get('mediaFiles') or [] if url],
```

Code after:
            'like_count': 1,
            'uploader': 'ソエジマケイタ',
            'uploader_id': 'soeji',
        }
    }]

    def _real_extract(self, url):
        video_id, uploader_id = self._match_valid_url(url).group('id', 'uploader_id')
        webpage = self._download_webpage(url, video_id)
        nuxt_data = self._search_nuxt_data(webpage, video_id, return_full_data=True)

        clip_info = traverse_obj(nuxt_data, ('ssrRefs', lambda _, v: v['__typename'] == 'PublicCreatorArchivedClip'), get_all=False)

        info = next((
            m for m in self._parse_html5_media_entries(url, webpage, video_id)
            if 'mp4' in traverse_obj(m, ('formats', ..., 'ext'))
        ), None)
        if not info:
            self.report_warning('Failed to find a desired media element. Falling back to using NUXT data.')
            info = {
                'formats': [{
                    'ext': 'mp4',
                    'url': url,
                } for url in clip_info.get('mediaFiles') or [] if url],
            }
        return {
            **info,
            'id': video_id,
            'title': clip_info.get('clipComment'),
            'timestamp': unified_timestamp(clip_info.get('createdAt')),
            'like_count': clip_info.get('likeCount'),
            'uploader_id': uploader_id,
            'uploader': traverse_obj(nuxt_data, (
                'ssrRefs', lambda _, v: v['__typename'] == 'PublicUser', 'username'), get_all=False),
        }