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

Code before:
        (r'video\.kcts9\.org', 'KCTS 9 (KCTS)'),  # http://kcts9.org/
        (r'video\.basinpbs\.org', 'Basin PBS (KPBT)'),  # http://www.basinpbs.org
        (r'video\.houstonpbs\.org', 'KUHT / Channel 8 (KUHT)'),  # http://www.houstonpublicmedia.org/
        # (r'tamu\.edu', 'KAMU - TV (KAMU)'),  # http://KAMU.tamu.edu
        # (r'kedt\.org', 'KEDT/Channel 16 (KEDT)'),  # http://www.kedt.org
        (r'video\.klrn\.org', 'KLRN (KLRN)'),  # http://www.klrn.org
        (r'video\.klru\.tv', 'KLRU (KLRU)'),  # http://www.klru.org
        # (r'kmbh\.org', 'KMBH-TV (KMBH)'),  # http://www.kmbh.org
        # (r'knct\.org', 'KNCT (KNCT)'),  # http://www.knct.org
        # (r'ktxt\.org', 'KTTZ-TV (KTXT)'),  # http://www.ktxt.org
        (r'video\.wtjx\.org', 'WTJX Channel 12 (WTJX)'),  # http://www.wtjx.org/
        (r'video\.ideastations\.org', 'WCVE PBS (WCVE)'),  # http://ideastations.org/
        (r'video\.kbtc\.org', 'KBTC Public Television (KBTC)'),  # http://kbtc.org
    )

    IE_NAME = 'pbs'
    IE_DESC = 'Public Broadcasting Service (PBS) and member stations: {}'.format(', '.join(list(zip(*_STATIONS))[1]))

    _VALID_URL = r'''(?x)https?://
        (?:
            # Player
            (?:video|player)\.pbs\.org/(?:widget/)?partnerplayer/(?P<player_id>[^/]+) |
            # Direct video URL, or article with embedded player
            (?:{})/(?:
              (?:(?:vir|port)alplayer|video)/(?P<id>[0-9]+)(?:[?/]|$) |
              (?:[^/]+/){{1,5}}(?P<presumptive_id>[^/]+?)(?:\.html)?/?(?:$|[?\#])
            )
        )
    '''.format('|'.join(next(zip(*_STATIONS))))

    _GEO_COUNTRIES = ['US']

    _TESTS = [
        {
            'url': 'http://www.pbs.org/tpt/constitution-usa-peter-sagal/watch/a-more-perfect-union/',
            'md5': '173dc391afd361fa72eab5d3d918968d',
            'info_dict': {
                'id': '2365006249',
                'ext': 'mp4',
                'title': 'Constitution USA with Peter Sagal - A More Perfect Union',
                'description': 'md5:31b664af3c65fd07fa460d306b837d00',
                'duration': 3190,
            },
        },
        {
            'url': 'http://www.pbs.org/wgbh/pages/frontline/losing-iraq/',
            'md5': '6f722cb3c3982186d34b0f13374499c7',
            'info_dict': {
                'id': '2365297690',
                'ext': 'mp4',
                'title': 'FRONTLINE - Losing Iraq',

Review comment (security):
`#`s in character classes don't need to be escaped
```suggestion
              (?:[^/?#]+/){{1,5}}(?P<presumptive_id>[^/?#]+?)(?:\.html)?/?(?:$|[?#])
```

Code after:
        (r'video\.kcts9\.org', 'KCTS 9 (KCTS)'),  # http://kcts9.org/
        (r'video\.basinpbs\.org', 'Basin PBS (KPBT)'),  # http://www.basinpbs.org
        (r'video\.houstonpbs\.org', 'KUHT / Channel 8 (KUHT)'),  # http://www.houstonpublicmedia.org/
        # (r'tamu\.edu', 'KAMU - TV (KAMU)'),  # http://KAMU.tamu.edu
        # (r'kedt\.org', 'KEDT/Channel 16 (KEDT)'),  # http://www.kedt.org
        (r'video\.klrn\.org', 'KLRN (KLRN)'),  # http://www.klrn.org
        (r'video\.klru\.tv', 'KLRU (KLRU)'),  # http://www.klru.org
        # (r'kmbh\.org', 'KMBH-TV (KMBH)'),  # http://www.kmbh.org
        # (r'knct\.org', 'KNCT (KNCT)'),  # http://www.knct.org
        # (r'ktxt\.org', 'KTTZ-TV (KTXT)'),  # http://www.ktxt.org
        (r'video\.wtjx\.org', 'WTJX Channel 12 (WTJX)'),  # http://www.wtjx.org/
        (r'video\.ideastations\.org', 'WCVE PBS (WCVE)'),  # http://ideastations.org/
        (r'video\.kbtc\.org', 'KBTC Public Television (KBTC)'),  # http://kbtc.org
    )

    IE_NAME = 'pbs'
    IE_DESC = 'Public Broadcasting Service (PBS) and member stations: {}'.format(', '.join(list(zip(*_STATIONS))[1]))

    _VALID_URL = r'''(?x)https?://
        (?:
            # Player
            (?:video|player)\.pbs\.org/(?:widget/)?partnerplayer/(?P<player_id>[^/?#]+) |
            # Direct video URL, or article with embedded player
            (?:{})/(?:
              (?:(?:vir|port)alplayer|video)/(?P<id>[0-9]+)(?:[?/#]|$) |
              (?:[^/?#]+/){{1,5}}(?P<presumptive_id>[^/?#]+?)(?:\.html)?/?(?:$|[?#])
            )
        )
    '''.format('|'.join(next(zip(*_STATIONS))))

    _GEO_COUNTRIES = ['US']

    _TESTS = [
        {
            'url': 'http://www.pbs.org/tpt/constitution-usa-peter-sagal/watch/a-more-perfect-union/',
            'md5': '173dc391afd361fa72eab5d3d918968d',
            'info_dict': {
                'id': '2365006249',
                'ext': 'mp4',
                'title': 'Constitution USA with Peter Sagal - A More Perfect Union',
                'description': 'md5:31b664af3c65fd07fa460d306b837d00',
                'duration': 3190,
            },
        },
        {
            'url': 'http://www.pbs.org/wgbh/pages/frontline/losing-iraq/',
            'md5': '6f722cb3c3982186d34b0f13374499c7',
            'info_dict': {
                'id': '2365297690',
                'ext': 'mp4',
                'title': 'FRONTLINE - Losing Iraq',