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

Code before:
from __future__ import unicode_literals

import os
import re

from .common import InfoExtractor, compat_urllib_parse_unquote
from ..utils import (
    HEADRequest,
    sanitized_Request,
    unified_timestamp,
    url_basename,
)


class BreitBartIE(InfoExtractor):
    _VALID_URL = r"https?:\/\/(?:www\.)breitbart.com/videos/v/(.*?)/"

    @classmethod
    def _get_video_id(cls, url):
        if '_VALID_URL_RE' not in cls.__dict__:
            cls._VALID_URL_RE = re.compile(cls._VALID_URL)

        if cls._VALID_URL_RE.match(url) is not None:
            return cls._VALID_URL_RE.match(url).group(1)
        else:
            return ""

    def _generic_id(self, url):
        return compat_urllib_parse_unquote(os.path.splitext(url.rstrip('/').split('/')[-1])[0])

    def _generic_title(self, url):
        return compat_urllib_parse_unquote(os.path.splitext(url_basename(url))[0])

    def _real_extract(self, url):
        video_id = self._get_video_id(url)
        if not video_id:
            return {}

        head_req = HEADRequest(url)
        head_response = self._request_webpage(
            head_req, video_id,
            note=False, errnote='Could not send HEAD request to %s' % url,
            fatal=False)

        info_dict = {
            'id': video_id,
            'title': self._generic_title(url),
            'timestamp': unified_timestamp(head_response.headers.get('Last-Modified'))
        }

        request = sanitized_Request(url)

Review comment (suggestion):
```suggestion
    _VALID_URL = r'https?:\/\/(?:www\.)breitbart.com/videos/v/(?P<id>[^/]+)'
```

1. Use single quotes everywhere
2. By defining an `id` group in the URL, u can just use `_match_id`
3. Add `_TESTS`

Code after:
from __future__ import unicode_literals

from .common import InfoExtractor


class BreitBartIE(InfoExtractor):
    _VALID_URL = r'https?:\/\/(?:www\.)breitbart.com/videos/v/(?P<id>[^/]+)'
    _TESTS = [{
        'url': 'https://www.breitbart.com/videos/v/5cOz1yup/?pl=Ij6NDOji',
        'md5': '0aa6d1d6e183ac5ca09207fe49f17ade',
        'info_dict': {
            'id': '5cOz1yup',
            'ext': 'mp4',
            'title': 'Watch \u2013 Clyburn: Statues in Congress Have to Go Because they Are Honoring Slavery',
            'description': 'md5:bac35eb0256d1cb17f517f54c79404d5',
            'thumbnail': 'https://cdn.jwplayer.com/thumbs/5cOz1yup-1920.jpg',
            'age_limit': 0,
        }
    }, {
        'url': 'https://www.breitbart.com/videos/v/eaiZjVOn/',
        'only_matching': True,
    }]

    def _real_extract(self, url):
        video_id = self._match_id(url)
        webpage = self._download_webpage(url, video_id)

        formats = self._extract_m3u8_formats(f'https://cdn.jwplayer.com/manifests/{video_id}.m3u8', video_id, ext='mp4')
        self._sort_formats(formats)
        return {
            'id': video_id,
            'title': self._og_search_title(
                webpage, default=None) or self._html_search_regex(
                r'(?s)<title>(.*?)</title>', webpage, 'video title'),
            'description': self._og_search_description(webpage),
            'thumbnail': self._og_search_thumbnail(webpage),
            'age_limit': self._rta_search(webpage),
            'formats': formats
        }