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

Code before:
            note='Downloading user info', fatal=False)
        self.assert_error(user_info)

        uploader = user_info.get('name')
        description = user_info.get('description')

        entries = []
        page = 1
        while page is not None:
            api_response = self._download_json(
                self.LIVE_HISTORY_API_URL % (user_id, page), user_id,
                note='Downloading page %d' % page)
            self.assert_error(api_response)
            lives = api_response.get('lives')
            if not lives:
                break
            for live in lives:
                # !(live.is_archive || live.is_live) === !live.is_archive && !live.is_live
                if not live.get('is_archive') and not live.get('is_live'):
                    # neither archive nor live is available, so skip it
                    # or the service will ban your IP address for a while
                    continue
                live_id = live.get('live_id')
                url = 'https://www.mirrativ.com/live/%s' % live_id
                entries.append(self.url_result(url, video_id=live_id, video_title=live.get('title')))
            page = api_response.get('next_page')

        return self.playlist_result(entries, user_id, uploader, description)


Review comment (refactor):
entries should be yielded so that `--playlist-end` may work correctly

The common way this is done is:

```py
    def _entries(self, user_id):
	    page = 1
        while page:
            ...
            for ...:
                yield self.url_result(...)
            page = ...

    def _real_extract(self, url):
        user_id = self._match_id(url)
		...
        return self.playlist_result(entries, user_id, ...)
```

If the `page` increments and the pagesize are known ahead of time, `PagedList` may be a better option

Code after:
            api_response = self._download_json(
                self.LIVE_HISTORY_API_URL % (user_id, page), user_id,
                note='Downloading page %d' % page)
            self.assert_error(api_response)
            lives = api_response.get('lives')
            if not lives:
                break
            for live in lives:
                if not live.get('is_archive') and not live.get('is_live'):
                    # neither archive nor live is available, so skip it
                    # or the service will ban your IP address for a while
                    continue
                live_id = live.get('live_id')
                url = 'https://www.mirrativ.com/live/%s' % live_id
                yield self.url_result(url, video_id=live_id, video_title=live.get('title'))
            page = api_response.get('next_page')

    def _real_extract(self, url):
        user_id = self._match_id(url)
        user_info = self._download_json(
            self.USER_INFO_API_URL % user_id, user_id,
            note='Downloading user info', fatal=False)
        self.assert_error(user_info)

        uploader = user_info.get('name')
        description = user_info.get('description')

        entries = self._entries(user_id)
        return self.playlist_result(entries, user_id, uploader, description)