@ -1,6 +1,6 @@
#!/usr/bin/env python
# coding: utf-8
# From Youtube samples : https://raw.githubusercontent.com/youtube/api-samples/master/python/upload_video.py # noqa
# From Youtube samples: https://raw.githubusercontent.com/youtube/api-samples/master/python/upload_video.py # noqa
import http.client
import httplib2
@ -60,6 +60,7 @@ def get_authenticated_service():
check_authenticated_scopes ( )
flow = InstalledAppFlow . from_client_secrets_file (
CLIENT_SECRETS_FILE , SCOPES )
if exists ( CREDENTIALS_PATH ) :
with open ( CREDENTIALS_PATH , ' r ' ) as f :
credential_params = json . load ( f )
@ -76,7 +77,7 @@ def get_authenticated_service():
p = copy . deepcopy ( vars ( credentials ) )
del p [ " expiry " ]
json . dump ( p , f )
return build ( API_SERVICE_NAME , API_VERSION , credentials = credentials , cache_discovery = False )
return build ( API_SERVICE_NAME , API_VERSION , credentials = credentials , cache_discovery = False )
def check_authenticated_scopes ( ) :
@ -181,14 +182,24 @@ def initialize_upload(youtube, options):
def get_playlist_by_name ( youtube , playlist_name ) :
response = youtube . playlists ( ) . list (
part = ' snippet,id ' ,
mine = True ,
maxResults = 50
) . execute ( )
for playlist in response [ " items " ] :
if playlist [ " snippet " ] [ ' title ' ] == playlist_name :
return playlist [ ' id ' ]
pageToken = " "
while pageToken != None :
response = youtube . playlists ( ) . list (
part = ' snippet,id ' ,
mine = True ,
maxResults = 50 ,
pageToken = pageToken
) . execute ( )
for playlist in response [ " items " ] :
if playlist [ " snippet " ] [ " title " ] == playlist_name :
return playlist [ " id " ]
# Ask next page if there are any
if " nextPageToken " in response :
pageToken = response [ " nextPageToken " ]
else :
pageToken = None
def create_playlist ( youtube , playlist_name ) :
@ -293,7 +304,7 @@ def resumable_upload(request, resource, method, options):
status , response = request . next_chunk ( )
if response is not None :
if method == ' insert ' and ' id ' in response :
logger . info ( ' Youtube : Video was successfully uploaded. ' )
logger . info ( ' Youtube: Video was successfully uploaded. ' )
template = ' Youtube: Watch it at https://youtu.be/ %s (post-encoding could take some time) '
logger . info ( template % response [ ' id ' ] )
template_stdout = ' https://youtu.be/ %s '
@ -305,36 +316,51 @@ def resumable_upload(request, resource, method, options):
elif method != ' insert ' or " id " not in response :
logger . info ( ' Youtube: Thumbnail was successfully set. ' )
else :
template = ( ' Youtube : The upload failed with an '
template = ( ' Youtube: The upload failed with an '
' unexpected response: %s ' )
logger . critical ( template % response )
exit ( 1 )
except HttpError as e :
if e . resp . status in RETRIABLE_STATUS_CODES :
template = ' Youtube : A retriable HTTP error %d occurred: \n %s '
template = ' Youtube: A retriable HTTP error %d occurred: \n %s '
error = template % ( e . resp . status , e . content )
else :
raise
except RETRIABLE_EXCEPTIONS as e :
error = ' Youtube : A retriable error occurred: %s ' % e
error = ' Youtube: A retriable error occurred: %s ' % e
if error is not None :
logger . warning ( error )
retry + = 1
if retry > MAX_RETRIES :
logger . error ( ' Youtube : No longer attempting to retry. ' )
logger . error ( ' Youtube: No longer attempting to retry. ' )
max_sleep = 2 * * retry
sleep_seconds = random . random ( ) * max_sleep
logger . warning ( ' Youtube : Sleeping %f seconds and then retrying... '
logger . warning ( ' Youtube: Sleeping %f seconds and then retrying... '
% sleep_seconds )
time . sleep ( sleep_seconds )
def hearthbeat ( ) :
""" Use the minimums credits possibles of the API so google does not readuce to 0 the allowed credits.
This apparently happens after 90 days without any usage of credits .
For more info see the official documentations :
- General informations about quotas : https : / / developers . google . com / youtube / v3 / getting - started #quota
- Quota costs for API requests : https : / / developers . google . com / youtube / v3 / determine_quota_cost
- ToS ( Americas ) #Usage and Quotas: https://developers.google.com/youtube/terms/api-services-terms-of-service#usage-and-quotas"""
youtube = get_authenticated_service ( )
try :
get_playlist_by_name ( youtube , " Foo " )
except HttpError as e :
logger . error ( ' Youtube: An HTTP error %d occurred on hearthbeat: \n %s ' %
( e . resp . status , e . content ) )
def run ( options ) :
youtube = get_authenticated_service ( )
try :
initialize_upload ( youtube , options )
except HttpError as e :
logger . error ( ' Youtube : An HTTP error %d occurred: \n %s ' % ( e . resp . status ,
logger . error ( ' Youtube: An HTTP error %d occurred: \n %s ' % ( e . resp . status ,
e . content ) )