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

Code before:
            'id': episode_id,
            'formats': self._extract_m3u8_formats(episode.get('file_name'), episode_id, fatal=False),
            'container': 'm4a_dash',  # force fixup, AAC-only HLS
            'was_live': True,
            'series': series_meta.get('title'),
            'thumbnail': url_or_none(headline.get('headline_image')) or series_meta.get('thumbnail'),
            **traverse_obj(episode, {
                'title': ('file_title', {str}),
                'description': ('file_title_sub', {str}),
                'timestamp': ('open_time', {unified_timestamp}),
                'release_timestamp': ('aa_vinfo4', {lambda x: x.split('_')[0]}, {unified_timestamp}),
            }),
        }

    def _real_initialize(self):
        if self._API_URL_TMPL:
            return
        api_config = self._download_xml(
            'https://www.nhk.or.jp/radio/config/config_web.xml', None, 'Downloading API config', fatal=False)
        NhkRadiruIE._API_URL_TMPL = try_call(lambda: f'https:{api_config.find(".//url_program_detail").text}')

    def _real_extract(self, url):
        site_id, corner_id, headline_id = self._match_valid_url(url).group('site', 'corner', 'headline')
        programme_id = f'{site_id}_{corner_id}'

        if site_id == '18439M2W42':  # XXX: News programmes use old API (for now?)
            meta = self._download_json(
                'https://www.nhk.or.jp/s-media/news/news-site/list/v1/all.json', programme_id)['main']
            series_meta = traverse_obj(meta, {
                'title': ('program_name', {str}),
                'channel': ('media_name', {str}),
                'uploader': ('media_name', {str}),
                'thumbnail': (('thumbnail_c', 'thumbnail_p'), {url_or_none}),
            }, get_all=False)

            if headline_id:
                headline = traverse_obj(
                    meta, ('detail_list', lambda _, v: v['headline_id'] == headline_id, any))
                if not headline:
                    raise ExtractorError('Content not found; it has most likely expired', expected=True)
                return self._extract_news_info(headline, programme_id, series_meta)

            def news_entries():
                for headline in traverse_obj(meta, ('detail_list', ..., {dict})):
                    yield self._extract_news_info(headline, programme_id, series_meta)

            return self.playlist_result(
                news_entries(), programme_id, description=meta.get('site_detail'), **series_meta)

        meta = self._download_json(
            'https://www.nhk.or.jp/radio-api/app/v1/web/ondemand/series', programme_id, query={

Review comment (refactor):
```suggestion
        # XXX: News programmes use the old API
        # Can't move this to NhkRadioNewsPageIE because news items still use the normal URL format
        if site_id == '18439M2W42':
```

Code after:
            'id': episode_id,
            'formats': self._extract_m3u8_formats(episode.get('file_name'), episode_id, fatal=False),
            'container': 'm4a_dash',  # force fixup, AAC-only HLS
            'was_live': True,
            'series': series_meta.get('title'),
            'thumbnail': url_or_none(headline.get('headline_image')) or series_meta.get('thumbnail'),
            **traverse_obj(episode, {
                'title': ('file_title', {str}),
                'description': ('file_title_sub', {str}),
                'timestamp': ('open_time', {unified_timestamp}),
                'release_timestamp': ('aa_vinfo4', {lambda x: x.split('_')[0]}, {unified_timestamp}),
            }),
        }

    def _real_initialize(self):
        if self._API_URL_TMPL:
            return
        api_config = self._download_xml(
            'https://www.nhk.or.jp/radio/config/config_web.xml', None, 'Downloading API config', fatal=False)
        NhkRadiruIE._API_URL_TMPL = try_call(lambda: f'https:{api_config.find(".//url_program_detail").text}')

    def _real_extract(self, url):
        site_id, corner_id, headline_id = self._match_valid_url(url).group('site', 'corner', 'headline')
        programme_id = f'{site_id}_{corner_id}'

        # XXX: News programmes use the old API
        # Can't move this to NhkRadioNewsPageIE because news items still use the normal URL format
        if site_id == '18439M2W42':
            meta = self._download_json(
                'https://www.nhk.or.jp/s-media/news/news-site/list/v1/all.json', programme_id)['main']
            series_meta = traverse_obj(meta, {
                'title': ('program_name', {str}),
                'channel': ('media_name', {str}),
                'uploader': ('media_name', {str}),
                'thumbnail': (('thumbnail_c', 'thumbnail_p'), {url_or_none}),
            }, get_all=False)

            if headline_id:
                headline = traverse_obj(
                    meta, ('detail_list', lambda _, v: v['headline_id'] == headline_id, any))
                if not headline:
                    raise ExtractorError('Content not found; it has most likely expired', expected=True)
                return self._extract_news_info(headline, programme_id, series_meta)

            def news_entries():
                for headline in traverse_obj(meta, ('detail_list', ..., {dict})):
                    yield self._extract_news_info(headline, programme_id, series_meta)

            return self.playlist_result(
                news_entries(), programme_id, description=meta.get('site_detail'), **series_meta)