[ruutu] Improve, make more robust and fix python 2.6 support

pull/2/head
Sergey M․ 10 years ago
parent 717b0239fd
commit 9414338a48

@ -3,88 +3,117 @@ from __future__ import unicode_literals
from .common import InfoExtractor from .common import InfoExtractor
from ..compat import compat_urllib_parse_urlparse from ..compat import compat_urllib_parse_urlparse
import re from ..utils import (
determine_ext,
int_or_none,
xpath_text,
)
class RuutuIE(InfoExtractor): class RuutuIE(InfoExtractor):
_VALID_URL = r'http://(www\.)?ruutu\.fi/ohjelmat/(?:[^/]+/)?(?P<id>.*)$' _VALID_URL = r'http://(?:www\.)?ruutu\.fi/ohjelmat/(?:[^/?#]+/)*(?P<id>[^/?#]+)'
_TESTS = [ _TESTS = [
{ {
'url': 'http://www.ruutu.fi/ohjelmat/oletko-aina-halunnut-tietaa-mita-tapahtuu-vain-hetki-ennen-lahetysta-nyt-se-selvisi', 'url': 'http://www.ruutu.fi/ohjelmat/oletko-aina-halunnut-tietaa-mita-tapahtuu-vain-hetki-ennen-lahetysta-nyt-se-selvisi',
'md5': 'ab2093f39be1ca8581963451b3c0234f', 'md5': 'ab2093f39be1ca8581963451b3c0234f',
'info_dict': { 'info_dict': {
'id': 'oletko-aina-halunnut-tietaa-mita-tapahtuu-vain-hetki-ennen-lahetysta-nyt-se-selvisi', 'id': '2058907',
'display_id': 'oletko-aina-halunnut-tietaa-mita-tapahtuu-vain-hetki-ennen-lahetysta-nyt-se-selvisi',
'ext': 'mp4', 'ext': 'mp4',
'title': 'Oletko aina halunnut tietää mitä tapahtuu vain hetki ennen lähetystä? - Nyt se selvisi!', 'title': 'Oletko aina halunnut tietää mitä tapahtuu vain hetki ennen lähetystä? - Nyt se selvisi!',
'description': 'Toinen toistaan huikeampia ohjelmaideoita ja täysin päätöntä sekoilua? No sitä juuri nimenomaan. Metro Helsingin Iltapäivän vieraaksi saapui Tuomas Kauhanen ja he Petra Kalliomaan kanssa keskustelivat hieman ennen lähetyksen alkua, mutta kamerat olivatkin jo päällä.', 'description': 'md5:cfc6ccf0e57a814360df464a91ff67d6',
'thumbnail': 're:^https?://.*\.jpg$',
'duration': 114,
'age_limit': 0,
}, },
'params': {
'format': 'http-1000',
}
}, },
{ {
'url': 'http://www.ruutu.fi/ohjelmat/superpesis/superpesis-katso-koko-kausi-ruudussa', 'url': 'http://www.ruutu.fi/ohjelmat/superpesis/superpesis-katso-koko-kausi-ruudussa',
'md5': '065a10ae4d5b8cfd9d0c3d332465e3d9', 'md5': '065a10ae4d5b8cfd9d0c3d332465e3d9',
'info_dict': { 'info_dict': {
'id': 'superpesis-katso-koko-kausi-ruudussa', 'id': '2057306',
'display_id': 'superpesis-katso-koko-kausi-ruudussa',
'ext': 'mp4', 'ext': 'mp4',
'title': 'Superpesis: katso koko kausi Ruudussa', 'title': 'Superpesis: katso koko kausi Ruudussa',
'description': 'Huippujännittävän Superpesiksen suoria ottelulähetyksiä seurataan Ruudussa kauden alusta viimeiseen finaaliin asti. Katso lisätiedot osoitteesta ruutu.fi/superpesis.', 'description': 'md5:44c44a99fdbe5b380ab74ebd75f0af77',
'thumbnail': 're:^https?://.*\.jpg$',
'duration': 40,
'age_limit': 0,
}, },
'params': {
'format': 'http-1000',
}
}, },
] ]
def _real_extract(self, url): def _real_extract(self, url):
mobj = re.match(self._VALID_URL, url) display_id = self._match_id(url)
video_id = mobj.group('id') webpage = self._download_webpage(url, display_id)
webpage = self._download_webpage(url, video_id)
media_id = self._html_search_regex(r'data-media-id="(\d+)"', webpage, 'media_id') video_id = self._search_regex(
media_json = self._parse_json(self._search_regex(r'jQuery.extend\([^,]+, (.*)\);', webpage, 'media_data'), video_id) r'data-media-id="(\d+)"', webpage, 'media id')
xml_url = media_json['ruutuplayer']['xmlUrl'].replace('{ID}', media_id)
media_xml = self._download_xml(xml_url, media_id) video_xml_url = None
media_data = self._search_regex(
r'jQuery\.extend\([^,]+,\s*(.+?)\);', webpage,
'media data', default=None)
if media_data:
media_json = self._parse_json(media_data, display_id, fatal=False)
if media_json:
xml_url = media_json.get('ruutuplayer', {}).get('xmlUrl')
if xml_url:
video_xml_url = xml_url.replace('{ID}', video_id)
if not video_xml_url:
video_xml_url = 'http://gatling.ruutu.fi/media-xml-cache?id=%s' % video_id
video_xml = self._download_xml(video_xml_url, video_id)
formats = [] formats = []
parsed_urls = [] processed_urls = []
for fmt in media_xml.findall('.//Clip//'):
url = fmt.text def extract_formats(node):
if not fmt.tag.endswith('File') or url in parsed_urls or \ for child in node:
'NOT_USED' in url: if child.tag.endswith('Files'):
continue extract_formats(child)
elif child.tag.endswith('File'):
video_url = child.text
if not video_url or video_url in processed_urls or 'NOT_USED' in video_url:
return
processed_urls.append(video_url)
ext = determine_ext(video_url)
if ext == 'm3u8':
formats.extend(self._extract_m3u8_formats(
video_url, video_id, 'mp4', m3u8_id='hls'))
elif ext == 'f4m':
formats.extend(self._extract_f4m_formats(
video_url, video_id, f4m_id='hds'))
else:
proto = compat_urllib_parse_urlparse(video_url).scheme
if not child.tag.startswith('HTTP') and proto != 'rtmp':
continue
preference = -1 if proto == 'rtmp' else 1
label = child.get('label')
tbr = int_or_none(child.get('bitrate'))
width, height = [int_or_none(x) for x in child.get('resolution', '').split('x')]
formats.append({
'format_id': '%s-%s' % (proto, label if label else tbr),
'url': video_url,
'width': width,
'height': height,
'tbr': tbr,
'preference': preference,
})
if url.endswith('m3u8'): extract_formats(video_xml.find('./Clip'))
formats.extend(self._extract_m3u8_formats(url, media_id, m3u8_id='hls'))
parsed_urls.append(url)
elif url.endswith('f4m'):
formats.extend(self._extract_f4m_formats(url, media_id, f4m_id='hds'))
parsed_urls.append(url)
else:
if not fmt.tag.startswith('HTTP'):
continue
proto = compat_urllib_parse_urlparse(url).scheme
width_str, height_str = fmt.get('resolution').split('x')
tbr = int(fmt.get('bitrate', 0))
formats.append({
'format_id': '%s-%d' % (proto, tbr),
'url': url,
'width': int(width_str),
'height': int(height_str),
'tbr': tbr,
'ext': url.rsplit('.', 1)[-1],
'live': True,
'protocol': proto,
})
self._sort_formats(formats) self._sort_formats(formats)
return { return {
'id': video_id, 'id': video_id,
'display_id': display_id,
'title': self._og_search_title(webpage), 'title': self._og_search_title(webpage),
'formats': formats,
'description': self._og_search_description(webpage), 'description': self._og_search_description(webpage),
'thumbnail': self._og_search_thumbnail(webpage), 'thumbnail': self._og_search_thumbnail(webpage),
'duration': int(media_xml.find('.//Runtime').text), 'duration': int_or_none(xpath_text(video_xml, './/Runtime', 'duration')),
'age_limit': int(media_xml.find('.//AgeLimit').text), 'age_limit': int_or_none(xpath_text(video_xml, './/AgeLimit', 'age limit')),
'formats': formats,
} }

Loading…
Cancel
Save