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

Code before:
            'live_status': 'is_live',
        },
    }, {
        'url': 'https://roya.tv/live-stream/10000',
        'only_matching': True,
    }]

    def _real_extract(self, url):
        media_id = self._match_id(url)
        stream_json = self._download_json(f'https://ticket.roya-tv.com/api/v5/fastchannel/{media_id}', media_id)

        secured_url = None
        if stream_json:
            secured_url = stream_json.get('data', {}).get('secured_url')

        if not secured_url:
            raise ExtractorError('Failed to extract stream')

        title = self.get_title(media_id)

        return {
            'id': media_id,
            'url': secured_url,
            'ext': 'mp4',
            'title': title,
            'is_live': 'live-stream' in url,
        }

    def get_title(self, media_id):
        schedule = self._download_json('https://backend.roya.tv/api/v01/channels/schedule-pagination', media_id)
        if schedule:
            schedule_data = schedule.get('data', {})
            if len(schedule_data) > 0:
                schedule_today = schedule_data[0]
                channel_schedules = schedule_today.get('channel', {})
                for channel_schedule in channel_schedules:
                    if str(channel_schedule.get('id')) == media_id:
                        return channel_schedule.get('title')
        return None


Review comment (suggestion):
The URL will always contain `live-stream`
```suggestion
            'is_live': True,
```

Code after:
from .common import InfoExtractor
from ..utils.traversal import traverse_obj


class RoyaLiveIE(InfoExtractor):
    _VALID_URL = r'https?://roya\.tv/live-stream/(?P<id>\d+)'
    _TESTS = [{
        'url': 'https://roya.tv/live-stream/1',
        'info_dict': {
            'id': '1',
            'title': r're:Roya TV \d{4}-\d{2}-\d{2} \d{2}:\d{2}',
            'ext': 'mp4',
            'live_status': 'is_live',
        },
    }, {
        'url': 'https://roya.tv/live-stream/21',
        'info_dict': {
            'id': '21',
            'title': r're:Roya News \d{4}-\d{2}-\d{2} \d{2}:\d{2}',
            'ext': 'mp4',
            'live_status': 'is_live',
        },
    }, {
        'url': 'https://roya.tv/live-stream/10000',
        'only_matching': True,
    }]

    def _real_extract(self, url):
        media_id = self._match_id(url)

        stream_url = self._download_json(
            f'https://ticket.roya-tv.com/api/v5/fastchannel/{media_id}', media_id)['data']['secured_url']

        title = traverse_obj(
            self._download_json('https://backend.roya.tv/api/v01/channels/schedule-pagination', media_id, fatal=False),
            ('data', 0, 'channel', lambda _, v: str(v['id']) == media_id, 'title', {str}, any))

        return {
            'id': media_id,
            'formats': self._extract_m3u8_formats(stream_url, media_id, 'mp4', m3u8_id='hls', live=True),
            'title': title,
            'is_live': True,
        }
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/roya.py (Python)

Code before:
            'ext': 'mp4',
            'is_live': True,
            'live_status': 'is_live',
        },
    }, {
        'url': 'https://roya.tv/live-stream/10000',
        'only_matching': True,
    }]

    def _real_extract(self, url):
        media_id = self._match_id(url)
        stream_json = self._download_json(f'https://ticket.roya-tv.com/api/v5/fastchannel/{media_id}', media_id)

        secured_url = None
        if stream_json:
            secured_url = stream_json.get('data', {}).get('secured_url')

        if not secured_url:
            raise ExtractorError('Failed to extract stream')

        title = self.get_title(media_id)

        return {
            'id': media_id,
            'url': secured_url,
            'ext': 'mp4',
            'title': title,
            'is_live': 'live-stream' in url,
        }

    def get_title(self, media_id):
        schedule = self._download_json('https://backend.roya.tv/api/v01/channels/schedule-pagination', media_id)
        if schedule:
            schedule_data = schedule.get('data', {})
            if len(schedule_data) > 0:
                schedule_today = schedule_data[0]
                channel_schedules = schedule_today.get('channel', {})
                for channel_schedule in channel_schedules:
                    if str(channel_schedule.get('id')) == media_id:
                        return channel_schedule.get('title')
        return None


Review comment (refactor):
m3u8 playlists need to be extracted
```suggestion
            'formats': self._extract_m3u8_formats(stream_url, media_id, 'mp4', m3u8_id='hls', live=True),
```

Code after:
from .common import InfoExtractor
from ..utils.traversal import traverse_obj


class RoyaLiveIE(InfoExtractor):
    _VALID_URL = r'https?://roya\.tv/live-stream/(?P<id>\d+)'
    _TESTS = [{
        'url': 'https://roya.tv/live-stream/1',
        'info_dict': {
            'id': '1',
            'title': r're:Roya TV \d{4}-\d{2}-\d{2} \d{2}:\d{2}',
            'ext': 'mp4',
            'live_status': 'is_live',
        },
    }, {
        'url': 'https://roya.tv/live-stream/21',
        'info_dict': {
            'id': '21',
            'title': r're:Roya News \d{4}-\d{2}-\d{2} \d{2}:\d{2}',
            'ext': 'mp4',
            'live_status': 'is_live',
        },
    }, {
        'url': 'https://roya.tv/live-stream/10000',
        'only_matching': True,
    }]

    def _real_extract(self, url):
        media_id = self._match_id(url)

        stream_url = self._download_json(
            f'https://ticket.roya-tv.com/api/v5/fastchannel/{media_id}', media_id)['data']['secured_url']

        title = traverse_obj(
            self._download_json('https://backend.roya.tv/api/v01/channels/schedule-pagination', media_id, fatal=False),
            ('data', 0, 'channel', lambda _, v: str(v['id']) == media_id, 'title', {str}, any))

        return {
            'id': media_id,
            'formats': self._extract_m3u8_formats(stream_url, media_id, 'mp4', m3u8_id='hls', live=True),
            'title': title,
            'is_live': True,
        }
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/roya.py (Python)

Code before:
from .common import InfoExtractor
from ..utils import ExtractorError


class RoyaIE(InfoExtractor):
    _VALID_URL = r'https?://roya\.tv/live-stream/(?P<id>\d+)'
    _TESTS = [{
        'url': 'https://roya.tv/live-stream/1',
        'info_dict': {
            'id': '1',
            'title': r're:Roya TV \d{4}-\d{2}-\d{2} \d{2}:\d{2}',
            'ext': 'mp4',
            'is_live': True,
            'live_status': 'is_live',
        },
    }, {
        'url': 'https://roya.tv/live-stream/21',
        'info_dict': {
            'id': '21',
            'title': r're:Roya News \d{4}-\d{2}-\d{2} \d{2}:\d{2}',
            'ext': 'mp4',
            'is_live': True,
            'live_status': 'is_live',
        },
    }, {
        'url': 'https://roya.tv/live-stream/10000',
        'only_matching': True,

Review comment (suggestion):
```suggestion
from ..utils.traversal import traverse_obj
```

Code after:
from .common import InfoExtractor
from ..utils.traversal import traverse_obj


class RoyaLiveIE(InfoExtractor):
    _VALID_URL = r'https?://roya\.tv/live-stream/(?P<id>\d+)'
    _TESTS = [{
        'url': 'https://roya.tv/live-stream/1',
        'info_dict': {
            'id': '1',
            'title': r're:Roya TV \d{4}-\d{2}-\d{2} \d{2}:\d{2}',
            'ext': 'mp4',
            'live_status': 'is_live',
        },
    }, {
        'url': 'https://roya.tv/live-stream/21',
        'info_dict': {
            'id': '21',
            'title': r're:Roya News \d{4}-\d{2}-\d{2} \d{2}:\d{2}',
            'ext': 'mp4',
            'live_status': 'is_live',
        },
    }, {
        'url': 'https://roya.tv/live-stream/10000',
        'only_matching': True,
    }]
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/roya.py (Python)

Code before:
            'ext': 'mp4',
            'is_live': True,
            'live_status': 'is_live',
        },
    }, {
        'url': 'https://roya.tv/live-stream/21',
        'info_dict': {
            'id': '21',
            'title': r're:Roya News \d{4}-\d{2}-\d{2} \d{2}:\d{2}',
            'ext': 'mp4',
            'is_live': True,
            'live_status': 'is_live',
        },
    }, {
        'url': 'https://roya.tv/live-stream/10000',
        'only_matching': True,
    }]

    def _real_extract(self, url):
        media_id = self._match_id(url)

        stream_url = self._download_json(
            f'https://ticket.roya-tv.com/api/v5/fastchannel/{media_id}', media_id)['data']['secured_url']

        title = traverse_obj(
            self._download_json('https://backend.roya.tv/api/v01/channels/schedule-pagination', media_id),
            ('data', 0, 'channel', lambda _, v: str(v['id']) == media_id, 'title', {str}, any))

        return {
            'id': media_id,
            'formats': self._extract_m3u8_formats(stream_url, media_id, 'mp4', m3u8_id='hls', live=True),
            'title': title,
            'is_live': True,
        }


Review comment (suggestion):
```suggestion
            self._download_json('https://backend.roya.tv/api/v01/channels/schedule-pagination', media_id, fatal=False),
```

Code after:
            'ext': 'mp4',
            'live_status': 'is_live',
        },
    }, {
        'url': 'https://roya.tv/live-stream/21',
        'info_dict': {
            'id': '21',
            'title': r're:Roya News \d{4}-\d{2}-\d{2} \d{2}:\d{2}',
            'ext': 'mp4',
            'live_status': 'is_live',
        },
    }, {
        'url': 'https://roya.tv/live-stream/10000',
        'only_matching': True,
    }]

    def _real_extract(self, url):
        media_id = self._match_id(url)

        stream_url = self._download_json(
            f'https://ticket.roya-tv.com/api/v5/fastchannel/{media_id}', media_id)['data']['secured_url']

        title = traverse_obj(
            self._download_json('https://backend.roya.tv/api/v01/channels/schedule-pagination', media_id, fatal=False),
            ('data', 0, 'channel', lambda _, v: str(v['id']) == media_id, 'title', {str}, any))

        return {
            'id': media_id,
            'formats': self._extract_m3u8_formats(stream_url, media_id, 'mp4', m3u8_id='hls', live=True),
            'title': title,
            'is_live': True,
        }
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/_extractors.py (Python)

Code before:
from .jtbc import (
    JTBCIE,
    JTBCProgramIE,
)
from .jwplatform import JWPlatformIE
from .kakao import KakaoIE
from .kaltura import KalturaIE
from .kankanews import KankaNewsIE
from .karaoketv import KaraoketvIE
from .kelbyone import KelbyOneIE
from .kenh14 import (
    Kenh14PlaylistIE,
    Kenh14VideoIE,
)
from .khanacademy import (
    KhanAcademyIE,
    KhanAcademyUnitIE,
)
from .kick import (
    KickClipIE,
    KickIE,
    KickVODIE,
)
from .kicker import KickerIE
from .kickstarter import KickStarterIE
from .kika import KikaIE, KikaPlaylistIE
from .kinja import KinjaEmbedIE
from .kinopoisk import KinoPoiskIE
from .kommunetv import KommunetvIE
from .kompas import KompasVideoIE
from .koo import KooIE
from .krasview import KrasViewIE
from .kth import KTHIE
from .ku6 import Ku6IE
from .kukululive import KukuluLiveIE
from .kuwo import (
    KuwoAlbumIE,
    KuwoCategoryIE,
    KuwoChartIE,
    KuwoIE,
    KuwoMvIE,
    KuwoSingerIE,
)
from .la7 import (
    LA7IE,
    LA7PodcastEpisodeIE,
    LA7PodcastIE,
)
from .laracasts import (
    LaracastsIE,
    LaracastsPlaylistIE,

Review comment (suggestion):
```suggestion
from .kika import (
    KikaIE,
    KikaPlaylistIE,
)
```

Code after:
from .jtbc import (
    JTBCIE,
    JTBCProgramIE,
)
from .jwplatform import JWPlatformIE
from .kakao import KakaoIE
from .kaltura import KalturaIE
from .kankanews import KankaNewsIE
from .karaoketv import KaraoketvIE
from .kelbyone import KelbyOneIE
from .kenh14 import (
    Kenh14PlaylistIE,
    Kenh14VideoIE,
)
from .khanacademy import (
    KhanAcademyIE,
    KhanAcademyUnitIE,
)
from .kick import (
    KickClipIE,
    KickIE,
    KickVODIE,
)
from .kicker import KickerIE
from .kickstarter import KickStarterIE
from .kika import (
    KikaIE,
    KikaPlaylistIE,
)
from .kinja import KinjaEmbedIE
from .kinopoisk import KinoPoiskIE
from .kommunetv import KommunetvIE
from .kompas import KompasVideoIE
from .koo import KooIE
from .krasview import KrasViewIE
from .kth import KTHIE
from .ku6 import Ku6IE
from .kukululive import KukuluLiveIE
from .kuwo import (
    KuwoAlbumIE,
    KuwoCategoryIE,
    KuwoChartIE,
    KuwoIE,
    KuwoMvIE,
    KuwoSingerIE,
)
from .la7 import (
    LA7IE,
    LA7PodcastEpisodeIE,
    LA7PodcastIE,
)
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/kika.py (Python)

Code before:
            'schießt ein greller, weißer Lichtstrahl aus dem Bildschirm. Marcus befindet sich plötzlich '
            'im Videospiel in der Rolle seines Lieblingshelden "Gorbar the Magnificent". Sowohl Marcus, '
            'als auch Gorbar, der sich nun in Marcus\' Zuhause befindet, stehen beide vor großen Herausforderungen.',
        },
        'playlist_count': 35,
    }]

    def _real_extract(self, url):
        def fetch_page(playlist_url):
            while playlist_url:
                data = self._download_json(playlist_url, playlist_id)
                for item in traverse_obj(data, ('content', ..., {dict})):
                    yield self.url_result(
                        item['api']['url'],
                        ie=KikaIE,
                        **traverse_obj(item, {
                            'id': ('id', {str}),
                            'title': ('title', {str}),
                            'duration': ('duration', {int_or_none}),
                            'timestamp': ('date', {parse_iso8601}),
                        }))
                # This becomes 'None' when reaching the last page
                playlist_url = data['links']['next']

        playlist_id = self._match_valid_url(url).group('id')
        brand_data = self._download_json(f'https://www.kika.de/_next-api/proxy/v1/brands/{playlist_id}', playlist_id)

        return self.playlist_result(fetch_page(brand_data['videoSubchannel']['videosPageUrl']),
                                    playlist_id, title=brand_data.get('title'), description=brand_data.get('description'))


Review comment (suggestion):
```suggestion
        brand_data = self._download_json(
            f'https://www.kika.de/_next-api/proxy/v1/brands/{playlist_id}', playlist_id)
```

Code after:
        },
        'playlist_count': 100,
    }]

    def _entries(self, playlist_url, playlist_id):
        for page in itertools.count(1):
            data = self._download_json(playlist_url, playlist_id, note=f'Downloading page {page}')
            for item in traverse_obj(data, ('content', lambda _, v: url_or_none(v['api']['url']))):
                yield self.url_result(
                    item['api']['url'], ie=KikaIE,
                    **traverse_obj(item, {
                        'id': ('id', {str}),
                        'title': ('title', {str}),
                        'duration': ('duration', {int_or_none}),
                        'timestamp': ('date', {parse_iso8601}),
                    }))

            playlist_url = traverse_obj(data, ('links', 'next', {url_or_none}))
            if not playlist_url:
                break

    def _real_extract(self, url):
        playlist_id = self._match_id(url)
        brand_data = self._download_json(
            f'https://www.kika.de/_next-api/proxy/v1/brands/{playlist_id}', playlist_id)

        return self.playlist_result(
            self._entries(brand_data['videoSubchannel']['videosPageUrl'], playlist_id),
            playlist_id, title=brand_data.get('title'), description=brand_data.get('description'))
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/kika.py (Python)

Code before:
        },
        'playlist_count': 100,
    }]

    def _entries(self, playlist_url, playlist_id):
        while playlist_url:
            data = self._download_json(playlist_url, playlist_id)
            for item in traverse_obj(data, ('content', lambda _, v: url_or_none(v['api']['url']))):
                yield self.url_result(
                    item['api']['url'], ie=KikaIE,
                    **traverse_obj(item, {
                        'id': ('id', {str}),
                        'title': ('title', {str}),
                        'duration': ('duration', {int_or_none}),
                        'timestamp': ('date', {parse_iso8601}),
                    }))
            # This becomes 'None' when reaching the last page
            playlist_url = traverse_obj(data, ('links', 'next', {url_or_none}))

    def _real_extract(self, url):
        playlist_id = self._match_id(url)
        brand_data = self._download_json(
            f'https://www.kika.de/_next-api/proxy/v1/brands/{playlist_id}', playlist_id)

        return self.playlist_result(self._entries(brand_data['videoSubchannel']['videosPageUrl'], playlist_id),
                                    playlist_id, title=brand_data.get('title'), description=brand_data.get('description'))


Review comment (suggestion):
```suggestion
        return self.playlist_result(
            self._entries(brand_data['videoSubchannel']['videosPageUrl'], playlist_id),
            playlist_id, title=brand_data.get('title'), description=brand_data.get('description'))
```

Code after:
            'description': 'md5:7b9d7f65561b82fa512f2cfb553c397d',
        },
        'playlist_count': 100,
    }]

    def _entries(self, playlist_url, playlist_id):
        for page in itertools.count(1):
            data = self._download_json(playlist_url, playlist_id, note=f'Downloading page {page}')
            for item in traverse_obj(data, ('content', lambda _, v: url_or_none(v['api']['url']))):
                yield self.url_result(
                    item['api']['url'], ie=KikaIE,
                    **traverse_obj(item, {
                        'id': ('id', {str}),
                        'title': ('title', {str}),
                        'duration': ('duration', {int_or_none}),
                        'timestamp': ('date', {parse_iso8601}),
                    }))

            playlist_url = traverse_obj(data, ('links', 'next', {url_or_none}))
            if not playlist_url:
                break

    def _real_extract(self, url):
        playlist_id = self._match_id(url)
        brand_data = self._download_json(
            f'https://www.kika.de/_next-api/proxy/v1/brands/{playlist_id}', playlist_id)

        return self.playlist_result(
            self._entries(brand_data['videoSubchannel']['videosPageUrl'], playlist_id),
            playlist_id, title=brand_data.get('title'), description=brand_data.get('description'))
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/iprima.py (Python)

Code before:
import json
import re
import time

from .common import InfoExtractor
from ..utils import (
    ExtractorError,
    determine_ext,
    js_to_json,
    traverse_obj,
)


class IPrimaIE(InfoExtractor):
    _VALID_URL = r'https?://(?!cnn)(?:[^/]+)\.iprima\.cz/(?:[^/]+/)*(?P<id>[^/?#&]+)'
    _GEO_BYPASS = False
    _NETRC_MACHINE = 'iprima'
    _AUTH_ROOT = 'https://ucet.iprima.cz'
    _DEVICE_ID = 'Windows Chrome'
    access_token = None

    _TESTS = [{
        'url': 'https://prima.iprima.cz/particka/92-epizoda',
        'info_dict': {
            'id': 'p51388',
            'ext': 'mp4',
            'title': 'Partička (92)',
            'description': 'md5:57943f6a50d6188288c3a579d2fd5f01',
            'episode': 'Partička (92)',
            'season': 'Partička',
            'series': 'Prima Partička',
            'episode_number': 92,
            'thumbnail': 'https://d31b9s05ygj54s.cloudfront.net/prima-plus/image/video-ef6cf9de-c980-4443-92e4-17fe8bccd45c-16x9.jpeg',
        },
        'params': {
            'skip_download': True,  # m3u8 download
        },
    }, {
        'url': 'https://zoom.iprima.cz/porady/krasy-kanarskych-ostrovu/tenerife-v-risi-ohne',
        'info_dict': {
            'id': 'p1412199',
            'ext': 'mp4',
            'episode_number': 3,
            'episode': 'Tenerife: V říši ohně',

Review comment (suggestion):
let's just inline these since they're only used once now
```suggestion
```

Code after:
import json
import re
import time

from .common import InfoExtractor
from ..utils import (
    ExtractorError,
    determine_ext,
    js_to_json,
    traverse_obj,
)


class IPrimaIE(InfoExtractor):
    _VALID_URL = r'https?://(?!cnn)(?:[^/]+)\.iprima\.cz/(?:[^/]+/)*(?P<id>[^/?#&]+)'
    _GEO_BYPASS = False
    _NETRC_MACHINE = 'iprima'
    access_token = None

    _TESTS = [{
        'url': 'https://prima.iprima.cz/particka/92-epizoda',
        'info_dict': {
            'id': 'p51388',
            'ext': 'mp4',
            'title': 'Partička (92)',
            'description': 'md5:57943f6a50d6188288c3a579d2fd5f01',
            'episode': 'Partička (92)',
            'season': 'Partička',
            'series': 'Prima Partička',
            'episode_number': 92,
            'thumbnail': 'https://d31b9s05ygj54s.cloudfront.net/prima-plus/image/video-ef6cf9de-c980-4443-92e4-17fe8bccd45c-16x9.jpeg',
        },
        'params': {
            'skip_download': True,  # m3u8 download
        },
    }, {
        'url': 'https://zoom.iprima.cz/porady/krasy-kanarskych-ostrovu/tenerife-v-risi-ohne',
        'info_dict': {
            'id': 'p1412199',
            'ext': 'mp4',
            'episode_number': 3,
            'episode': 'Tenerife: V říši ohně',
            'description': 'md5:4b4a05c574b5eaef130e68d4811c3f2c',
            'duration': 3111.0,