mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-04-10 13:02:59 +00:00
Update calendar registration to use TV and Limited Input Device flow
This commit is contained in:
@@ -5,8 +5,7 @@ from google_auth_oauthlib.flow import InstalledAppFlow
|
|||||||
from google.oauth2.credentials import Credentials
|
from google.oauth2.credentials import Credentials
|
||||||
from google.auth.transport.requests import Request
|
from google.auth.transport.requests import Request
|
||||||
import pickle
|
import pickle
|
||||||
import urllib.parse
|
import requests
|
||||||
import socket
|
|
||||||
|
|
||||||
# If modifying these scopes, delete the file token.pickle.
|
# If modifying these scopes, delete the file token.pickle.
|
||||||
SCOPES = ['https://www.googleapis.com/auth/calendar.readonly']
|
SCOPES = ['https://www.googleapis.com/auth/calendar.readonly']
|
||||||
@@ -20,6 +19,28 @@ def save_credentials(creds, token_path):
|
|||||||
with open(token_path, 'wb') as token:
|
with open(token_path, 'wb') as token:
|
||||||
pickle.dump(creds, token)
|
pickle.dump(creds, token)
|
||||||
|
|
||||||
|
def get_device_code(client_id, client_secret):
|
||||||
|
"""Get device code for TV and Limited Input Device flow."""
|
||||||
|
url = 'https://oauth2.googleapis.com/device/code'
|
||||||
|
data = {
|
||||||
|
'client_id': client_id,
|
||||||
|
'scope': ' '.join(SCOPES)
|
||||||
|
}
|
||||||
|
response = requests.post(url, data=data)
|
||||||
|
return response.json()
|
||||||
|
|
||||||
|
def poll_for_token(client_id, client_secret, device_code):
|
||||||
|
"""Poll for token using device code."""
|
||||||
|
url = 'https://oauth2.googleapis.com/token'
|
||||||
|
data = {
|
||||||
|
'client_id': client_id,
|
||||||
|
'client_secret': client_secret,
|
||||||
|
'device_code': device_code,
|
||||||
|
'grant_type': 'urn:ietf:params:oauth:grant-type:device_code'
|
||||||
|
}
|
||||||
|
response = requests.post(url, data=data)
|
||||||
|
return response.json()
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
config = load_config()
|
config = load_config()
|
||||||
calendar_config = config.get('calendar', {})
|
calendar_config = config.get('calendar', {})
|
||||||
@@ -43,34 +64,54 @@ def main():
|
|||||||
print("1. Go to https://console.cloud.google.com")
|
print("1. Go to https://console.cloud.google.com")
|
||||||
print("2. Create a project or select existing project")
|
print("2. Create a project or select existing project")
|
||||||
print("3. Enable the Google Calendar API")
|
print("3. Enable the Google Calendar API")
|
||||||
print("4. Configure the OAuth consent screen")
|
print("4. Configure the OAuth consent screen (select TV and Limited Input Device)")
|
||||||
print("5. Create OAuth 2.0 credentials (Desktop application)")
|
print("5. Create OAuth 2.0 credentials (TV and Limited Input Device)")
|
||||||
print("6. Download the credentials and save as credentials.json")
|
print("6. Download the credentials and save as credentials.json")
|
||||||
return
|
return
|
||||||
|
|
||||||
# Create the flow using the client secrets file from the Google API Console
|
# Load client credentials
|
||||||
flow = InstalledAppFlow.from_client_secrets_file(
|
with open(creds_file, 'r') as f:
|
||||||
creds_file, SCOPES,
|
client_config = json.load(f)
|
||||||
redirect_uri='urn:ietf:wg:oauth:2.0:oob' # Use out-of-band flow for headless environment
|
|
||||||
)
|
client_id = client_config['installed']['client_id']
|
||||||
|
client_secret = client_config['installed']['client_secret']
|
||||||
|
|
||||||
# Generate URL for authorization
|
# Get device code
|
||||||
auth_url, _ = flow.authorization_url(prompt='consent')
|
device_info = get_device_code(client_id, client_secret)
|
||||||
|
|
||||||
print("\nPlease visit this URL to authorize this application:")
|
print("\nTo authorize this application, visit:")
|
||||||
print(auth_url)
|
print(device_info['verification_url'])
|
||||||
print("\nAfter authorizing, you will receive a code. Enter that code below:")
|
print("\nAnd enter the code:")
|
||||||
|
print(device_info['user_code'])
|
||||||
code = input("Enter the authorization code: ")
|
print("\nWaiting for authorization...")
|
||||||
|
|
||||||
# Exchange the authorization code for credentials
|
|
||||||
flow.fetch_token(code=code)
|
|
||||||
creds = flow.credentials
|
|
||||||
|
|
||||||
# Save the credentials
|
# Poll for token
|
||||||
save_credentials(creds, token_file)
|
while True:
|
||||||
print(f"\nCredentials saved successfully to {token_file}")
|
token_info = poll_for_token(client_id, client_secret, device_info['device_code'])
|
||||||
print("You can now run the LED Matrix display with calendar integration!")
|
|
||||||
|
if 'access_token' in token_info:
|
||||||
|
# Create credentials object
|
||||||
|
creds = Credentials(
|
||||||
|
token=token_info['access_token'],
|
||||||
|
refresh_token=token_info.get('refresh_token'),
|
||||||
|
token_uri="https://oauth2.googleapis.com/token",
|
||||||
|
client_id=client_id,
|
||||||
|
client_secret=client_secret,
|
||||||
|
scopes=SCOPES
|
||||||
|
)
|
||||||
|
|
||||||
|
# Save the credentials
|
||||||
|
save_credentials(creds, token_file)
|
||||||
|
print(f"\nCredentials saved successfully to {token_file}")
|
||||||
|
print("You can now run the LED Matrix display with calendar integration!")
|
||||||
|
break
|
||||||
|
elif token_info.get('error') == 'authorization_pending':
|
||||||
|
import time
|
||||||
|
time.sleep(device_info['interval'])
|
||||||
|
else:
|
||||||
|
print(f"\nError during authorization: {token_info.get('error')}")
|
||||||
|
print("Please try again.")
|
||||||
|
return
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
Reference in New Issue
Block a user