| #!/usr/bin/python |
| # |
| # Copyright (C) 2008 Google Inc. |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| |
| """YouTubeService extends GDataService to streamline YouTube operations. |
| |
| YouTubeService: Provides methods to perform CRUD operations on YouTube feeds. |
| Extends GDataService. |
| """ |
| |
| __author__ = ('api.stephaniel@gmail.com (Stephanie Liu), ' |
| 'api.jhartmann@gmail.com (Jochen Hartmann)') |
| |
| try: |
| from xml.etree import cElementTree as ElementTree |
| except ImportError: |
| try: |
| import cElementTree as ElementTree |
| except ImportError: |
| try: |
| from xml.etree import ElementTree |
| except ImportError: |
| from elementtree import ElementTree |
| import os |
| import atom |
| import gdata |
| import gdata.service |
| import gdata.youtube |
| |
| YOUTUBE_SERVER = 'gdata.youtube.com' |
| YOUTUBE_SERVICE = 'youtube' |
| YOUTUBE_CLIENTLOGIN_AUTHENTICATION_URL = 'https://www.google.com/youtube/accounts/ClientLogin' |
| YOUTUBE_SUPPORTED_UPLOAD_TYPES = ('mov', 'avi', 'wmv', 'mpg', 'quicktime', |
| 'flv', 'mp4', 'x-flv') |
| YOUTUBE_QUERY_VALID_TIME_PARAMETERS = ('today', 'this_week', 'this_month', |
| 'all_time') |
| YOUTUBE_QUERY_VALID_ORDERBY_PARAMETERS = ('published', 'viewCount', 'rating', |
| 'relevance') |
| YOUTUBE_QUERY_VALID_RACY_PARAMETERS = ('include', 'exclude') |
| YOUTUBE_QUERY_VALID_FORMAT_PARAMETERS = ('1', '5', '6') |
| YOUTUBE_STANDARDFEEDS = ('most_recent', 'recently_featured', |
| 'top_rated', 'most_viewed','watch_on_mobile') |
| YOUTUBE_UPLOAD_URI = 'http://uploads.gdata.youtube.com/feeds/api/users' |
| YOUTUBE_UPLOAD_TOKEN_URI = 'http://gdata.youtube.com/action/GetUploadToken' |
| YOUTUBE_VIDEO_URI = 'http://gdata.youtube.com/feeds/api/videos' |
| YOUTUBE_USER_FEED_URI = 'http://gdata.youtube.com/feeds/api/users' |
| YOUTUBE_PLAYLIST_FEED_URI = 'http://gdata.youtube.com/feeds/api/playlists' |
| |
| YOUTUBE_STANDARD_FEEDS = 'http://gdata.youtube.com/feeds/api/standardfeeds' |
| YOUTUBE_STANDARD_TOP_RATED_URI = '%s/%s' % (YOUTUBE_STANDARD_FEEDS, 'top_rated') |
| YOUTUBE_STANDARD_MOST_VIEWED_URI = '%s/%s' % (YOUTUBE_STANDARD_FEEDS, |
| 'most_viewed') |
| YOUTUBE_STANDARD_RECENTLY_FEATURED_URI = '%s/%s' % (YOUTUBE_STANDARD_FEEDS, |
| 'recently_featured') |
| YOUTUBE_STANDARD_WATCH_ON_MOBILE_URI = '%s/%s' % (YOUTUBE_STANDARD_FEEDS, |
| 'watch_on_mobile') |
| YOUTUBE_STANDARD_TOP_FAVORITES_URI = '%s/%s' % (YOUTUBE_STANDARD_FEEDS, |
| 'top_favorites') |
| YOUTUBE_STANDARD_MOST_RECENT_URI = '%s/%s' % (YOUTUBE_STANDARD_FEEDS, |
| 'most_recent') |
| YOUTUBE_STANDARD_MOST_DISCUSSED_URI = '%s/%s' % (YOUTUBE_STANDARD_FEEDS, |
| 'most_discussed') |
| YOUTUBE_STANDARD_MOST_LINKED_URI = '%s/%s' % (YOUTUBE_STANDARD_FEEDS, |
| 'most_linked') |
| YOUTUBE_STANDARD_MOST_RESPONDED_URI = '%s/%s' % (YOUTUBE_STANDARD_FEEDS, |
| 'most_responded') |
| YOUTUBE_SCHEMA = 'http://gdata.youtube.com/schemas' |
| |
| YOUTUBE_RATING_LINK_REL = '%s#video.ratings' % YOUTUBE_SCHEMA |
| |
| YOUTUBE_COMPLAINT_CATEGORY_SCHEME = '%s/%s' % (YOUTUBE_SCHEMA, |
| 'complaint-reasons.cat') |
| YOUTUBE_SUBSCRIPTION_CATEGORY_SCHEME = '%s/%s' % (YOUTUBE_SCHEMA, |
| 'subscriptiontypes.cat') |
| |
| YOUTUBE_COMPLAINT_CATEGORY_TERMS = ('PORN', 'VIOLENCE', 'HATE', 'DANGEROUS', |
| 'RIGHTS', 'SPAM') |
| YOUTUBE_CONTACT_STATUS = ('accepted', 'rejected') |
| YOUTUBE_CONTACT_CATEGORY = ('Friends', 'Family') |
| |
| UNKOWN_ERROR = 1000 |
| YOUTUBE_BAD_REQUEST = 400 |
| YOUTUBE_CONFLICT = 409 |
| YOUTUBE_INTERNAL_SERVER_ERROR = 500 |
| YOUTUBE_INVALID_ARGUMENT = 601 |
| YOUTUBE_INVALID_CONTENT_TYPE = 602 |
| YOUTUBE_NOT_A_VIDEO = 603 |
| YOUTUBE_INVALID_KIND = 604 |
| |
| |
| class Error(Exception): |
| """Base class for errors within the YouTube service.""" |
| pass |
| |
| class RequestError(Error): |
| """Error class that is thrown in response to an invalid HTTP Request.""" |
| pass |
| |
| class YouTubeError(Error): |
| """YouTube service specific error class.""" |
| pass |
| |
| class YouTubeService(gdata.service.GDataService): |
| |
| """Client for the YouTube service. |
| |
| Performs all documented Google Data YouTube API functions, such as inserting, |
| updating and deleting videos, comments, playlist, subscriptions etc. |
| YouTube Service requires authentication for any write, update or delete |
| actions. |
| |
| Attributes: |
| email: An optional string identifying the user. Required only for |
| authenticated actions. |
| password: An optional string identifying the user's password. |
| source: An optional string identifying the name of your application. |
| server: An optional address of the YouTube API server. gdata.youtube.com |
| is provided as the default value. |
| additional_headers: An optional dictionary containing additional headers |
| to be passed along with each request. Use to store developer key. |
| client_id: An optional string identifying your application, required for |
| authenticated requests, along with a developer key. |
| developer_key: An optional string value. Register your application at |
| http://code.google.com/apis/youtube/dashboard to obtain a (free) key. |
| """ |
| |
| def __init__(self, email=None, password=None, source=None, |
| server=YOUTUBE_SERVER, additional_headers=None, client_id=None, |
| developer_key=None, **kwargs): |
| """Creates a client for the YouTube service. |
| |
| Args: |
| email: string (optional) The user's email address, used for |
| authentication. |
| password: string (optional) The user's password. |
| source: string (optional) The name of the user's application. |
| server: string (optional) The name of the server to which a connection |
| will be opened. Default value: 'gdata.youtube.com'. |
| client_id: string (optional) Identifies your application, required for |
| authenticated requests, along with a developer key. |
| developer_key: string (optional) Register your application at |
| http://code.google.com/apis/youtube/dashboard to obtain a (free) key. |
| **kwargs: The other parameters to pass to gdata.service.GDataService |
| constructor. |
| """ |
| |
| gdata.service.GDataService.__init__( |
| self, email=email, password=password, service=YOUTUBE_SERVICE, |
| source=source, server=server, additional_headers=additional_headers, |
| **kwargs) |
| |
| if client_id is not None: |
| self.additional_headers['X-Gdata-Client'] = client_id |
| |
| if developer_key is not None: |
| self.additional_headers['X-GData-Key'] = 'key=%s' % developer_key |
| |
| self.auth_service_url = YOUTUBE_CLIENTLOGIN_AUTHENTICATION_URL |
| |
| def GetYouTubeVideoFeed(self, uri): |
| """Retrieve a YouTubeVideoFeed. |
| |
| Args: |
| uri: A string representing the URI of the feed that is to be retrieved. |
| |
| Returns: |
| A YouTubeVideoFeed if successfully retrieved. |
| """ |
| return self.Get(uri, converter=gdata.youtube.YouTubeVideoFeedFromString) |
| |
| def GetYouTubeVideoEntry(self, uri=None, video_id=None): |
| """Retrieve a YouTubeVideoEntry. |
| |
| Either a uri or a video_id must be provided. |
| |
| Args: |
| uri: An optional string representing the URI of the entry that is to |
| be retrieved. |
| video_id: An optional string representing the ID of the video. |
| |
| Returns: |
| A YouTubeVideoFeed if successfully retrieved. |
| |
| Raises: |
| YouTubeError: You must provide at least a uri or a video_id to the |
| GetYouTubeVideoEntry() method. |
| """ |
| if uri is None and video_id is None: |
| raise YouTubeError('You must provide at least a uri or a video_id ' |
| 'to the GetYouTubeVideoEntry() method') |
| elif video_id and not uri: |
| uri = '%s/%s' % (YOUTUBE_VIDEO_URI, video_id) |
| return self.Get(uri, converter=gdata.youtube.YouTubeVideoEntryFromString) |
| |
| def GetYouTubeContactFeed(self, uri=None, username='default'): |
| """Retrieve a YouTubeContactFeed. |
| |
| Either a uri or a username must be provided. |
| |
| Args: |
| uri: An optional string representing the URI of the contact feed that |
| is to be retrieved. |
| username: An optional string representing the username. Defaults to the |
| currently authenticated user. |
| |
| Returns: |
| A YouTubeContactFeed if successfully retrieved. |
| |
| Raises: |
| YouTubeError: You must provide at least a uri or a username to the |
| GetYouTubeContactFeed() method. |
| """ |
| if uri is None: |
| uri = '%s/%s/%s' % (YOUTUBE_USER_FEED_URI, username, 'contacts') |
| return self.Get(uri, converter=gdata.youtube.YouTubeContactFeedFromString) |
| |
| def GetYouTubeContactEntry(self, uri): |
| """Retrieve a YouTubeContactEntry. |
| |
| Args: |
| uri: A string representing the URI of the contact entry that is to |
| be retrieved. |
| |
| Returns: |
| A YouTubeContactEntry if successfully retrieved. |
| """ |
| return self.Get(uri, converter=gdata.youtube.YouTubeContactEntryFromString) |
| |
| def GetYouTubeVideoCommentFeed(self, uri=None, video_id=None): |
| """Retrieve a YouTubeVideoCommentFeed. |
| |
| Either a uri or a video_id must be provided. |
| |
| Args: |
| uri: An optional string representing the URI of the comment feed that |
| is to be retrieved. |
| video_id: An optional string representing the ID of the video for which |
| to retrieve the comment feed. |
| |
| Returns: |
| A YouTubeVideoCommentFeed if successfully retrieved. |
| |
| Raises: |
| YouTubeError: You must provide at least a uri or a video_id to the |
| GetYouTubeVideoCommentFeed() method. |
| """ |
| if uri is None and video_id is None: |
| raise YouTubeError('You must provide at least a uri or a video_id ' |
| 'to the GetYouTubeVideoCommentFeed() method') |
| elif video_id and not uri: |
| uri = '%s/%s/%s' % (YOUTUBE_VIDEO_URI, video_id, 'comments') |
| return self.Get( |
| uri, converter=gdata.youtube.YouTubeVideoCommentFeedFromString) |
| |
| def GetYouTubeVideoCommentEntry(self, uri): |
| """Retrieve a YouTubeVideoCommentEntry. |
| |
| Args: |
| uri: A string representing the URI of the comment entry that is to |
| be retrieved. |
| |
| Returns: |
| A YouTubeCommentEntry if successfully retrieved. |
| """ |
| return self.Get( |
| uri, converter=gdata.youtube.YouTubeVideoCommentEntryFromString) |
| |
| def GetYouTubeUserFeed(self, uri=None, username=None): |
| """Retrieve a YouTubeVideoFeed of user uploaded videos |
| |
| Either a uri or a username must be provided. This will retrieve list |
| of videos uploaded by specified user. The uri will be of format |
| "http://gdata.youtube.com/feeds/api/users/{username}/uploads". |
| |
| Args: |
| uri: An optional string representing the URI of the user feed that is |
| to be retrieved. |
| username: An optional string representing the username. |
| |
| Returns: |
| A YouTubeUserFeed if successfully retrieved. |
| |
| Raises: |
| YouTubeError: You must provide at least a uri or a username to the |
| GetYouTubeUserFeed() method. |
| """ |
| if uri is None and username is None: |
| raise YouTubeError('You must provide at least a uri or a username ' |
| 'to the GetYouTubeUserFeed() method') |
| elif username and not uri: |
| uri = '%s/%s/%s' % (YOUTUBE_USER_FEED_URI, username, 'uploads') |
| return self.Get(uri, converter=gdata.youtube.YouTubeUserFeedFromString) |
| |
| def GetYouTubeUserEntry(self, uri=None, username=None): |
| """Retrieve a YouTubeUserEntry. |
| |
| Either a uri or a username must be provided. |
| |
| Args: |
| uri: An optional string representing the URI of the user entry that is |
| to be retrieved. |
| username: An optional string representing the username. |
| |
| Returns: |
| A YouTubeUserEntry if successfully retrieved. |
| |
| Raises: |
| YouTubeError: You must provide at least a uri or a username to the |
| GetYouTubeUserEntry() method. |
| """ |
| if uri is None and username is None: |
| raise YouTubeError('You must provide at least a uri or a username ' |
| 'to the GetYouTubeUserEntry() method') |
| elif username and not uri: |
| uri = '%s/%s' % (YOUTUBE_USER_FEED_URI, username) |
| return self.Get(uri, converter=gdata.youtube.YouTubeUserEntryFromString) |
| |
| def GetYouTubePlaylistFeed(self, uri=None, username='default'): |
| """Retrieve a YouTubePlaylistFeed (a feed of playlists for a user). |
| |
| Either a uri or a username must be provided. |
| |
| Args: |
| uri: An optional string representing the URI of the playlist feed that |
| is to be retrieved. |
| username: An optional string representing the username. Defaults to the |
| currently authenticated user. |
| |
| Returns: |
| A YouTubePlaylistFeed if successfully retrieved. |
| |
| Raises: |
| YouTubeError: You must provide at least a uri or a username to the |
| GetYouTubePlaylistFeed() method. |
| """ |
| if uri is None: |
| uri = '%s/%s/%s' % (YOUTUBE_USER_FEED_URI, username, 'playlists') |
| return self.Get(uri, converter=gdata.youtube.YouTubePlaylistFeedFromString) |
| |
| def GetYouTubePlaylistEntry(self, uri): |
| """Retrieve a YouTubePlaylistEntry. |
| |
| Args: |
| uri: A string representing the URI of the playlist feed that is to |
| be retrieved. |
| |
| Returns: |
| A YouTubePlaylistEntry if successfully retrieved. |
| """ |
| return self.Get(uri, converter=gdata.youtube.YouTubePlaylistEntryFromString) |
| |
| def GetYouTubePlaylistVideoFeed(self, uri=None, playlist_id=None): |
| """Retrieve a YouTubePlaylistVideoFeed (a feed of videos on a playlist). |
| |
| Either a uri or a playlist_id must be provided. |
| |
| Args: |
| uri: An optional string representing the URI of the playlist video feed |
| that is to be retrieved. |
| playlist_id: An optional string representing the Id of the playlist whose |
| playlist video feed is to be retrieved. |
| |
| Returns: |
| A YouTubePlaylistVideoFeed if successfully retrieved. |
| |
| Raises: |
| YouTubeError: You must provide at least a uri or a playlist_id to the |
| GetYouTubePlaylistVideoFeed() method. |
| """ |
| if uri is None and playlist_id is None: |
| raise YouTubeError('You must provide at least a uri or a playlist_id ' |
| 'to the GetYouTubePlaylistVideoFeed() method') |
| elif playlist_id and not uri: |
| uri = '%s/%s' % (YOUTUBE_PLAYLIST_FEED_URI, playlist_id) |
| return self.Get( |
| uri, converter=gdata.youtube.YouTubePlaylistVideoFeedFromString) |
| |
| def GetYouTubeVideoResponseFeed(self, uri=None, video_id=None): |
| """Retrieve a YouTubeVideoResponseFeed. |
| |
| Either a uri or a playlist_id must be provided. |
| |
| Args: |
| uri: An optional string representing the URI of the video response feed |
| that is to be retrieved. |
| video_id: An optional string representing the ID of the video whose |
| response feed is to be retrieved. |
| |
| Returns: |
| A YouTubeVideoResponseFeed if successfully retrieved. |
| |
| Raises: |
| YouTubeError: You must provide at least a uri or a video_id to the |
| GetYouTubeVideoResponseFeed() method. |
| """ |
| if uri is None and video_id is None: |
| raise YouTubeError('You must provide at least a uri or a video_id ' |
| 'to the GetYouTubeVideoResponseFeed() method') |
| elif video_id and not uri: |
| uri = '%s/%s/%s' % (YOUTUBE_VIDEO_URI, video_id, 'responses') |
| return self.Get( |
| uri, converter=gdata.youtube.YouTubeVideoResponseFeedFromString) |
| |
| def GetYouTubeVideoResponseEntry(self, uri): |
| """Retrieve a YouTubeVideoResponseEntry. |
| |
| Args: |
| uri: A string representing the URI of the video response entry that |
| is to be retrieved. |
| |
| Returns: |
| A YouTubeVideoResponseEntry if successfully retrieved. |
| """ |
| return self.Get( |
| uri, converter=gdata.youtube.YouTubeVideoResponseEntryFromString) |
| |
| def GetYouTubeSubscriptionFeed(self, uri=None, username='default'): |
| """Retrieve a YouTubeSubscriptionFeed. |
| |
| Either the uri of the feed or a username must be provided. |
| |
| Args: |
| uri: An optional string representing the URI of the feed that is to |
| be retrieved. |
| username: An optional string representing the username whose subscription |
| feed is to be retrieved. Defaults to the currently authenticted user. |
| |
| Returns: |
| A YouTubeVideoSubscriptionFeed if successfully retrieved. |
| """ |
| if uri is None: |
| uri = '%s/%s/%s' % (YOUTUBE_USER_FEED_URI, username, 'subscriptions') |
| return self.Get( |
| uri, converter=gdata.youtube.YouTubeSubscriptionFeedFromString) |
| |
| def GetYouTubeSubscriptionEntry(self, uri): |
| """Retrieve a YouTubeSubscriptionEntry. |
| |
| Args: |
| uri: A string representing the URI of the entry that is to be retrieved. |
| |
| Returns: |
| A YouTubeVideoSubscriptionEntry if successfully retrieved. |
| """ |
| return self.Get( |
| uri, converter=gdata.youtube.YouTubeSubscriptionEntryFromString) |
| |
| def GetYouTubeRelatedVideoFeed(self, uri=None, video_id=None): |
| """Retrieve a YouTubeRelatedVideoFeed. |
| |
| Either a uri for the feed or a video_id is required. |
| |
| Args: |
| uri: An optional string representing the URI of the feed that is to |
| be retrieved. |
| video_id: An optional string representing the ID of the video for which |
| to retrieve the related video feed. |
| |
| Returns: |
| A YouTubeRelatedVideoFeed if successfully retrieved. |
| |
| Raises: |
| YouTubeError: You must provide at least a uri or a video_id to the |
| GetYouTubeRelatedVideoFeed() method. |
| """ |
| if uri is None and video_id is None: |
| raise YouTubeError('You must provide at least a uri or a video_id ' |
| 'to the GetYouTubeRelatedVideoFeed() method') |
| elif video_id and not uri: |
| uri = '%s/%s/%s' % (YOUTUBE_VIDEO_URI, video_id, 'related') |
| return self.Get( |
| uri, converter=gdata.youtube.YouTubeVideoFeedFromString) |
| |
| def GetTopRatedVideoFeed(self): |
| """Retrieve the 'top_rated' standard video feed. |
| |
| Returns: |
| A YouTubeVideoFeed if successfully retrieved. |
| """ |
| return self.GetYouTubeVideoFeed(YOUTUBE_STANDARD_TOP_RATED_URI) |
| |
| def GetMostViewedVideoFeed(self): |
| """Retrieve the 'most_viewed' standard video feed. |
| |
| Returns: |
| A YouTubeVideoFeed if successfully retrieved. |
| """ |
| return self.GetYouTubeVideoFeed(YOUTUBE_STANDARD_MOST_VIEWED_URI) |
| |
| def GetRecentlyFeaturedVideoFeed(self): |
| """Retrieve the 'recently_featured' standard video feed. |
| |
| Returns: |
| A YouTubeVideoFeed if successfully retrieved. |
| """ |
| return self.GetYouTubeVideoFeed(YOUTUBE_STANDARD_RECENTLY_FEATURED_URI) |
| |
| def GetWatchOnMobileVideoFeed(self): |
| """Retrieve the 'watch_on_mobile' standard video feed. |
| |
| Returns: |
| A YouTubeVideoFeed if successfully retrieved. |
| """ |
| return self.GetYouTubeVideoFeed(YOUTUBE_STANDARD_WATCH_ON_MOBILE_URI) |
| |
| def GetTopFavoritesVideoFeed(self): |
| """Retrieve the 'top_favorites' standard video feed. |
| |
| Returns: |
| A YouTubeVideoFeed if successfully retrieved. |
| """ |
| return self.GetYouTubeVideoFeed(YOUTUBE_STANDARD_TOP_FAVORITES_URI) |
| |
| def GetMostRecentVideoFeed(self): |
| """Retrieve the 'most_recent' standard video feed. |
| |
| Returns: |
| A YouTubeVideoFeed if successfully retrieved. |
| """ |
| return self.GetYouTubeVideoFeed(YOUTUBE_STANDARD_MOST_RECENT_URI) |
| |
| def GetMostDiscussedVideoFeed(self): |
| """Retrieve the 'most_discussed' standard video feed. |
| |
| Returns: |
| A YouTubeVideoFeed if successfully retrieved. |
| """ |
| return self.GetYouTubeVideoFeed(YOUTUBE_STANDARD_MOST_DISCUSSED_URI) |
| |
| def GetMostLinkedVideoFeed(self): |
| """Retrieve the 'most_linked' standard video feed. |
| |
| Returns: |
| A YouTubeVideoFeed if successfully retrieved. |
| """ |
| return self.GetYouTubeVideoFeed(YOUTUBE_STANDARD_MOST_LINKED_URI) |
| |
| def GetMostRespondedVideoFeed(self): |
| """Retrieve the 'most_responded' standard video feed. |
| |
| Returns: |
| A YouTubeVideoFeed if successfully retrieved. |
| """ |
| return self.GetYouTubeVideoFeed(YOUTUBE_STANDARD_MOST_RESPONDED_URI) |
| |
| def GetUserFavoritesFeed(self, username='default'): |
| """Retrieve the favorites feed for a given user. |
| |
| Args: |
| username: An optional string representing the username whose favorites |
| feed is to be retrieved. Defaults to the currently authenticated user. |
| |
| Returns: |
| A YouTubeVideoFeed if successfully retrieved. |
| """ |
| favorites_feed_uri = '%s/%s/%s' % (YOUTUBE_USER_FEED_URI, username, |
| 'favorites') |
| return self.GetYouTubeVideoFeed(favorites_feed_uri) |
| |
| def InsertVideoEntry(self, video_entry, filename_or_handle, |
| youtube_username='default', |
| content_type='video/quicktime'): |
| """Upload a new video to YouTube using the direct upload mechanism. |
| |
| Needs authentication. |
| |
| Args: |
| video_entry: The YouTubeVideoEntry to upload. |
| filename_or_handle: A file-like object or file name where the video |
| will be read from. |
| youtube_username: An optional string representing the username into whose |
| account this video is to be uploaded to. Defaults to the currently |
| authenticated user. |
| content_type: An optional string representing internet media type |
| (a.k.a. mime type) of the media object. Currently the YouTube API |
| supports these types: |
| o video/mpeg |
| o video/quicktime |
| o video/x-msvideo |
| o video/mp4 |
| o video/x-flv |
| |
| Returns: |
| The newly created YouTubeVideoEntry if successful. |
| |
| Raises: |
| AssertionError: video_entry must be a gdata.youtube.VideoEntry instance. |
| YouTubeError: An error occurred trying to read the video file provided. |
| gdata.service.RequestError: An error occurred trying to upload the video |
| to the API server. |
| """ |
| |
| # We need to perform a series of checks on the video_entry and on the |
| # file that we plan to upload, such as checking whether we have a valid |
| # video_entry and that the file is the correct type and readable, prior |
| # to performing the actual POST request. |
| |
| try: |
| assert(isinstance(video_entry, gdata.youtube.YouTubeVideoEntry)) |
| except AssertionError: |
| raise YouTubeError({'status':YOUTUBE_INVALID_ARGUMENT, |
| 'body':'`video_entry` must be a gdata.youtube.VideoEntry instance', |
| 'reason':'Found %s, not VideoEntry' % type(video_entry) |
| }) |
| #majtype, mintype = content_type.split('/') |
| # |
| #try: |
| # assert(mintype in YOUTUBE_SUPPORTED_UPLOAD_TYPES) |
| #except (ValueError, AssertionError): |
| # raise YouTubeError({'status':YOUTUBE_INVALID_CONTENT_TYPE, |
| # 'body':'This is not a valid content type: %s' % content_type, |
| # 'reason':'Accepted content types: %s' % |
| # ['video/%s' % (t) for t in YOUTUBE_SUPPORTED_UPLOAD_TYPES]}) |
| |
| if (isinstance(filename_or_handle, (str, unicode)) |
| and os.path.exists(filename_or_handle)): |
| mediasource = gdata.MediaSource() |
| mediasource.setFile(filename_or_handle, content_type) |
| elif hasattr(filename_or_handle, 'read'): |
| import StringIO |
| if hasattr(filename_or_handle, 'seek'): |
| filename_or_handle.seek(0) |
| file_handle = filename_or_handle |
| name = 'video' |
| if hasattr(filename_or_handle, 'name'): |
| name = filename_or_handle.name |
| mediasource = gdata.MediaSource(file_handle, content_type, |
| content_length=file_handle.len, file_name=name) |
| else: |
| raise YouTubeError({'status':YOUTUBE_INVALID_ARGUMENT, 'body': |
| '`filename_or_handle` must be a path name or a file-like object', |
| 'reason': ('Found %s, not path name or object ' |
| 'with a .read() method' % type(filename_or_handle))}) |
| upload_uri = '%s/%s/%s' % (YOUTUBE_UPLOAD_URI, youtube_username, |
| 'uploads') |
| self.additional_headers['Slug'] = mediasource.file_name |
| |
| # Using a nested try statement to retain Python 2.4 compatibility |
| try: |
| try: |
| return self.Post(video_entry, uri=upload_uri, media_source=mediasource, |
| converter=gdata.youtube.YouTubeVideoEntryFromString) |
| except gdata.service.RequestError, e: |
| raise YouTubeError(e.args[0]) |
| finally: |
| del(self.additional_headers['Slug']) |
| |
| def CheckUploadStatus(self, video_entry=None, video_id=None): |
| """Check upload status on a recently uploaded video entry. |
| |
| Needs authentication. Either video_entry or video_id must be provided. |
| |
| Args: |
| video_entry: An optional YouTubeVideoEntry whose upload status to check |
| video_id: An optional string representing the ID of the uploaded video |
| whose status is to be checked. |
| |
| Returns: |
| A tuple containing (video_upload_state, detailed_message) or None if |
| no status information is found. |
| |
| Raises: |
| YouTubeError: You must provide at least a video_entry or a video_id to the |
| CheckUploadStatus() method. |
| """ |
| if video_entry is None and video_id is None: |
| raise YouTubeError('You must provide at least a uri or a video_id ' |
| 'to the CheckUploadStatus() method') |
| elif video_id and not video_entry: |
| video_entry = self.GetYouTubeVideoEntry(video_id=video_id) |
| |
| control = video_entry.control |
| if control is not None: |
| draft = control.draft |
| if draft is not None: |
| if draft.text == 'yes': |
| yt_state = control.extension_elements[0] |
| if yt_state is not None: |
| state_value = yt_state.attributes['name'] |
| message = '' |
| if yt_state.text is not None: |
| message = yt_state.text |
| |
| return (state_value, message) |
| |
| def GetFormUploadToken(self, video_entry, uri=YOUTUBE_UPLOAD_TOKEN_URI): |
| """Receives a YouTube Token and a YouTube PostUrl from a YouTubeVideoEntry. |
| |
| Needs authentication. |
| |
| Args: |
| video_entry: The YouTubeVideoEntry to upload (meta-data only). |
| uri: An optional string representing the URI from where to fetch the |
| token information. Defaults to the YOUTUBE_UPLOADTOKEN_URI. |
| |
| Returns: |
| A tuple containing the URL to which to post your video file, along |
| with the youtube token that must be included with your upload in the |
| form of: (post_url, youtube_token). |
| """ |
| try: |
| response = self.Post(video_entry, uri) |
| except gdata.service.RequestError, e: |
| raise YouTubeError(e.args[0]) |
| |
| tree = ElementTree.fromstring(response) |
| |
| for child in tree: |
| if child.tag == 'url': |
| post_url = child.text |
| elif child.tag == 'token': |
| youtube_token = child.text |
| return (post_url, youtube_token) |
| |
| def UpdateVideoEntry(self, video_entry): |
| """Updates a video entry's meta-data. |
| |
| Needs authentication. |
| |
| Args: |
| video_entry: The YouTubeVideoEntry to update, containing updated |
| meta-data. |
| |
| Returns: |
| An updated YouTubeVideoEntry on success or None. |
| """ |
| for link in video_entry.link: |
| if link.rel == 'edit': |
| edit_uri = link.href |
| return self.Put(video_entry, uri=edit_uri, |
| converter=gdata.youtube.YouTubeVideoEntryFromString) |
| |
| def DeleteVideoEntry(self, video_entry): |
| """Deletes a video entry. |
| |
| Needs authentication. |
| |
| Args: |
| video_entry: The YouTubeVideoEntry to be deleted. |
| |
| Returns: |
| True if entry was deleted successfully. |
| """ |
| for link in video_entry.link: |
| if link.rel == 'edit': |
| edit_uri = link.href |
| return self.Delete(edit_uri) |
| |
| def AddRating(self, rating_value, video_entry): |
| """Add a rating to a video entry. |
| |
| Needs authentication. |
| |
| Args: |
| rating_value: The integer value for the rating (between 1 and 5). |
| video_entry: The YouTubeVideoEntry to be rated. |
| |
| Returns: |
| True if the rating was added successfully. |
| |
| Raises: |
| YouTubeError: rating_value must be between 1 and 5 in AddRating(). |
| """ |
| if rating_value < 1 or rating_value > 5: |
| raise YouTubeError('rating_value must be between 1 and 5 in AddRating()') |
| |
| entry = gdata.GDataEntry() |
| rating = gdata.youtube.Rating(min='1', max='5') |
| rating.extension_attributes['name'] = 'value' |
| rating.extension_attributes['value'] = str(rating_value) |
| entry.extension_elements.append(rating) |
| |
| for link in video_entry.link: |
| if link.rel == YOUTUBE_RATING_LINK_REL: |
| rating_uri = link.href |
| |
| return self.Post(entry, uri=rating_uri) |
| |
| def AddComment(self, comment_text, video_entry): |
| """Add a comment to a video entry. |
| |
| Needs authentication. Note that each comment that is posted must contain |
| the video entry that it is to be posted to. |
| |
| Args: |
| comment_text: A string representing the text of the comment. |
| video_entry: The YouTubeVideoEntry to be commented on. |
| |
| Returns: |
| True if the comment was added successfully. |
| """ |
| content = atom.Content(text=comment_text) |
| comment_entry = gdata.youtube.YouTubeVideoCommentEntry(content=content) |
| comment_post_uri = video_entry.comments.feed_link[0].href |
| |
| return self.Post(comment_entry, uri=comment_post_uri) |
| |
| def AddVideoResponse(self, video_id_to_respond_to, video_response): |
| """Add a video response. |
| |
| Needs authentication. |
| |
| Args: |
| video_id_to_respond_to: A string representing the ID of the video to be |
| responded to. |
| video_response: YouTubeVideoEntry to be posted as a response. |
| |
| Returns: |
| True if video response was posted successfully. |
| """ |
| post_uri = '%s/%s/%s' % (YOUTUBE_VIDEO_URI, video_id_to_respond_to, |
| 'responses') |
| return self.Post(video_response, uri=post_uri) |
| |
| def DeleteVideoResponse(self, video_id, response_video_id): |
| """Delete a video response. |
| |
| Needs authentication. |
| |
| Args: |
| video_id: A string representing the ID of video that contains the |
| response. |
| response_video_id: A string representing the ID of the video that was |
| posted as a response. |
| |
| Returns: |
| True if video response was deleted succcessfully. |
| """ |
| delete_uri = '%s/%s/%s/%s' % (YOUTUBE_VIDEO_URI, video_id, 'responses', |
| response_video_id) |
| return self.Delete(delete_uri) |
| |
| def AddComplaint(self, complaint_text, complaint_term, video_id): |
| """Add a complaint for a particular video entry. |
| |
| Needs authentication. |
| |
| Args: |
| complaint_text: A string representing the complaint text. |
| complaint_term: A string representing the complaint category term. |
| video_id: A string representing the ID of YouTubeVideoEntry to |
| complain about. |
| |
| Returns: |
| True if posted successfully. |
| |
| Raises: |
| YouTubeError: Your complaint_term is not valid. |
| """ |
| if complaint_term not in YOUTUBE_COMPLAINT_CATEGORY_TERMS: |
| raise YouTubeError('Your complaint_term is not valid') |
| |
| content = atom.Content(text=complaint_text) |
| category = atom.Category(term=complaint_term, |
| scheme=YOUTUBE_COMPLAINT_CATEGORY_SCHEME) |
| |
| complaint_entry = gdata.GDataEntry(content=content, category=[category]) |
| post_uri = '%s/%s/%s' % (YOUTUBE_VIDEO_URI, video_id, 'complaints') |
| |
| return self.Post(complaint_entry, post_uri) |
| |
| def AddVideoEntryToFavorites(self, video_entry, username='default'): |
| """Add a video entry to a users favorite feed. |
| |
| Needs authentication. |
| |
| Args: |
| video_entry: The YouTubeVideoEntry to add. |
| username: An optional string representing the username to whose favorite |
| feed you wish to add the entry. Defaults to the currently |
| authenticated user. |
| Returns: |
| The posted YouTubeVideoEntry if successfully posted. |
| """ |
| post_uri = '%s/%s/%s' % (YOUTUBE_USER_FEED_URI, username, 'favorites') |
| |
| return self.Post(video_entry, post_uri, |
| converter=gdata.youtube.YouTubeVideoEntryFromString) |
| |
| def DeleteVideoEntryFromFavorites(self, video_id, username='default'): |
| """Delete a video entry from the users favorite feed. |
| |
| Needs authentication. |
| |
| Args: |
| video_id: A string representing the ID of the video that is to be removed |
| username: An optional string representing the username of the user's |
| favorite feed. Defaults to the currently authenticated user. |
| |
| Returns: |
| True if entry was successfully deleted. |
| """ |
| edit_link = '%s/%s/%s/%s' % (YOUTUBE_USER_FEED_URI, username, 'favorites', |
| video_id) |
| return self.Delete(edit_link) |
| |
| def AddPlaylist(self, playlist_title, playlist_description, |
| playlist_private=None): |
| """Add a new playlist to the currently authenticated users account. |
| |
| Needs authentication. |
| |
| Args: |
| playlist_title: A string representing the title for the new playlist. |
| playlist_description: A string representing the description of the |
| playlist. |
| playlist_private: An optional boolean, set to True if the playlist is |
| to be private. |
| |
| Returns: |
| The YouTubePlaylistEntry if successfully posted. |
| """ |
| playlist_entry = gdata.youtube.YouTubePlaylistEntry( |
| title=atom.Title(text=playlist_title), |
| description=gdata.youtube.Description(text=playlist_description)) |
| if playlist_private: |
| playlist_entry.private = gdata.youtube.Private() |
| |
| playlist_post_uri = '%s/%s/%s' % (YOUTUBE_USER_FEED_URI, 'default', |
| 'playlists') |
| return self.Post(playlist_entry, playlist_post_uri, |
| converter=gdata.youtube.YouTubePlaylistEntryFromString) |
| |
| def UpdatePlaylist(self, playlist_id, new_playlist_title, |
| new_playlist_description, playlist_private=None, |
| username='default'): |
| """Update a playlist with new meta-data. |
| |
| Needs authentication. |
| |
| Args: |
| playlist_id: A string representing the ID of the playlist to be updated. |
| new_playlist_title: A string representing a new title for the playlist. |
| new_playlist_description: A string representing a new description for the |
| playlist. |
| playlist_private: An optional boolean, set to True if the playlist is |
| to be private. |
| username: An optional string representing the username whose playlist is |
| to be updated. Defaults to the currently authenticated user. |
| |
| Returns: |
| A YouTubePlaylistEntry if the update was successful. |
| """ |
| updated_playlist = gdata.youtube.YouTubePlaylistEntry( |
| title=atom.Title(text=new_playlist_title), |
| description=gdata.youtube.Description(text=new_playlist_description)) |
| if playlist_private: |
| updated_playlist.private = gdata.youtube.Private() |
| |
| playlist_put_uri = '%s/%s/playlists/%s' % (YOUTUBE_USER_FEED_URI, username, |
| playlist_id) |
| |
| return self.Put(updated_playlist, playlist_put_uri, |
| converter=gdata.youtube.YouTubePlaylistEntryFromString) |
| |
| def DeletePlaylist(self, playlist_uri): |
| """Delete a playlist from the currently authenticated users playlists. |
| |
| Needs authentication. |
| |
| Args: |
| playlist_uri: A string representing the URI of the playlist that is |
| to be deleted. |
| |
| Returns: |
| True if successfully deleted. |
| """ |
| return self.Delete(playlist_uri) |
| |
| def AddPlaylistVideoEntryToPlaylist( |
| self, playlist_uri, video_id, custom_video_title=None, |
| custom_video_description=None): |
| """Add a video entry to a playlist, optionally providing a custom title |
| and description. |
| |
| Needs authentication. |
| |
| Args: |
| playlist_uri: A string representing the URI of the playlist to which this |
| video entry is to be added. |
| video_id: A string representing the ID of the video entry to add. |
| custom_video_title: An optional string representing a custom title for |
| the video (only shown on the playlist). |
| custom_video_description: An optional string representing a custom |
| description for the video (only shown on the playlist). |
| |
| Returns: |
| A YouTubePlaylistVideoEntry if successfully posted. |
| """ |
| playlist_video_entry = gdata.youtube.YouTubePlaylistVideoEntry( |
| atom_id=atom.Id(text=video_id)) |
| if custom_video_title: |
| playlist_video_entry.title = atom.Title(text=custom_video_title) |
| if custom_video_description: |
| playlist_video_entry.description = gdata.youtube.Description( |
| text=custom_video_description) |
| |
| return self.Post(playlist_video_entry, playlist_uri, |
| converter=gdata.youtube.YouTubePlaylistVideoEntryFromString) |
| |
| def UpdatePlaylistVideoEntryMetaData( |
| self, playlist_uri, playlist_entry_id, new_video_title, |
| new_video_description, new_video_position): |
| """Update the meta data for a YouTubePlaylistVideoEntry. |
| |
| Needs authentication. |
| |
| Args: |
| playlist_uri: A string representing the URI of the playlist that contains |
| the entry to be updated. |
| playlist_entry_id: A string representing the ID of the entry to be |
| updated. |
| new_video_title: A string representing the new title for the video entry. |
| new_video_description: A string representing the new description for |
| the video entry. |
| new_video_position: An integer representing the new position on the |
| playlist for the video. |
| |
| Returns: |
| A YouTubePlaylistVideoEntry if the update was successful. |
| """ |
| playlist_video_entry = gdata.youtube.YouTubePlaylistVideoEntry( |
| title=atom.Title(text=new_video_title), |
| description=gdata.youtube.Description(text=new_video_description), |
| position=gdata.youtube.Position(text=str(new_video_position))) |
| |
| playlist_put_uri = playlist_uri + '/' + playlist_entry_id |
| |
| return self.Put(playlist_video_entry, playlist_put_uri, |
| converter=gdata.youtube.YouTubePlaylistVideoEntryFromString) |
| |
| def DeletePlaylistVideoEntry(self, playlist_uri, playlist_video_entry_id): |
| """Delete a playlist video entry from a playlist. |
| |
| Needs authentication. |
| |
| Args: |
| playlist_uri: A URI representing the playlist from which the playlist |
| video entry is to be removed from. |
| playlist_video_entry_id: A string representing id of the playlist video |
| entry that is to be removed. |
| |
| Returns: |
| True if entry was successfully deleted. |
| """ |
| delete_uri = '%s/%s' % (playlist_uri, playlist_video_entry_id) |
| return self.Delete(delete_uri) |
| |
| def AddSubscriptionToChannel(self, username_to_subscribe_to, |
| my_username = 'default'): |
| """Add a new channel subscription to the currently authenticated users |
| account. |
| |
| Needs authentication. |
| |
| Args: |
| username_to_subscribe_to: A string representing the username of the |
| channel to which we want to subscribe to. |
| my_username: An optional string representing the name of the user which |
| we want to subscribe. Defaults to currently authenticated user. |
| |
| Returns: |
| A new YouTubeSubscriptionEntry if successfully posted. |
| """ |
| subscription_category = atom.Category( |
| scheme=YOUTUBE_SUBSCRIPTION_CATEGORY_SCHEME, |
| term='channel') |
| subscription_username = gdata.youtube.Username( |
| text=username_to_subscribe_to) |
| |
| subscription_entry = gdata.youtube.YouTubeSubscriptionEntry( |
| category=subscription_category, |
| username=subscription_username) |
| |
| post_uri = '%s/%s/%s' % (YOUTUBE_USER_FEED_URI, my_username, |
| 'subscriptions') |
| |
| return self.Post(subscription_entry, post_uri, |
| converter=gdata.youtube.YouTubeSubscriptionEntryFromString) |
| |
| def AddSubscriptionToFavorites(self, username, my_username = 'default'): |
| """Add a new subscription to a users favorites to the currently |
| authenticated user's account. |
| |
| Needs authentication |
| |
| Args: |
| username: A string representing the username of the user's favorite feed |
| to subscribe to. |
| my_username: An optional string representing the username of the user |
| that is to be subscribed. Defaults to currently authenticated user. |
| |
| Returns: |
| A new YouTubeSubscriptionEntry if successful. |
| """ |
| subscription_category = atom.Category( |
| scheme=YOUTUBE_SUBSCRIPTION_CATEGORY_SCHEME, |
| term='favorites') |
| subscription_username = gdata.youtube.Username(text=username) |
| |
| subscription_entry = gdata.youtube.YouTubeSubscriptionEntry( |
| category=subscription_category, |
| username=subscription_username) |
| |
| post_uri = '%s/%s/%s' % (YOUTUBE_USER_FEED_URI, my_username, |
| 'subscriptions') |
| |
| return self.Post(subscription_entry, post_uri, |
| converter=gdata.youtube.YouTubeSubscriptionEntryFromString) |
| |
| def AddSubscriptionToQuery(self, query, my_username = 'default'): |
| """Add a new subscription to a specific keyword query to the currently |
| authenticated user's account. |
| |
| Needs authentication |
| |
| Args: |
| query: A string representing the keyword query to subscribe to. |
| my_username: An optional string representing the username of the user |
| that is to be subscribed. Defaults to currently authenticated user. |
| |
| Returns: |
| A new YouTubeSubscriptionEntry if successful. |
| """ |
| subscription_category = atom.Category( |
| scheme=YOUTUBE_SUBSCRIPTION_CATEGORY_SCHEME, |
| term='query') |
| subscription_query_string = gdata.youtube.QueryString(text=query) |
| |
| subscription_entry = gdata.youtube.YouTubeSubscriptionEntry( |
| category=subscription_category, |
| query_string=subscription_query_string) |
| |
| post_uri = '%s/%s/%s' % (YOUTUBE_USER_FEED_URI, my_username, |
| 'subscriptions') |
| |
| return self.Post(subscription_entry, post_uri, |
| converter=gdata.youtube.YouTubeSubscriptionEntryFromString) |
| |
| |
| |
| def DeleteSubscription(self, subscription_uri): |
| """Delete a subscription from the currently authenticated user's account. |
| |
| Needs authentication. |
| |
| Args: |
| subscription_uri: A string representing the URI of the subscription that |
| is to be deleted. |
| |
| Returns: |
| True if deleted successfully. |
| """ |
| return self.Delete(subscription_uri) |
| |
| def AddContact(self, contact_username, my_username='default'): |
| """Add a new contact to the currently authenticated user's contact feed. |
| |
| Needs authentication. |
| |
| Args: |
| contact_username: A string representing the username of the contact |
| that you wish to add. |
| my_username: An optional string representing the username to whose |
| contact the new contact is to be added. |
| |
| Returns: |
| A YouTubeContactEntry if added successfully. |
| """ |
| contact_category = atom.Category( |
| scheme = 'http://gdata.youtube.com/schemas/2007/contact.cat', |
| term = 'Friends') |
| contact_username = gdata.youtube.Username(text=contact_username) |
| contact_entry = gdata.youtube.YouTubeContactEntry( |
| category=contact_category, |
| username=contact_username) |
| |
| contact_post_uri = '%s/%s/%s' % (YOUTUBE_USER_FEED_URI, my_username, |
| 'contacts') |
| |
| return self.Post(contact_entry, contact_post_uri, |
| converter=gdata.youtube.YouTubeContactEntryFromString) |
| |
| def UpdateContact(self, contact_username, new_contact_status, |
| new_contact_category, my_username='default'): |
| """Update a contact, providing a new status and a new category. |
| |
| Needs authentication. |
| |
| Args: |
| contact_username: A string representing the username of the contact |
| that is to be updated. |
| new_contact_status: A string representing the new status of the contact. |
| This can either be set to 'accepted' or 'rejected'. |
| new_contact_category: A string representing the new category for the |
| contact, either 'Friends' or 'Family'. |
| my_username: An optional string representing the username of the user |
| whose contact feed we are modifying. Defaults to the currently |
| authenticated user. |
| |
| Returns: |
| A YouTubeContactEntry if updated succesfully. |
| |
| Raises: |
| YouTubeError: New contact status must be within the accepted values. Or |
| new contact category must be within the accepted categories. |
| """ |
| if new_contact_status not in YOUTUBE_CONTACT_STATUS: |
| raise YouTubeError('New contact status must be one of %s' % |
| (' '.join(YOUTUBE_CONTACT_STATUS))) |
| if new_contact_category not in YOUTUBE_CONTACT_CATEGORY: |
| raise YouTubeError('New contact category must be one of %s' % |
| (' '.join(YOUTUBE_CONTACT_CATEGORY))) |
| |
| contact_category = atom.Category( |
| scheme='http://gdata.youtube.com/schemas/2007/contact.cat', |
| term=new_contact_category) |
| |
| contact_status = gdata.youtube.Status(text=new_contact_status) |
| contact_entry = gdata.youtube.YouTubeContactEntry( |
| category=contact_category, |
| status=contact_status) |
| |
| contact_put_uri = '%s/%s/%s/%s' % (YOUTUBE_USER_FEED_URI, my_username, |
| 'contacts', contact_username) |
| |
| return self.Put(contact_entry, contact_put_uri, |
| converter=gdata.youtube.YouTubeContactEntryFromString) |
| |
| def DeleteContact(self, contact_username, my_username='default'): |
| """Delete a contact from a users contact feed. |
| |
| Needs authentication. |
| |
| Args: |
| contact_username: A string representing the username of the contact |
| that is to be deleted. |
| my_username: An optional string representing the username of the user's |
| contact feed from which to delete the contact. Defaults to the |
| currently authenticated user. |
| |
| Returns: |
| True if the contact was deleted successfully |
| """ |
| contact_edit_uri = '%s/%s/%s/%s' % (YOUTUBE_USER_FEED_URI, my_username, |
| 'contacts', contact_username) |
| return self.Delete(contact_edit_uri) |
| |
| def _GetDeveloperKey(self): |
| """Getter for Developer Key property. |
| |
| Returns: |
| If the developer key has been set, a string representing the developer key |
| is returned or None. |
| """ |
| if 'X-GData-Key' in self.additional_headers: |
| return self.additional_headers['X-GData-Key'][4:] |
| else: |
| return None |
| |
| def _SetDeveloperKey(self, developer_key): |
| """Setter for Developer Key property. |
| |
| Sets the developer key in the 'X-GData-Key' header. The actual value that |
| is set is 'key=' plus the developer_key that was passed. |
| """ |
| self.additional_headers['X-GData-Key'] = 'key=' + developer_key |
| |
| developer_key = property(_GetDeveloperKey, _SetDeveloperKey, |
| doc="""The Developer Key property""") |
| |
| def _GetClientId(self): |
| """Getter for Client Id property. |
| |
| Returns: |
| If the client_id has been set, a string representing it is returned |
| or None. |
| """ |
| if 'X-Gdata-Client' in self.additional_headers: |
| return self.additional_headers['X-Gdata-Client'] |
| else: |
| return None |
| |
| def _SetClientId(self, client_id): |
| """Setter for Client Id property. |
| |
| Sets the 'X-Gdata-Client' header. |
| """ |
| self.additional_headers['X-Gdata-Client'] = client_id |
| |
| client_id = property(_GetClientId, _SetClientId, |
| doc="""The ClientId property""") |
| |
| def Query(self, uri): |
| """Performs a query and returns a resulting feed or entry. |
| |
| Args: |
| uri: A string representing the URI of the feed that is to be queried. |
| |
| Returns: |
| On success, a tuple in the form: |
| (boolean succeeded=True, ElementTree._Element result) |
| On failure, a tuple in the form: |
| (boolean succeeded=False, {'status': HTTP status code from server, |
| 'reason': HTTP reason from the server, |
| 'body': HTTP body of the server's response}) |
| """ |
| result = self.Get(uri) |
| return result |
| |
| def YouTubeQuery(self, query): |
| """Performs a YouTube specific query and returns a resulting feed or entry. |
| |
| Args: |
| query: A Query object or one if its sub-classes (YouTubeVideoQuery, |
| YouTubeUserQuery or YouTubePlaylistQuery). |
| |
| Returns: |
| Depending on the type of Query object submitted returns either a |
| YouTubeVideoFeed, a YouTubeUserFeed, a YouTubePlaylistFeed. If the |
| Query object provided was not YouTube-related, a tuple is returned. |
| On success the tuple will be in this form: |
| (boolean succeeded=True, ElementTree._Element result) |
| On failure, the tuple will be in this form: |
| (boolean succeeded=False, {'status': HTTP status code from server, |
| 'reason': HTTP reason from the server, |
| 'body': HTTP body of the server response}) |
| """ |
| result = self.Query(query.ToUri()) |
| if isinstance(query, YouTubeUserQuery): |
| return gdata.youtube.YouTubeUserFeedFromString(result.ToString()) |
| elif isinstance(query, YouTubePlaylistQuery): |
| return gdata.youtube.YouTubePlaylistFeedFromString(result.ToString()) |
| elif isinstance(query, YouTubeVideoQuery): |
| return gdata.youtube.YouTubeVideoFeedFromString(result.ToString()) |
| else: |
| return result |
| |
| class YouTubeVideoQuery(gdata.service.Query): |
| |
| """Subclasses gdata.service.Query to represent a YouTube Data API query. |
| |
| Attributes are set dynamically via properties. Properties correspond to |
| the standard Google Data API query parameters with YouTube Data API |
| extensions. Please refer to the API documentation for details. |
| |
| Attributes: |
| vq: The vq parameter, which is only supported for video feeds, specifies a |
| search query term. Refer to API documentation for further details. |
| orderby: The orderby parameter, which is only supported for video feeds, |
| specifies the value that will be used to sort videos in the search |
| result set. Valid values for this parameter are relevance, published, |
| viewCount and rating. |
| time: The time parameter, which is only available for the top_rated, |
| top_favorites, most_viewed, most_discussed, most_linked and |
| most_responded standard feeds, restricts the search to videos uploaded |
| within the specified time. Valid values for this parameter are today |
| (1 day), this_week (7 days), this_month (1 month) and all_time. |
| The default value for this parameter is all_time. |
| format: The format parameter specifies that videos must be available in a |
| particular video format. Refer to the API documentation for details. |
| racy: The racy parameter allows a search result set to include restricted |
| content as well as standard content. Valid values for this parameter |
| are include and exclude. By default, restricted content is excluded. |
| lr: The lr parameter restricts the search to videos that have a title, |
| description or keywords in a specific language. Valid values for the lr |
| parameter are ISO 639-1 two-letter language codes. |
| restriction: The restriction parameter identifies the IP address that |
| should be used to filter videos that can only be played in specific |
| countries. |
| location: A string of geo coordinates. Note that this is not used when the |
| search is performed but rather to filter the returned videos for ones |
| that match to the location entered. |
| feed: str (optional) The base URL which is the beginning of the query URL. |
| defaults to 'http://%s/feeds/videos' % (YOUTUBE_SERVER) |
| """ |
| |
| def __init__(self, video_id=None, feed_type=None, text_query=None, |
| params=None, categories=None, feed=None): |
| |
| if feed_type in YOUTUBE_STANDARDFEEDS and feed is None: |
| feed = 'http://%s/feeds/standardfeeds/%s' % (YOUTUBE_SERVER, feed_type) |
| elif (feed_type is 'responses' or feed_type is 'comments' and video_id |
| and feed is None): |
| feed = 'http://%s/feeds/videos/%s/%s' % (YOUTUBE_SERVER, video_id, |
| feed_type) |
| elif feed is None: |
| feed = 'http://%s/feeds/videos' % (YOUTUBE_SERVER) |
| |
| gdata.service.Query.__init__(self, feed, text_query=text_query, |
| params=params, categories=categories) |
| |
| def _GetVideoQuery(self): |
| if 'vq' in self: |
| return self['vq'] |
| else: |
| return None |
| |
| def _SetVideoQuery(self, val): |
| self['vq'] = val |
| |
| vq = property(_GetVideoQuery, _SetVideoQuery, |
| doc="""The video query (vq) query parameter""") |
| |
| def _GetOrderBy(self): |
| if 'orderby' in self: |
| return self['orderby'] |
| else: |
| return None |
| |
| def _SetOrderBy(self, val): |
| if val not in YOUTUBE_QUERY_VALID_ORDERBY_PARAMETERS: |
| if val.startswith('relevance_lang_') is False: |
| raise YouTubeError('OrderBy must be one of: %s ' % |
| ' '.join(YOUTUBE_QUERY_VALID_ORDERBY_PARAMETERS)) |
| self['orderby'] = val |
| |
| orderby = property(_GetOrderBy, _SetOrderBy, |
| doc="""The orderby query parameter""") |
| |
| def _GetTime(self): |
| if 'time' in self: |
| return self['time'] |
| else: |
| return None |
| |
| def _SetTime(self, val): |
| if val not in YOUTUBE_QUERY_VALID_TIME_PARAMETERS: |
| raise YouTubeError('Time must be one of: %s ' % |
| ' '.join(YOUTUBE_QUERY_VALID_TIME_PARAMETERS)) |
| self['time'] = val |
| |
| time = property(_GetTime, _SetTime, |
| doc="""The time query parameter""") |
| |
| def _GetFormat(self): |
| if 'format' in self: |
| return self['format'] |
| else: |
| return None |
| |
| def _SetFormat(self, val): |
| if val not in YOUTUBE_QUERY_VALID_FORMAT_PARAMETERS: |
| raise YouTubeError('Format must be one of: %s ' % |
| ' '.join(YOUTUBE_QUERY_VALID_FORMAT_PARAMETERS)) |
| self['format'] = val |
| |
| format = property(_GetFormat, _SetFormat, |
| doc="""The format query parameter""") |
| |
| def _GetRacy(self): |
| if 'racy' in self: |
| return self['racy'] |
| else: |
| return None |
| |
| def _SetRacy(self, val): |
| if val not in YOUTUBE_QUERY_VALID_RACY_PARAMETERS: |
| raise YouTubeError('Racy must be one of: %s ' % |
| ' '.join(YOUTUBE_QUERY_VALID_RACY_PARAMETERS)) |
| self['racy'] = val |
| |
| racy = property(_GetRacy, _SetRacy, |
| doc="""The racy query parameter""") |
| |
| def _GetLanguageRestriction(self): |
| if 'lr' in self: |
| return self['lr'] |
| else: |
| return None |
| |
| def _SetLanguageRestriction(self, val): |
| self['lr'] = val |
| |
| lr = property(_GetLanguageRestriction, _SetLanguageRestriction, |
| doc="""The lr (language restriction) query parameter""") |
| |
| def _GetIPRestriction(self): |
| if 'restriction' in self: |
| return self['restriction'] |
| else: |
| return None |
| |
| def _SetIPRestriction(self, val): |
| self['restriction'] = val |
| |
| restriction = property(_GetIPRestriction, _SetIPRestriction, |
| doc="""The restriction query parameter""") |
| |
| def _GetLocation(self): |
| if 'location' in self: |
| return self['location'] |
| else: |
| return None |
| |
| def _SetLocation(self, val): |
| self['location'] = val |
| |
| location = property(_GetLocation, _SetLocation, |
| doc="""The location query parameter""") |
| |
| |
| |
| class YouTubeUserQuery(YouTubeVideoQuery): |
| |
| """Subclasses YouTubeVideoQuery to perform user-specific queries. |
| |
| Attributes are set dynamically via properties. Properties correspond to |
| the standard Google Data API query parameters with YouTube Data API |
| extensions. |
| """ |
| |
| def __init__(self, username=None, feed_type=None, subscription_id=None, |
| text_query=None, params=None, categories=None): |
| |
| uploads_favorites_playlists = ('uploads', 'favorites', 'playlists') |
| |
| if feed_type is 'subscriptions' and subscription_id and username: |
| feed = "http://%s/feeds/users/%s/%s/%s" % (YOUTUBE_SERVER, username, |
| feed_type, subscription_id) |
| elif feed_type is 'subscriptions' and not subscription_id and username: |
| feed = "http://%s/feeds/users/%s/%s" % (YOUTUBE_SERVER, username, |
| feed_type) |
| elif feed_type in uploads_favorites_playlists: |
| feed = "http://%s/feeds/users/%s/%s" % (YOUTUBE_SERVER, username, |
| feed_type) |
| else: |
| feed = "http://%s/feeds/users" % (YOUTUBE_SERVER) |
| |
| YouTubeVideoQuery.__init__(self, feed=feed, text_query=text_query, |
| params=params, categories=categories) |
| |
| |
| class YouTubePlaylistQuery(YouTubeVideoQuery): |
| |
| """Subclasses YouTubeVideoQuery to perform playlist-specific queries. |
| |
| Attributes are set dynamically via properties. Properties correspond to |
| the standard Google Data API query parameters with YouTube Data API |
| extensions. |
| """ |
| |
| def __init__(self, playlist_id, text_query=None, params=None, |
| categories=None): |
| if playlist_id: |
| feed = "http://%s/feeds/playlists/%s" % (YOUTUBE_SERVER, playlist_id) |
| else: |
| feed = "http://%s/feeds/playlists" % (YOUTUBE_SERVER) |
| |
| YouTubeVideoQuery.__init__(self, feed=feed, text_query=text_query, |
| params=params, categories=categories) |