Skip to content

Instantly share code, notes, and snippets.

@arseniy-panfilov
Created September 15, 2022 01:26
Show Gist options
  • Save arseniy-panfilov/3c2a024388dc64e469944f78e348f1af to your computer and use it in GitHub Desktop.
Save arseniy-panfilov/3c2a024388dc64e469944f78e348f1af to your computer and use it in GitHub Desktop.
Script to bulk share albums created via Google Photos API. Primary use was to bypass the API bug which only returns 100 photos per album: once the album is shared, API starts to properly return all photos.
#!/usr/bin/env python
# coding: utf-8
import os
import pickle
import json
from time import sleep
import google_auth_httplib2 # This gotta be installed for build() to work
from googleapiclient.discovery import build
from googleapiclient.http import HttpError
from google.auth.transport.requests import Request
from google_auth_oauthlib.flow import InstalledAppFlow
# Setup the Photo v1 API. You'll need to download client_secret.json and put it next to this script.
# In Google Cloud console: Credentials -> [OAuth 2.0 Client ID credentials] -> DOWNLOAD JSON (button is at the top of the screen)
SCOPES = ['https://www.googleapis.com/auth/photoslibrary.readonly', "https://www.googleapis.com/auth/photoslibrary.sharing"]
creds = None
if(os.path.exists("token.pickle")):
with open("token.pickle", "rb") as tokenFile:
creds = pickle.load(tokenFile)
if not creds or not creds.valid:
if (creds and creds.expired and creds.refresh_token):
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file('client_secret.json', SCOPES)
creds = flow.run_local_server(port = 0)
with open("token.pickle", "wb") as tokenFile:
pickle.dump(creds, tokenFile)
service = build('photoslibrary', 'v1', credentials = creds, static_discovery=False)
# Pull albums
albums = []
next_page = None
start = True
while next_page or start:
start = False
results = service.albums().list(pageSize=50, fields="nextPageToken,albums(id,title,shareInfo)", pageToken=next_page).execute()
albums += results.get('albums', [])
next_page = results.get('nextPageToken')
albums_dict = {a['id']: a['title'] for a in albums}
already_shared = {a['id'] for a in albums if a.get('shareInfo')}
# Uncomment to review already shared albums
#for album_id in already_shared:
#print(albums_dict[album_id])
# Without these sharing has no effect
share_body = {
'sharedAlbumOptions': {
'isCollaborative': True,
'isCommentable': True
}
}
not_shared = {album_id for album_id in albums_dict.keys() if album_id not in already_shared}
for album_id in not_shared:
try:
service.albums().share(albumId=album_id, body=share_body).execute()
print("Shared '%s'" % albums_dict[album_id])
except HttpError as e:
print("Couldn't share '%s' (%s)" % (albums_dict[album_id], e))
# the API limit is 30 requests per minute and I'm good at math
sleep(2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment