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

Code before:
    def _fetch_page(self, url, playlist_id, page):
        page += 1
        webpage = self._download_webpage(
            f'{url}/{page}', playlist_id, note=f'Downloading page: {page}', expected_status=404)

        # Note: episodes not available will default to the URL https://radiocomercial.pt/podcasts/<season>.
        episodies_html = ''.join(get_elements_html_by_class('position-relative', webpage) or '')
        episodes = traverse_obj(
            get_elements_html_by_class('tm-ouvir-podcast', episodies_html),
            (..., {extract_attributes}, 'href'))

        for entry in episodes:
            yield self.url_result(urljoin('https://radiocomercial.pt', entry), RadioComercialIE)

    def _real_extract(self, url):
        podcast, season = self._match_valid_url(url).group('id', 'season')
        playlist_id = join_nonempty(podcast, season, delim='_t')
        url = update_url(url, query=None, fragment=None)
        webpage = self._download_webpage(url, playlist_id)

        name = try_call(lambda: get_element_text_and_html_by_tag('h1', webpage)[0])
        title = name if name == season else join_nonempty(name, season, delim=' - Temporada ')

        return self.playlist_result(OnDemandPagedList(
            functools.partial(self._fetch_page, url, playlist_id), self._PAGE_SIZE),
            playlist_id, title)


Review comment (suggestion):
```suggestion
        return self.playlist_from_matches(
            self._entries(url, playlist_id), playlist_id, title, ie=RadioComercialIE)
```

Code after:
    def _entries(self, url, playlist_id):
        for page in itertools.count(1):
            try:
                webpage = self._download_webpage(
                    f'{url}/{page}', playlist_id, f'Downloading page {page}')
            except ExtractorError as e:
                if isinstance(e.cause, HTTPError) and e.cause.status == 404:
                    break
                raise

            episodes = get_elements_html_by_class('tm-ouvir-podcast', webpage)
            if not episodes:
                break
            for url_path in traverse_obj(episodes, (..., {extract_attributes}, 'href')):
                episode_url = urljoin(url, url_path)
                if RadioComercialIE.suitable(episode_url):
                    yield episode_url

    def _real_extract(self, url):
        podcast, season = self._match_valid_url(url).group('id', 'season')
        playlist_id = join_nonempty(podcast, season, delim='_t')
        url = update_url(url, query=None, fragment=None)
        webpage = self._download_webpage(url, playlist_id)

        name = try_call(lambda: get_element_text_and_html_by_tag('h1', webpage)[0])
        title = name if name == season else join_nonempty(name, season, delim=' - Temporada ')

        return self.playlist_from_matches(
            self._entries(url, playlist_id), playlist_id, title, ie=RadioComercialIE)
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/zenporn.py (Python)

Code before:
from .common import InfoExtractor
from ..utils import (
    ExtractorError,
    determine_ext,
    int_or_none,
    traverse_obj,
    unified_strdate
)


class ZenPornIE(InfoExtractor):
    IE_DESC = 'ZenPorn'
    _VALID_URL = r'https?://(?:www\.)?zenporn\.com/video/(?P<id>\d+)'
    _TESTS = [{
        'url': 'https://zenporn.com/video/15627016/desi-bhabi-ki-chudai',
        'md5': '07bd576b5920714d74975c054ca28dee',
        'info_dict': {
            'id': '15627016',
            'extr_id': '9563799',
            'ext': 'mp4',
            'title': 'md5:669eafd3bbc688aa29770553b738ada2',
            'description': '',
            'thumbnail': 'md5:2fc044a19bab450fef8f1931e7920a18',
            'post_date': '20230925',
            'uploader': 'md5:9fae59847f1f58d1da8f2772016c12f3',
            'age_limit': 18
        }
    }, {
        'url': 'https://zenporn.com/video/15570701',
        'md5': 'acba0d080d692664fcc8c4e5502b1a67',
        'info_dict': {
            'id': '15570701',

Review comment (suggestion):
```suggestion
    unified_strdate,
```
Try to always use a trailing comma in multiline cases, to ease the diff in case of changes

Code after:
import base64
import binascii

from .common import InfoExtractor
from ..utils import ExtractorError, determine_ext, unified_strdate, url_or_none
from ..utils.traversal import traverse_obj


class ZenPornIE(InfoExtractor):
    _VALID_URL = r'https?://(?:www\.)?zenporn\.com/video/(?P<id>\d+)'
    _TESTS = [{
        'url': 'https://zenporn.com/video/15627016/desi-bhabi-ki-chudai',
        'md5': '07bd576b5920714d74975c054ca28dee',
        'info_dict': {
            'id': '9563799',
            'display_id': '15627016',
            'ext': 'mp4',
            'title': 'md5:669eafd3bbc688aa29770553b738ada2',
            'description': '',
            'thumbnail': 'md5:2fc044a19bab450fef8f1931e7920a18',
            'upload_date': '20230925',
            'uploader': 'md5:9fae59847f1f58d1da8f2772016c12f3',
            'age_limit': 18,
        }
    }, {
        'url': 'https://zenporn.com/video/15570701',
        'md5': 'acba0d080d692664fcc8c4e5502b1a67',
        'info_dict': {
            'id': '2297875',
            'display_id': '15570701',
            'ext': 'mp4',
            'title': 'md5:47aebdf87644ec91e8b1a844bc832451',
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/zenporn.py (Python)

Code before:

        ext_domain, extr_id = self._search_regex(
            r'https://(?P<ext_domain>[\w.-]+\.\w{3})/embed/(?P<extr_id>\d+)/',
            webpage, 'embed info', group=('ext_domain', 'extr_id'), fatal=True)

        info_json = self._download_json(
            self._gen_info_url(ext_domain, extr_id), video_id,
            note='Downloading video info JSON', fatal=True)

        video_json = self._download_json(
            f'https://{ext_domain}/api/videofile.php', video_id, query={
                'video_id': extr_id,
                'lifetime': 8640000,
            }, note='Downloading video metadata JSON', fatal=True)

        encoded_url = video_json[0]['video_url']

        decoded_url = self._decode_video_url(encoded_url)
        if not decoded_url:
            raise ExtractorError('Unable to decode the video url')

        return {
            'id': video_id,
            'extr_id': extr_id,
            'ext': traverse_obj(
                video_json, (..., 'format', {determine_ext}), get_all=False),
            'url': f'https://{ext_domain}{decoded_url}',
            'age_limit': 18,
            **traverse_obj(info_json, ('video', {
                'title': ('title', {str}),
                'description': ('description', {str}),
                'thumbnail': ('thumb', {url_or_none}),
                'post_date': ('post_date', {unified_strdate}),
                'uploader': ('user', 'username', {str}),
            })),
        }


Review comment (suggestion):
if we're using index `0` for the download url we should probably use it here too, yeah?
```suggestion
            'ext': traverse_obj(video_json, (0, 'format', {determine_ext})),
```

Code after:
            self._gen_info_url(ext_domain, video_id), video_id, fatal=False)

        video_json = self._download_json(
            f'https://{ext_domain}/api/videofile.php', video_id, query={
                'video_id': video_id,
                'lifetime': 8640000,
            }, note='Downloading video file JSON', errnote='Failed to download video file JSON')

        decoded_url = self._decode_video_url(video_json[0]['video_url'])
        if not decoded_url:
            raise ExtractorError('Unable to decode the video url')

        return {
            'id': video_id,
            'display_id': display_id,
            'ext': traverse_obj(video_json, (0, 'format', {determine_ext})),
            'url': f'https://{ext_domain}{decoded_url}',
            'age_limit': 18,
            **traverse_obj(info_json, ('video', {
                'title': ('title', {str}),
                'description': ('description', {str}),
                'thumbnail': ('thumb', {url_or_none}),
                'upload_date': ('post_date', {unified_strdate}),
                'uploader': ('user', 'username', {str}),
            })),
        }
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/zenporn.py (Python)

Code before:
        video_id = self._match_id(url)
        webpage = self._download_webpage(url, video_id)

        ext_domain, extr_id = self._search_regex(
            r'https://(?P<ext_domain>[\w.-]+\.\w{3})/embed/(?P<extr_id>\d+)/',
            webpage, 'embed info', group=('ext_domain', 'extr_id'), fatal=True)

        info_json = self._download_json(
            self._gen_info_url(ext_domain, extr_id), video_id,
            note='Downloading video info JSON', fatal=True)

        video_json = self._download_json(
            f'https://{ext_domain}/api/videofile.php', video_id, query={
                'video_id': extr_id,
                'lifetime': 8640000,
            }, note='Downloading video metadata JSON', fatal=True)

        encoded_url = video_json[0]['video_url']

        decoded_url = self._decode_video_url(encoded_url)
        if not decoded_url:
            raise ExtractorError('Unable to decode the video url')

        return {
            'id': video_id,
            'extr_id': extr_id,
            'ext': traverse_obj(
                video_json, (..., 'format', {determine_ext}), get_all=False),
            'url': f'https://{ext_domain}{decoded_url}',
            'age_limit': 18,
            **traverse_obj(info_json, ('video', {
                'title': ('title', {str}),
                'description': ('description', {str}),
                'thumbnail': ('thumb', {url_or_none}),
                'post_date': ('post_date', {unified_strdate}),
                'uploader': ('user', 'username', {str}),
            })),
        }


Review comment (refactor):
if we want to extract this value, we need to use a common info_dict field like `display_id`:
```suggestion
            'display_id': extr_id,
```
although arguably this should be the `id` and `video_id` should actually be `display_id`.

whichever you decide, tests will need to be updated

Code after:

        info_json = self._download_json(
            self._gen_info_url(ext_domain, video_id), video_id, fatal=False)

        video_json = self._download_json(
            f'https://{ext_domain}/api/videofile.php', video_id, query={
                'video_id': video_id,
                'lifetime': 8640000,
            }, note='Downloading video file JSON', errnote='Failed to download video file JSON')

        decoded_url = self._decode_video_url(video_json[0]['video_url'])
        if not decoded_url:
            raise ExtractorError('Unable to decode the video url')

        return {
            'id': video_id,
            'display_id': display_id,
            'ext': traverse_obj(video_json, (0, 'format', {determine_ext})),
            'url': f'https://{ext_domain}{decoded_url}',
            'age_limit': 18,
            **traverse_obj(info_json, ('video', {
                'title': ('title', {str}),
                'description': ('description', {str}),
                'thumbnail': ('thumb', {url_or_none}),
                'upload_date': ('post_date', {unified_strdate}),
                'uploader': ('user', 'username', {str}),
            })),
        }
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/zenporn.py (Python)

Code before:
import base64
import binascii
from .common import InfoExtractor
from ..utils import (
    ExtractorError,
    determine_ext,
    traverse_obj,
    unified_strdate,
    url_or_none,
)


class ZenPornIE(InfoExtractor):
    IE_DESC = 'ZenPorn'
    _VALID_URL = r'https?://(?:www\.)?zenporn\.com/video/(?P<id>\d+)'
    _TESTS = [{
        'url': 'https://zenporn.com/video/15627016/desi-bhabi-ki-chudai',
        'md5': '07bd576b5920714d74975c054ca28dee',
        'info_dict': {
            'id': '9563799',
            'display_id': '15627016',
            'ext': 'mp4',
            'title': 'md5:669eafd3bbc688aa29770553b738ada2',
            'description': '',
            'thumbnail': 'md5:2fc044a19bab450fef8f1931e7920a18',
            'upload_date': '20230925',
            'uploader': 'md5:9fae59847f1f58d1da8f2772016c12f3',
            'age_limit': 18
        }
    }, {
        'url': 'https://zenporn.com/video/15570701',
        'md5': 'acba0d080d692664fcc8c4e5502b1a67',
        'info_dict': {
            'id': '2297875',
            'display_id': '15570701',

Review comment (refactor):
```suggestion
import base64
import binascii

from .common import InfoExtractor
from ..utils import ExtractorError, determine_ext, unified_strdate, url_or_none
from ..utils.traversal import traverse_obj
```

Code after:
import base64
import binascii

from .common import InfoExtractor
from ..utils import ExtractorError, determine_ext, unified_strdate, url_or_none
from ..utils.traversal import traverse_obj


class ZenPornIE(InfoExtractor):
    _VALID_URL = r'https?://(?:www\.)?zenporn\.com/video/(?P<id>\d+)'
    _TESTS = [{
        'url': 'https://zenporn.com/video/15627016/desi-bhabi-ki-chudai',
        'md5': '07bd576b5920714d74975c054ca28dee',
        'info_dict': {
            'id': '9563799',
            'display_id': '15627016',
            'ext': 'mp4',
            'title': 'md5:669eafd3bbc688aa29770553b738ada2',
            'description': '',
            'thumbnail': 'md5:2fc044a19bab450fef8f1931e7920a18',
            'upload_date': '20230925',
            'uploader': 'md5:9fae59847f1f58d1da8f2772016c12f3',
            'age_limit': 18,
        }
    }, {
        'url': 'https://zenporn.com/video/15570701',
        'md5': 'acba0d080d692664fcc8c4e5502b1a67',
        'info_dict': {
            'id': '2297875',
            'display_id': '15570701',
            'ext': 'mp4',
            'title': 'md5:47aebdf87644ec91e8b1a844bc832451',
            'description': '',
            'thumbnail': 'https://mstn.nv7s.com/contents/videos_screenshots/2297000/2297875/480x270/1.jpg',
            'upload_date': '20230921',
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/zenporn.py (Python)

Code before:

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

        ext_domain, extr_id = self._search_regex(
            r'https://(?P<ext_domain>[\w.-]+\.\w{3})/embed/(?P<extr_id>\d+)/',
            webpage, 'embed info', group=('ext_domain', 'extr_id'))

        info_json = self._download_json(
            self._gen_info_url(ext_domain, extr_id), video_id,
            note='Downloading video info JSON')

        video_json = self._download_json(
            f'https://{ext_domain}/api/videofile.php', video_id, query={
                'video_id': extr_id,
                'lifetime': 8640000,
            }, note='Downloading video metadata JSON')

        decoded_url = self._decode_video_url(video_json[0]['video_url'])
        if not decoded_url:
            raise ExtractorError('Unable to decode the video url')

        return {
            'id': extr_id,
            'display_id': video_id,
            'ext': traverse_obj(video_json, (0, 'format', {determine_ext})),
            'url': f'https://{ext_domain}{decoded_url}',
            'age_limit': 18,
            **traverse_obj(info_json, ('video', {
                'title': ('title', {str}),
                'description': ('description', {str}),
                'thumbnail': ('thumb', {url_or_none}),
                'upload_date': ('post_date', {unified_strdate}),
                'uploader': ('user', 'username', {str}),
            })),
        }


Review comment (suggestion):
```suggestion
            'id': video_id,
            'display_id': display_id,
```

Code after:
        ext_domain, video_id = self._search_regex(
            r'https://(?P<ext_domain>[\w.-]+\.\w{3})/embed/(?P<extr_id>\d+)/',
            webpage, 'embed info', group=('ext_domain', 'extr_id'))

        info_json = self._download_json(
            self._gen_info_url(ext_domain, video_id), video_id, fatal=False)

        video_json = self._download_json(
            f'https://{ext_domain}/api/videofile.php', video_id, query={
                'video_id': video_id,
                'lifetime': 8640000,
            }, note='Downloading video file JSON', errnote='Failed to download video file JSON')

        decoded_url = self._decode_video_url(video_json[0]['video_url'])
        if not decoded_url:
            raise ExtractorError('Unable to decode the video url')

        return {
            'id': video_id,
            'display_id': display_id,
            'ext': traverse_obj(video_json, (0, 'format', {determine_ext})),
            'url': f'https://{ext_domain}{decoded_url}',
            'age_limit': 18,
            **traverse_obj(info_json, ('video', {
                'title': ('title', {str}),
                'description': ('description', {str}),
                'thumbnail': ('thumb', {url_or_none}),
                'upload_date': ('post_date', {unified_strdate}),
                'uploader': ('user', 'username', {str}),
            })),
        }
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/theguardian.py (Python)

Code before:
            'id': 'the-audio-long-read',
            'title': 'The Audio Long Read | News | The Guardian',
            'description': 'md5:5462994a27527309562b25b6defc4ef3'
        },
        'playlist_mincount': 1008
    }]

    def _fetch_page(self, url, playlist_id, page):
        page += 1
        webpage = self._download_webpage(
            f'{url}?page={page}', playlist_id, note=f'Downloading page: {page}', expected_status=404)

        episodes = traverse_obj(
            get_elements_html_by_class('fc-item--type-media', webpage),
            (..., {extract_attributes}, 'data-id'))

        for entry in episodes:
            yield self.url_result(urljoin('https://www.theguardian.com', entry), TheGuardianPodcastIE)

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

        title = self._generic_title(url, webpage, default='')
        description = self._og_search_description(webpage) or get_element_by_class(
            'header__description', webpage)

        return self.playlist_result(OnDemandPagedList(
            functools.partial(self._fetch_page, url, podcast_id), self._PAGE_SIZE),
            podcast_id, title, description)


Review comment (refactor):
Might be nice to extract a title without the " | The Guardian" junk at the end. Also use `clean_html` just in case
```suggestion
        title = clean_html(get_element_by_class(
            'index-page-header__title', webpage)) or self._generic_title(url, webpage)
        description = self._og_search_description(webpage) or clean_html(get_element_by_class(
            'header__description', webpage))
```

Code after:
            'id': 'the-audio-long-read',
            'title': 'The Audio Long Read',
            'description': 'md5:5462994a27527309562b25b6defc4ef3'
        },
        'playlist_mincount': 996
    }]

    def _entries(self, url, playlist_id):
        for page in itertools.count(1):
            webpage, urlh = self._download_webpage_handle(
                url, playlist_id, f'Downloading page {page}', query={'page': page})
            if 'page' not in parse_qs(urlh.url):
                break

            episodes = get_elements_html_by_class('fc-item--type-media', webpage)
            for url_path in traverse_obj(episodes, (..., {extract_attributes}, 'data-id')):
                yield url_path

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

        webpage = self._download_webpage(url, podcast_id)

        title = clean_html(get_element_by_class(
            'index-page-header__title', webpage) or get_element_by_class('flagship-audio__title', webpage))
        description = self._og_search_description(webpage) or self._html_search_meta(
            'description', webpage)

        return self.playlist_from_matches(
            self._entries(url, podcast_id), podcast_id, title, description=description,
            ie=TheGuardianPodcastIE, getter=lambda x: urljoin('https://www.theguardian.com', x))
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/theguardian.py (Python)

Code before:
            'description': 'md5:5462994a27527309562b25b6defc4ef3'
        },
        'playlist_mincount': 996
    }]

    def _entries(self, url, playlist_id):
        for page in itertools.count(1):
            webpage, urlh = self._download_webpage_handle(
                url, playlist_id, f'Downloading page {page}', query={'page': page})
            if '?' not in urlh.url:
                break

            episodes = get_elements_html_by_class('fc-item--type-media', webpage)
            for url_path in traverse_obj(episodes, (..., {extract_attributes}, 'data-id')):
                episode_url = urljoin('https://www.theguardian.com', url_path)
                if episode_url:
                    yield episode_url

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

        webpage = self._download_webpage(url, podcast_id)

        title = clean_html(get_element_by_class(
            'index-page-header__title', webpage) or get_element_by_class(
                'flagship-audio__title', webpage))
        description = self._og_search_description(webpage) or self._html_search_meta(
            'description', webpage)

        return self.playlist_from_matches(
            self._entries(url, podcast_id), podcast_id, title, description=description,
            ie=TheGuardianPodcastIE)


Review comment (suggestion):
a line that's a little long looks less weird here imo
```suggestion
            'index-page-header__title', webpage) or get_element_by_class('flagship-audio__title', webpage))
```

Code after:
            'title': 'The Audio Long Read',
            'description': 'md5:5462994a27527309562b25b6defc4ef3'
        },
        'playlist_mincount': 996
    }]

    def _entries(self, url, playlist_id):
        for page in itertools.count(1):
            webpage, urlh = self._download_webpage_handle(
                url, playlist_id, f'Downloading page {page}', query={'page': page})
            if 'page' not in parse_qs(urlh.url):
                break

            episodes = get_elements_html_by_class('fc-item--type-media', webpage)
            for url_path in traverse_obj(episodes, (..., {extract_attributes}, 'data-id')):
                yield url_path

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

        webpage = self._download_webpage(url, podcast_id)

        title = clean_html(get_element_by_class(
            'index-page-header__title', webpage) or get_element_by_class('flagship-audio__title', webpage))
        description = self._og_search_description(webpage) or self._html_search_meta(
            'description', webpage)

        return self.playlist_from_matches(
            self._entries(url, podcast_id), podcast_id, title, description=description,
            ie=TheGuardianPodcastIE, getter=lambda x: urljoin('https://www.theguardian.com', x))