diff --git a/python/channel_section_localizations.py b/python/channel_section_localizations.py index a20ecf02..b809d5df 100644 --- a/python/channel_section_localizations.py +++ b/python/channel_section_localizations.py @@ -1,17 +1,22 @@ #!/usr/bin/python -# Usage example: +# Retrieve or set localized channel section metadata. +# See the Prerequisites section in the README file in this directory +# for more information about running this sample locally. + +# Usage examples: +# python channel_sections_localizations.py --action=list --mine=True # python channel_sections_localizations.py --action='' --channel_section_id='' --default_language='' --language='' --title='' -import httplib2 +import argparse import os -import sys +import re -from apiclient.discovery import build -from apiclient.errors import HttpError -from oauth2client.client import flow_from_clientsecrets -from oauth2client.file import Storage -from oauth2client.tools import argparser, run_flow +import google.oauth2.credentials +import google_auth_oauthlib.flow +from googleapiclient.discovery import build +from googleapiclient.errors import HttpError +from google_auth_oauthlib.flow import InstalledAppFlow # The CLIENT_SECRETS_FILE variable specifies the name of a file that contains @@ -25,135 +30,181 @@ # https://developers.google.com/youtube/v3/guides/authentication # For more information about the client_secrets.json file format, see: # https://developers.google.com/api-client-library/python/guide/aaa_client_secrets -CLIENT_SECRETS_FILE = "client_secrets.json" +CLIENT_SECRETS_FILE = 'client_secret.json' # This OAuth 2.0 access scope allows for full read/write access to the # authenticated user's account. -YOUTUBE_READ_WRITE_SCOPE = "https://www.googleapis.com/auth/youtube" -YOUTUBE_API_SERVICE_NAME = "youtube" -YOUTUBE_API_VERSION = "v3" - -# This variable defines a message to display if the CLIENT_SECRETS_FILE is -# missing. -MISSING_CLIENT_SECRETS_MESSAGE = """ -WARNING: Please configure OAuth 2.0 - -To make this sample run you will need to populate the client_secrets.json file -found at: - %s -with information from the APIs Console -https://console.developers.google.com - -For more information about the client_secrets.json file format, please visit: -https://developers.google.com/api-client-library/python/guide/aaa_client_secrets -""" % os.path.abspath(os.path.join(os.path.dirname(__file__), - CLIENT_SECRETS_FILE)) - -# Authorize the request and store authorization credentials. -def get_authenticated_service(args): - flow = flow_from_clientsecrets(CLIENT_SECRETS_FILE, scope=YOUTUBE_READ_WRITE_SCOPE, - message=MISSING_CLIENT_SECRETS_MESSAGE) - - storage = Storage("%s-oauth2.json" % sys.argv[0]) - credentials = storage.get() - - if credentials is None or credentials.invalid: - credentials = run_flow(flow, storage, args) +SCOPES = ['https://www.googleapis.com/auth/youtube'] +API_SERVICE_NAME = 'youtube' +API_VERSION = 'v3' - return build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION, - http=credentials.authorize(httplib2.Http())) +ACTIONS = ('get', 'list', 'set') +# Authorize the request and store authorization credentials. +def get_authenticated_service(): + flow = InstalledAppFlow.from_client_secrets_file(CLIENT_SECRETS_FILE, SCOPES) + credentials = flow.run_console() + return build(API_SERVICE_NAME, API_VERSION, credentials = credentials) # Call the API's channelSections.update method to update an existing channel section's # default language, and localized title in a specific language. -def set_channel_section_localization(youtube, channel_section_id, default_language, language, title): +def set_channel_section_localization(youtube, args): + + # Retrieve the snippet and localizations for the channel section. results = youtube.channelSections().list( - part="snippet,localizations", - id=channel_section_id + part='snippet,contentDetails,localizations', + id=args.channel_section_id ).execute() - channel_section = results["items"][0] - # Ensure that a value is set for the resource's snippet.defaultLanguage property. - channel_section["snippet"]["defaultLanguage"] = default_language - if "localizations" not in channel_section: - channel_section["localizations"] = {} - channel_section["localizations"][language] = { - "title": title - } + channel_section = results['items'][0] + + # If the language argument is set, set the localized title for that language. + # The "title" argument has a default value to make the script simpler to run + # as a demo. But in an actual app, you would likely want to set its value. + if args.language and args.language != '': + if 'localizations' not in channel_section: + channel_section['localizations'] = {} + + channel_section['localizations'][args.language] = { + 'title': args.title, + } + + # If the default language is set AND there is localized metadata for that + # language, set the channel section's title and description to match the + # localized title and description for the newly set default language. + if args.default_language: + channel_section['snippet']['defaultLanguage'] = args.default_language + if args.default_language in channel_section['localizations']: + channel_section['snippet']['title'] = ( + channel_section['localizations'][args.default_language]['title']) update_result = youtube.channelSections().update( - part="snippet,localizations", + part='snippet,contentDetails,localizations', body=channel_section ).execute() - localization = update_result["localizations"][language] - - print ("Updated channel section '%s' default language to '%s', localized title" - " to '%s' in language '%s'" % (channel_section_id, localization["title"], language)) - + if args.language: + for language in update_result['localizations']: + # Languages with locales, like "pt-br" are returned as pt-BR in metadata. + # This ensures that the language specified when running the script can be + # matched to the language returned in the metadata. + if language.lower() == args.language.lower(): + localization = update_result['localizations'][args.language] + print ('Updated channel section %s localized title to %s in \'%s\'.' % + (args.channel_section_id, localization['title'], args.language)) + break + + if (args.default_language and + args.default_language == update_result['snippet']['defaultLanguage']): + print 'Updated default language to %s.' % args.default_language # Call the API's channelSections.list method to retrieve an existing channel section localization. # If the localized text is not available in the requested language, # this method will return text in the default language. -def get_channel_section_localization(youtube, channel_section_id, language): +def get_channel_section_localization(youtube, args): results = youtube.channelSections().list( - part="snippet", - id=channel_section_id, - hl=language + part='snippet', + id=args.channel_section_id, + hl=args.language ).execute() # The localized object contains localized text if the hl parameter specified # a language for which localized text is available. Otherwise, the localized # object will contain metadata in the default language. - localized = results["items"][0]["snippet"]["localized"] - - print "Channel section title is '%s' in language '%s'" % (localized["title"], language) + localized = results['items'][0]['snippet']['localized'] + print('The channel section\'s title is \'%s\' in language \'%s\'.' % + (localized['title'], language)) -# Call the API's channelSections.list method to list the existing channel section localizations. -def list_channel_section_localizations(youtube, channel_section_id): +# Call the API's channelSections.list method to list all existing localizations +# for the channel section. +def list_channel_section_localizations(youtube, args): results = youtube.channelSections().list( - part="snippet,localizations", - id=channel_section_id + part='snippet,localizations', + id=args.channel_section_id ).execute() - localizations = results["items"][0]["localizations"] + localizations = results['items'][0]['localizations'] for language, localization in localizations.iteritems(): - print "Channel section title is '%s' in language '%s'" % (localization["title"], language) - - -if __name__ == "__main__": - # The "action" option specifies the action to be processed. - argparser.add_argument("--action", help="Action") - # The "channel_section_id" option specifies the ID of the selected YouTube channel section. - argparser.add_argument("--channel_section_id", - help="ID for channel section for which the localization will be applied.") - # The "default_language" option specifies the language of the channel section's default metadata. - argparser.add_argument("--default_language", - help="Default language of the channel section to update.", default="en") - # The "language" option specifies the language of the localization that is being processed. - argparser.add_argument("--language", help="Language of the localization.", default="de") - # The "title" option specifies the localized title of the channel section to be set. - argparser.add_argument("--title", help="Localized title of the channel section to be set.", - default="Localized Title") - - args = argparser.parse_args() - - if not args.channel_section_id: - exit("Please specify channel section id using the --channel_section_id= parameter.") - - youtube = get_authenticated_service(args) + print('The channel section title is \'%s\' in language \'%s\'.' % + (localization['title'], language)) + +# Call the API's channelSections.list method to list localizations for all +# channel sections in the authorizing user\'s channel. This function might +# be called as a way of identifying the ID of the section you actually want +# to update. +def list_my_channel_section_localizations(youtube, args): + results = youtube.channelSections().list( + part='snippet,localizations', + mine=True, + ).execute() + + print(results) + + for i in range(0, len(results['items'])): + item = results['items'][i] + print str(item['snippet']['position']) + ':' + print ' ID: ' + item['id'] + print ' Type: ' + item['snippet']['type'] + if ('title' in item['snippet'] and item['snippet']['title']): + print ' Title: ' + str(item['snippet']['title']) + + if 'localizations' in results['items'][i]: + localizations = results['items'][i]['localizations'] + print(' Localized titles by language:') + for language, localization in localizations.iteritems(): + print(' ' + language + ': ' + localization['title']) + else: + print(' No localizations. :(\n') + + #for language, localization in localizations.iteritems(): + # print('The channel section title is \'%s\' in language \'%s\'.' % + # (localization['title'], language)) + + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + # The 'action' option specifies the action to be processed. + parser.add_argument('--action', choices=ACTIONS, required=True, + help='The type of operation. Supported values are: "get", "list", "set"') + # The ID of the channel section for which data is being retrieved or updated. + parser.add_argument('--channel_section_id', + help='ID of channel section for which localized data is being ' + + 'retrieved or updated.') + # The language of the channel section's default metadata. + parser.add_argument('--default_language', + help='Default language of the channel section to update.') + # The language of the localization that is being processed. + parser.add_argument('--language', help='Language of the localized metadata.') + # The localized channel section title for the specified language. + parser.add_argument('--title', + help='Localized title of the channel section to be set.', + default='Localized Title') + # The language of the channel section's default metadata. + parser.add_argument('--mine', type=bool, default=False, + help='List localizations for all of my channel sections.') + + args = parser.parse_args() + + if not args.channel_section_id and not args.mine: + exit('You must either specify a channel section ID using the ' + + '--channel_section_id argument or retrieve localizations ' + + 'for all of your channel sections by setting the --mine ' + + 'argument to True.') + + youtube = get_authenticated_service() try: if args.action == 'set': - set_channel_section_localization(youtube, args.channel_section_id, args.default_language, args.language, args.title) + set_channel_section_localization(youtube, args) elif args.action == 'get': - get_channel_section_localization(youtube, args.channel_section_id, args.language) + get_channel_section_localization(youtube, args) elif args.action == 'list': - list_channel_section_localizations(youtube, args.channel_section_id) + if args.mine: + list_my_channel_section_localizations(youtube, args) + else: + list_channel_section_localizations(youtube, args) else: - exit("Please specify a valid action using the --action= parameter.") + exit('Please specify a valid action using the --action= parameter.') except HttpError, e: - print "An HTTP error %d occurred:\n%s" % (e.resp.status, e.content) - else: - print "Set and retrieved localized metadata for a channel section." + print 'An HTTP error %d occurred:\n%s' % (e.resp.status, e.content)