| 
									
										
										
										
											2015-02-19 01:43:20 +01:00
										 |  |  | from __future__ import unicode_literals | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import re | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | from .common import InfoExtractor | 
					
						
							| 
									
										
										
										
											2015-05-31 04:05:26 +06:00
										 |  |  | from ..compat import compat_urlparse | 
					
						
							| 
									
										
										
										
											2015-02-19 01:43:20 +01:00
										 |  |  | from ..utils import ( | 
					
						
							|  |  |  |     int_or_none, | 
					
						
							|  |  |  |     js_to_json, | 
					
						
							|  |  |  |     mimetype2ext, | 
					
						
							| 
									
										
										
										
											2015-02-18 18:12:48 -08:00
										 |  |  |     ExtractorError, | 
					
						
							| 
									
										
										
										
											2015-02-19 01:43:20 +01:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-19 05:53:09 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-19 01:43:20 +01:00
										 |  |  | class ImgurIE(InfoExtractor): | 
					
						
							| 
									
										
										
										
											2016-10-30 17:01:48 +08:00
										 |  |  |     _VALID_URL = r'https?://(?:i\.)?imgur\.com/(?:(?:gallery|(?:topic|r)/[^/]+)/)?(?P<id>[a-zA-Z0-9]{6,})(?:[/?#&]+|\.[a-z]+)?$' | 
					
						
							| 
									
										
										
										
											2015-02-19 01:43:20 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     _TESTS = [{ | 
					
						
							|  |  |  |         'url': 'https://i.imgur.com/A61SaA1.gifv', | 
					
						
							|  |  |  |         'info_dict': { | 
					
						
							|  |  |  |             'id': 'A61SaA1', | 
					
						
							|  |  |  |             'ext': 'mp4', | 
					
						
							| 
									
										
										
										
											2015-02-20 02:52:03 +01:00
										 |  |  |             'title': 're:Imgur GIF$|MRW gifv is up and running without any bugs$', | 
					
						
							| 
									
										
										
										
											2015-12-21 01:50:07 +01:00
										 |  |  |             'description': 'Imgur: The most awesome images on the Internet.', | 
					
						
							| 
									
										
										
										
											2015-02-19 01:43:20 +01:00
										 |  |  |         }, | 
					
						
							| 
									
										
										
										
											2015-02-18 18:12:48 -08:00
										 |  |  |     }, { | 
					
						
							|  |  |  |         'url': 'https://imgur.com/A61SaA1', | 
					
						
							|  |  |  |         'info_dict': { | 
					
						
							|  |  |  |             'id': 'A61SaA1', | 
					
						
							|  |  |  |             'ext': 'mp4', | 
					
						
							| 
									
										
										
										
											2015-02-20 02:52:03 +01:00
										 |  |  |             'title': 're:Imgur GIF$|MRW gifv is up and running without any bugs$', | 
					
						
							| 
									
										
										
										
											2015-12-21 01:50:07 +01:00
										 |  |  |             'description': 'Imgur: The most awesome images on the Internet.', | 
					
						
							| 
									
										
										
										
											2015-02-18 18:12:48 -08:00
										 |  |  |         }, | 
					
						
							| 
									
										
										
										
											2015-12-21 01:50:07 +01:00
										 |  |  |     }, { | 
					
						
							|  |  |  |         'url': 'https://imgur.com/gallery/YcAQlkx', | 
					
						
							|  |  |  |         'info_dict': { | 
					
						
							|  |  |  |             'id': 'YcAQlkx', | 
					
						
							|  |  |  |             'ext': 'mp4', | 
					
						
							|  |  |  |             'title': 'Classic Steve Carell gif...cracks me up everytime....damn the repost downvotes....', | 
					
						
							|  |  |  |             'description': 'Imgur: The most awesome images on the Internet.' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2015-12-22 21:48:48 +06:00
										 |  |  |     }, { | 
					
						
							|  |  |  |         'url': 'http://imgur.com/topic/Funny/N8rOudd', | 
					
						
							|  |  |  |         'only_matching': True, | 
					
						
							| 
									
										
										
										
											2016-10-30 17:01:48 +08:00
										 |  |  |     }, { | 
					
						
							|  |  |  |         'url': 'http://imgur.com/r/aww/VQcQPhM', | 
					
						
							|  |  |  |         'only_matching': True, | 
					
						
							| 
									
										
										
										
											2015-02-19 01:43:20 +01:00
										 |  |  |     }] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def _real_extract(self, url): | 
					
						
							|  |  |  |         video_id = self._match_id(url) | 
					
						
							| 
									
										
										
										
											2015-05-31 04:05:26 +06:00
										 |  |  |         webpage = self._download_webpage( | 
					
						
							|  |  |  |             compat_urlparse.urljoin(url, video_id), video_id) | 
					
						
							| 
									
										
										
										
											2015-02-19 01:43:20 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-13 16:46:07 +07:00
										 |  |  |         width = int_or_none(self._og_search_property( | 
					
						
							|  |  |  |             'video:width', webpage, default=None)) | 
					
						
							|  |  |  |         height = int_or_none(self._og_search_property( | 
					
						
							|  |  |  |             'video:height', webpage, default=None)) | 
					
						
							| 
									
										
										
										
											2015-02-19 01:43:20 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-19 05:53:09 +01:00
										 |  |  |         video_elements = self._search_regex( | 
					
						
							| 
									
										
										
										
											2015-02-19 01:43:20 +01:00
										 |  |  |             r'(?s)<div class="video-elements">(.*?)</div>', | 
					
						
							| 
									
										
										
										
											2015-02-19 05:53:09 +01:00
										 |  |  |             webpage, 'video elements', default=None) | 
					
						
							| 
									
										
										
										
											2015-02-18 19:47:54 -08:00
										 |  |  |         if not video_elements: | 
					
						
							|  |  |  |             raise ExtractorError( | 
					
						
							| 
									
										
										
										
											2015-02-19 05:53:09 +01:00
										 |  |  |                 'No sources found for video %s. Maybe an image?' % video_id, | 
					
						
							|  |  |  |                 expected=True) | 
					
						
							| 
									
										
										
										
											2015-02-18 19:47:54 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-19 01:43:20 +01:00
										 |  |  |         formats = [] | 
					
						
							|  |  |  |         for m in re.finditer(r'<source\s+src="(?P<src>[^"]+)"\s+type="(?P<type>[^"]+)"', video_elements): | 
					
						
							|  |  |  |             formats.append({ | 
					
						
							|  |  |  |                 'format_id': m.group('type').partition('/')[2], | 
					
						
							|  |  |  |                 'url': self._proto_relative_url(m.group('src')), | 
					
						
							|  |  |  |                 'ext': mimetype2ext(m.group('type')), | 
					
						
							|  |  |  |                 'acodec': 'none', | 
					
						
							|  |  |  |                 'width': width, | 
					
						
							|  |  |  |                 'height': height, | 
					
						
							|  |  |  |                 'http_headers': { | 
					
						
							|  |  |  |                     'User-Agent': 'youtube-dl (like wget)', | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |             }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         gif_json = self._search_regex( | 
					
						
							|  |  |  |             r'(?s)var\s+videoItem\s*=\s*(\{.*?\})', | 
					
						
							|  |  |  |             webpage, 'GIF code', fatal=False) | 
					
						
							|  |  |  |         if gif_json: | 
					
						
							|  |  |  |             gifd = self._parse_json( | 
					
						
							|  |  |  |                 gif_json, video_id, transform_source=js_to_json) | 
					
						
							|  |  |  |             formats.append({ | 
					
						
							|  |  |  |                 'format_id': 'gif', | 
					
						
							|  |  |  |                 'preference': -10, | 
					
						
							|  |  |  |                 'width': width, | 
					
						
							|  |  |  |                 'height': height, | 
					
						
							|  |  |  |                 'ext': 'gif', | 
					
						
							|  |  |  |                 'acodec': 'none', | 
					
						
							|  |  |  |                 'vcodec': 'gif', | 
					
						
							|  |  |  |                 'container': 'gif', | 
					
						
							|  |  |  |                 'url': self._proto_relative_url(gifd['gifUrl']), | 
					
						
							|  |  |  |                 'filesize': gifd.get('size'), | 
					
						
							|  |  |  |                 'http_headers': { | 
					
						
							|  |  |  |                     'User-Agent': 'youtube-dl (like wget)', | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |             }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self._sort_formats(formats) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return { | 
					
						
							|  |  |  |             'id': video_id, | 
					
						
							|  |  |  |             'formats': formats, | 
					
						
							|  |  |  |             'description': self._og_search_description(webpage), | 
					
						
							|  |  |  |             'title': self._og_search_title(webpage), | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2015-08-30 19:03:21 +06:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class ImgurAlbumIE(InfoExtractor): | 
					
						
							| 
									
										
										
										
											2015-12-22 21:48:48 +06:00
										 |  |  |     _VALID_URL = r'https?://(?:i\.)?imgur\.com/(?:(?:a|gallery|topic/[^/]+)/)?(?P<id>[a-zA-Z0-9]{5})(?:[/?#&]+)?$' | 
					
						
							| 
									
										
										
										
											2015-08-30 19:03:21 +06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-22 21:48:48 +06:00
										 |  |  |     _TESTS = [{ | 
					
						
							| 
									
										
										
										
											2015-08-30 19:03:21 +06:00
										 |  |  |         'url': 'http://imgur.com/gallery/Q95ko', | 
					
						
							|  |  |  |         'info_dict': { | 
					
						
							|  |  |  |             'id': 'Q95ko', | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |         'playlist_count': 25, | 
					
						
							| 
									
										
										
										
											2015-12-22 21:48:48 +06:00
										 |  |  |     }, { | 
					
						
							|  |  |  |         'url': 'http://imgur.com/a/j6Orj', | 
					
						
							|  |  |  |         'only_matching': True, | 
					
						
							|  |  |  |     }, { | 
					
						
							|  |  |  |         'url': 'http://imgur.com/topic/Aww/ll5Vk', | 
					
						
							|  |  |  |         'only_matching': True, | 
					
						
							|  |  |  |     }] | 
					
						
							| 
									
										
										
										
											2015-08-30 19:03:21 +06:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def _real_extract(self, url): | 
					
						
							|  |  |  |         album_id = self._match_id(url) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-22 21:48:48 +06:00
										 |  |  |         album_images = self._download_json( | 
					
						
							|  |  |  |             'http://imgur.com/gallery/%s/album_images/hit.json?all=true' % album_id, | 
					
						
							|  |  |  |             album_id, fatal=False) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if album_images: | 
					
						
							|  |  |  |             data = album_images.get('data') | 
					
						
							|  |  |  |             if data and isinstance(data, dict): | 
					
						
							|  |  |  |                 images = data.get('images') | 
					
						
							|  |  |  |                 if images and isinstance(images, list): | 
					
						
							|  |  |  |                     entries = [ | 
					
						
							|  |  |  |                         self.url_result('http://imgur.com/%s' % image['hash']) | 
					
						
							|  |  |  |                         for image in images if image.get('hash')] | 
					
						
							|  |  |  |                     return self.playlist_result(entries, album_id) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Fallback to single video | 
					
						
							|  |  |  |         return self.url_result('http://imgur.com/%s' % album_id, ImgurIE.ie_key()) |