+class IGNIE(IGNBaseIE):
+ """
+ Extractor for some of the IGN sites, like www.ign.com, es.ign.com de.ign.com.
+ Some videos of it.ign.com are also supported
+ """
+ _VIDEO_PATH_RE = r'/(?:\d{4}/\d{2}/\d{2}/)?(?P<id>.+?)'
+ _PLAYLIST_PATH_RE = r'(?:/?\?(?P<filt>[^&#]+))?'
+ _VALID_URL = (
+ r'https?://(?:.+?\.ign|www\.pcmag)\.com/videos(?:%s)'
+ % '|'.join((_VIDEO_PATH_RE + r'(?:[/?&#]|$)', _PLAYLIST_PATH_RE)))
+ IE_NAME = 'ign.com'
+ _PAGE_TYPE = 'video'
+
+ _TESTS = [{
+ 'url': 'http://www.ign.com/videos/2013/06/05/the-last-of-us-review',
+ 'md5': 'd2e1586d9987d40fad7867bf96a018ea',
+ 'info_dict': {
+ 'id': '8f862beef863986b2785559b9e1aa599',
+ 'ext': 'mp4',
+ 'title': 'The Last of Us Review',
+ 'description': 'md5:c8946d4260a4d43a00d5ae8ed998870c',
+ 'timestamp': 1370440800,
+ 'upload_date': '20130605',
+ 'tags': 'count:9',
+ 'display_id': 'the-last-of-us-review',
+ 'thumbnail': 'https://assets1.ignimgs.com/vid/thumbnails/user/2014/03/26/lastofusreviewmimig2.jpg',
+ 'duration': 440,
+ },
+ 'params': {
+ 'nocheckcertificate': True,
+ },
+ }, {
+ 'url': 'http://www.pcmag.com/videos/2015/01/06/010615-whats-new-now-is-gogo-snooping-on-your-data',
+ 'md5': 'f1581a6fe8c5121be5b807684aeac3f6',
+ 'info_dict': {
+ 'id': 'ee10d774b508c9b8ec07e763b9125b91',
+ 'ext': 'mp4',
+ 'title': 'What\'s New Now: Is GoGo Snooping on Your Data?',
+ 'description': 'md5:817a20299de610bd56f13175386da6fa',
+ 'timestamp': 1420571160,
+ 'upload_date': '20150106',
+ 'tags': 'count:4',
+ },
+ 'skip': '404 Not Found',
+ }, {
+ 'url': 'https://www.ign.com/videos/is-a-resident-evil-4-remake-on-the-way-ign-daily-fix',
+ 'only_matching': True,
+ }]
+
+ @classmethod
+ def _extract_embed_urls(cls, url, webpage):
+ grids = re.findall(
+ r'''(?s)<section\b[^>]+\bclass\s*=\s*['"](?:[\w-]+\s+)*?content-feed-grid(?!\B|-)[^>]+>(.+?)</section[^>]*>''',
+ webpage)
+ return filter(None,
+ (urljoin(url, m.group('path')) for m in re.finditer(
+ r'''<a\b[^>]+\bhref\s*=\s*('|")(?P<path>/videos%s)\1'''
+ % cls._VIDEO_PATH_RE, grids[0] if grids else '')))
+
+ def _real_extract(self, url):
+ display_id, filt = self._match_valid_url(url).group('id', 'filt')
+ if display_id:
+ return self._extract_video(url, display_id)
+ return self._extract_playlist(url, filt or 'all')
+
+ def _extract_playlist(self, url, display_id):
+ webpage = self._download_webpage(url, display_id)
+
+ return self.playlist_result(
+ (self.url_result(u, self.ie_key())
+ for u in self._extract_embed_urls(url, webpage)),
+ playlist_id=display_id)
+
+ def _extract_video(self, url, display_id):
+ video = self._checked_call_api(display_id)
+
+ info = self._extract_video_info(video)
+
+ return merge_dicts({
+ 'display_id': display_id,
+ }, info)
+
+
+class IGNVideoIE(IGNBaseIE):