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

Code before:
import functools

from .common import InfoExtractor
from ..utils import (
    ExtractorError,
    OnDemandPagedList,
    clean_html,
    determine_ext,
    format_field,
    int_or_none,
    join_nonempty,
    parse_codecs,
    parse_iso8601,
    url_or_none,
    urljoin,
)
from ..utils.traversal import traverse_obj


class FloatplaneBaseIE(InfoExtractor):
    def _base_extract(self, url, base_url, do_impersonate):
        post_id = self._match_id(url)

        post_data = self._download_json(
            f'{base_url}/api/v3/content/post', post_id, query={'id': post_id},
            note='Downloading post data', errnote='Unable to download post data', impersonate=do_impersonate)

        if not any(traverse_obj(post_data, ('metadata', ('hasVideo', 'hasAudio')))):
            raise ExtractorError('Post does not contain a video or audio track', expected=True)

        uploader_url = format_field(
            post_data, [('creator', 'urlname')], f'{base_url}/channel/%s/home') or None

        common_info = {
            'uploader_url': uploader_url,
            'channel_url': urljoin(f'{uploader_url}/', traverse_obj(post_data, ('channel', 'urlname'))),
            'availability': self._availability(needs_subscription=True),
            **traverse_obj(post_data, {
                'uploader': ('creator', 'title', {str}),
                'uploader_id': ('creator', 'id', {str}),
                'channel': ('channel', 'title', {str}),
                'channel_id': ('channel', 'id', {str}),
                'release_timestamp': ('releaseDate', {parse_iso8601}),
            }),
        }

        items = []
        for media in traverse_obj(post_data, (('videoAttachments', 'audioAttachments'), ...)):
            media_id = media['id']
            media_typ = media.get('type') or 'video'


Review comment (suggestion):
see above comment
```suggestion
            f'{self._BASE_URL}/api/v3/content/post', post_id, query={'id': post_id},
            note='Downloading post data', errnote='Unable to download post data',
            impersonate=self._IMPERSONATE_TARGET)
```

Code after:
import functools

from .common import InfoExtractor
from ..utils import (
    ExtractorError,
    OnDemandPagedList,
    clean_html,
    determine_ext,
    format_field,
    int_or_none,
    join_nonempty,
    parse_codecs,
    parse_iso8601,
    url_or_none,
    urljoin,
)
from ..utils.traversal import traverse_obj


class FloatplaneBaseIE(InfoExtractor):
    def _real_extract(self, url):
        post_id = self._match_id(url)

        post_data = self._download_json(
            f'{self._BASE_URL}/api/v3/content/post', post_id, query={'id': post_id},
            note='Downloading post data', errnote='Unable to download post data',
            impersonate=self._IMPERSONATE_TARGET)

        if not any(traverse_obj(post_data, ('metadata', ('hasVideo', 'hasAudio')))):
            raise ExtractorError('Post does not contain a video or audio track', expected=True)

        uploader_url = format_field(
            post_data, [('creator', 'urlname')], f'{self._BASE_URL}/channel/%s/home') or None

        common_info = {
            'uploader_url': uploader_url,
            'channel_url': urljoin(f'{uploader_url}/', traverse_obj(post_data, ('channel', 'urlname'))),
            'availability': self._availability(needs_subscription=True),
            **traverse_obj(post_data, {
                'uploader': ('creator', 'title', {str}),
                'uploader_id': ('creator', 'id', {str}),
                'channel': ('channel', 'title', {str}),
                'channel_id': ('channel', 'id', {str}),
                'release_timestamp': ('releaseDate', {parse_iso8601}),
            }),
        }

        items = []
        for media in traverse_obj(post_data, (('videoAttachments', 'audioAttachments'), ...)):
            media_id = media['id']
            media_typ = media.get('type') or 'video'