]> jfr.im git - yt-dlp.git/blobdiff - yt_dlp/extractor/ruv.py
[cleanup] Add more ruff rules (#10149)
[yt-dlp.git] / yt_dlp / extractor / ruv.py
index 8f3cc40956275f8280344dcf0166dca86fefd443..5e55a4059c82323885c1dc36229f8cd87576f1f7 100644 (file)
@@ -1,9 +1,8 @@
-# coding: utf-8
-from __future__ import unicode_literals
-
 from .common import InfoExtractor
 from ..utils import (
     determine_ext,
+    parse_duration,
+    traverse_obj,
     unified_timestamp,
 )
 
@@ -99,3 +98,89 @@ def _real_extract(self, url):
             'timestamp': timestamp,
             'formats': formats,
         }
+
+
+class RuvSpilaIE(InfoExtractor):
+    IE_NAME = 'ruv.is:spila'
+    _VALID_URL = r'https?://(?:www\.)?ruv\.is/(?:(?:sjon|ut)varp|(?:krakka|ung)ruv)/spila/.+/(?P<series_id>[0-9]+)/(?P<id>[a-z0-9]+)'
+    _TESTS = [{
+        'url': 'https://www.ruv.is/sjonvarp/spila/ithrottir/30657/9jcnd4',
+        'info_dict': {
+            'id': '9jcnd4',
+            'ext': 'mp4',
+            'title': '01.02.2022',
+            'chapters': 'count:4',
+            'timestamp': 1643743500,
+            'upload_date': '20220201',
+            'thumbnail': 'https://d38kdhuogyllre.cloudfront.net/fit-in/1960x/filters:quality(65)/hd_posters/94boog-iti3jg.jpg',
+            'description': 'Íþróttafréttir.',
+            'age_limit': 0,
+        },
+    }, {
+        'url': 'https://www.ruv.is/utvarp/spila/i-ljosi-sogunnar/23795/7hqkre',
+        'info_dict': {
+            'id': '7hqkre',
+            'ext': 'mp3',
+            'thumbnail': 'https://d38kdhuogyllre.cloudfront.net/fit-in/1960x/filters:quality(65)/hd_posters/7hqkre-7uepao.jpg',
+            'description': 'md5:8d7046549daff35e9a3190dc9901a120',
+            'chapters': [],
+            'upload_date': '20220204',
+            'timestamp': 1643965500,
+            'title': 'Nellie Bly II',
+            'age_limit': 0,
+        },
+    }, {
+        'url': 'https://www.ruv.is/ungruv/spila/ungruv/28046/8beuph',
+        'only_matching': True,
+    }, {
+        'url': 'https://www.ruv.is/krakkaruv/spila/krakkafrettir/30712/9jbgb0',
+        'only_matching': True,
+    }]
+
+    def _real_extract(self, url):
+        display_id, series_id = self._match_valid_url(url).group('id', 'series_id')
+        program = self._download_json(
+            'https://www.ruv.is/gql/', display_id, query={'query': '''{
+                Program(id: %s){
+                    title image description short_description
+                    episodes(id: {value: "%s"}) {
+                        rating title duration file image firstrun description
+                        clips {
+                            time text
+                        }
+                        subtitles {
+                            name value
+                        }
+                    }
+                }
+            }''' % (series_id, display_id)})['data']['Program']  # noqa: UP031
+        episode = program['episodes'][0]
+
+        subs = {}
+        for trk in episode.get('subtitles'):
+            if trk.get('name') and trk.get('value'):
+                subs.setdefault(trk['name'], []).append({'url': trk['value'], 'ext': 'vtt'})
+
+        media_url = episode['file']
+        if determine_ext(media_url) == 'm3u8':
+            formats = self._extract_m3u8_formats(media_url, display_id)
+        else:
+            formats = [{'url': media_url}]
+
+        clips = [
+            {'start_time': parse_duration(c.get('time')), 'title': c.get('text')}
+            for c in episode.get('clips') or []]
+
+        return {
+            'id': display_id,
+            'title': traverse_obj(program, ('episodes', 0, 'title'), 'title'),
+            'description': traverse_obj(
+                program, ('episodes', 0, 'description'), 'description', 'short_description',
+                expected_type=lambda x: x or None),
+            'subtitles': subs,
+            'thumbnail': episode.get('image', '').replace('$$IMAGESIZE$$', '1960') or None,
+            'timestamp': unified_timestamp(episode.get('firstrun')),
+            'formats': formats,
+            'age_limit': episode.get('rating'),
+            'chapters': clips,
+        }