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

Code before:

        entries, current_season = [], None
        for ep_id, ep, season in paths:
            if season:
                current_season = season
                continue
            entries.append(self.url_result(
                f'http://www.crunchyroll.com{ep}', CrunchyrollIE.ie_key(), ep_id, season=current_season))

        return {
            '_type': 'playlist',
            'id': show_id,
            'title': title,
            'entries': reversed(entries),
        }


class CrunchyrollBetaBaseIE(CrunchyrollBaseIE):
    params = None

    def _get_params(self, lang):
        if not CrunchyrollBetaBaseIE.params:
            if self._get_cookies(f'https://beta.crunchyroll.com/{lang}').get('etp_rt'):
                auth = 'cookie'
            else:
                auth = 'client id'

            initial_state, app_config = self._get_beta_embedded_json(self._download_webpage(
                f'https://beta.crunchyroll.com/{lang}', None, note='Retrieving main page'), None)
            api_domain = app_config['cxApiParams']['apiDomain']

            if auth == 'client id':
                client_id = app_config['cxApiParams']['anonClientId']
                grant_type = 'client_id'
            else:
                client_id = app_config['cxApiParams']['accountAuthClientId']
                grant_type = 'etp_rt_cookie'

            auth_response = self._download_json(
                f'{api_domain}/auth/v1/token', None, note=f'Authenticating with {auth}',
                headers={
                    'Authorization': 'Basic ' + str(base64.b64encode(('%s:' % client_id).encode('ascii')), 'ascii')
                }, data=f'grant_type={grant_type}'.encode('ascii'))
            policy_response = self._download_json(
                f'{api_domain}/index/v2', None, note='Retrieving signed policy',
                headers={
                    'Authorization': auth_response['token_type'] + ' ' + auth_response['access_token']
                })
            cms = traverse_obj(policy_response, 'cms_beta', 'cms')
            bucket = cms['bucket']
            params = {

Review comment (security):
```suggestion
            if self._get_cookies(f'https://beta.crunchyroll.com/{lang}').get('etp_rt'):
                grant_type, key = 'etp_rt_cookie', 'accountAuthClientId'
            else:
                grant_type, key = 'client_id', 'anonClientId'
```
should make it  much simpler (see comment below)

Code after:

        entries, current_season = [], None
        for ep_id, ep, season in paths:
            if season:
                current_season = season
                continue
            entries.append(self.url_result(
                f'http://www.crunchyroll.com{ep}', CrunchyrollIE.ie_key(), ep_id, season=current_season))

        return {
            '_type': 'playlist',
            'id': show_id,
            'title': title,
            'entries': reversed(entries),
        }


class CrunchyrollBetaBaseIE(CrunchyrollBaseIE):
    params = None

    def _get_params(self, lang):
        if not CrunchyrollBetaBaseIE.params:
            if self._get_cookies(f'https://beta.crunchyroll.com/{lang}').get('etp_rt'):
                grant_type, key = 'etp_rt_cookie', 'accountAuthClientId'
            else:
                grant_type, key = 'client_id', 'anonClientId'

            initial_state, app_config = self._get_beta_embedded_json(self._download_webpage(
                f'https://beta.crunchyroll.com/{lang}', None, note='Retrieving main page'), None)
            api_domain = app_config['cxApiParams']['apiDomain']

            auth_response = self._download_json(
                f'{api_domain}/auth/v1/token', None, note=f'Authenticating with grant_type={grant_type}',
                headers={
                    'Authorization': 'Basic ' + str(base64.b64encode(('%s:' % app_config['cxApiParams'][key]).encode('ascii')), 'ascii')
                }, data=f'grant_type={grant_type}'.encode('ascii'))
            policy_response = self._download_json(
                f'{api_domain}/index/v2', None, note='Retrieving signed policy',
                headers={
                    'Authorization': auth_response['token_type'] + ' ' + auth_response['access_token']
                })
            cms = traverse_obj(policy_response, 'cms_beta', 'cms')
            bucket = cms['bucket']
            params = {
                'Policy': cms['policy'],
                'Signature': cms['signature'],
                'Key-Pair-Id': cms['key_pair_id']
            }
            locale = traverse_obj(initial_state, ('localization', 'locale'))
            if locale:
                params['locale'] = locale