You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

82 lines
3.0 KiB

  1. # coding: utf-8
  2. from __future__ import unicode_literals
  3. import json
  4. from .radiocanada import RadioCanadaIE
  5. from ..compat import compat_HTTPError
  6. from ..utils import (
  7. ExtractorError,
  8. int_or_none,
  9. merge_dicts,
  10. )
  11. class TouTvIE(RadioCanadaIE):
  12. _NETRC_MACHINE = 'toutv'
  13. IE_NAME = 'tou.tv'
  14. _VALID_URL = r'https?://ici\.tou\.tv/(?P<id>[a-zA-Z0-9_-]+(?:/S[0-9]+[EC][0-9]+)?)'
  15. _TESTS = [{
  16. 'url': 'http://ici.tou.tv/garfield-tout-court/S2015E17',
  17. 'info_dict': {
  18. 'id': '122017',
  19. 'ext': 'mp4',
  20. 'title': 'Saison 2015 Épisode 17',
  21. 'description': 'La photo de famille 2',
  22. 'upload_date': '20100717',
  23. },
  24. 'params': {
  25. # m3u8 download
  26. 'skip_download': True,
  27. },
  28. 'skip': '404 Not Found',
  29. }, {
  30. 'url': 'http://ici.tou.tv/hackers',
  31. 'only_matching': True,
  32. }, {
  33. 'url': 'https://ici.tou.tv/l-age-adulte/S01C501',
  34. 'only_matching': True,
  35. }]
  36. _CLIENT_KEY = '4dd36440-09d5-4468-8923-b6d91174ad36'
  37. def _real_initialize(self):
  38. email, password = self._get_login_info()
  39. if email is None:
  40. return
  41. try:
  42. self._access_token = self._download_json(
  43. 'https://services.radio-canada.ca/toutv/profiling/accounts/login',
  44. None, 'Logging in', data=json.dumps({
  45. 'ClientId': self._CLIENT_KEY,
  46. 'ClientSecret': '34026772-244b-49b6-8b06-317b30ac9a20',
  47. 'Email': email,
  48. 'Password': password,
  49. 'Scope': 'id.write media-validation.read',
  50. }).encode(), headers={
  51. 'Authorization': 'client-key ' + self._CLIENT_KEY,
  52. 'Content-Type': 'application/json;charset=utf-8',
  53. })['access_token']
  54. except ExtractorError as e:
  55. if isinstance(e.cause, compat_HTTPError) and e.cause.code == 401:
  56. error = self._parse_json(e.cause.read().decode(), None)['Message']
  57. raise ExtractorError(error, expected=True)
  58. raise
  59. self._claims = self._call_api('validation/v2/getClaims')['claims']
  60. def _real_extract(self, url):
  61. path = self._match_id(url)
  62. metadata = self._download_json('http://ici.tou.tv/presentation/%s' % path, path)
  63. # IsDrm does not necessarily mean the video is DRM protected (see
  64. # https://github.com/ytdl-org/youtube-dl/issues/13994).
  65. if metadata.get('IsDrm'):
  66. self.report_warning('This video is probably DRM protected.', path)
  67. video_id = metadata['IdMedia']
  68. details = metadata['Details']
  69. return merge_dicts({
  70. 'id': video_id,
  71. 'title': details.get('OriginalTitle'),
  72. 'thumbnail': details.get('ImageUrl'),
  73. 'duration': int_or_none(details.get('LengthInSeconds')),
  74. }, self._extract_info(metadata.get('AppCode', 'toutv'), video_id))