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

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

from .common import InfoExtractor


class ManotoTVIE(InfoExtractor):
    IE_NAME = 'Manoto TV (Episode / Video)'
    _VALID_URL = r'https?://(?:www\.)?manototv\.com/episode/(?P<id>[0-9]+)'
    _TEST = {
        'url': 'https://www.manototv.com/episode/12576',
        'info_dict': {
            'id': '12576',
            'title': 'Seh Mah Taatili',
            'description': 'مجموعه ای از فیلم های سینمای کلاسیک ایران',
            'thumbnail': r're:^https?://.*\.jpeg$',
            'ext': 'm3u8',
        }
    }

    def _real_extract(self, url):
        video_id = self._match_id(url)
        json = self._download_json('https://dak1vd5vmi7x6.cloudfront.net/api/v1/publicrole/showmodule/episodedetails?id=' + video_id, video_id)
        details = json.get('details', {})
        title = details.get('analyticsEpisodeTitle', '')
        video_url = details.get('videoM3u8Url', '')
        description = details.get('showSynopsis', '')
        thumbnail = details.get('episodelandscapeImgIxUrl', '')
        ext = 'm3u8'
        formats = self._extract_m3u8_formats(video_url, video_id, ext)
        return {
            'id': video_id,
            'title': title,
            'description': description,
            'thumbnail': thumbnail,
            'ext': ext,
            'formats': formats,
        }


class ManotoTVShowIE(InfoExtractor):
    IE_NAME = 'Manoto TV (Show / Playlist)'

Review comment (suggestion):
the site doesn't have individual videos?
If it does then add to tests if it doesn't then remove ` / Video` from IE name

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

from .common import InfoExtractor
from ..utils import (
    clean_html,
    int_or_none,
    traverse_obj
)


_API_URL = 'https://dak1vd5vmi7x6.cloudfront.net/api/v1/publicrole/{}/{}?id={}'


class ManotoTVIE(InfoExtractor):
    IE_DESC = 'Manoto TV (Episode)'
    _VALID_URL = r'https?://(?:www\.)?manototv\.com/episode/(?P<id>[0-9]+)'
    _TESTS = [{
        'url': 'https://www.manototv.com/episode/8475',
        'info_dict': {
            'id': '8475',
            'series': 'خانه های رویایی با برادران اسکات',
            'season_number': 7,
            'episode_number': 25,
            'episode_id': 'My Dream Home S7: Carol & John',
            'duration': 3600,
            'categories': ['سرگرمی'],
            'title': 'کارول و جان',
            'description': 'md5:d0fff1f8ba5c6775d312a00165d1a97e',
            'thumbnail': r're:^https?://.*\.(jpeg|png|jpg)$',
            'ext': 'mp4'
        },
        'params': {
            'skip_download': 'm3u8',
        }
    }, {
        'url': 'https://www.manototv.com/episode/12576',
        'info_dict': {
            'id': '12576',
            'series': 'فیلم های ایرانی',
            'episode_id': 'Seh Mah Taatili',
            'duration': 5400,
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/manoto.py (Python)

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

from .common import InfoExtractor, traverse_obj


_API_URL = 'https://dak1vd5vmi7x6.cloudfront.net/api/v1/publicrole/{}/{}?id={}'
EXT = 'mp4'

class ManotoTVIE(InfoExtractor):
    IE_NAME = 'Manoto TV (Episode)'
    _VALID_URL = r'https?://(?:www\.)?manototv\.com/episode/(?P<id>[0-9]+)'
    _TEST = {
        'url': 'https://www.manototv.com/episode/12576',
        'info_dict': {
            'id': '12576',
            'series': 'فیلم های ایرانی',
            'season_number': 0,
            'episode_number': 0,
            'episode_id': 'Seh Mah Taatili',
            'duration': 5400,
            'view_count': 10550,
            'categories': ['سرگرمی'],
            'title': 'سه ماه تعطیلی',
            'description': 'سه ماه تعطیلی فیلمی به کارگردانی و نویسندگی شاپور قریب ساختهٔ سال ۱۳۵۶ است.<br/><br/>',
            'thumbnail': r're:^https?://.*\.jpeg$',
            'ext': EXT
        }
    }

    def _real_extract(self, url):
        video_id = self._match_id(url)
        episode_json = self._download_json(_API_URL.format('showmodule', 'episodedetails', video_id), video_id)
        details = episode_json.get('details', {})
        series = details.get('showTitle')
        season_number = details.get('analyticsSeasonNumber')

Review comment (refactor):
Don't this break `--download-archive`? Maybe you should use `IE_DESC`. Same applies to other extractors in this PR.

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

from .common import InfoExtractor
from ..utils import (
    clean_html,
    int_or_none,
    traverse_obj
)


_API_URL = 'https://dak1vd5vmi7x6.cloudfront.net/api/v1/publicrole/{}/{}?id={}'


class ManotoTVIE(InfoExtractor):
    IE_DESC = 'Manoto TV (Episode)'
    _VALID_URL = r'https?://(?:www\.)?manototv\.com/episode/(?P<id>[0-9]+)'
    _TESTS = [{
        'url': 'https://www.manototv.com/episode/8475',
        'info_dict': {
            'id': '8475',
            'series': 'خانه های رویایی با برادران اسکات',
            'season_number': 7,
            'episode_number': 25,
            'episode_id': 'My Dream Home S7: Carol & John',
            'duration': 3600,
            'categories': ['سرگرمی'],
            'title': 'کارول و جان',
            'description': 'md5:d0fff1f8ba5c6775d312a00165d1a97e',
            'thumbnail': r're:^https?://.*\.(jpeg|png|jpg)$',
            'ext': 'mp4'
        },
        'params': {
            'skip_download': 'm3u8',
        }
    }, {
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/playsuisse.py (Python)

Code before:
# coding: utf-8
import json

from .common import InfoExtractor
from ..utils import int_or_none


class PlaySuisseIE(InfoExtractor):
    _VALID_URL = r'https?://(?:www\.)?playsuisse\.ch/watch/(?P<id>[0-9]+)'
    _TESTS = [
        {
            'url': 'https://www.playsuisse.ch/watch/763211/0',
            'md5': '0d716b7a16c3e6ab784ef817ee9a20c1',
            'info_dict': {
                'id': '763211',
                'ext': 'mp4',
                'title': 'Knochen',
                'description': 'md5:8ea7a8076ba000cd9e8bc132fd0afdd8'
            }
        },
        {
            'url': 'https://www.playsuisse.ch/watch/808675/0',
            'md5': '7c59b60aadd84b3e36d46dea01125442',
            'info_dict': {
                'id': '808675',
                'ext': 'mp4',
                'title': 'Der Läufer',
                'description': 'md5:9f61265c7e6dcc3e046137a792b275fd'
            }
        },
        {
            'url': 'https://www.playsuisse.ch/watch/817193/0',

Review comment (refactor):
```
class PlaySuisseIE(InfoExtractor):
    IE_DESC = 'playsuisse.ch'
```
This PR doesn't work for me without this change. Otherwise I get this error:
```
ERROR: 'PlaySuisseIE' object has no attribute 'IE_DESC'
```
I'm not sure if that's the right approach though (@pukkandan ?)

Code after:
import json

from .common import InfoExtractor
from ..utils import int_or_none, traverse_obj


class PlaySuisseIE(InfoExtractor):
    _VALID_URL = r'https?://(?:www\.)?playsuisse\.ch/watch/(?P<id>[0-9]+)'
    _TESTS = [
        {
            'url': 'https://www.playsuisse.ch/watch/763211/0',
            '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',
                'episode_number': 1,
                'thumbnail': 'md5:9260abe0c0ec9b69914d0a10d54c5878'
            }
        },
        {
            'url': 'https://www.playsuisse.ch/watch/808675/0',
            'md5': '818b94c1d2d7c4beef953f12cb8f3e75',
            'info_dict': {
                'id': '808675',
                'ext': 'mp4',
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/gotostage.py (Python)

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

from .common import InfoExtractor
from ..compat import compat_str
from ..utils import (
    url_or_none,
    try_get)

import json


class GoToStageIE(InfoExtractor):
    _VALID_URL = r'https?://(?:www\.)?gotostage\.com/channel/[a-z0-9]+/recording/(?P<id>[a-z0-9]+)/watch'
    _TESTS = [{
        'url': 'https://www.gotostage.com/channel/8901680603948959494/recording/60bb55548d434f21b9ce4f0e225c4895/watch',
        'md5': 'ca72ce990cdcd7a2bd152f7217e319a2',
        'info_dict': {
            'id': '60bb55548d434f21b9ce4f0e225c4895',
            'ext': 'mp4',
            'title': 'What is GoToStage?',
            'thumbnail': r're:^https?://.*\.jpg$',
            'duration': 93.924711
        }
    }, {
        'url': 'https://www.gotostage.com/channel/bacc3d3535b34bafacc3f4ef8d4df78a/recording/831e74cd3e0042be96defba627b6f676/watch?source=HOMEPAGE',
        'only_matching': True,
    }]

    def _real_extract(self, url):
        video_id = self._match_id(url)
        metadata = self._download_json(
            'https://api.gotostage.com/contents?ids=%s' % video_id,

Review comment (suggestion):
```suggestion
from ..utils import (
    try_get,
    url_or_none,
)
```

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

from .common import InfoExtractor
from ..compat import compat_str
from ..utils import (
    try_get,
    url_or_none
)

import json


class GoToStageIE(InfoExtractor):
    _VALID_URL = r'https?://(?:www\.)?gotostage\.com/channel/[a-z0-9]+/recording/(?P<id>[a-z0-9]+)/watch'
    _TESTS = [{
        'url': 'https://www.gotostage.com/channel/8901680603948959494/recording/60bb55548d434f21b9ce4f0e225c4895/watch',
        'md5': 'ca72ce990cdcd7a2bd152f7217e319a2',
        'info_dict': {
            'id': '60bb55548d434f21b9ce4f0e225c4895',
            'ext': 'mp4',
            'title': 'What is GoToStage?',
            'thumbnail': r're:^https?://.*\.jpg$',
            'duration': 93.924711
        }
    }, {
        'url': 'https://www.gotostage.com/channel/bacc3d3535b34bafacc3f4ef8d4df78a/recording/831e74cd3e0042be96defba627b6f676/watch?source=HOMEPAGE',
        'only_matching': True,
    }]

    def _real_extract(self, url):
        video_id = self._match_id(url)
        metadata = self._download_json(
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/gotostage.py (Python)

Code before:

        registration_response = self._download_json(
            'https://api-registrations.logmeininc.com/registrations',
            video_id,
            data=json.dumps(registration_data).encode(),
            expected_status=409,
            headers={'Content-Type': 'application/json'},
            note='Register user',
            errnote='Unable to register user')

        content_response = self._download_json(
            'https://api.gotostage.com/contents/%s/asset' % video_id,
            video_id,
            headers={'x-registrantkey': try_get(registration_response, lambda x: x['registrationKey'], compat_str)},
            note='Get download url',
            errnote='Unable to get download url')

        return {
            'id': video_id,
            'title': try_get(metadata, lambda x: x[0]['title'], compat_str),
            'url': try_get(content_response, lambda x: x['cdnLocation'], compat_str),
            'ext': 'mp4',
            'thumbnail': url_or_none(try_get(metadata, lambda x: x[0]['thumbnail']['location'])),
            'duration': try_get(metadata, lambda x: x[0]['duration'], float),
            'categories': [try_get(metadata, lambda x: x[0]['category'], compat_str)],
            'is_live': False}


Review comment (suggestion):
```suggestion
            'is_live': False
        }
```

Code after:
            'email': 'foobar@example.com'
        }

        registration_response = self._download_json(
            'https://api-registrations.logmeininc.com/registrations',
            video_id,
            data=json.dumps(registration_data).encode(),
            expected_status=409,
            headers={'Content-Type': 'application/json'},
            note='Register user',
            errnote='Unable to register user')

        content_response = self._download_json(
            'https://api.gotostage.com/contents/%s/asset' % video_id,
            video_id,
            headers={'x-registrantkey': registration_response['registrationKey']},
            note='Get download url',
            errnote='Unable to get download url')

        return {
            'id': video_id,
            'title': try_get(metadata, lambda x: x['title'], compat_str),
            'url': try_get(content_response, lambda x: x['cdnLocation'], compat_str),
            'ext': 'mp4',
            'thumbnail': url_or_none(try_get(metadata, lambda x: x['thumbnail']['location'])),
            'duration': try_get(metadata, lambda x: x['duration'], float),
            'categories': [try_get(metadata, lambda x: x['category'], compat_str)],
            'is_live': False
        }
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/ninenow.py (Python)

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

from .common import InfoExtractor
from ..compat import compat_str
from ..utils import (
    ExtractorError,
    int_or_none,
    float_or_none,
    smuggle_url,
    unified_timestamp,
    unified_strdate,
    try_get,
)


class NineNowIE(InfoExtractor):
    IE_NAME = '9now.com.au'
    _VALID_URL = r'https?://(?:www\.)?9now\.com\.au/(?:[^/]+/){2}(?P<id>[^/?#]+)'
    _GEO_COUNTRIES = ['AU']
    _TESTS = [{
        # episode of series
        'url': 'https://www.9now.com.au/lego-masters/season-3/episode-3',
        'md5': '62feeb8d534697c2c1bee11b27bf020d',
        'info_dict': {
            'id': '6249614030001',
            'title': 'Episode 3',
            'ext': 'mp4',
            'season_number': 3,
            'episode_number': 3,
            'description': 'In the first elimination of the competition, teams will have 10 hours to build a world inside a snow globe.',
            'uploader_id': '4460760524001',
            'timestamp': 1619002200,
            'upload_date': '20210421',
        },
    }]

Review comment (suggestion):
```suggestion
    str_or_none,
    unified_timestamp,
```

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

from .common import InfoExtractor
from ..compat import compat_str
from ..utils import (
    ExtractorError,
    int_or_none,
    float_or_none,
    smuggle_url,
    str_or_none,
    try_get,
    unified_strdate,
    unified_timestamp,
)


class NineNowIE(InfoExtractor):
    IE_NAME = '9now.com.au'
    _VALID_URL = r'https?://(?:www\.)?9now\.com\.au/(?:[^/]+/){2}(?P<id>[^/?#]+)'
    _GEO_COUNTRIES = ['AU']
    _TESTS = [{
        # clip
        'url': 'https://www.9now.com.au/afl-footy-show/2016/clip-ciql02091000g0hp5oktrnytc',
        'md5': '17cf47d63ec9323e562c9957a968b565',
        'info_dict': {
            'id': '16801',
            'ext': 'mp4',
            'title': 'St. Kilda\'s Joey Montagna on the potential for a player\'s strike',
            'description': 'Is a boycott of the NAB Cup "on the table"?',
            'uploader_id': '4460760524001',
            'upload_date': '20160713',
            'timestamp': 1468421266,
        },
        'skip': 'Only available in Australia',
    }, {
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/ninenow.py (Python)

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

from .common import InfoExtractor
from ..compat import compat_str
from ..utils import (
    ExtractorError,
    int_or_none,
    float_or_none,
    smuggle_url,
    str_or_none,
    unified_timestamp,
    unified_strdate,
    try_get,
)


class NineNowIE(InfoExtractor):
    IE_NAME = '9now.com.au'
    _VALID_URL = r'https?://(?:www\.)?9now\.com\.au/(?:[^/]+/){2}(?P<id>[^/?#]+)'
    _GEO_COUNTRIES = ['AU']
    _TESTS = [{
        # episode of series
        'url': 'https://www.9now.com.au/lego-masters/season-3/episode-3',
        'md5': '62feeb8d534697c2c1bee11b27bf020d',
        'info_dict': {
            'id': '6249614030001',
            'title': 'Episode 3',
            'ext': 'mp4',
            'season_number': 3,
            'episode_number': 3,
            'description': 'In the first elimination of the competition, teams will have 10 hours to build a world inside a snow globe.',
            'uploader_id': '4460760524001',
            'timestamp': 1619002200,
            'upload_date': '20210421',
        },
    }]
    BRIGHTCOVE_URL_TEMPLATE = 'http://players.brightcove.net/4460760524001/default_default/index.html?videoId=%s'


Review comment (suggestion):
```suggestion
    str_or_none,
    try_get,
    unified_strdate,
    unified_timestamp,
```

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

from .common import InfoExtractor
from ..compat import compat_str
from ..utils import (
    ExtractorError,
    int_or_none,
    float_or_none,
    smuggle_url,
    str_or_none,
    try_get,
    unified_strdate,
    unified_timestamp,
)


class NineNowIE(InfoExtractor):
    IE_NAME = '9now.com.au'
    _VALID_URL = r'https?://(?:www\.)?9now\.com\.au/(?:[^/]+/){2}(?P<id>[^/?#]+)'
    _GEO_COUNTRIES = ['AU']
    _TESTS = [{
        # clip
        'url': 'https://www.9now.com.au/afl-footy-show/2016/clip-ciql02091000g0hp5oktrnytc',
        'md5': '17cf47d63ec9323e562c9957a968b565',
        'info_dict': {
            'id': '16801',
            'ext': 'mp4',
            'title': 'St. Kilda\'s Joey Montagna on the potential for a player\'s strike',
            'description': 'Is a boycott of the NAB Cup "on the table"?',
            'uploader_id': '4460760524001',
            'upload_date': '20160713',
            'timestamp': 1468421266,
        },
        'skip': 'Only available in Australia',
    }, {
        # episode
        'url': 'https://www.9now.com.au/afl-footy-show/2016/episode-19',
        'only_matching': True,
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/nzherald.py (Python)

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

from .brightcove import BrightcoveNewIE
from ..compat import compat_str
from .common import InfoExtractor
from ..utils import (
    ExtractorError,
    traverse_obj
)


class NZHeraldIE(InfoExtractor):
    IE_NAME = 'nzherald'
    _VALID_URL = r'https?://(?:www\.)?nzherald\.co\.nz/[\w\/-]+\/(?P<id>[A-Z0-9]+)'
    _TESTS = [
        {
            'url': 'https://www.nzherald.co.nz/nz/weather-heavy-rain-gales-across-nz-most-days-this-week/PTG7QWY4E2225YHZ5NAIRBTYTQ/',
            'info_dict': {
                'id': '6271084466001',
                'ext': 'mp4',
                'title': 'MetService severe weather warning: September 6th - 7th',
                'timestamp': 1630891576,
                'upload_date': '20210906',
                'uploader_id': '1308227299001',
                'description': 'md5:db6ca335a22e2cdf37ab9d2bcda52902'
            }

        }, {
            # Webpage has brightcove embed player url
            'url': 'https://www.nzherald.co.nz/travel/pencarrow-coastal-trail/HDVTPJEPP46HJ2UEMK4EGD2DFI/',
            'info_dict': {
                'id': '6261791733001',
                'ext': 'mp4',
                'title': 'Pencarrow Coastal Trail',

Review comment (refactor):
```suggestion
from .brightcove import BrightcoveNewIE
from .common import InfoExtractor

from ..compat import compat_str
from ..utils import (
    ExtractorError,
    traverse_obj
)
```

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

from .brightcove import BrightcoveNewIE
from .common import InfoExtractor

from ..compat import compat_str
from ..utils import (
    ExtractorError,
    traverse_obj
)


class NZHeraldIE(InfoExtractor):
    IE_NAME = 'nzherald'
    _VALID_URL = r'https?://(?:www\.)?nzherald\.co\.nz/[\w\/-]+\/(?P<id>[A-Z0-9]+)'
    _TESTS = [
        {
            'url': 'https://www.nzherald.co.nz/nz/weather-heavy-rain-gales-across-nz-most-days-this-week/PTG7QWY4E2225YHZ5NAIRBTYTQ/',
            'info_dict': {
                'id': '6271084466001',
                'ext': 'mp4',
                'title': 'MetService severe weather warning: September 6th - 7th',
                'timestamp': 1630891576,
                'upload_date': '20210906',
                'uploader_id': '1308227299001',
                'description': 'md5:db6ca335a22e2cdf37ab9d2bcda52902'
            }

        }, {
            # Webpage has brightcove embed player url
            'url': 'https://www.nzherald.co.nz/travel/pencarrow-coastal-trail/HDVTPJEPP46HJ2UEMK4EGD2DFI/',
            'info_dict': {
                'id': '6261791733001',
                'ext': 'mp4',
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/musescore.py (Python)

Code before:
            'thumbnail': r're:(?:https?://)(?:www\.)?musescore\.com/.*\.png[^$]+',
            'uploader': 'ClassicMan',
            'creator': 'Ludwig van Beethoven (1770–1827)',
        }
    }]

    def _real_extract(self, url):
        webpage = self._download_webpage(url, None)
        url = self._og_search_url(webpage) or url
        id = self._match_id(url)
        mp3_url = self._download_json(f'https://musescore.com/api/jmuse?id={id}&index=0&type=mp3&v2=1', id,
                                      headers={'authorization': '63794e5461e4cfa046edfbdddfccc1ac16daffd2'})['info']['url']
        formats = [{
            'url': mp3_url,
            'ext': 'mp3',
            'vcodec': 'none',
        }]

        return {
            'id': id,
            'formats': formats,
            'title': self._og_search_title(webpage),
            'description': self._og_search_description(webpage),
            'thumbnail': self._og_search_thumbnail(webpage),
            'uploader': self._html_search_meta('musescore:author', webpage, 'uploader'),
            'creator': self._html_search_meta('musescore:composer', webpage, 'composer'),
        }


Review comment (security):
I don't think this is accurate extraction; it should give you `Download and print in PDF or MIDI free sheet music for <title> Theme by <author of song> arranged by <uploader> for <instrument> (<formation>)` according to its HTML. Using `_search_json_ld` is the easiest way I think

Code after:
            'thumbnail': r're:(?:https?://)(?:www\.)?musescore\.com/.*\.png[^$]+',
            'uploader': 'ClassicMan',
            'creator': 'Ludwig van Beethoven (1770–1827)',
        }
    }, {
        'url': 'https://musescore.com/minh_cuteee/scores/6555384',
        'only_matching': True,
    }]

    def _real_extract(self, url):
        webpage = self._download_webpage(url, None)
        url = self._og_search_url(webpage) or url
        id = self._match_id(url)
        mp3_url = self._download_json(f'https://musescore.com/api/jmuse?id={id}&index=0&type=mp3&v2=1', id,
                                      headers={'authorization': '63794e5461e4cfa046edfbdddfccc1ac16daffd2'})['info']['url']
        formats = [{
            'url': mp3_url,
            'ext': 'mp3',
            'vcodec': 'none',
        }]

        return {
            'id': id,
            'formats': formats,
            'title': self._og_search_title(webpage),
            'description': self._og_search_description(webpage),
            'thumbnail': self._og_search_thumbnail(webpage),
            'uploader': self._html_search_meta('musescore:author', webpage, 'uploader'),
            'creator': self._html_search_meta('musescore:composer', webpage, 'composer'),
        }