def _parse(self, url, **kwargs): """Return metadata for the given URL that matches :attr:`url_pattern`. :type url: unicode :param url: A remote URL string. :param \*\*kwargs: The named matches from the url match object. :rtype: dict :returns: Any extracted metadata. """ id = kwargs['id'] yt_service = gdata.youtube.service.YouTubeService() yt_service.ssl = False entry = yt_service.GetYouTubeVideoEntry(video_id=id) thumb = max(entry.media.thumbnail, key=attrgetter('width')) if entry.media.description.text: description = unicode(entry.media.description.text, 'utf-8') else: description = None return { 'unique_id': id, 'duration': int(entry.media.duration.seconds), 'display_name': unicode(entry.media.title.text, 'utf-8'), 'description': description, 'thumbnail_url': thumb.url, 'type': VIDEO, }
def get_embed_details_youtube(id): """Given a YouTube video ID, return the associated thumbnail URL and the duration of the video. :param id: a valid YouTube video ID :type id: string :returns: Thumbnail URL (or None), and duration (or None) :rtype: tuple (string, int) """ yt_service = gdata.youtube.service.YouTubeService() yt_service.ssl = False entry = yt_service.GetYouTubeVideoEntry(video_id=id) duration = int(entry.media.duration.seconds) tn = max(entry.media.thumbnail, key=lambda tn: int(tn.width)) thumb_url = tn.url title = unicode(entry.media.title.text, 'utf-8') return thumb_url, duration, title
class YoutubeStorage(EmbedStorageEngine): engine_type = u'YoutubeStorage' """A uniquely identifying unicode string for the StorageEngine.""" default_name = N_(u'YouTube') url_pattern = re.compile( r''' ^(http(s?)://)? # http:// or https:// (youtu\.be/ # youtu.be short url OR: |(\w+\.)?youtube\.com/watch\?(.*&)?v= # www.youtube.com/watch?v= OR |(\w+\.)?youtube\.com/embed/) # www.youtube.com/embed/ OR (?P<id>[^&#]+) # video unique ID ''', re.VERBOSE) """A compiled pattern object that uses named groupings for matches.""" def _parse(self, url, **kwargs): """Return metadata for the given URL that matches :attr:`url_pattern`. :type url: unicode :param url: A remote URL string. :param \*\*kwargs: The named matches from the url match object. :rtype: dict :returns: Any extracted metadata. """ id = kwargs['id'] yt_service = gdata.youtube.service.YouTubeService() yt_service.ssl = False try: entry = yt_service.GetYouTubeVideoEntry(video_id=id) except gdata.service.RequestError, request_error: e = request_error.args[0] if e['status'] == 403 and e['body'] == 'Private video': raise UserStorageError( _('This video is private and cannot be embedded.')) elif e['status'] == 400 and e['body'] == 'Invalid id': raise UserStorageError( _('Invalid YouTube URL. This video does not exist.')) raise UserStorageError(_('YouTube Error: %s') % e['body']) try: thumb = max(entry.media.thumbnail, key=attrgetter('width')).url except (AttributeError, ValueError, TypeError): # At least one video has been found to return no thumbnails. # Try adding this later http://www.youtube.com/watch?v=AQTYoRpCXwg thumb = None # Some videos at some times do not return a complete response, and these # attributes are missing. We can just ignore this. try: description = unicode(entry.media.description.text, 'utf-8') or None except (AttributeError, ValueError, TypeError, UnicodeDecodeError): description = None try: title = unicode(entry.media.title.text, 'utf-8') except (AttributeError, ValueError, TypeError, UnicodeDecodeError): title = None try: duration = int(entry.media.duration.seconds) except (AttributeError, ValueError, TypeError): duration = None return { 'unique_id': id, 'duration': duration, 'display_name': title, 'description': description, 'thumbnail_url': thumb, 'type': VIDEO, }