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

Code before:
from .common import InfoExtractor
from ..utils import (
    extract_attributes,
    int_or_none,
    str_or_none,
    traverse_obj,
    unescapeHTML,
    url_or_none,
)


class ZaikoIE(InfoExtractor):
    _VALID_URL = r'https?://(?:www\.)?zaiko\.io/event/(?P<id>\d+)/stream(?:/\d+)+'
    _TESTS = [{
        'url': 'https://zaiko.io/event/324868/stream/20571/20571',
        'info_dict': {
            'id': '324868',
            'ext': 'mp4',
            'title': 'ZAIKO STREAMING TEST',
            'alt_title': '[VOD] ZAIKO STREAMING TEST_20210603(Do Not Delete)',
            'uploader_id': '454',
            'uploader': 'ZAIKO ZERO',
            'timestamp': 1583809200,
            'thumbnail': r're:https://[a-z0-9]+.cloudfront.net/[a-z0-9_]+/[a-z0-9_]+',
            'upload_date': '20200310',
            'categories': ['Tech House'],
        }
    }]

    def _parse_vue_element_attr(self, name, string, video_id):
        page_elem = self._search_regex(rf'(<{name}[^>]+>)', string, name)
        attrs = {}
        for key, value in extract_attributes(page_elem).items():
            if key.startswith(':'):
                attrs[key[1:]] = self._parse_json(
                    value, video_id, transform_source=unescapeHTML, fatal=False)
        return attrs


Review comment (suggestion):
apparently there are artist subdomains too, e.g. https://vark-live.zaiko.io/
```suggestion
    _VALID_URL = r'https?://(?:[\w-]+\.)?zaiko\.io/event/(?P<id>\d+)/stream(?:/\d+)+'
```

Code after:
from .common import InfoExtractor
from ..utils import (
    ExtractorError,
    extract_attributes,
    int_or_none,
    str_or_none,
    traverse_obj,
    unescapeHTML,
    url_or_none,
)


class ZaikoIE(InfoExtractor):
    _VALID_URL = r'https?://(?:[\w-]+\.)?zaiko\.io/event/(?P<id>\d+)/stream(?:/\d+)+'
    _TESTS = [{
        'url': 'https://zaiko.io/event/324868/stream/20571/20571',
        'info_dict': {
            'id': '324868',
            'ext': 'mp4',
            'title': 'ZAIKO STREAMING TEST',
            'alt_title': '[VOD] ZAIKO STREAMING TEST_20210603(Do Not Delete)',
            'uploader_id': '454',
            'uploader': 'ZAIKO ZERO',
            'release_timestamp': 1583809200,
            'thumbnail': r're:https://[a-z0-9]+.cloudfront.net/[a-z0-9_]+/[a-z0-9_]+',
            'release_date': '20200310',
            'categories': ['Tech House'],
            'live_status': 'was_live',
        },
        'params': {'skip_download': 'm3u8'},
    }]

    def _parse_vue_element_attr(self, name, string, video_id):
        page_elem = self._search_regex(rf'(<{name}[^>]+>)', string, name)
        attrs = {}
        for key, value in extract_attributes(page_elem).items():
            if key.startswith(':'):
                attrs[key[1:]] = self._parse_json(
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/funker530.py (Python)

Code before:
# coding: utf-8
from __future__ import unicode_literals

import re

from .common import InfoExtractor
from .rumble import RumbleEmbedIE
from .youtube import YoutubeIE
from ..utils import clean_html


class Funker530IE(InfoExtractor):
    _VALID_URL = r'https?:\/\/(?:www\.)?funker530\.com\/video\/(?P<id>[^\/]+)\/?'
    # TODO: `python test/test_download.py TestDownload.test_Funker530` only runs the first test?
    _TESTS = [{
        'url': 'https://funker530.com/video/azov-patrol-caught-in-open-under-automatic-grenade-launcher-fire/',
        'md5': '085f50fea27523a388bbc22e123e09c8',
        'info_dict': {
            'id': 'v2qbmu4',
            'ext': 'mp4',
            'title': 'Azov Patrol Caught In Open Under Automatic Grenade Launcher Fire',
            'thumbnail': r're:^https?://.*\.jpg$',
            'uploader': 'Funker530',
            'channel': 'Funker530',
            'channel_url': 'https://rumble.com/c/c-1199543',
            'width': 1280,
            'height': 720,
            'fps': 25,
            'duration': 27,
            'upload_date': '20230608',

Review comment (suggestion):
`unicode_literals` isn't necessary

and IMO we should use the (non-fatal) `_search_regex` method instead of importing `re`

Code after:
from .common import InfoExtractor
from .rumble import RumbleEmbedIE
from .youtube import YoutubeIE
from ..utils import ExtractorError, clean_html, get_element_by_class, strip_or_none


class Funker530IE(InfoExtractor):
    _VALID_URL = r'https?://(?:www\.)?funker530\.com/video/(?P<id>[^/?#]+)'
    _TESTS = [{
        'url': 'https://funker530.com/video/azov-patrol-caught-in-open-under-automatic-grenade-launcher-fire/',
        'md5': '085f50fea27523a388bbc22e123e09c8',
        'info_dict': {
            'id': 'v2qbmu4',
            'ext': 'mp4',
            'title': 'Azov Patrol Caught In Open Under Automatic Grenade Launcher Fire',
            'thumbnail': r're:^https?://.*\.jpg$',
            'uploader': 'Funker530',
            'channel': 'Funker530',
            'channel_url': 'https://rumble.com/c/c-1199543',
            'width': 1280,
            'height': 720,
            'fps': 25,
            'duration': 27,
            'upload_date': '20230608',
            'timestamp': 1686241321,
            'live_status': 'not_live',
            'description': 'md5:bea2e1f458095414e04b5ac189c2f980',
        }
    }, {
        'url': 'https://funker530.com/video/my-friends-joined-the-russians-civdiv/',
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/funker530.py (Python)

Code before:
# coding: utf-8
from __future__ import unicode_literals

import re

from .common import InfoExtractor
from .rumble import RumbleEmbedIE
from .youtube import YoutubeIE
from ..utils import clean_html


class Funker530IE(InfoExtractor):
    _VALID_URL = r'https?:\/\/(?:www\.)?funker530\.com\/video\/(?P<id>[^\/]+)\/?'
    # TODO: `python test/test_download.py TestDownload.test_Funker530` only runs the first test?
    _TESTS = [{
        'url': 'https://funker530.com/video/azov-patrol-caught-in-open-under-automatic-grenade-launcher-fire/',
        'md5': '085f50fea27523a388bbc22e123e09c8',
        'info_dict': {
            'id': 'v2qbmu4',
            'ext': 'mp4',
            'title': 'Azov Patrol Caught In Open Under Automatic Grenade Launcher Fire',
            'thumbnail': r're:^https?://.*\.jpg$',
            'uploader': 'Funker530',
            'channel': 'Funker530',
            'channel_url': 'https://rumble.com/c/c-1199543',
            'width': 1280,
            'height': 720,
            'fps': 25,
            'duration': 27,
            'upload_date': '20230608',
            'timestamp': 1686241321,
            'live_status': 'not_live',
            'description': 'md5:bea2e1f458095414e04b5ac189c2f980',
        }
    }, {
        'url': 'https://funker530.com/video/my-friends-joined-the-russians-civdiv/',
        'md5': '',
        'info_dict': {

Review comment (security):
don't need to escape forward slashes, and also watch out for queries and fragments at the end of the `id`
```suggestion
    _VALID_URL = r'https?://(?:www\.)?funker530\.com/video/(?P<id>[^/?#]+)'
```

Code after:
from .common import InfoExtractor
from .rumble import RumbleEmbedIE
from .youtube import YoutubeIE
from ..utils import ExtractorError, clean_html, get_element_by_class, strip_or_none


class Funker530IE(InfoExtractor):
    _VALID_URL = r'https?://(?:www\.)?funker530\.com/video/(?P<id>[^/?#]+)'
    _TESTS = [{
        'url': 'https://funker530.com/video/azov-patrol-caught-in-open-under-automatic-grenade-launcher-fire/',
        'md5': '085f50fea27523a388bbc22e123e09c8',
        'info_dict': {
            'id': 'v2qbmu4',
            'ext': 'mp4',
            'title': 'Azov Patrol Caught In Open Under Automatic Grenade Launcher Fire',
            'thumbnail': r're:^https?://.*\.jpg$',
            'uploader': 'Funker530',
            'channel': 'Funker530',
            'channel_url': 'https://rumble.com/c/c-1199543',
            'width': 1280,
            'height': 720,
            'fps': 25,
            'duration': 27,
            'upload_date': '20230608',
            'timestamp': 1686241321,
            'live_status': 'not_live',
            'description': 'md5:bea2e1f458095414e04b5ac189c2f980',
        }
    }, {
        'url': 'https://funker530.com/video/my-friends-joined-the-russians-civdiv/',
        'md5': 'a42c2933391210662e93e867d7124b70',
        'info_dict': {
            'id': 'k-pk4bOvoac',
            'ext': 'mp4',
            'view_count': int,
            'channel': 'Civ Div',
            'comment_count': int,
            'channel_follower_count': int,
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/funker530.py (Python)

Code before:
# coding: utf-8

from .common import InfoExtractor
from .rumble import RumbleEmbedIE
from .youtube import YoutubeIE
from ..utils import clean_html, ExtractorError, strip_or_none, get_element_by_class


class Funker530IE(InfoExtractor):
    _VALID_URL = r'https?://(?:www\.)?funker530\.com/video/(?P<id>[^/?#]+)'
    _TESTS = [{
        'url': 'https://funker530.com/video/azov-patrol-caught-in-open-under-automatic-grenade-launcher-fire/',
        'md5': '085f50fea27523a388bbc22e123e09c8',
        'info_dict': {
            'id': 'v2qbmu4',
            'ext': 'mp4',
            'title': 'Azov Patrol Caught In Open Under Automatic Grenade Launcher Fire',
            'thumbnail': r're:^https?://.*\.jpg$',
            'uploader': 'Funker530',
            'channel': 'Funker530',
            'channel_url': 'https://rumble.com/c/c-1199543',
            'width': 1280,
            'height': 720,
            'fps': 25,
            'duration': 27,
            'upload_date': '20230608',
            'timestamp': 1686241321,
            'live_status': 'not_live',
            'description': 'md5:bea2e1f458095414e04b5ac189c2f980',
        }
    }, {

Review comment (refactor):
sort class before function, then alphabetically
or use isort
```suggestion
from ..utils import ExtractorError, clean_html, get_element_by_class, strip_or_none
```

Code after:
from .common import InfoExtractor
from .rumble import RumbleEmbedIE
from .youtube import YoutubeIE
from ..utils import ExtractorError, clean_html, get_element_by_class, strip_or_none


class Funker530IE(InfoExtractor):
    _VALID_URL = r'https?://(?:www\.)?funker530\.com/video/(?P<id>[^/?#]+)'
    _TESTS = [{
        'url': 'https://funker530.com/video/azov-patrol-caught-in-open-under-automatic-grenade-launcher-fire/',
        'md5': '085f50fea27523a388bbc22e123e09c8',
        'info_dict': {
            'id': 'v2qbmu4',
            'ext': 'mp4',
            'title': 'Azov Patrol Caught In Open Under Automatic Grenade Launcher Fire',
            'thumbnail': r're:^https?://.*\.jpg$',
            'uploader': 'Funker530',
            'channel': 'Funker530',
            'channel_url': 'https://rumble.com/c/c-1199543',
            'width': 1280,
            'height': 720,
            'fps': 25,
            'duration': 27,
            'upload_date': '20230608',
            'timestamp': 1686241321,
            'live_status': 'not_live',
            'description': 'md5:bea2e1f458095414e04b5ac189c2f980',
        }
    }, {
        'url': 'https://funker530.com/video/my-friends-joined-the-russians-civdiv/',
        'md5': 'a42c2933391210662e93e867d7124b70',
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/funker530.py (Python)

Code before:
            'like_count': int,
            'description': 'md5:aef75ec3f59c07a0e39400f609b24429',
            'live_status': 'not_live',
            'age_limit': 0,
            'uploader': 'Civ Div',
            'categories': ['People & Blogs'],
            'title': 'My “Friends” joined the Russians.',
            'availability': 'public',
            'upload_date': '20230608',
            'playable_in_embed': True,
        }
    }]

    def _real_extract(self, url):
        display_id = self._match_id(url)
        webpage = self._download_webpage(url, display_id)
        info = {}
        rumble_urls = RumbleEmbedIE._extract_embed_urls(url, webpage)
        if rumble_urls:
            info.update({'url': rumble_urls[0], 'ie_key': RumbleEmbedIE.ie_key()})
        else:
            youtube_url = next(YoutubeIE._extract_embed_urls(url, webpage), None)
            if youtube_url:
                info.update({'url': youtube_url, 'ie_key': YoutubeIE.ie_key()})
        if not info:
            raise ExtractorError('No videos found on webpage')

        return {
            **info,
            '_type': 'url_transparent',
            'description': strip_or_none(self._search_regex(
                r'(?s)(.+)About the Author', clean_html(get_element_by_class('video-desc-paragraph', webpage)),
                'description', default=None))
        }


Review comment (refactor):
```suggestion
            raise ExtractorError('No videos found on webpage', expected=True)
```

Code after:
            'live_status': 'not_live',
            'age_limit': 0,
            'uploader': 'Civ Div',
            'categories': ['People & Blogs'],
            'title': 'My “Friends” joined the Russians.',
            'availability': 'public',
            'upload_date': '20230608',
            'playable_in_embed': True,
            'heatmap': 'count:100',
        }
    }]

    def _real_extract(self, url):
        display_id = self._match_id(url)
        webpage = self._download_webpage(url, display_id)
        rumble_url = list(RumbleEmbedIE._extract_embed_urls(url, webpage))
        if rumble_url:
            info = {'url': rumble_url[0], 'ie_key': RumbleEmbedIE.ie_key()}
        else:
            youtube_url = list(YoutubeIE._extract_embed_urls(url, webpage))
            if youtube_url:
                info = {'url': youtube_url[0], 'ie_key': YoutubeIE.ie_key()}
        if not info:
            raise ExtractorError('No videos found on webpage', expected=True)

        return {
            **info,
            '_type': 'url_transparent',
            'description': strip_or_none(self._search_regex(
                r'(?s)(.+)About the Author', clean_html(get_element_by_class('video-desc-paragraph', webpage)),
                'description', default=None))
        }
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/_extractors.py (Python)

Code before:
from .yandexvideo import (
    YandexVideoIE,
    YandexVideoPreviewIE,
    ZenYandexIE,
    ZenYandexChannelIE,
)
from .yapfiles import YapFilesIE
from .yappy import YappyIE
from .yesjapan import YesJapanIE
from .yinyuetai import YinYueTaiIE
from .yle_areena import YleAreenaIE
from .ynet import YnetIE
from .youjizz import YouJizzIE
from .youku import (
    YoukuIE,
    YoukuShowIE,
)
from .younow import (
    YouNowLiveIE,
    YouNowChannelIE,
    YouNowMomentIE,
)
from .youporn import YouPornIE
from .yourporn import YourPornIE
from .yourupload import YourUploadIE
from .zaiko import ZaikoIE, ZaikoETicketIE
from .zapiks import ZapiksIE
from .zattoo import (
    BBVTVIE,
    BBVTVLiveIE,
    BBVTVRecordingsIE,
    EinsUndEinsTVIE,
    EinsUndEinsTVLiveIE,
    EinsUndEinsTVRecordingsIE,
    EWETVIE,
    EWETVLiveIE,
    EWETVRecordingsIE,
    GlattvisionTVIE,
    GlattvisionTVLiveIE,
    GlattvisionTVRecordingsIE,
    MNetTVIE,
    MNetTVLiveIE,
    MNetTVRecordingsIE,
    NetPlusTVIE,
    NetPlusTVLiveIE,
    NetPlusTVRecordingsIE,
    OsnatelTVIE,
    OsnatelTVLiveIE,
    OsnatelTVRecordingsIE,
    QuantumTVIE,
    QuantumTVLiveIE,

Review comment (suggestion):
```suggestion
from .zaiko import (
    ZaikoIE,
    ZaikoETicketIE,
)
```

Code after:
from .yandexvideo import (
    YandexVideoIE,
    YandexVideoPreviewIE,
    ZenYandexIE,
    ZenYandexChannelIE,
)
from .yapfiles import YapFilesIE
from .yappy import YappyIE
from .yesjapan import YesJapanIE
from .yinyuetai import YinYueTaiIE
from .yle_areena import YleAreenaIE
from .ynet import YnetIE
from .youjizz import YouJizzIE
from .youku import (
    YoukuIE,
    YoukuShowIE,
)
from .younow import (
    YouNowLiveIE,
    YouNowChannelIE,
    YouNowMomentIE,
)
from .youporn import YouPornIE
from .yourporn import YourPornIE
from .yourupload import YourUploadIE
from .zaiko import (
    ZaikoIE,
    ZaikoETicketIE,
)
from .zapiks import ZapiksIE
from .zattoo import (
    BBVTVIE,
    BBVTVLiveIE,
    BBVTVRecordingsIE,
    EinsUndEinsTVIE,
    EinsUndEinsTVLiveIE,
    EinsUndEinsTVRecordingsIE,
    EWETVIE,
    EWETVLiveIE,
    EWETVRecordingsIE,
    GlattvisionTVIE,
    GlattvisionTVLiveIE,
    GlattvisionTVRecordingsIE,
    MNetTVIE,
    MNetTVLiveIE,
    MNetTVRecordingsIE,
    NetPlusTVIE,
    NetPlusTVLiveIE,
    NetPlusTVRecordingsIE,
    OsnatelTVIE,
    OsnatelTVLiveIE,
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/vk.py (Python)

Code before:
            'live_status': 'is_live',
        },
        'skip': 'livestream',
        'params': {'skip_download': True},
    }]

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

        initial_state = self._extract_initial_state(url, username)
        stream_info = traverse_obj(initial_state, ('stream', 'stream', 'data', 'stream', {dict}))
        if not stream_info:
            stream_info = self._download_json(
                f'https://api.vkplay.live/v1/blog/{username}/public_video_stream', username)
        formats = self._extract_formats(stream_info, username)
        if not formats and not traverse_obj(stream_info, ('isOnline', {bool})):
            raise UserNotLive(video_id=username)

        return {
            'formats': formats,
            **self._extract_common_meta(stream_info),
            **traverse_obj(stream_info, {
                'id': ('id', {str}),
                'uploader': ('user', 'nick', {str_or_none}),
                'uploader_id': ('user', 'id', {int_or_none}),
                'concurrent_view_count': ('count', 'viewers', {int_or_none}),
                'is_live': ('isOnline', {bool}),
            })
        }


Review comment (refactor):
similar to the other return comment, I think these could all be moved into `_extract_common_meta`

it's fine to return a `None` value for `concurrent_view_count` in `VKPlayIE._real_extract`

Code after:
            'release_timestamp': 1687209962,
            'release_date': '20230619',
            'thumbnail': r're:https://images.vkplay.live/public_video_stream/12279401/preview\?change_time=\d+',
            'view_count': int,
            'concurrent_view_count': int,
            'like_count': int,
            'categories': ['EVE Online'],
            'live_status': 'is_live',
        },
        'skip': 'livestream',
        'params': {'skip_download': True},
    }]

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

        stream_info = self._download_json(
            f'https://api.vkplay.live/v1/blog/{username}/public_video_stream', username, fatal=False)
        if not stream_info:
            stream_info = self._extract_from_initial_state(url, username, ('stream', 'stream', 'data', 'stream'))

        formats = self._extract_formats(stream_info, username)
        if not formats and not traverse_obj(stream_info, ('isOnline', {bool})):
            raise UserNotLive(video_id=username)

        return {
            **self._extract_common_meta(stream_info),
            'formats': formats,
        }
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/vk.py (Python)

Code before:
            'title': r're:эскапизм крута .*',
            'uploader': 'Bayda',
            'uploader_id': 12279401,
            'release_timestamp': 1687209962,
            'release_date': '20230619',
            'thumbnail': r're:https://images.vkplay.live/public_video_stream/12279401/preview\?change_time=\d+',
            'view_count': int,
            'concurrent_view_count': int,
            'like_count': int,
            'categories': ['EVE Online'],
            'live_status': 'is_live',
        },
        'skip': 'livestream',
        'params': {'skip_download': True},
    }]

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

        stream_info = self._download_json(
            f'https://api.vkplay.live/v1/blog/{username}/public_video_stream', username, fatal=False)
        if not stream_info:
            initial_state = self._extract_initial_state(url, username)
            stream_info = traverse_obj(initial_state, ('stream', 'stream', 'data', 'stream', {dict}))
        if not stream_info:
            raise ExtractorError("Failed to extract live stream info")

        formats = self._extract_formats(stream_info, username)
        if not formats and not traverse_obj(stream_info, ('isOnline', {bool})):
            raise UserNotLive(video_id=username)

        return {
            'formats': formats,
            **self._extract_common_meta(stream_info),
            **traverse_obj(stream_info, {
                'is_live': ('isOnline', {bool}),
            })
        }


Review comment (refactor):
same here if we change `_extract_initial_state`
```suggestion
            initial_state = self._extract_initial_state(url, username, ('stream', 'stream', 'data', 'stream'))
```

Code after:
        'info_dict': {
            'id': 'f02c321e-427b-408d-b12f-ae34e53e0ea2',
            'ext': 'mp4',
            'title': r're:эскапизм крута .*',
            'uploader': 'Bayda',
            'uploader_id': 12279401,
            'release_timestamp': 1687209962,
            'release_date': '20230619',
            'thumbnail': r're:https://images.vkplay.live/public_video_stream/12279401/preview\?change_time=\d+',
            'view_count': int,
            'concurrent_view_count': int,
            'like_count': int,
            'categories': ['EVE Online'],
            'live_status': 'is_live',
        },
        'skip': 'livestream',
        'params': {'skip_download': True},
    }]

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

        stream_info = self._download_json(
            f'https://api.vkplay.live/v1/blog/{username}/public_video_stream', username, fatal=False)
        if not stream_info:
            stream_info = self._extract_from_initial_state(url, username, ('stream', 'stream', 'data', 'stream'))

        formats = self._extract_formats(stream_info, username)
        if not formats and not traverse_obj(stream_info, ('isOnline', {bool})):
            raise UserNotLive(video_id=username)

        return {
            **self._extract_common_meta(stream_info),
            'formats': formats,
        }