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

Code before:
    _TESTS = [{
        'url': 'https://puhutv.com/deniz-yildizi-detay',
        'info_dict': {
            'title': 'Deniz Yıldızı',
            'id': 'deniz-yildizi',
        },
        'playlist_mincount': 205,
    }, {
        # a film detail page which is using same url with serie page
        'url': 'https://puhutv.com/kaybedenler-kulubu-detay',
        'only_matching': True,
    }]

    def _extract_entries(self, seasons):
        for season in seasons:
            season_id = season.get('id')
            if not season_id:
                continue
            page = 1
            per = 100
            has_more = True
            while has_more is True:
                season = self._download_json(
                    f'https://appservice.puhutv.com/api/seasons/{season_id}/episodes?v=2',
                    season_id, f'Downloading episode {(page - 1) * per}-{page * per} metadata', query={
                        'page': page,
                        'per': per,
                    })['data']

                episodes = season['episodes']
                for episode in episodes:
                    video_id = episode['id']
                    video_title = episode['name']
                    slug = episode.get('slug') or episode['assets'][0]['slug']
                    if not slug:
                        continue

                    yield self.url_result(f'https://puhutv.com/{slug}',
                                          ie=PuhuTVIE.ie_key(), video_id=video_id,
                                          video_title=video_title)
                page += 1
                has_more = season['has_more']

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

        info = self._download_json(
            urljoin(url, f'/api/slug/{playlist_id}-detay'),
            playlist_id)['data']

        seasons = info.get('seasons')

Review comment (suggestion):
I'd prefer to keep the note as it was before. If we say we're downloading `episode 400-500` but there are only `456` episodes, this would be confusing for the user
```suggestion
                    f'https://appservice.puhutv.com/api/seasons/{season_id}/episodes?v=2',
                    season_id, f'Downloading page {page}', query={
                        'page': page,
```

Code after:
    IE_NAME = 'puhutv:serie'
    _TESTS = [{
        'url': 'https://puhutv.com/deniz-yildizi-detay',
        'info_dict': {
            'title': 'Deniz Yıldızı',
            'id': 'deniz-yildizi',
        },
        'playlist_mincount': 205,
    }, {
        # a film detail page which is using same url with serie page
        'url': 'https://puhutv.com/bizim-icin-sampiyon-detay',
        'only_matching': True,
    }]

    def _extract_entries(self, seasons):
        for season in seasons:
            season_id = season.get('id')
            if not season_id:
                continue
            page = 1
            has_more = True
            while has_more is True:
                season = self._download_json(
                    f'https://appservice.puhutv.com/api/seasons/{season_id}/episodes?v=2',
                    season_id, f'Downloading page {page}', query={
                        'page': page,
                        'per': 100,
                    })['data']

                for episode in traverse_obj(season, ('episodes', lambda _, v: v.get('slug') or v['assets'][0]['slug'])):
                    slug = episode.get('slug') or episode['assets'][0]['slug']
                    yield self.url_result(
                        f'https://puhutv.com/{slug}', PuhuTVIE, episode.get('id'), episode.get('name'))

                page += 1
                has_more = traverse_obj(season, 'has_more')

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

        info = self._download_json(
            urljoin(url, f'/api/slug/{playlist_id}-detay'),
            playlist_id)['data']

        seasons = info.get('seasons')
        if seasons:
            return self.playlist_result(
                self._extract_entries(seasons), playlist_id, info.get('name'))

        # For films, these are using same url with series
        video_id = info.get('slug')