]> jfr.im git - yt-dlp.git/blob - yt_dlp/extractor/theweatherchannel.py
[extractor] Deprecate `_sort_formats`
[yt-dlp.git] / yt_dlp / extractor / theweatherchannel.py
1 import json
2
3 from .theplatform import ThePlatformIE
4 from ..utils import (
5 determine_ext,
6 parse_duration,
7 parse_iso8601,
8 )
9
10
11 class TheWeatherChannelIE(ThePlatformIE): # XXX: Do not subclass from concrete IE
12 _VALID_URL = r'https?://(?:www\.)?weather\.com(?P<asset_name>(?:/(?P<locale>[a-z]{2}-[A-Z]{2}))?/(?:[^/]+/)*video/(?P<id>[^/?#]+))'
13 _TESTS = [{
14 'url': 'https://weather.com/series/great-outdoors/video/ice-climber-is-in-for-a-shock',
15 'md5': 'c4cbe74c9c17c5676b704b950b73dd92',
16 'info_dict': {
17 'id': 'cc82397e-cc3f-4d11-9390-a785add090e8',
18 'ext': 'mp4',
19 'title': 'Ice Climber Is In For A Shock',
20 'description': 'md5:55606ce1378d4c72e6545e160c9d9695',
21 'uploader': 'TWC - Digital (No Distro)',
22 'uploader_id': '6ccd5455-16bb-46f2-9c57-ff858bb9f62c',
23 'upload_date': '20160720',
24 'timestamp': 1469018835,
25 }
26 }, {
27 'url': 'https://weather.com/en-CA/international/videos/video/unidentified-object-falls-from-sky-in-india',
28 'only_matching': True,
29 }]
30
31 def _real_extract(self, url):
32 asset_name, locale, display_id = self._match_valid_url(url).groups()
33 if not locale:
34 locale = 'en-US'
35 video_data = list(self._download_json(
36 'https://weather.com/api/v1/p/redux-dal', display_id, data=json.dumps([{
37 'name': 'getCMSAssetsUrlConfig',
38 'params': {
39 'language': locale.replace('-', '_'),
40 'query': {
41 'assetName': {
42 '$in': asset_name,
43 },
44 },
45 }
46 }]).encode(), headers={
47 'Content-Type': 'application/json',
48 })['dal']['getCMSAssetsUrlConfig'].values())[0]['data'][0]
49 video_id = video_data['id']
50 seo_meta = video_data.get('seometa', {})
51 title = video_data.get('title') or seo_meta['title']
52
53 urls = []
54 thumbnails = []
55 formats = []
56 for variant_id, variant_url in video_data.get('variants', []).items():
57 variant_url = variant_url.strip()
58 if not variant_url or variant_url in urls:
59 continue
60 urls.append(variant_url)
61 ext = determine_ext(variant_url)
62 if ext == 'jpg':
63 thumbnails.append({
64 'url': variant_url,
65 'id': variant_id,
66 })
67 elif ThePlatformIE.suitable(variant_url):
68 tp_formats, _ = self._extract_theplatform_smil(variant_url, video_id)
69 formats.extend(tp_formats)
70 elif ext == 'm3u8':
71 formats.extend(self._extract_m3u8_formats(
72 variant_url, video_id, 'mp4', 'm3u8_native',
73 m3u8_id=variant_id, fatal=False))
74 elif ext == 'f4m':
75 formats.extend(self._extract_f4m_formats(
76 variant_url, video_id, f4m_id=variant_id, fatal=False))
77 else:
78 formats.append({
79 'url': variant_url,
80 'format_id': variant_id,
81 })
82
83 cc_url = video_data.get('cc_url')
84
85 return {
86 'id': video_id,
87 'display_id': display_id,
88 'title': title,
89 'description': video_data.get('description') or seo_meta.get('description') or seo_meta.get('og:description'),
90 'duration': parse_duration(video_data.get('duration')),
91 'uploader': video_data.get('providername'),
92 'uploader_id': video_data.get('providerid'),
93 'timestamp': parse_iso8601(video_data.get('publishdate')),
94 'subtitles': {locale[:2]: [{'url': cc_url}]} if cc_url else None,
95 'thumbnails': thumbnails,
96 'formats': formats,
97 }