1 from __future__ 
import unicode_literals
 
   5 from .mtv 
import MTVServicesInfoExtractor
 
   8     compat_urllib_parse_urlencode
, 
  17 class ComedyCentralIE(MTVServicesInfoExtractor
): 
  18     _VALID_URL 
= r
'''(?x)https?://(?:www\.)?cc\.com/ 
  19         (video-clips|episodes|cc-studios|video-collections|full-episodes|shows) 
  21     _FEED_URL 
= 'http://comedycentral.com/feeds/mrss/' 
  24         'url': 'http://www.cc.com/video-clips/kllhuv/stand-up-greg-fitzsimmons--uncensored---too-good-of-a-mother', 
  25         'md5': 'c4f48e9eda1b16dd10add0744344b6d8', 
  27             'id': 'cef0cbb3-e776-4bc9-b62e-8016deccb354', 
  29             'title': 'CC:Stand-Up|Greg Fitzsimmons: Life on Stage|Uncensored - Too Good of a Mother', 
  30             'description': 'After a certain point, breastfeeding becomes c**kblocking.', 
  33         'url': 'http://www.cc.com/shows/the-daily-show-with-trevor-noah/interviews/6yx39d/exclusive-rand-paul-extended-interview', 
  34         'only_matching': True, 
  38 class ComedyCentralShowsIE(MTVServicesInfoExtractor
): 
  39     IE_DESC 
= 'The Daily Show / The Colbert Report' 
  40     # urls can be abbreviations like :thedailyshow 
  41     # urls for episodes like: 
  42     # or urls for clips like: http://www.thedailyshow.com/watch/mon-december-10-2012/any-given-gun-day 
  43     #                     or: http://www.colbertnation.com/the-colbert-report-videos/421667/november-29-2012/moon-shattering-news 
  44     #                     or: http://www.colbertnation.com/the-colbert-report-collections/422008/festival-of-lights/79524 
  45     _VALID_URL 
= r
'''(?x)^(:(?P<shortname>tds|thedailyshow) 
  47                           (?P<showname>thedailyshow|thecolbertreport|tosh)\.(?:cc\.)?com/ 
  48                          ((?:full-)?episodes/(?:[0-9a-z]{6}/)?(?P<episode>.*)| 
  50                               (?:(?:guests/[^/]+|videos|video-(?:clips|playlists)|special-editions|news-team/[^/]+)/[^/]+/(?P<videotitle>[^/?#]+)) 
  51                               |(the-colbert-report-(videos|collections)/(?P<clipID>[0-9]+)/[^/]*/(?P<cntitle>.*?)) 
  52                               |(watch/(?P<date>[^/]*)/(?P<tdstitle>.*)) 
  55                               extended-interviews/(?P<interID>[0-9a-z]+)/ 
  56                               (?:playlist_tds_extended_)?(?P<interview_title>[^/?#]*?) 
  57                               (?:/[^/?#]?|[?#]|$)))) 
  60         'url': 'http://thedailyshow.cc.com/watch/thu-december-13-2012/kristen-stewart', 
  61         'md5': '4e2f5cb088a83cd8cdb7756132f9739d', 
  63             'id': 'ab9ab3e7-5a98-4dbe-8b21-551dc0523d55', 
  65             'upload_date': '20121213', 
  66             'description': 'Kristen Stewart learns to let loose in "On the Road."', 
  67             'uploader': 'thedailyshow', 
  68             'title': 'thedailyshow kristen-stewart part 1', 
  71         'url': 'http://thedailyshow.cc.com/extended-interviews/b6364d/sarah-chayes-extended-interview', 
  73             'id': 'sarah-chayes-extended-interview', 
  74             'description': 'Carnegie Endowment Senior Associate Sarah Chayes discusses how corrupt institutions function throughout the world in her book "Thieves of State: Why Corruption Threatens Global Security."', 
  75             'title': 'thedailyshow Sarah Chayes Extended Interview', 
  80                     'id': '0baad492-cbec-4ec1-9e50-ad91c291127f', 
  82                     'upload_date': '20150129', 
  83                     'description': 'Carnegie Endowment Senior Associate Sarah Chayes discusses how corrupt institutions function throughout the world in her book "Thieves of State: Why Corruption Threatens Global Security."', 
  84                     'uploader': 'thedailyshow', 
  85                     'title': 'thedailyshow sarah-chayes-extended-interview part 1', 
  90                     'id': '1e4fb91b-8ce7-4277-bd7c-98c9f1bbd283', 
  92                     'upload_date': '20150129', 
  93                     'description': 'Carnegie Endowment Senior Associate Sarah Chayes discusses how corrupt institutions function throughout the world in her book "Thieves of State: Why Corruption Threatens Global Security."', 
  94                     'uploader': 'thedailyshow', 
  95                     'title': 'thedailyshow sarah-chayes-extended-interview part 2', 
 100             'skip_download': True, 
 103         'url': 'http://thedailyshow.cc.com/extended-interviews/xm3fnq/andrew-napolitano-extended-interview', 
 104         'only_matching': True, 
 106         'url': 'http://thecolbertreport.cc.com/videos/29w6fx/-realhumanpraise-for-fox-news', 
 107         'only_matching': True, 
 109         'url': 'http://thecolbertreport.cc.com/videos/gh6urb/neil-degrasse-tyson-pt--1?xrs=eml_col_031114', 
 110         'only_matching': True, 
 112         'url': 'http://thedailyshow.cc.com/guests/michael-lewis/3efna8/exclusive---michael-lewis-extended-interview-pt--3', 
 113         'only_matching': True, 
 115         'url': 'http://thedailyshow.cc.com/episodes/sy7yv0/april-8--2014---denis-leary', 
 116         'only_matching': True, 
 118         'url': 'http://thecolbertreport.cc.com/episodes/8ase07/april-8--2014---jane-goodall', 
 119         'only_matching': True, 
 121         'url': 'http://thedailyshow.cc.com/video-playlists/npde3s/the-daily-show-19088-highlights', 
 122         'only_matching': True, 
 124         'url': 'http://thedailyshow.cc.com/video-playlists/t6d9sg/the-daily-show-20038-highlights/be3cwo', 
 125         'only_matching': True, 
 127         'url': 'http://thedailyshow.cc.com/special-editions/2l8fdb/special-edition---a-look-back-at-food', 
 128         'only_matching': True, 
 130         'url': 'http://thedailyshow.cc.com/news-team/michael-che/7wnfel/we-need-to-talk-about-israel', 
 131         'only_matching': True, 
 133         'url': 'http://tosh.cc.com/video-clips/68g93d/twitter-users-share-summer-plans', 
 134         'only_matching': True, 
 137     _available_formats 
= ['3500', '2200', '1700', '1200', '750', '400'] 
 139     _video_extensions 
= { 
 147     _video_dimensions 
= { 
 156     def _real_extract(self
, url
): 
 157         mobj 
= re
.match(self
._VALID
_URL
, url
) 
 159         if mobj
.group('shortname'): 
 160             return self
.url_result('http://www.cc.com/shows/the-daily-show-with-trevor-noah/full-episodes') 
 162         if mobj
.group('clip'): 
 163             if mobj
.group('videotitle'): 
 164                 epTitle 
= mobj
.group('videotitle') 
 165             elif mobj
.group('showname') == 'thedailyshow': 
 166                 epTitle 
= mobj
.group('tdstitle') 
 168                 epTitle 
= mobj
.group('cntitle') 
 170         elif mobj
.group('interview'): 
 171             epTitle 
= mobj
.group('interview_title') 
 174             dlNewest 
= not mobj
.group('episode') 
 176                 epTitle 
= mobj
.group('showname') 
 178                 epTitle 
= mobj
.group('episode') 
 179         show_name 
= mobj
.group('showname') 
 181         webpage
, htmlHandle 
= self
._download
_webpage
_handle
(url
, epTitle
) 
 183             url 
= htmlHandle
.geturl() 
 184             mobj 
= re
.match(self
._VALID
_URL
, url
, re
.VERBOSE
) 
 186                 raise ExtractorError('Invalid redirected URL: ' + url
) 
 187             if mobj
.group('episode') == '': 
 188                 raise ExtractorError('Redirected URL is still not specific: ' + url
) 
 189             epTitle 
= (mobj
.group('episode') or mobj
.group('videotitle')).rpartition('/')[-1] 
 191         mMovieParams 
= re
.findall('(?:<param name="movie" value="|var url = ")(http://media.mtvnservices.com/([^"]*(?:episode|video).*?:.*?))"', webpage
) 
 192         if len(mMovieParams
) == 0: 
 193             # The Colbert Report embeds the information in a without 
 194             # a URL prefix; so extract the alternate reference 
 195             # and then add the URL prefix manually. 
 197             altMovieParams 
= re
.findall('data-mgid="([^"]*(?:episode|video|playlist).*?:.*?)"', webpage
) 
 198             if len(altMovieParams
) == 0: 
 199                 raise ExtractorError('unable to find Flash URL in webpage ' + url
) 
 201                 mMovieParams 
= [('http://media.mtvnservices.com/' + altMovieParams
[0], altMovieParams
[0])] 
 203         uri 
= mMovieParams
[0][1] 
 204         # Correct cc.com in uri 
 205         uri 
= re
.sub(r
'(episode:[^.]+)(\.cc)?\.com', r
'\1.com', uri
) 
 207         index_url 
= 'http://%s.cc.com/feeds/mrss?%s' % (show_name
, compat_urllib_parse_urlencode({'uri': uri
})) 
 208         idoc 
= self
._download
_xml
( 
 210             'Downloading show index', 'Unable to download episode index') 
 212         title 
= idoc
.find('./channel/title').text
 
 213         description 
= idoc
.find('./channel/description').text
 
 216         item_els 
= idoc
.findall('.//item') 
 217         for part_num
, itemEl 
in enumerate(item_els
): 
 218             upload_date 
= unified_strdate(itemEl
.findall('./pubDate')[0].text
) 
 219             thumbnail 
= itemEl
.find('.//{http://search.yahoo.com/mrss/}thumbnail').attrib
.get('url') 
 221             content 
= itemEl
.find('.//{http://search.yahoo.com/mrss/}content') 
 222             duration 
= float_or_none(content
.attrib
.get('duration')) 
 223             mediagen_url 
= content
.attrib
['url'] 
 224             guid 
= itemEl
.find('./guid').text
.rpartition(':')[-1] 
 226             cdoc 
= self
._download
_xml
( 
 227                 mediagen_url
, epTitle
, 
 228                 'Downloading configuration for segment %d / %d' % (part_num 
+ 1, len(item_els
))) 
 231             for rendition 
in cdoc
.findall('.//rendition'): 
 232                 finfo 
= (rendition
.attrib
['bitrate'], rendition
.findall('./src')[0].text
) 
 236             for format
, rtmp_video_url 
in turls
: 
 237                 w
, h 
= self
._video
_dimensions
.get(format
, (None, None)) 
 239                     'format_id': 'vhttp-%s' % format
, 
 240                     'url': self
._transform
_rtmp
_url
(rtmp_video_url
), 
 241                     'ext': self
._video
_extensions
.get(format
, 'mp4'), 
 246                     'format_id': 'rtmp-%s' % format
, 
 247                     'url': rtmp_video_url
.replace('viacomccstrm', 'viacommtvstrm'), 
 248                     'ext': self
._video
_extensions
.get(format
, 'mp4'), 
 252                 self
._sort
_formats
(formats
) 
 254             subtitles 
= self
._extract
_subtitles
(cdoc
, guid
) 
 256             virtual_id 
= show_name 
+ ' ' + epTitle 
+ ' part ' + compat_str(part_num 
+ 1) 
 261                 'uploader': show_name
, 
 262                 'upload_date': upload_date
, 
 263                 'duration': duration
, 
 264                 'thumbnail': thumbnail
, 
 265                 'description': description
, 
 266                 'subtitles': subtitles
, 
 273             'title': show_name 
+ ' ' + title
, 
 274             'description': description
,