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

Code before:
        user, post_id = self._match_valid_url(url).group('user', 'post_id')
        post = self._download_json(
            f'https://api.boosty.to/v1/blog/{user}/post/{post_id}',
            post_id,
            note='Downloading post data',
            errnote='Unable to download post data')
        post_title = self._extract_title(post, post_id, url)
        entries = self._extract_entries(post, post_id, post_title)
        if not entries:
            raise ExtractorError(
                'no video found', video_id=post_id, expected=True)
        result = {
            'id': post_id,
            'title': post_title,
            'channel': traverse_obj(post, ('user', 'name')),
            'timestamp': dict_get(post, ('publishTime', 'createdAt')),
            'modified_timestamp': post.get('updatedAt'),
            'tags': [tag['title'] for tag in post.get('tags', [])],
            'like_count': traverse_obj(post, ('count', 'likes')),
        }
        if len(entries) == 1:
            result.update(entries[0])
        else:
            result['_type'] = 'playlist'
            result['entries'] = entries
        return result

    def _extract_title(self, post, post_id, url):
        title = post.get('title')
        if title:
            return title
        # falling back to parsing html page as a last resort
        webpage = self._download_webpage(url, video_id=post_id)
        return (
            self._og_search_title(webpage, fatal=False)
            or self._html_extract_title(webpage, fatal=True))

    def _extract_entries(self, post, post_id, post_title):
        entries = []
        for item in post['data']:
            url = None
            formats = None
            item_id = item.get('id', post_id)
            item_type = item.get('type')
            if item_type == 'video':
                url = item.get('url')
            elif item_type == 'ok_video':
                formats = self._extract_formats(
                    item.get('playerUrls', []), item_id)
            if not url and not formats:
                continue

Review comment (refactor):
And finally, we can then also return that common metadata for the playlist.
```suggestion
        if not entries:
            raise ExtractorError('No videos found', expected=True)
        if len(entries) == 1:
            return entries[0]
        return self.playlist_result(entries, post_id, post_title, **common_metadata)
```
The tests will need to be slightly updated.

Code after:
                'thumbnail': r're:^https://i\.mycdn\.me/videoPreview\?',
            },
        }],
    }, {
        # single external video (youtube)
        'url': 'https://boosty.to/denischuzhoy/posts/6094a487-bcec-4cf8-a453-43313b463c38',
        'info_dict': {
            'id': 'EXelTnve5lY',
            'title': 'Послание Президента Федеральному Собранию | Класс народа',
            'upload_date': '20210425',
            'channel': 'Денис Чужой',
            'tags': 'count:10',
            'like_count': int,
            'ext': 'mp4',
            'duration': 816,
            'view_count': int,
            'thumbnail': r're:^https://i\.ytimg\.com/',
            'age_limit': 0,
            'availability': 'public',
            'categories': list,
            'channel_follower_count': int,
            'channel_id': 'UCCzVNbWZfYpBfyofCCUD_0w',
            'channel_is_verified': bool,
            'channel_url': r're:^https://www\.youtube\.com/',
            'comment_count': int,
            'description': str,
            'heatmap': 'count:100',
            'live_status': str,
            'playable_in_embed': bool,
            'uploader': str,
            'uploader_id': str,
            'uploader_url': r're:^https://www\.youtube\.com/',
        },
    }]

    _MP4_TYPES = ('tiny', 'lowest', 'low', 'medium', 'high', 'full_hd', 'quad_hd', 'ultra_hd')

    def _extract_formats(self, player_urls, video_id):
        formats = []
        quality = qualities(self._MP4_TYPES)
        for player_url in traverse_obj(player_urls, lambda _, v: url_or_none(v['url'])):
            url = player_url['url']
            format_type = player_url.get('type')
            if format_type in ('hls', 'hls_live', 'live_ondemand_hls', 'live_playback_hls'):
                formats.extend(self._extract_m3u8_formats(url, video_id, m3u8_id='hls', fatal=False))
            elif format_type in ('dash', 'dash_live', 'live_playback_dash'):
                formats.extend(self._extract_mpd_formats(url, video_id, mpd_id='dash', fatal=False))
            elif format_type in self._MP4_TYPES:
                formats.append({
                    'url': url,
                    'ext': 'mp4',