| 
									
										
										
										
											2014-01-07 09:35:34 +01:00
										 |  |  | from __future__ import unicode_literals | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import re | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | from .common import InfoExtractor | 
					
						
							|  |  |  | from ..utils import ( | 
					
						
							|  |  |  |     unified_strdate, | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class KhanAcademyIE(InfoExtractor): | 
					
						
							| 
									
										
										
										
											2014-09-09 22:09:32 +07:00
										 |  |  |     _VALID_URL = r'^https?://(?:(?:www|api)\.)?khanacademy\.org/(?P<key>[^/]+)/(?:[^/]+/){,2}(?P<id>[^?#/]+)(?:$|[?#])' | 
					
						
							| 
									
										
										
										
											2014-01-07 09:35:34 +01:00
										 |  |  |     IE_NAME = 'KhanAcademy' | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-28 00:58:24 +02:00
										 |  |  |     _TESTS = [{ | 
					
						
							| 
									
										
										
										
											2014-01-07 09:35:34 +01:00
										 |  |  |         'url': 'http://www.khanacademy.org/video/one-time-pad', | 
					
						
							|  |  |  |         'md5': '7021db7f2d47d4fff89b13177cb1e8f4', | 
					
						
							|  |  |  |         'info_dict': { | 
					
						
							| 
									
										
										
										
											2014-08-28 00:58:24 +02:00
										 |  |  |             'id': 'one-time-pad', | 
					
						
							|  |  |  |             'ext': 'mp4', | 
					
						
							| 
									
										
										
										
											2014-01-07 09:35:34 +01:00
										 |  |  |             'title': 'The one-time pad', | 
					
						
							|  |  |  |             'description': 'The perfect cipher', | 
					
						
							|  |  |  |             'duration': 176, | 
					
						
							|  |  |  |             'uploader': 'Brit Cruise', | 
					
						
							| 
									
										
										
										
											2015-01-05 12:28:35 +01:00
										 |  |  |             'uploader_id': 'khanacademy', | 
					
						
							| 
									
										
										
										
											2014-01-07 09:35:34 +01:00
										 |  |  |             'upload_date': '20120411', | 
					
						
							| 
									
										
										
										
											2015-01-05 12:28:35 +01:00
										 |  |  |         }, | 
					
						
							|  |  |  |         'add_ie': ['Youtube'], | 
					
						
							| 
									
										
										
										
											2014-08-28 00:58:24 +02:00
										 |  |  |     }, { | 
					
						
							|  |  |  |         'url': 'https://www.khanacademy.org/math/applied-math/cryptography', | 
					
						
							|  |  |  |         'info_dict': { | 
					
						
							|  |  |  |             'id': 'cryptography', | 
					
						
							|  |  |  |             'title': 'Journey into cryptography', | 
					
						
							|  |  |  |             'description': 'How have humans protected their secret messages through history? What has changed today?', | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |         'playlist_mincount': 3, | 
					
						
							|  |  |  |     }] | 
					
						
							| 
									
										
										
										
											2014-01-07 09:35:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def _real_extract(self, url): | 
					
						
							|  |  |  |         m = re.match(self._VALID_URL, url) | 
					
						
							|  |  |  |         video_id = m.group('id') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if m.group('key') == 'video': | 
					
						
							|  |  |  |             data = self._download_json( | 
					
						
							|  |  |  |                 'http://api.khanacademy.org/api/v1/videos/' + video_id, | 
					
						
							|  |  |  |                 video_id, 'Downloading video info') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             upload_date = unified_strdate(data['date_added']) | 
					
						
							|  |  |  |             uploader = ', '.join(data['author_names']) | 
					
						
							|  |  |  |             return { | 
					
						
							|  |  |  |                 '_type': 'url_transparent', | 
					
						
							|  |  |  |                 'url': data['url'], | 
					
						
							|  |  |  |                 'id': video_id, | 
					
						
							|  |  |  |                 'title': data['title'], | 
					
						
							|  |  |  |                 'thumbnail': data['image_url'], | 
					
						
							|  |  |  |                 'duration': data['duration'], | 
					
						
							|  |  |  |                 'description': data['description'], | 
					
						
							|  |  |  |                 'uploader': uploader, | 
					
						
							|  |  |  |                 'upload_date': upload_date, | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             # topic | 
					
						
							|  |  |  |             data = self._download_json( | 
					
						
							|  |  |  |                 'http://api.khanacademy.org/api/v1/topic/' + video_id, | 
					
						
							|  |  |  |                 video_id, 'Downloading topic info') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             entries = [ | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     '_type': 'url', | 
					
						
							|  |  |  |                     'url': c['url'], | 
					
						
							|  |  |  |                     'id': c['id'], | 
					
						
							|  |  |  |                     'title': c['title'], | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 for c in data['children'] if c['kind'] in ('Video', 'Topic')] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             return { | 
					
						
							|  |  |  |                 '_type': 'playlist', | 
					
						
							|  |  |  |                 'id': video_id, | 
					
						
							|  |  |  |                 'title': data['title'], | 
					
						
							|  |  |  |                 'description': data['description'], | 
					
						
							|  |  |  |                 'entries': entries, | 
					
						
							|  |  |  |             } |