2 from __future__ import unicode_literals
6 from .common import InfoExtractor
8 compat_urllib_parse_urlencode,
18 class CamdemyIE(InfoExtractor):
19 _VALID_URL = r'https?://(?:www\.)?camdemy\.com/media/(?P<id>\d+)'
22 'url': 'http://www.camdemy.com/media/5181/',
23 'md5': '5a5562b6a98b37873119102e052e311b',
27 'title': 'Ch1-1 Introduction, Signals (02-23-2012)',
28 'thumbnail': 're:^https?://.*\.jpg$',
29 'creator': 'ss11spring',
30 'upload_date': '20130114',
34 # With non-empty description
35 # webpage returns "No permission or not login"
36 'url': 'http://www.camdemy.com/media/13885',
37 'md5': '4576a3bb2581f86c61044822adbd1249',
41 'title': 'EverCam + Camdemy QuickStart',
42 'thumbnail': 're:^https?://.*\.jpg$',
43 'description': 'md5:2a9f989c2b153a2342acee579c6e7db6',
47 # External source (YouTube)
48 'url': 'http://www.camdemy.com/media/14842',
52 'title': 'Excel 2013 Tutorial - How to add Password Protection',
53 'description': 'Excel 2013 Tutorial for Beginners - How to add Password Protection',
54 'upload_date': '20130211',
55 'uploader': 'Hun Kim',
56 'uploader_id': 'hunkimtutorials',
59 'skip_download': True,
63 def _real_extract(self, url):
64 video_id = self._match_id(url)
66 webpage = self._download_webpage(url, video_id)
68 src_from = self._html_search_regex(
69 r"class=['\"]srcFrom['\"][^>]*>Sources?(?:\s+from)?\s*:\s*<a[^>]+(?:href|title)=(['\"])(?P<url>(?:(?!\1).)+)\1",
70 webpage, 'external source', default=None, group='url')
72 return self.url_result(src_from)
74 oembed_obj = self._download_json(
75 'http://www.camdemy.com/oembed/?format=json&url=' + url, video_id)
77 thumb_url = oembed_obj['thumbnail_url']
78 video_folder = compat_urlparse.urljoin(thumb_url, 'video/')
79 file_list_doc = self._download_xml(
80 compat_urlparse.urljoin(video_folder, 'fileList.xml'),
81 video_id, 'Downloading filelist XML')
82 file_name = file_list_doc.find('./video/item/fileName').text
83 video_url = compat_urlparse.urljoin(video_folder, file_name)
85 # Some URLs return "No permission or not login" in a webpage despite being
86 # freely available via oembed JSON URL (e.g. http://www.camdemy.com/media/13885)
87 upload_date = unified_strdate(self._search_regex(
88 r'>published on ([^<]+)<', webpage,
89 'upload date', default=None))
90 view_count = str_to_int(self._search_regex(
91 r'role=["\']viewCnt["\'][^>]*>([\d,.]+) views',
92 webpage, 'view count', default=None))
93 description = self._html_search_meta(
94 'description', webpage, default=None) or clean_html(
95 oembed_obj.get('description'))
100 'title': oembed_obj['title'],
101 'thumbnail': thumb_url,
102 'description': description,
103 'creator': oembed_obj['author_name'],
104 'duration': oembed_obj['duration'],
105 'upload_date': upload_date,
106 'view_count': view_count,
110 class CamdemyFolderIE(InfoExtractor):
111 _VALID_URL = r'https?://www.camdemy.com/folder/(?P<id>\d+)'
113 # links with trailing slash
114 'url': 'http://www.camdemy.com/folder/450',
117 'title': '信號與系統 2012 & 2011 (Signals and Systems)',
119 'playlist_mincount': 145
121 # links without trailing slash
123 'url': 'http://www.camdemy.com/folder/853',
126 'title': '科學計算 - 使用 Matlab'
128 'playlist_mincount': 20
130 # with displayMode parameter. For testing the codes to add parameters
131 'url': 'http://www.camdemy.com/folder/853/?displayMode=defaultOrderByOrg',
134 'title': '科學計算 - 使用 Matlab'
136 'playlist_mincount': 20
139 def _real_extract(self, url):
140 folder_id = self._match_id(url)
142 # Add displayMode=list so that all links are displayed in a single page
143 parsed_url = list(compat_urlparse.urlparse(url))
144 query = dict(compat_urlparse.parse_qsl(parsed_url[4]))
145 query.update({'displayMode': 'list'})
146 parsed_url[4] = compat_urllib_parse_urlencode(query)
147 final_url = compat_urlparse.urlunparse(parsed_url)
149 page = self._download_webpage(final_url, folder_id)
150 matches = re.findall(r"href='(/media/\d+/?)'", page)
152 entries = [self.url_result('http://www.camdemy.com' + media_path)
153 for media_path in matches]
155 folder_title = self._html_search_meta('keywords', page)
157 return self.playlist_result(entries, folder_id, folder_title)