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

Code before:
import json

from .common import InfoExtractor
from ..utils import int_or_none, traverse_obj, urlencode_postdata, parse_qs, ExtractorError, update_url_query


class PlaySuisseIE(InfoExtractor):
    _NETRC_MACHINE = 'playsuisse'
    _VALID_URL = r'https?://(?:www\.)?playsuisse\.ch/(?:watch|detail)/(?:[^#]*[?&]episodeId=)?(?P<id>[0-9]+)'
    _TESTS = [
        {
            # Old URL
            'url': 'https://www.playsuisse.ch/watch/763211/0',
            'only_matching': True,
        },
        {
            # episode in a series
            'url': 'https://www.playsuisse.ch/watch/763182?episodeId=763211',
            'md5': '82df2a470b2dfa60c2d33772a8a60cf8',
            'info_dict': {
                'id': '763211',
                'ext': 'mp4',
                'title': 'Knochen',
                'description': 'md5:8ea7a8076ba000cd9e8bc132fd0afdd8',
                'duration': 3344,
                'series': 'Wilder',
                'season': 'Season 1',
                'season_number': 1,
                'episode': 'Knochen',

Review comment (refactor):
use `isort`
```suggestion
from ..utils import (
    ExtractorError,
    int_or_none,
    parse_qs,
    traverse_obj,
    update_url_query,
    urlencode_postdata,
)
```

Code after:
import json

from .common import InfoExtractor
from ..utils import (
    ExtractorError,
    int_or_none,
    parse_qs,
    traverse_obj,
    update_url_query,
    urlencode_postdata,
)


class PlaySuisseIE(InfoExtractor):
    _NETRC_MACHINE = 'playsuisse'
    _VALID_URL = r'https?://(?:www\.)?playsuisse\.ch/(?:watch|detail)/(?:[^#]*[?&]episodeId=)?(?P<id>[0-9]+)'
    _TESTS = [
        {
            # Old URL
            'url': 'https://www.playsuisse.ch/watch/763211/0',
            'only_matching': True,
        },
        {
            # episode in a series
            'url': 'https://www.playsuisse.ch/watch/763182?episodeId=763211',
            'md5': '82df2a470b2dfa60c2d33772a8a60cf8',
            'info_dict': {
                'id': '763211',
                'ext': 'mp4',
Repository: yt-dlp/yt-dlp
File: yt_dlp/cookies.py (Python)

Code before:
import base64
import collections
import contextlib
import http.cookiejar
import http.cookies
import io
import json
import os
import re
import shutil
import struct
import subprocess
import sys
import tempfile
import time
import urllib.request
from datetime import datetime, timedelta, timezone
from enum import Enum, auto
from hashlib import pbkdf2_hmac

from .aes import (
    aes_cbc_decrypt_bytes,
    aes_gcm_decrypt_and_verify_bytes,
    unpad_pkcs7,
)
from .compat import functools, compat_os_name
from .dependencies import (
    _SECRETSTORAGE_UNAVAILABLE_REASON,
    secretstorage,
    sqlite3,
)
from .minicurses import MultilinePrinter, QuietMultilinePrinter
from .utils import (
    DownloadError,
    Popen,
    error_to_str,
    expand_path,
    is_path_like,
    sanitize_url,
    str_or_none,
    try_call,
    write_string,
)
from .utils._utils import _YDLLogger
from .utils.networking import normalize_url

CHROMIUM_BASED_BROWSERS = {'brave', 'chrome', 'chromium', 'edge', 'opera', 'vivaldi'}
SUPPORTED_BROWSERS = CHROMIUM_BASED_BROWSERS | {'firefox', 'safari'}


class YDLLogger(_YDLLogger):

Review comment (suggestion):
```suggestion
from .compat import functools  # isort: split
from .compat import compat_os_name
```

Code after:
import base64
import collections
import contextlib
import http.cookiejar
import http.cookies
import io
import json
import os
import re
import shutil
import struct
import subprocess
import sys
import tempfile
import time
import urllib.request
from datetime import datetime, timedelta, timezone
from enum import Enum, auto
from hashlib import pbkdf2_hmac

from .aes import (
    aes_cbc_decrypt_bytes,
    aes_gcm_decrypt_and_verify_bytes,
    unpad_pkcs7,
)
from .compat import functools  # isort: split
from .compat import compat_os_name
from .dependencies import (
    _SECRETSTORAGE_UNAVAILABLE_REASON,
    secretstorage,
    sqlite3,
)
from .minicurses import MultilinePrinter, QuietMultilinePrinter
from .utils import (
    DownloadError,
    Popen,
    error_to_str,
    expand_path,
    is_path_like,
    sanitize_url,
    str_or_none,
    try_call,
    write_string,
)
from .utils._utils import _YDLLogger
from .utils.networking import normalize_url

CHROMIUM_BASED_BROWSERS = {'brave', 'chrome', 'chromium', 'edge', 'opera', 'vivaldi'}
SUPPORTED_BROWSERS = CHROMIUM_BASED_BROWSERS | {'firefox', 'safari'}
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/radiko.py (Python)

Code before:
    }]

    def _real_extract(self, url):
        station = self._match_id(url)
        self.report_warning('Downloader will not stop at the end of the program! Press Ctrl+C to stop')

        auth_token, area_id = self._auth_client()
        # get current time in JST (GMT+9:00 w/o DST)
        vid_now = time_seconds(hours=9)

        prog, station_program, ft, _, _ = self._find_program(station, station, vid_now)

        title = prog.find('title').text
        description = clean_html(prog.find('info').text)
        station_name = station_program.find('.//name').text
        performers = self._extract_performers(prog)

        formats = self._extract_formats(
            video_id=station, station=station, is_onair=True,
            ft=ft, cursor=vid_now, auth_token=auth_token, area_id=area_id,
            query={})

        return {
            'id': station,
            'title': title,
            'artists': performers,
            'description': description,
            'uploader': station_name,
            'uploader_id': station,
            'timestamp': ft,
            'formats': formats,
            'is_live': True,
        }


Review comment (refactor):
```suggestion
            'artist': self._extract_performers(prog),
```

Code after:
        'url': 'https://radiko.jp/#!/live/JOAK-FM',
        'only_matching': True,
    }]

    def _real_extract(self, url):
        station = self._match_id(url)
        self.report_warning('Downloader will not stop at the end of the program! Press Ctrl+C to stop')

        auth_token, area_id = self._auth_client()
        # get current time in JST (GMT+9:00 w/o DST)
        vid_now = time_seconds(hours=9)

        prog, station_program, ft, _, _ = self._find_program(station, station, vid_now)

        title = prog.find('title').text
        description = clean_html(prog.find('info').text)
        station_name = station_program.find('.//name').text

        formats = self._extract_formats(
            video_id=station, station=station, is_onair=True,
            ft=ft, cursor=vid_now, auth_token=auth_token, area_id=area_id,
            query={})

        return {
            'id': station,
            'title': title,
            'artist': self._extract_performers(prog),
            'description': description,
            'uploader': station_name,
            'uploader_id': station,
            'timestamp': ft,
            'formats': formats,
            'is_live': True,
        }
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/zetland.py (Python)

Code before:
from .common import InfoExtractor
from ..utils import merge_dicts, unified_timestamp, url_or_none
from ..utils.traversal import traverse_obj


class ZetlandDKArticleIE(InfoExtractor):
    _VALID_URL = r'https://www\.zetland\.dk/\w+/(?P<id>(?P<story_id>\w{8})-(?P<uploader_id>\w{8})-(?:\w{5}))'
    _TESTS = [{
        'url': 'https://www.zetland.dk/historie/sO9aq2MY-a81VP3BY-66e69?utm_source=instagram&utm_medium=linkibio&utm_campaign=artikel',
        'info_dict': {
            'id': 'sO9aq2MY-a81VP3BY-66e69',
            'ext': 'mp3',
            'modified_date': '20240118',
            'title': 'Afsnit 1: “Det føltes som en kidnapning.” ',
            'upload_date': '20240116',
            'uploader_id': 'a81VP3BY',
            'modified_timestamp': 1705568739,
            'release_timestamp': 1705377592,
            'uploader_url': 'https://www.zetland.dk/skribent/a81VP3BY',
            'uploader': 'Helle Fuusager',
            'release_date': '20240116',
            'thumbnail': r're:https://zetland\.imgix\.net/2aafe500-b14e-11ee-bf83-65d5e1283a57/Zetland_Image_1\.jpg',
            'description': 'md5:9619d426772c133f5abb26db27f26a01',
            'timestamp': 1705377592,
            'series_id': '62d54630-e87b-4ab1-a255-8de58dbe1b14',
        }

    }]

    def _real_extract(self, url):
        display_id, uploader_id = self._match_valid_url(url).group('id', 'uploader_id')
        webpage = self._download_webpage(url, display_id)

Review comment (suggestion):
```suggestion
    _VALID_URL = r'https?://www\.zetland\.dk/\w+/(?P<id>(?P<story_id>\w{8})-(?P<uploader_id>\w{8})-(?:\w{5}))'
```

Code after:
from .common import InfoExtractor
from ..utils import merge_dicts, unified_timestamp, url_or_none
from ..utils.traversal import traverse_obj


class ZetlandDKArticleIE(InfoExtractor):
    _VALID_URL = r'https?://www\.zetland\.dk/\w+/(?P<id>(?P<story_id>\w{8})-(?P<uploader_id>\w{8})-(?:\w{5}))'
    _TESTS = [{
        'url': 'https://www.zetland.dk/historie/sO9aq2MY-a81VP3BY-66e69?utm_source=instagram&utm_medium=linkibio&utm_campaign=artikel',
        'info_dict': {
            'id': 'sO9aq2MY-a81VP3BY-66e69',
            'ext': 'mp3',
            'modified_date': '20240118',
            'title': 'Afsnit 1: “Det føltes som en kidnapning.” ',
            'upload_date': '20240116',
            'uploader_id': 'a81VP3BY',
            'modified_timestamp': 1705568739,
            'release_timestamp': 1705377592,
            'uploader_url': 'https://www.zetland.dk/skribent/a81VP3BY',
            'uploader': 'Helle Fuusager',
            'release_date': '20240116',
            'thumbnail': r're:https://zetland\.imgix\.net/2aafe500-b14e-11ee-bf83-65d5e1283a57/Zetland_Image_1\.jpg',
            'description': 'md5:9619d426772c133f5abb26db27f26a01',
            'timestamp': 1705377592,
            'series_id': '62d54630-e87b-4ab1-a255-8de58dbe1b14',
        }

    }]

    def _real_extract(self, url):
        display_id, uploader_id = self._match_valid_url(url).group('id', 'uploader_id')
        webpage = self._download_webpage(url, display_id)
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/khanacademy.py (Python)

Code before:
        },
        'playlist_mincount': 50,
    }]

    def _parse_component_props(self, component_props, display_id):
        course = component_props['course']
        selected_unit = traverse_obj(course, (
            'unitChildren', lambda _, v: v['relativeUrl'] == f'/{display_id}'), get_all=False) or course

        def build_entry(entry):
            return self.url_result(urljoin(
                'https://www.khanacademy.org', entry['canonicalUrl']),
                KhanAcademyIE, title=entry.get('translatedTitle'))

        entries = traverse_obj(selected_unit, (
            (('unitChildren', ...), None), 'allOrderedChildren', ..., 'curatedChildren',
            lambda _, v: v['contentKind'] == 'Video' and v['canonicalUrl'], {build_entry}))

        return self.playlist_result(
            entries,
            display_id=display_id,
            **traverse_obj(selected_unit, {
                'id': ('id', {str}),
                'title': ('translatedTitle', {str}),
                'description': ('translatedDescription', {str}),
                '_old_archive_ids': ('slug', {str}, {lambda x: [make_archive_id(self, x)]}),
            }))


Review comment (suggestion):
```suggestion
                '_old_archive_ids': ('slug', {str}, {lambda x: [make_archive_id(self, x)] if x else None}),
```

Code after:
            'display_id': 'computing/computer-science',
            '_old_archive_ids': ['khanacademyunit computer-science'],
        },
        'playlist_mincount': 50,
    }]

    def _parse_component_props(self, component_props, display_id):
        course = component_props['course']
        selected_unit = traverse_obj(course, (
            'unitChildren', lambda _, v: v['relativeUrl'] == f'/{display_id}', any)) or course

        def build_entry(entry):
            return self.url_result(urljoin(
                'https://www.khanacademy.org', entry['canonicalUrl']),
                KhanAcademyIE, title=entry.get('translatedTitle'))

        entries = traverse_obj(selected_unit, (
            (('unitChildren', ...), None), 'allOrderedChildren', ..., 'curatedChildren',
            lambda _, v: v['contentKind'] == 'Video' and v['canonicalUrl'], {build_entry}))

        return self.playlist_result(
            entries,
            display_id=display_id,
            **traverse_obj(selected_unit, {
                'id': ('id', {str}),
                'title': ('translatedTitle', {str}),
                'description': ('translatedDescription', {str}),
                '_old_archive_ids': ('slug', {str}, {lambda x: [make_archive_id(self, x)] if x else None}),
            }))
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/tv5mondeplus.py (Python)

Code before:
                    })

        process_video_files(video_files)

        metadata = self._parse_json(
            vpl_data.get('data-metadata') or '{}', display_id, fatal=False)

        if not video_id:
            video_id = self._search_regex(
                (r'data-guid=["\']([\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12})',
                 r'id_contenu["\']\s:\s*(\d+)'), webpage, 'video id',
                default=display_id)

        return {
            **traverse_obj(metadata, ('content', {
                'id': ('id', {str}),
                'title': ('title', {str}),
                'episode': ('title', {str}),
                'series': ('series', {str}),
                'timestamp': ('publishDate_ts', {int_or_none}),
                'duration': ('duration', {int_or_none}),
            })),
            'id': video_id,
            'display_id': display_id,
            'title': clean_html(get_element_by_class('main-title', webpage)),
            'description': clean_html(get_element_by_class('text', get_element_html_by_class('ep-summary', webpage))),
            'thumbnail': url_or_none(vpl_data.get('data-image')),
            'formats': formats,
            'subtitles': self._extract_subtitles(self._parse_json(
                traverse_obj(vpl_data, ('data-captions', {str}), default='{}'), display_id, fatal=False)),
        }


Review comment (suggestion):
this is fatal if we don't do this:
```suggestion
            'description': clean_html(get_element_by_class('text', get_element_html_by_class('ep-summary', webpage) or '')),
```

Code after:
                    })

        process_video_files(video_files)

        metadata = self._parse_json(
            vpl_data.get('data-metadata') or '{}', display_id, fatal=False)

        if not video_id:
            video_id = self._search_regex(
                (r'data-guid=["\']([\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12})',
                 r'id_contenu["\']\s:\s*(\d+)'), webpage, 'video id',
                default=display_id)

        return {
            **traverse_obj(metadata, ('content', {
                'id': ('id', {str}),
                'title': ('title', {str}),
                'episode': ('title', {str}),
                'series': ('series', {str}),
                'timestamp': ('publishDate_ts', {int_or_none}),
                'duration': ('duration', {int_or_none}),
            })),
            'id': video_id,
            'display_id': display_id,
            'title': clean_html(get_element_by_class('main-title', webpage)),
            'description': clean_html(get_element_by_class('text', get_element_html_by_class('ep-summary', webpage) or '')),
            'thumbnail': url_or_none(vpl_data.get('data-image')),
            'formats': formats,
            'subtitles': self._extract_subtitles(self._parse_json(
                traverse_obj(vpl_data, ('data-captions', {str}), default='{}'), display_id, fatal=False)),
        }
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/boosty.py (Python)

Code before:
from .common import InfoExtractor
from ..utils import ExtractorError, dict_get, qualities, traverse_obj


class BoostyIE(InfoExtractor):
    _VALID_URL = r'https?://(?:www\.)?boosty\.to/(?P<user>[^/#?]+)/posts/(?P<post_id>[^/#?]+)'
    _TESTS = [{
        # single ok_video
        'url': 'https://boosty.to/kuplinov/posts/e55d050c-e3bb-4873-a7db-ac7a49b40c38',
        'info_dict': {
            'id': 'd7473824-352e-48e2-ae53-d4aa39459968',
            'title': 'phasma_3',
            'channel': 'Kuplinov',
            'timestamp': 1655049000,
            'upload_date': '20220612',
            'modified_timestamp': 1668680993,
            'modified_date': '20221117',
            'tags': ['куплинов', 'phasmophobia'],
            'like_count': int,
            'ext': 'mp4',
            'duration': 105,
            'view_count': int,
            'thumbnail': r're:^https://i.mycdn.me/videoPreview\?',
        },
    }, {
        # multiple ok_video
        'url': 'https://boosty.to/maddyson/posts/0c652798-3b35-471f-8b48-a76a0b28736f',

Review comment (refactor):
```suggestion
from .common import InfoExtractor
from .youtube import YoutubeIE
from ..utils import (
    ExtractorError,
    int_or_none,
    qualities,
    str_or_none,
    url_or_none,
)
from ..utils.traversal import traverse_obj
```

Code after:
from .common import InfoExtractor
from .youtube import YoutubeIE
from ..utils import (
    ExtractorError,
    int_or_none,
    qualities,
    str_or_none,
    url_or_none,
)
from ..utils.traversal import traverse_obj


class BoostyIE(InfoExtractor):
    _VALID_URL = r'https?://(?:www\.)?boosty\.to/(?P<user>[^/#?]+)/posts/(?P<post_id>[^/#?]+)'
    _TESTS = [{
        # single ok_video
        'url': 'https://boosty.to/kuplinov/posts/e55d050c-e3bb-4873-a7db-ac7a49b40c38',
        'info_dict': {
            'id': 'd7473824-352e-48e2-ae53-d4aa39459968',
            'title': 'phasma_3',
            'channel': 'Kuplinov',
            'channel_id': '7958701',
            'timestamp': 1655031975,
            'upload_date': '20220612',
            'release_timestamp': 1655049000,
            'release_date': '20220612',
            'modified_timestamp': 1668680993,
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/flextv.py (Python)

Code before:
    }, {
        'url': 'https://www.flextv.co.kr/channels/746/live',
        'only_matching': True,
    }]

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

        try:
            stream_data = self._download_json(
                f'https://api.flextv.co.kr/api/channels/{channel_id}/stream?option=all', channel_id)
        except ExtractorError as e:
            if isinstance(e.cause, HTTPError) and e.cause.status == 400:
                raise UserNotLive(video_id=channel_id)

        playlist_url = traverse_obj(stream_data, ('sources', 0, 'url'))
        formats, subtitles = self._extract_m3u8_formats_and_subtitles(
            playlist_url, channel_id, 'mp4')

        return {
            'id': channel_id,
            'formats': formats,
            'subtitles': subtitles,
            'is_live': True,
            **traverse_obj(stream_data, {
                'title': ('stream', 'title', {str_or_none}),
                'timestamp': ('stream', 'createdAt', {parse_iso8601}),
                'thumbnail': ('thumbUrl', {url_or_none}),
                'channel': ('owner', 'name', {str_or_none}),
                'channel_id': ('owner', 'id', {int_or_none}),
            }),
        }


Review comment (suggestion):
unless we know that we need to stringify (e.g. int id => str), it's better to just expect type with `{str}`
```suggestion
                'title': ('stream', 'title', {str}),
```

Code after:
            'ext': 'mp4',
            'title': r're:^214하나만\.\.\. ',
            'thumbnail': r're:^https?://.+\.jpg',
            'upload_date': r're:\d{8}',
            'timestamp': int,
            'live_status': 'is_live',
            'channel': 'Hi별',
            'channel_id': '244396',
        },
        'skip': 'The channel is offline',
    }, {
        'url': 'https://www.flextv.co.kr/channels/746/live',
        'only_matching': True,
    }]

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

        try:
            stream_data = self._download_json(
                f'https://api.flextv.co.kr/api/channels/{channel_id}/stream',
                channel_id, query={'option': 'all'})
        except ExtractorError as e:
            if isinstance(e.cause, HTTPError) and e.cause.status == 400:
                raise UserNotLive(video_id=channel_id)
            raise

        playlist_url = stream_data['sources'][0]['url']
        formats, subtitles = self._extract_m3u8_formats_and_subtitles(
            playlist_url, channel_id, 'mp4')

        return {
            'id': channel_id,
            'formats': formats,
            'subtitles': subtitles,
            'is_live': True,
            **traverse_obj(stream_data, {
                'title': ('stream', 'title', {str}),
                'timestamp': ('stream', 'createdAt', {parse_iso8601}),
                'thumbnail': ('thumbUrl', {url_or_none}),
                'channel': ('owner', 'name', {str}),
                'channel_id': ('owner', 'id', {str_or_none}),
            }),
        }
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/flextv.py (Python)

Code before:

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

        try:
            stream_data = self._download_json(
                f'https://api.flextv.co.kr/api/channels/{channel_id}/stream?option=all', channel_id)
        except ExtractorError as e:
            if isinstance(e.cause, HTTPError) and e.cause.status == 400:
                raise UserNotLive(video_id=channel_id)

        playlist_url = traverse_obj(stream_data, ('sources', 0, 'url'))
        formats, subtitles = self._extract_m3u8_formats_and_subtitles(
            playlist_url, channel_id, 'mp4')

        return {
            'id': channel_id,
            'formats': formats,
            'subtitles': subtitles,
            'is_live': True,
            **traverse_obj(stream_data, {
                'title': ('stream', 'title', {str_or_none}),
                'timestamp': ('stream', 'createdAt', {parse_iso8601}),
                'thumbnail': ('thumbUrl', {url_or_none}),
                'channel': ('owner', 'name', {str_or_none}),
                'channel_id': ('owner', 'id', {int_or_none}),
            }),
        }


Review comment (suggestion):
`channel_id` needs to be a string so we actually wanna call `str_or_none` there
```suggestion
                'channel': ('owner', 'name', {str}),
                'channel_id': ('owner', 'id', {str_or_none}),
```

Code after:
            'timestamp': int,
            'live_status': 'is_live',
            'channel': 'Hi별',
            'channel_id': '244396',
        },
        'skip': 'The channel is offline',
    }, {
        'url': 'https://www.flextv.co.kr/channels/746/live',
        'only_matching': True,
    }]

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

        try:
            stream_data = self._download_json(
                f'https://api.flextv.co.kr/api/channels/{channel_id}/stream',
                channel_id, query={'option': 'all'})
        except ExtractorError as e:
            if isinstance(e.cause, HTTPError) and e.cause.status == 400:
                raise UserNotLive(video_id=channel_id)
            raise

        playlist_url = stream_data['sources'][0]['url']
        formats, subtitles = self._extract_m3u8_formats_and_subtitles(
            playlist_url, channel_id, 'mp4')

        return {
            'id': channel_id,
            'formats': formats,
            'subtitles': subtitles,
            'is_live': True,
            **traverse_obj(stream_data, {
                'title': ('stream', 'title', {str}),
                'timestamp': ('stream', 'createdAt', {parse_iso8601}),
                'thumbnail': ('thumbUrl', {url_or_none}),
                'channel': ('owner', 'name', {str}),
                'channel_id': ('owner', 'id', {str_or_none}),
            }),
        }