Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/zingmp3.py (Python)

Code before:
            self._api_url(url_type, params), display_id or params.get('id'),
            note=f'Downloading {url_type} JSON metadata', **kwargs)
        return (resp or {}).get('data') or {}

    def _real_initialize(self):
        if not self._cookies_passed:
            self._request_webpage(
                self._api_url('bai-hat', {'id': ''}), None, note='Updating cookies')

    def _parse_items(self, items):
        for url in traverse_obj(items, (..., 'link')) or []:
            yield self.url_result(urljoin(self._DOMAIN, url))

    def _fetch_page(self, id_, url_type, page):
        raise NotImplementedError('This method must be implemented by subclasses')

    def _paged_list(self, _id, url_type):
        page = 1
        entries = []
        while True:
            data = self._fetch_page(_id, url_type, page)
            entries.extend(self._parse_items(data.get('items')))
            if not data.get('hasMore') or len(entries) > data.get('total'):
                break
            page += 1
        return entries


class ZingMp3IE(ZingMp3BaseIE):
    _VALID_URL = ZingMp3BaseIE._VALID_URL_TMPL % 'bai-hat|video-clip|embed'
    IE_NAME = 'zingmp3'
    IE_DESC = 'zingmp3.vn'
    _TESTS = [{
        'url': 'https://mp3.zing.vn/bai-hat/Xa-Mai-Xa-Bao-Thy/ZWZB9WAB.html',
        'md5': 'ead7ae13693b3205cbc89536a077daed',
        'info_dict': {
            'id': 'ZWZB9WAB',
            'title': 'Xa Mãi Xa',
            'ext': 'mp3',
            'thumbnail': r're:^https?://.+\.jpg',
            'subtitles': {
                'origin': [{
                    'ext': 'lrc',
                }]
            },
            'duration': 255,
            'track': 'Xa Mãi Xa',
            'artist': 'Bảo Thy',
            'album': 'Special Album',
            'album_artist': 'Bảo Thy',
        },

Review comment (suggestion):
```suggestion
        count = 0
        for page in itertool.count(1):
            data = self._fetch_page(_id, url_type, page)
            entries = self._parse_items(data.get('items'))
            count += len(entries)
            yield from entries
            if not data.get('hasMore') or count > data.get('total'):
                break
```

Make lazy

Code after:

    def _real_initialize(self):
        if not self._cookies_passed:
            self._request_webpage(
                self._api_url('bai-hat', {'id': ''}), None, note='Updating cookies')

    def _parse_items(self, items):
        for url in traverse_obj(items, (..., 'link')) or []:
            yield self.url_result(urljoin(self._DOMAIN, url))

    def _fetch_page(self, id_, url_type, page):
        raise NotImplementedError('This method must be implemented by subclasses')

    def _paged_list(self, _id, url_type):
        count = 0
        for page in itertools.count(1):
            data = self._fetch_page(_id, url_type, page)
            entries = list(self._parse_items(data.get('items')))
            count += len(entries)
            yield from entries
            if not data.get('hasMore') or try_call(lambda: count > data['total']):
                break


class ZingMp3IE(ZingMp3BaseIE):
    _VALID_URL = ZingMp3BaseIE._VALID_URL_TMPL % 'bai-hat|video-clip|embed'
    IE_NAME = 'zingmp3'
    IE_DESC = 'zingmp3.vn'
    _TESTS = [{
        'url': 'https://mp3.zing.vn/bai-hat/Xa-Mai-Xa-Bao-Thy/ZWZB9WAB.html',
        'md5': 'ead7ae13693b3205cbc89536a077daed',
        'info_dict': {
            'id': 'ZWZB9WAB',
            'title': 'Xa Mãi Xa',
            'ext': 'mp3',
            'thumbnail': r're:^https?://.+\.jpg',
            'subtitles': {
                'origin': [{
                    'ext': 'lrc',
                }]
            },
            'duration': 255,
            'track': 'Xa Mãi Xa',
            'artist': 'Bảo Thy',
            'album': 'Special Album',
            'album_artist': 'Bảo Thy',
        },
    }, {
        'url': 'https://zingmp3.vn/video-clip/Suong-Hoa-Dua-Loi-K-ICM-RYO/ZO8ZF7C7.html',
        'md5': '3c2081e79471a2f4a3edd90b70b185ea',
        'info_dict': {