| 
									
										
										
										
											2015-04-15 22:17:45 -04:00
										 |  |  | # coding: utf-8 | 
					
						
							|  |  |  | from __future__ import unicode_literals | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | from .common import InfoExtractor | 
					
						
							| 
									
										
										
										
											2015-04-18 03:50:22 +06:00
										 |  |  | from ..utils import ( | 
					
						
							|  |  |  |     int_or_none, | 
					
						
							|  |  |  |     float_or_none, | 
					
						
							|  |  |  |     qualities, | 
					
						
							| 
									
										
										
										
											2015-07-07 14:22:13 +08:00
										 |  |  |     ExtractorError, | 
					
						
							| 
									
										
										
										
											2015-04-18 03:50:22 +06:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-15 22:17:45 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | class GfycatIE(InfoExtractor): | 
					
						
							| 
									
										
										
										
											2017-09-27 17:48:47 +02:00
										 |  |  |     _VALID_URL = r'https?://(?:www\.)?gfycat\.com/(?:ifr/|gifs/detail/)?(?P<id>[^/?#]+)' | 
					
						
							| 
									
										
										
										
											2015-07-07 14:16:56 +08:00
										 |  |  |     _TESTS = [{ | 
					
						
							| 
									
										
										
										
											2015-04-18 03:50:22 +06:00
										 |  |  |         'url': 'http://gfycat.com/DeadlyDecisiveGermanpinscher', | 
					
						
							|  |  |  |         'info_dict': { | 
					
						
							|  |  |  |             'id': 'DeadlyDecisiveGermanpinscher', | 
					
						
							|  |  |  |             'ext': 'mp4', | 
					
						
							|  |  |  |             'title': 'Ghost in the Shell', | 
					
						
							|  |  |  |             'timestamp': 1410656006, | 
					
						
							|  |  |  |             'upload_date': '20140914', | 
					
						
							|  |  |  |             'uploader': 'anonymous', | 
					
						
							|  |  |  |             'duration': 10.4, | 
					
						
							|  |  |  |             'view_count': int, | 
					
						
							|  |  |  |             'like_count': int, | 
					
						
							|  |  |  |             'dislike_count': int, | 
					
						
							|  |  |  |             'categories': list, | 
					
						
							|  |  |  |             'age_limit': 0, | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2015-07-07 14:16:56 +08:00
										 |  |  |     }, { | 
					
						
							|  |  |  |         'url': 'http://gfycat.com/ifr/JauntyTimelyAmazontreeboa', | 
					
						
							|  |  |  |         'info_dict': { | 
					
						
							|  |  |  |             'id': 'JauntyTimelyAmazontreeboa', | 
					
						
							|  |  |  |             'ext': 'mp4', | 
					
						
							|  |  |  |             'title': 'JauntyTimelyAmazontreeboa', | 
					
						
							|  |  |  |             'timestamp': 1411720126, | 
					
						
							|  |  |  |             'upload_date': '20140926', | 
					
						
							|  |  |  |             'uploader': 'anonymous', | 
					
						
							|  |  |  |             'duration': 3.52, | 
					
						
							|  |  |  |             'view_count': int, | 
					
						
							|  |  |  |             'like_count': int, | 
					
						
							|  |  |  |             'dislike_count': int, | 
					
						
							|  |  |  |             'categories': list, | 
					
						
							|  |  |  |             'age_limit': 0, | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2017-09-27 17:48:47 +02:00
										 |  |  |     }, { | 
					
						
							|  |  |  |         'url': 'https://gfycat.com/gifs/detail/UnconsciousLankyIvorygull', | 
					
						
							|  |  |  |         'only_matching': True | 
					
						
							| 
									
										
										
										
											2015-07-07 14:16:56 +08:00
										 |  |  |     }] | 
					
						
							| 
									
										
										
										
											2015-04-15 22:17:45 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def _real_extract(self, url): | 
					
						
							|  |  |  |         video_id = self._match_id(url) | 
					
						
							| 
									
										
										
										
											2015-04-18 03:50:22 +06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         gfy = self._download_json( | 
					
						
							|  |  |  |             'http://gfycat.com/cajax/get/%s' % video_id, | 
					
						
							| 
									
										
										
										
											2015-07-07 14:22:13 +08:00
										 |  |  |             video_id, 'Downloading video info') | 
					
						
							|  |  |  |         if 'error' in gfy: | 
					
						
							|  |  |  |             raise ExtractorError('Gfycat said: ' + gfy['error'], expected=True) | 
					
						
							|  |  |  |         gfy = gfy['gfyItem'] | 
					
						
							| 
									
										
										
										
											2015-04-18 03:50:22 +06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         title = gfy.get('title') or gfy['gfyName'] | 
					
						
							|  |  |  |         description = gfy.get('description') | 
					
						
							|  |  |  |         timestamp = int_or_none(gfy.get('createDate')) | 
					
						
							|  |  |  |         uploader = gfy.get('userName') | 
					
						
							|  |  |  |         view_count = int_or_none(gfy.get('views')) | 
					
						
							|  |  |  |         like_count = int_or_none(gfy.get('likes')) | 
					
						
							|  |  |  |         dislike_count = int_or_none(gfy.get('dislikes')) | 
					
						
							|  |  |  |         age_limit = 18 if gfy.get('nsfw') == '1' else 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         width = int_or_none(gfy.get('width')) | 
					
						
							|  |  |  |         height = int_or_none(gfy.get('height')) | 
					
						
							|  |  |  |         fps = int_or_none(gfy.get('frameRate')) | 
					
						
							|  |  |  |         num_frames = int_or_none(gfy.get('numFrames')) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         duration = float_or_none(num_frames, fps) if num_frames and fps else None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         categories = gfy.get('tags') or gfy.get('extraLemmas') or [] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         FORMATS = ('gif', 'webm', 'mp4') | 
					
						
							|  |  |  |         quality = qualities(FORMATS) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         formats = [] | 
					
						
							|  |  |  |         for format_id in FORMATS: | 
					
						
							|  |  |  |             video_url = gfy.get('%sUrl' % format_id) | 
					
						
							|  |  |  |             if not video_url: | 
					
						
							|  |  |  |                 continue | 
					
						
							| 
									
										
										
										
											2017-06-09 00:24:23 +07:00
										 |  |  |             filesize = int_or_none(gfy.get('%sSize' % format_id)) | 
					
						
							| 
									
										
										
										
											2015-04-18 03:50:22 +06:00
										 |  |  |             formats.append({ | 
					
						
							|  |  |  |                 'url': video_url, | 
					
						
							|  |  |  |                 'format_id': format_id, | 
					
						
							|  |  |  |                 'width': width, | 
					
						
							|  |  |  |                 'height': height, | 
					
						
							|  |  |  |                 'fps': fps, | 
					
						
							|  |  |  |                 'filesize': filesize, | 
					
						
							|  |  |  |                 'quality': quality(format_id), | 
					
						
							|  |  |  |             }) | 
					
						
							| 
									
										
										
										
											2015-04-15 22:17:45 -04:00
										 |  |  |         self._sort_formats(formats) | 
					
						
							| 
									
										
										
										
											2015-04-18 03:50:22 +06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-15 22:17:45 -04:00
										 |  |  |         return { | 
					
						
							| 
									
										
										
										
											2015-04-18 03:50:22 +06:00
										 |  |  |             'id': video_id, | 
					
						
							|  |  |  |             'title': title, | 
					
						
							|  |  |  |             'description': description, | 
					
						
							|  |  |  |             'timestamp': timestamp, | 
					
						
							|  |  |  |             'uploader': uploader, | 
					
						
							|  |  |  |             'duration': duration, | 
					
						
							|  |  |  |             'view_count': view_count, | 
					
						
							|  |  |  |             'like_count': like_count, | 
					
						
							|  |  |  |             'dislike_count': dislike_count, | 
					
						
							|  |  |  |             'categories': categories, | 
					
						
							|  |  |  |             'age_limit': age_limit, | 
					
						
							|  |  |  |             'formats': formats, | 
					
						
							| 
									
										
										
										
											2015-04-15 22:17:45 -04:00
										 |  |  |         } |