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

Code before:
        }


class BandcampWeeklyIE(BandcampIE):  # XXX: Do not subclass from concrete IE
    IE_NAME = 'Bandcamp:weekly'
    _VALID_URL = r'https?://(?:www\.)?bandcamp\.com(?:/radio)?/?\?.*?(?<=[?&])show=(?P<id>\d+)'
    _TESTS = [{
        'url': 'https://bandcamp.com/radio?show=224',
        'md5': '61acc9a002bed93986b91168aa3ab433',
        'info_dict': {
            'id': '224',
            'ext': 'mp3',
            'title': 'BC Weekly April 4th 2017 - Magic Moments',
            'description': 'md5:5d48150916e8e02d030623a48512c874',
            'duration': 5829.77,
            'release_date': '20170404',
            'series': 'Bandcamp Weekly',
            'episode': 'Magic Moments',
            'episode_id': '224',
        },
        'params': {
            'format': 'mp3-128',
        },
    }, {
        'url': 'https://bandcamp.com/?blah/blah@&show=228',
        'only_matching': True,
    }, {
        'url': 'https://bandcamp.com/radio/?foo=bar&show=224',
        'only_matching': True,
    }]

    def _real_extract(self, url):
        show_id = self._match_id(url)
        audio_data = self._download_json(
            'https://bandcamp.com/api/bcradio_api/1/get_show',
            show_id, 'Downloading radio show JSON',
            data=json.dumps({'id': show_id}).encode(),
            headers={'Content-Type': 'application/json'})['radioShowAudio']
        raw_metadata = self._extract_data_attr(
            self._download_webpage(url, show_id, fatal=False), show_id, 'blob', fatal=False)
        metadata = traverse_obj(raw_metadata, (
            'appData', 'shows', lambda _, v: str(v['showId']) == show_id, any)) or {}
        thumbnail = format_field(metadata, 'imageId', 'https://f4.bcbits.com/img/%s_0.jpg', default=None)

        return {
            'id': show_id,
            'title': metadata.get('title') or audio_data.get('title'),
            'thumbnail': thumbnail,
            'description': metadata.get('desc') or metadata.get('short_desc'),
            'duration': float_or_none(metadata.get('duration')),
            'is_live': False,

Review comment (refactor):
I meant that you should remove this
```suggestion
```
then reapply my `_VALID_URL` suggestion

Code after:
            'description': current.get('about'),
            'entries': entries,
        }


class BandcampWeeklyIE(BandcampIE):  # XXX: Do not subclass from concrete IE
    IE_NAME = 'Bandcamp:weekly'
    _VALID_URL = r'https?://(?:www\.)?bandcamp\.com/radio/?\?(?:[^#]+&)?show=(?P<id>\d+)'
    _TESTS = [{
        'url': 'https://bandcamp.com/radio?show=224',
        'md5': '61acc9a002bed93986b91168aa3ab433',
        'info_dict': {
            'id': '224',
            'ext': 'mp3',
            'title': 'Bandcamp Weekly, 2017-04-04',
            'description': 'md5:5d48150916e8e02d030623a48512c874',
            'thumbnail': 'https://f4.bcbits.com/img/9982549_0.jpg',
            'series': 'Bandcamp Weekly',
            'episode_id': '224',
            'release_timestamp': 1491264000,
            'release_date': '20170404',
            'duration': 5829.77,
        },
        'params': {
            'format': 'mp3-128',
        },
    }, {
        'url': 'https://bandcamp.com/radio/?foo=bar&show=224',
        'only_matching': True,
    }]

    def _real_extract(self, url):
        show_id = self._match_id(url)
        audio_data = self._download_json(
            'https://bandcamp.com/api/bcradio_api/1/get_show',
            show_id, 'Downloading radio show JSON',
            data=json.dumps({'id': show_id}).encode(),
            headers={'Content-Type': 'application/json'})['radioShowAudio']

        stream_url = audio_data['streamUrl']
        format_id = traverse_obj(stream_url, ({parse_qs}, 'enc', -1))
        encoding, _, bitrate_str = (format_id or '').partition('-')

        webpage = self._download_webpage(url, show_id, fatal=False)
        metadata = traverse_obj(
            self._extract_data_attr(webpage, show_id, 'blob', fatal=False),
            ('appData', 'shows', lambda _, v: str(v['showId']) == show_id, any)) or {}

        series_title = audio_data.get('title') or metadata.get('title')
        release_timestamp = unified_timestamp(audio_data.get('date')) or unified_timestamp(metadata.get('date'))