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

Code before:
                'thumbnail': ('Image', {url_or_none}),
            })),
        }


class TuneInPodcastIE(TuneInBaseIE):
    IE_NAME = 'tunein:podcast:program'
    _PAGE_SIZE = 20
    _VALID_URL = r'https?://tunein\.com/podcasts(?:/[^/?#]+)?/[^/?#]+(?P<id>p\d+)/?(?:\?(?![^#]*(?i:\btopicid)=)[^#]*)?(?:#|$)'
    _TESTS = [{
        'url': 'https://tunein.com/podcasts/Technology-Podcasts/Artificial-Intelligence-p1153019/',
        'info_dict': {
            'id': 'p1153019',
            'title': 'Lex Fridman Podcast',
        },
        'playlist_mincount': 200,
    }, {
        'url': 'https://tunein.com/podcasts/World-News/BBC-News-p14/',
        'info_dict': {
            'id': 'p14',
            'title': 'BBC News',
        },
        'playlist_mincount': 35,
    }]

    def _entries(self, podcast_id):
        for page in itertools.count():
            contents = self._call_api(
                podcast_id, 'contents',
                f'Downloading page {page + 1}', query={
                    'filter': 't:free',
                    'limit': self._PAGE_SIZE,
                    'offset': page * self._PAGE_SIZE,
                })

            yield from traverse_obj(contents, (
                'Items', ..., 'GuideId', {str}, filter, all, filter))

            if not traverse_obj(contents, ('Paging', 'Next', {url_or_none})):
                break

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

        return self.playlist_from_matches(
            self._entries(podcast_id), podcast_id,
            traverse_obj(self._call_api(podcast_id), ('Item', 'Title', {str})),
            getter=lambda x: update_url_query(url, {'topicId': x[1:]}))


class TuneInPodcastEpisodeIE(TuneInBaseIE):

Review comment (suggestion):
```suggestion
    }]

    @classmethod
    def suitable(cls, url):
        return False if TuneInPodcastEpisodeIE.suitable(url) else super().suitable(url)

```

Code after:
                'location': ('Properties', 'Location', 'DisplayName', {str}),
                'thumbnail': ('Image', {url_or_none}),
            })),
        }


class TuneInPodcastIE(TuneInBaseIE):
    IE_NAME = 'tunein:podcast:program'
    _PAGE_SIZE = 20
    _VALID_URL = r'https?://tunein\.com/podcasts(?:/[^/?#]+){1,2}(?P<id>p\d+)'
    _TESTS = [{
        'url': 'https://tunein.com/podcasts/Technology-Podcasts/Artificial-Intelligence-p1153019/',
        'info_dict': {
            'id': 'p1153019',
            'title': 'Lex Fridman Podcast',
        },
        'playlist_mincount': 200,
    }, {
        'url': 'https://tunein.com/podcasts/World-News/BBC-News-p14/',
        'info_dict': {
            'id': 'p14',
            'title': 'BBC News',
        },
        'playlist_mincount': 35,
    }]

    @classmethod
    def suitable(cls, url):
        return False if TuneInPodcastEpisodeIE.suitable(url) else super().suitable(url)

    def _fetch_page(self, url, podcast_id, page=0):
        items = self._call_api(
            podcast_id, 'contents', f'Downloading page {page + 1}', query={
                'filter': 't:free',
                'limit': self._PAGE_SIZE,
                'offset': page * self._PAGE_SIZE,
            },
        )['Items']

        for item in traverse_obj(items, (..., 'GuideId', {str}, filter)):
            yield self.url_result(update_url_query(url, {'topicId': item[1:]}))

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

        return self.playlist_result(OnDemandPagedList(
            functools.partial(self._fetch_page, url, podcast_id), self._PAGE_SIZE),
            podcast_id, traverse_obj(self._call_api(podcast_id), ('Item', 'Title', {str})))


class TuneInPodcastEpisodeIE(TuneInBaseIE):