]>
Raphaƫl G. Git Repositories - youtubedl/blob - youtube_dl/extractor/noco.py
   2 from __future__ 
import unicode_literals
 
   8 from .common 
import InfoExtractor
 
  12     compat_urllib_request
, 
  23 class NocoIE(InfoExtractor
): 
  24     _VALID_URL 
= r
'http://(?:(?:www\.)?noco\.tv/emission/|player\.noco\.tv/\?idvideo=)(?P<id>\d+)' 
  25     _LOGIN_URL 
= 'http://noco.tv/do.php' 
  26     _API_URL_TEMPLATE 
= 'https://api.noco.tv/1.1/%s?ts=%s&tk=%s' 
  27     _SUB_LANG_TEMPLATE 
= '&sub_lang=%s' 
  28     _NETRC_MACHINE 
= 'noco' 
  32             'url': 'http://noco.tv/emission/11538/nolife/ami-ami-idol-hello-france/', 
  33             'md5': '0a993f0058ddbcd902630b2047ef710e', 
  37                 'title': 'Ami Ami Idol - Hello! France', 
  38                 'description': 'md5:4eaab46ab68fa4197a317a88a53d3b86', 
  39                 'upload_date': '20140412', 
  44             'skip': 'Requires noco account', 
  47             'url': 'http://noco.tv/emission/12610/lbl42/the-guild/s01e01-wake-up-call', 
  48             'md5': 'c190f1f48e313c55838f1f412225934d', 
  52                 'title': 'The Guild #1 - Wake-Up Call', 
  53                 'timestamp': 1403863200, 
  54                 'upload_date': '20140627', 
  59             'skip': 'Requires noco account', 
  63     def _real_initialize(self
): 
  67         (username
, password
) = self
._get
_login
_info
() 
  77         request 
= compat_urllib_request
.Request(self
._LOGIN
_URL
, compat_urllib_parse
.urlencode(login_form
)) 
  78         request
.add_header('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8') 
  80         login 
= self
._download
_json
(request
, None, 'Logging in as %s' % username
) 
  83             raise ExtractorError('Unable to login: %s' % clean_html(login
['erreur']), expected
=True) 
  85     def _call_api(self
, path
, video_id
, note
, sub_lang
=None): 
  86         ts 
= compat_str(int(time
.time() * 1000)) 
  87         tk 
= hashlib
.md5((hashlib
.md5(ts
.encode('ascii')).hexdigest() + '#8S?uCraTedap6a').encode('ascii')).hexdigest() 
  88         url 
= self
._API
_URL
_TEMPLATE 
% (path
, ts
, tk
) 
  90             url 
+= self
._SUB
_LANG
_TEMPLATE 
% sub_lang
 
  92         resp 
= self
._download
_json
(url
, video_id
, note
) 
  94         if isinstance(resp
, dict) and resp
.get('error'): 
  95             self
._raise
_error
(resp
['error'], resp
['description']) 
  99     def _raise_error(self
, error
, description
): 
 100         raise ExtractorError( 
 101             '%s returned error: %s - %s' % (self
.IE_NAME
, error
, description
), 
 104     def _real_extract(self
, url
): 
 105         mobj 
= re
.match(self
._VALID
_URL
, url
) 
 106         video_id 
= mobj
.group('id') 
 108         medias 
= self
._call
_api
( 
 109             'shows/%s/medias' % video_id
, 
 110             video_id
, 'Downloading video JSON') 
 112         show 
= self
._call
_api
( 
 113             'shows/by_id/%s' % video_id
, 
 114             video_id
, 'Downloading show JSON')[0] 
 116         options 
= self
._call
_api
( 
 117             'users/init', video_id
, 
 118             'Downloading user options JSON')['options'] 
 119         audio_lang_pref 
= options
.get('audio_language') or options
.get('language', 'fr') 
 121         if audio_lang_pref 
== 'original': 
 122             audio_lang_pref 
= show
['original_lang'] 
 124             audio_lang_pref 
= list(medias
.keys())[0] 
 125         elif audio_lang_pref 
not in medias
: 
 126             audio_lang_pref 
= 'fr' 
 128         qualities 
= self
._call
_api
( 
 130             video_id
, 'Downloading qualities JSON') 
 134         for audio_lang
, audio_lang_dict 
in medias
.items(): 
 135             preference 
= 1 if audio_lang 
== audio_lang_pref 
else 0 
 136             for sub_lang
, lang_dict 
in audio_lang_dict
['video_list'].items(): 
 137                 for format_id
, fmt 
in lang_dict
['quality_list'].items(): 
 138                     format_id_extended 
= 'audio-%s_sub-%s_%s' % (audio_lang
, sub_lang
, format_id
) 
 140                     video 
= self
._call
_api
( 
 141                         'shows/%s/video/%s/%s' % (video_id
, format_id
.lower(), audio_lang
), 
 142                         video_id
, 'Downloading %s video JSON' % format_id_extended
, 
 143                         sub_lang 
if sub_lang 
!= 'none' else None) 
 145                     file_url 
= video
['file'] 
 149                     if file_url 
in ['forbidden', 'not found']: 
 150                         popmessage 
= video
['popmessage'] 
 151                         self
._raise
_error
(popmessage
['title'], popmessage
['message']) 
 155                         'format_id': format_id_extended
, 
 156                         'width': int_or_none(fmt
.get('res_width')), 
 157                         'height': int_or_none(fmt
.get('res_lines')), 
 158                         'abr': int_or_none(fmt
.get('audiobitrate')), 
 159                         'vbr': int_or_none(fmt
.get('videobitrate')), 
 160                         'filesize': int_or_none(fmt
.get('filesize')), 
 161                         'format_note': qualities
[format_id
].get('quality_name'), 
 162                         'quality': qualities
[format_id
].get('priority'), 
 163                         'preference': preference
, 
 166         self
._sort
_formats
(formats
) 
 168         timestamp 
= parse_iso8601(show
.get('online_date_start_utc'), ' ') 
 169         uploader 
= show
.get('partner_name') 
 170         uploader_id 
= show
.get('partner_key') 
 171         duration 
= float_or_none(show
.get('duration_ms'), 1000) 
 174         for thumbnail_key
, thumbnail_url 
in show
.items(): 
 175             m 
= re
.search(r
'^screenshot_(?P<width>\d+)x(?P<height>\d+)$', thumbnail_key
) 
 179                 'url': thumbnail_url
, 
 180                 'width': int(m
.group('width')), 
 181                 'height': int(m
.group('height')), 
 184         episode 
= show
.get('show_TT') or show
.get('show_OT') 
 185         family 
= show
.get('family_TT') or show
.get('family_OT') 
 186         episode_number 
= show
.get('episode_number') 
 192             title 
+= ' #' + compat_str(episode_number
) 
 194             title 
+= ' - ' + episode
 
 196         description 
= show
.get('show_resume') or show
.get('family_resume') 
 201             'description': description
, 
 202             'thumbnails': thumbnails
, 
 203             'timestamp': timestamp
, 
 204             'uploader': uploader
, 
 205             'uploader_id': uploader_id
, 
 206             'duration': duration
,