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

Code before:
from __future__ import annotations
import abc
import dataclasses
import functools
import os.path

from ._utils import _get_exe_version_output, detect_exe_version, int_or_none


# NOT public API
def runtime_version_tuple(v):
    # NB: will return (0,) if `v` is an invalid version string
    return tuple(int_or_none(x, default=0) for x in v.split('.'))


def determine_runtime_path(path, basename):
    if not path:
        return basename
    if os.path.isdir(path):
        return os.path.join(path, basename)
    return path


@dataclasses.dataclass(frozen=True)
class JsRuntimeInfo:
    name: str
    path: str
    version: str
    version_tuple: tuple[int, ...]
    supported: bool = True


class JsRuntime(abc.ABC):
    def __init__(self, path=None):
        self._path = path

    @functools.cached_property
    def info(self) -> JsRuntimeInfo | None:
        return self._info()

    @abc.abstractmethod

Review comment (suggestion):
we probably don't want others to use this for now
```suggestion
def _determine_runtime_path(path, basename):
```

Code after:
from __future__ import annotations
import abc
import dataclasses
import functools
import os.path

from ._utils import _get_exe_version_output, detect_exe_version, int_or_none


# NOT public API
def runtime_version_tuple(v):
    # NB: will return (0,) if `v` is an invalid version string
    return tuple(int_or_none(x, default=0) for x in v.split('.'))


def _determine_runtime_path(path, basename):
    if not path:
        return basename
    if os.path.isdir(path):
        return os.path.join(path, basename)
    return path


@dataclasses.dataclass(frozen=True)
class JsRuntimeInfo:
    name: str
    path: str
    version: str
    version_tuple: tuple[int, ...]
    supported: bool = True


class JsRuntime(abc.ABC):
    def __init__(self, path=None):
        self._path = path

    @functools.cached_property
    def info(self) -> JsRuntimeInfo | None:
        return self._info()

    @abc.abstractmethod
Repository: yt-dlp/yt-dlp
File: yt_dlp/utils/_jsruntime.py (Python)

Code before:
from __future__ import annotations
import abc
import dataclasses
import functools
import os.path

from ._utils import _get_exe_version_output, detect_exe_version, int_or_none


# NOT public API
def runtime_version_tuple(v):
    # NB: will return (0,) if `v` is an invalid version string
    return tuple(int_or_none(x, default=0) for x in v.split('.'))


def determine_runtime_path(path, basename):
    if not path:
        return basename
    if os.path.isdir(path):
        return os.path.join(path, basename)
    return path


@dataclasses.dataclass(frozen=True)
class JsRuntimeInfo:
    name: str
    path: str
    version: str
    version_tuple: tuple[int, ...]
    supported: bool = True


class JsRuntime(abc.ABC):
    def __init__(self, path=None):
        self._path = path

    @functools.cached_property
    def info(self) -> JsRuntimeInfo | None:
        return self._info()

    @abc.abstractmethod
    def _info(self) -> JsRuntimeInfo | None:

Review comment (suggestion):
Maybe this? We could allow people using `--js-runtimes deno:` to mean current workdir?
```suggestion
    if path is None:
```

Code after:
from __future__ import annotations
import abc
import dataclasses
import functools
import os.path

from ._utils import _get_exe_version_output, detect_exe_version, int_or_none


# NOT public API
def runtime_version_tuple(v):
    # NB: will return (0,) if `v` is an invalid version string
    return tuple(int_or_none(x, default=0) for x in v.split('.'))


def _determine_runtime_path(path, basename):
    if not path:
        return basename
    if os.path.isdir(path):
        return os.path.join(path, basename)
    return path


@dataclasses.dataclass(frozen=True)
class JsRuntimeInfo:
    name: str
    path: str
    version: str
    version_tuple: tuple[int, ...]
    supported: bool = True


class JsRuntime(abc.ABC):
    def __init__(self, path=None):
        self._path = path

    @functools.cached_property
    def info(self) -> JsRuntimeInfo | None:
        return self._info()

    @abc.abstractmethod
    def _info(self) -> JsRuntimeInfo | None:
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/yfanefa.py (Python)

Code before:
        webpage = self._download_webpage(url, video_id)
        title = self._og_search_title(webpage) or self._html_extract_title(webpage)

        player_match = re.search(r'iwPlayer\.options\[[^\]]+\]\s*=\s*({.*?});', webpage, re.DOTALL)
        if not player_match:
            raise ExtractorError('Could not find player configuration')

        config_str = player_match.group(1).replace('\\/', '/')
        url_match = re.search(r'"url":"(https://media\.yfanefa\.com/storage/v1/(?:hls|file)/[^"]+)"', config_str)
        sig_match = re.search(r'"signature":"(\?[^"]*)"', config_str)

        if not url_match:
            raise ExtractorError('Could not extract video URL')

        m3u8_url = url_match.group(1)

        if sig_match and sig_match.group(1):
            signature = sig_match.group(1)
            if signature and not signature.startswith('?'):
                signature = '?' + signature
            m3u8_url += signature

        m3u8_url = m3u8_url.replace('\\', '')

        if m3u8_url.endswith('.m3u8'):
            formats = self._extract_m3u8_formats(m3u8_url, video_id, 'mp4', m3u8_id='hls')
        else:
            formats = [{
                'url': m3u8_url,
                'ext': 'mp4',
            }]

        return {
            'id': video_id,
            'title': title,
            'formats': formats,
            'http_headers': {'Referer': url},
        }


Review comment (refactor):
Lets inline title, and use the player_data to fill in some more metadata
```suggestion
        return {
            'id': video_id,
            'title': self._og_search_title(webpage, default=None) or self._html_extract_title(webpage),
            'formats': formats,
            **traverse_obj(player_data, {
                'thumbnail': ('preview', {url_or_none}),
                'duration': ('duration', {int_or_none}),
            }),
        }
```


Code after:
    def _real_extract(self, url):
        video_id = self._match_id(url)

        webpage = self._download_webpage(url, video_id)
        player_data = self._search_json(
            r'iwPlayer\.options\["[\w.]+"\]\s*=', webpage, 'player options', video_id)

        formats = []
        video_url = join_nonempty(player_data['url'], player_data.get('signature'), delim='')
        if determine_ext(video_url) == 'm3u8':
            formats = self._extract_m3u8_formats(
                video_url, video_id, 'mp4', m3u8_id='hls')
        else:
            formats = [{'url': video_url, 'ext': 'mp4'}]

        return {
            'id': video_id.strip('/').replace('/', '-'),
            'title':
                self._og_search_title(webpage, default=None)
                or remove_end(self._html_extract_title(webpage), ' | Yorkshire Film Archive'),
            'formats': formats,
            **traverse_obj(player_data, {
                'thumbnail': ('preview', {url_or_none}),
                'duration': ('duration', {int_or_none}),
            }),
        }
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/yfanefa.py (Python)

Code before:
import re

from .common import InfoExtractor
from ..utils import ExtractorError


class YfanefaIE(InfoExtractor):
    IE_NAME = 'yfanefa'

    # FIXED: Capture entire path until ? or #
    _VALID_URL = r'https?://(?:www\.)?yfanefa\.com/(?P<id>[^?#]+)'

    _TESTS = [{
        'url': 'https://www.yfanefa.com/record/2717',
        'info_dict': {
            'id': 'record/2717',
            'ext': 'mp4',
            'title': 'THE HALLAMSHIRE RIFLES LEAVING SHEFFIELD, 1914',
        },
        'params': {'skip_download': True},
    }, {
        'url': 'https://www.yfanefa.com/news/53',
        'info_dict': {
            'id': 'news/53',
            'ext': 'mp4',
            'title': 'Memory Bank:  Bradford Launch',
        },
        'params': {'skip_download': True},
    }, {

Review comment (refactor):
```suggestion
from .common import InfoExtractor
from ..utils import determine_ext, int_or_none, join_nonempty, url_or_none
from ..utils.traversal import traverse_obj
```

Code after:
from .common import InfoExtractor
from ..utils import (
    determine_ext,
    int_or_none,
    join_nonempty,
    remove_end,
    url_or_none,
)
from ..utils.traversal import traverse_obj


class YfanefaIE(InfoExtractor):
    IE_NAME = 'yfanefa'
    _VALID_URL = r'https?://(?:www\.)?yfanefa\.com/(?P<id>[^?#]+)'
    _TESTS = [{
        'url': 'https://www.yfanefa.com/record/2717',
        'info_dict': {
            'id': 'record-2717',
            'ext': 'mp4',
            'title': 'THE HALLAMSHIRE RIFLES LEAVING SHEFFIELD, 1914',
            'duration': 5239,
            'thumbnail': r're:https://media\.yfanefa\.com/storage/v1/file/',
        },
    }, {
        'url': 'https://www.yfanefa.com/news/53',
        'info_dict': {
            'id': 'news-53',
            'ext': 'mp4',
            'title': 'Memory Bank:  Bradford Launch',
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/medaltv.py (Python)

Code before:

from .common import InfoExtractor
from ..utils import (
    int_or_none,
    str_or_none,
    url_or_none,
)
from ..utils.traversal import traverse_obj


class MedalTVIE(InfoExtractor):
    _VALID_URL = r'https?://(?:www\.)?medal\.tv/games/[^/?#&]+/clips/(?P<id>[^/?#&]+)'
    _TESTS = [{
        'url': 'https://medal.tv/games/valorant/clips/jTBFnLKdLy15K',
        'md5': '03e4911fdcf7fce563090705c2e79267',
        'info_dict': {
            'id': 'jTBFnLKdLy15K',
            'ext': 'mp4',
            'title': "Mornu's clutch",
            'description': '',
            'uploader': 'Aciel',
            'timestamp': 1651628243,
            'upload_date': '20220504',
            'uploader_id': '19335460',
            'uploader_url': 'https://medal.tv/users/19335460',
            'comment_count': int,
            'view_count': int,

Review comment (refactor):
```suggestion
from .common import InfoExtractor
```

Code after:
from .common import InfoExtractor
from ..utils import (
    int_or_none,
    url_or_none,
)
from ..utils.traversal import traverse_obj


class MedalTVIE(InfoExtractor):
    _VALID_URL = r'https?://(?:www\.)?medal\.tv/games/[^/?#&]+/clips/(?P<id>[^/?#&]+)'
    _TESTS = [{
        'url': 'https://medal.tv/games/valorant/clips/jTBFnLKdLy15K',
        'md5': '03e4911fdcf7fce563090705c2e79267',
        'info_dict': {
            'id': 'jTBFnLKdLy15K',
            'ext': 'mp4',
            'title': "Mornu's clutch",
            'description': '',
            'uploader': 'Aciel',
            'timestamp': 1651628243,
            'upload_date': '20220504',
            'uploader_id': '19335460',
            'uploader_url': 'https://medal.tv/users/19335460',
            'comment_count': int,
            'view_count': int,
            'like_count': int,
            'duration': 13,
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/agalega.py (Python)

Code before:
import json
import re

from .common import ExtractorError, InfoExtractor
from ..utils import (
    int_or_none,
    require,
    str_or_none,
    traverse_obj,
    url_or_none,
)


class AGalegaBaseIE(InfoExtractor):
    _VALID_URL = False

    def _get_access_token(self, video_id: str) -> dict[str, str] | None:
        token_url = 'https://www.agalega.gal/api/fetch-api/jwt/token'
        body_data = json.dumps({
            'username': None,
            'password': None,
            'client': 'crtvg',
            'checkExistsCookies': False,
        }).encode()

        token_raw = self._download_json(token_url, video_id, data=body_data)

        if token_raw is not None:
            access_token = str_or_none(token_raw.get('access'))
            if access_token is not None:
                return {'authorization': f'jwtok {access_token}'}
            else:
                return None
        return None


class AGalegaVideosIE(AGalegaBaseIE):
    IE_NAME = 'agalega:videos'
    _VALID_URL = r'https?://(?:www\.)?agalega\.gal/videos/(?:detail/)?(?P<id>[0-9]+)'
    _TESTS = [{
        'url': 'https://www.agalega.gal/videos/288664-lr-ninguencheconta',
        'md5': '04533a66c5f863d08dd9724b11d1c223',

Review comment (suggestion):
```suggestion
    def _get_access_token(self, video_id):
```

Code after:
import json
import time

from .common import InfoExtractor
from ..utils import jwt_decode_hs256, url_or_none
from ..utils.traversal import traverse_obj


class AGalegaBaseIE(InfoExtractor):
    _access_token = None

    @staticmethod
    def _jwt_is_expired(token):
        return jwt_decode_hs256(token)['exp'] - time.time() < 120

    def _refresh_access_token(self, video_id):
        AGalegaBaseIE._access_token = self._download_json(
            'https://www.agalega.gal/api/fetch-api/jwt/token', video_id,
            note='Downloading access token',
            data=json.dumps({
                'username': None,
                'password': None,
                'client': 'crtvg',
                'checkExistsCookies': False,
            }).encode())['access']

    def _call_api(self, endpoint, display_id, note, fatal=True, query=None):
        if not AGalegaBaseIE._access_token or self._jwt_is_expired(AGalegaBaseIE._access_token):
            self._refresh_access_token(endpoint)
        return self._download_json(
            f'https://api-agalega.interactvty.com/api/2.0/contents/{endpoint}', display_id,
            note=note, fatal=fatal, query=query,
            headers={'Authorization': f'jwtok {AGalegaBaseIE._access_token}'})


class AGalegaIE(AGalegaBaseIE):
    IE_NAME = 'agalega:videos'
    _VALID_URL = r'https?://(?:www\.)?agalega\.gal/videos/(?:detail/)?(?P<id>[0-9]+)'
    _TESTS = [{
        'url': 'https://www.agalega.gal/videos/288664-lr-ninguencheconta',
        'md5': '04533a66c5f863d08dd9724b11d1c223',
        'info_dict': {
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/agalega.py (Python)

Code before:
import json

from .common import InfoExtractor
from ..utils import require, str_or_none, traverse_obj, url_or_none


class AGalegaBaseIE(InfoExtractor):
    def _call_api(self, video_id):
        access_token = self._download_json(
            'https://www.agalega.gal/api/fetch-api/jwt/token', video_id,
            note='Downloading access token',
            data=json.dumps({
                'username': None,
                'password': None,
                'client': 'crtvg',
                'checkExistsCookies': False,
            }).encode())['access']
        return {'authorization': f'jwtok {access_token}'}


class AGalegaVideosIE(AGalegaBaseIE):
    IE_NAME = 'agalega:videos'
    _VALID_URL = r'https?://(?:www\.)?agalega\.gal/videos/(?:detail/)?(?P<id>[0-9]+)'
    _TESTS = [{
        'url': 'https://www.agalega.gal/videos/288664-lr-ninguencheconta',
        'md5': '04533a66c5f863d08dd9724b11d1c223',
        'info_dict': {
            'id': '288664',
            'title': 'Roberto e Ángel Martín atenden consultas dos espectadores',
            'description': 'O cómico ademais fai un repaso dalgúns momentos da súa traxectoria profesional',
            'thumbnail': 'https://crtvg-bucket.flumotion.cloud/content_cards/2ef32c3b9f6249d9868fd8f11d389d3d.png',
            'ext': 'mp4',
        },

Review comment (security):
I don't understand the rename. `_call_api` is what you would use for a generic api wrapper method. I would rename to `_fetch_auth_headers`

Code after:
import json
import time

from .common import InfoExtractor
from ..utils import jwt_decode_hs256, url_or_none
from ..utils.traversal import traverse_obj


class AGalegaBaseIE(InfoExtractor):
    _access_token = None

    @staticmethod
    def _jwt_is_expired(token):
        return jwt_decode_hs256(token)['exp'] - time.time() < 120

    def _refresh_access_token(self, video_id):
        AGalegaBaseIE._access_token = self._download_json(
            'https://www.agalega.gal/api/fetch-api/jwt/token', video_id,
            note='Downloading access token',
            data=json.dumps({
                'username': None,
                'password': None,
                'client': 'crtvg',
                'checkExistsCookies': False,
            }).encode())['access']

    def _call_api(self, endpoint, display_id, note, fatal=True, query=None):
        if not AGalegaBaseIE._access_token or self._jwt_is_expired(AGalegaBaseIE._access_token):
            self._refresh_access_token(endpoint)
        return self._download_json(
            f'https://api-agalega.interactvty.com/api/2.0/contents/{endpoint}', display_id,
            note=note, fatal=fatal, query=query,
            headers={'Authorization': f'jwtok {AGalegaBaseIE._access_token}'})
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/_extractors.py (Python)

Code before:
)
from .adn import (
    ADNIE,
    ADNSeasonIE,
)
from .adobeconnect import AdobeConnectIE
from .adobetv import AdobeTVVideoIE
from .adultswim import AdultSwimIE
from .aenetworks import (
    AENetworksCollectionIE,
    AENetworksIE,
    AENetworksShowIE,
    BiographyIE,
    HistoryPlayerIE,
    HistoryTopicIE,
)
from .aeonco import AeonCoIE
from .afreecatv import (
    AfreecaTVCatchStoryIE,
    AfreecaTVIE,
    AfreecaTVLiveIE,
    AfreecaTVUserIE,
)
from .agalega import (
    AGalegaVideosIE,
)
from .agora import (
    TokFMAuditionIE,
    TokFMPodcastIE,
    WyborczaPodcastIE,
    WyborczaVideoIE,
)
from .airtv import AirTVIE
from .aitube import AitubeKZVideoIE
from .aliexpress import AliExpressLiveIE
from .aljazeera import AlJazeeraIE
from .allocine import AllocineIE
from .allstar import (
    AllstarIE,
    AllstarProfileIE,
)
from .alphaporno import AlphaPornoIE
from .alsace20tv import (
    Alsace20TVEmbedIE,
    Alsace20TVIE,
)
from .altcensored import (
    AltCensoredChannelIE,
    AltCensoredIE,
)
from .alura import (

Review comment (suggestion):
Just name it `AGalegaIE`
```suggestion
from .agalega import AGalegaIE
```

Code after:
)
from .adn import (
    ADNIE,
    ADNSeasonIE,
)
from .adobeconnect import AdobeConnectIE
from .adobetv import AdobeTVVideoIE
from .adultswim import AdultSwimIE
from .aenetworks import (
    AENetworksCollectionIE,
    AENetworksIE,
    AENetworksShowIE,
    BiographyIE,
    HistoryPlayerIE,
    HistoryTopicIE,
)
from .aeonco import AeonCoIE
from .afreecatv import (
    AfreecaTVCatchStoryIE,
    AfreecaTVIE,
    AfreecaTVLiveIE,
    AfreecaTVUserIE,
)
from .agalega import AGalegaIE
from .agora import (
    TokFMAuditionIE,
    TokFMPodcastIE,
    WyborczaPodcastIE,
    WyborczaVideoIE,
)
from .airtv import AirTVIE
from .aitube import AitubeKZVideoIE
from .aliexpress import AliExpressLiveIE
from .aljazeera import AlJazeeraIE
from .allocine import AllocineIE
from .allstar import (
    AllstarIE,
    AllstarProfileIE,
)
from .alphaporno import AlphaPornoIE
from .alsace20tv import (
    Alsace20TVEmbedIE,
    Alsace20TVIE,
)
from .altcensored import (
    AltCensoredChannelIE,
    AltCensoredIE,
)
from .alura import (
    AluraCourseIE,
    AluraIE,
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/agalega.py (Python)

Code before:
        video_id = self._match_id(url)
        content_data = self._call_api(
            f'content/{video_id}/', video_id, note='Downloading content data', fatal=False,
            query={
                'optional_fields': 'image,is_premium,short_description,has_subtitle',
            })
        resource_data = self._call_api(
            f'content_resources/{video_id}/', video_id, note='Downloading resource data',
            query={
                'optional_fields': 'media_url',
            })

        formats = []
        subtitles = {}
        for m3u8_url in traverse_obj(resource_data, ('results', ..., 'media_url', {url_or_none})):
            fmts, subs = self._extract_m3u8_formats_and_subtitles(
                m3u8_url, video_id, ext='mp4', m3u8_id='hls')
            formats.extend(fmts)
            self._merge_subtitles(subs, target=subtitles)
        return {
            'id': video_id,
            'formats': formats,
            'subtitles': subtitles,
            **traverse_obj(content_data, {
                'title': ('name', {str_or_none}),
                'description': (('description', 'short_description'), {str_or_none}, any),
                'thumbnail': ('image', {url_or_none}),
            }),
        }


Review comment (suggestion):
```suggestion
                'title': ('name', {str}),
                'description': (('description', 'short_description'), {str}, any),
```

Code after:
        video_id = self._match_id(url)
        content_data = self._call_api(
            f'content/{video_id}/', video_id, note='Downloading content data', fatal=False,
            query={
                'optional_fields': 'image,is_premium,short_description,has_subtitle',
            })
        resource_data = self._call_api(
            f'content_resources/{video_id}/', video_id, note='Downloading resource data',
            query={
                'optional_fields': 'media_url',
            })

        formats = []
        subtitles = {}
        for m3u8_url in traverse_obj(resource_data, ('results', ..., 'media_url', {url_or_none})):
            fmts, subs = self._extract_m3u8_formats_and_subtitles(
                m3u8_url, video_id, ext='mp4', m3u8_id='hls')
            formats.extend(fmts)
            self._merge_subtitles(subs, target=subtitles)

        return {
            'id': video_id,
            'formats': formats,
            'subtitles': subtitles,
            **traverse_obj(content_data, {
                'title': ('name', {str}),
                'description': (('description', 'short_description'), {str}, any),
                'thumbnail': ('image', {url_or_none}),
            }),
        }