# coding: utf-8 from __future__ import unicode_literals from .common import InfoExtractor from ..utils import ( int_or_none, float_or_none, qualities, ExtractorError, ) class GfycatIE(InfoExtractor): _VALID_URL = r'https?://(?:www\.)?gfycat\.com/(?:ifr/|gifs/detail/)?(?P<id>[^/?#]+)' _TESTS = [{ '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, } }, { '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, } }, { 'url': 'https://gfycat.com/gifs/detail/UnconsciousLankyIvorygull', 'only_matching': True }] def _real_extract(self, url): video_id = self._match_id(url) gfy = self._download_json( 'http://gfycat.com/cajax/get/%s' % video_id, video_id, 'Downloading video info') if 'error' in gfy: raise ExtractorError('Gfycat said: ' + gfy['error'], expected=True) gfy = gfy['gfyItem'] 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 filesize = int_or_none(gfy.get('%sSize' % format_id)) formats.append({ 'url': video_url, 'format_id': format_id, 'width': width, 'height': height, 'fps': fps, 'filesize': filesize, 'quality': quality(format_id), }) self._sort_formats(formats) return { '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, }