import httplib2 import os import random import sys import time from apiclient.discovery import build from apiclient.errors import HttpError from apiclient.http import MediaFileUpload from oauth2client.client import flow_from_clientsecrets from oauth2client.file import Storage from oauth2client.tools import argparser, run_flow from googleapiclient.http import MediaFileUpload # Explicitly tell the underlying HTTP transport library not to retry, since # we are handling retry logic ourselves. httplib2.RETRIES = 1 # Maximum number of times to retry before giving up. MAX_RETRIES = 10 # Always retry when these exceptions are raised. RETRIABLE_EXCEPTIONS = (httplib2.HttpLib2Error, IOError) # Always retry when an apiclient.errors.HttpError with one of these status # codes is raised. RETRIABLE_STATUS_CODES = [500, 502, 503, 504] try: import comfy except ModuleNotFoundError: print("comfy not found, using fallback") comfy = lambda: None comfy.__path__ = lambda: None comfy.__path__._path = ["."] comfy_dir = comfy.__path__._path[0] base_dir = os.path.dirname(comfy_dir) CLIENT_SECRETS_FILE = os.path.join(base_dir, "google-credentials.json") CLIENT_SECRETS_FILE = r"Q:\GDE\custom_nodes\EternalKernelLiteGraphNodes\modules\youtube.py-oauth2-secrets.json" # This OAuth 2.0 access scope allows an application to upload files to the # authenticated user's YouTube channel, but doesn't allow other types of access. YOUTUBE_UPLOAD_SCOPE = "https://www.googleapis.com/auth/youtube.upload" 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 API Console https://console.cloud.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)) VALID_PRIVACY_STATUSES = ("public", "private", "unlisted") def get_authenticated_service(args): flow = flow_from_clientsecrets(CLIENT_SECRETS_FILE, scope=YOUTUBE_UPLOAD_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) return build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION, http=credentials.authorize(httplib2.Http())) def initialize_upload(youtube_api, options): tags = None if options.keywords: tags = options.keywords.split(",") body = dict( snippet=dict( title=options.title, description=options.description, tags=tags, categoryId=options.category ), status=dict( privacyStatus=options.privacyStatus ) ) # Call the API's videos.insert method to create and upload the video. insert_request = youtube_api.videos().insert( part=",".join(body.keys()), body=body, media_body=MediaFileUpload(options.file, chunksize=-1, resumable=True) ) video_id = resumable_upload(insert_request) return video_id def resumable_upload(insert_request): response = None error = None retry = 0 while response is None: try: print("Uploading file...") status, response = insert_request.next_chunk() if response is not None: if 'id' in response: print("Video id '%s' was successfully uploaded." % response['id']) return response['id'] else: exit("The upload failed with an unexpected response: %s" % response) except HttpError as e: if e.resp.status in RETRIABLE_STATUS_CODES: error = "A retriable HTTP error %d occurred:\n%s" % (e.resp.status, e.content) else: raise except RETRIABLE_EXCEPTIONS as e: error = "A retriable error occurred: %s" % e if error is not None: print(error) retry += 1 if retry > MAX_RETRIES: exit("No longer attempting to retry.") max_sleep = 2 ** retry sleep_seconds = random.random() * max_sleep print("Sleeping %f seconds and then retrying..." % sleep_seconds) time.sleep(sleep_seconds) def upload_thumbnail(youtube, video_id, thumbnail_path): print("Uploading thumbnail...") request = youtube.thumbnails().set( videoId=video_id, media_body=MediaFileUpload(thumbnail_path) ) response = request.execute() print("Thumbnail uploaded successfully.") if __name__ == '__main__': argparser.add_argument("--file", required=True, help="Video file to upload") argparser.add_argument("--title", help="Video title", default="Test Title") argparser.add_argument("--description", help="Video description", default="Test Description") argparser.add_argument("--category", default="22", help="Numeric video category. See https://developers.google.com/youtube/v3/docs/videoCategories/list") argparser.add_argument("--keywords", help="Video keywords, comma separated", default="") argparser.add_argument("--privacyStatus", choices=VALID_PRIVACY_STATUSES, default=VALID_PRIVACY_STATUSES[0], help="Video privacy status.") argparser.add_argument("--thumbnail", help="Path to thumbnail image file") args = argparser.parse_args() if not os.path.exists(args.file): exit("Please specify a valid file using the --file= parameter.") youtube = get_authenticated_service(args) try: video_id = initialize_upload(youtube, args) if args.thumbnail: if not os.path.exists(args.thumbnail): print("Thumbnail file does not exist. Skipping thumbnail upload.") else: upload_thumbnail(youtube, video_id, args.thumbnail) except HttpError as e: print("An HTTP error %d occurred:\n%s" % (e.resp.status, e.content))