Update calendar registration for headless environment

This commit is contained in:
ChuckBuilds
2025-04-21 09:14:50 -05:00
parent 62afd33154
commit f4b37d012b

View File

@@ -5,9 +5,6 @@ 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 webbrowser
from http.server import HTTPServer, BaseHTTPRequestHandler
import threading
import urllib.parse import urllib.parse
import socket import socket
@@ -23,32 +20,6 @@ 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)
class OAuthHandler(BaseHTTPRequestHandler):
def do_GET(self):
# Parse the query parameters
query_components = urllib.parse.parse_qs(urllib.parse.urlparse(self.path).query)
if 'code' in query_components:
# Store the authorization code
self.server.auth_code = query_components['code'][0]
# Send success response to browser
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
self.wfile.write(b"Authorization successful! You can close this window.")
else:
# Send error response
self.send_response(400)
self.send_header('Content-type', 'text/html')
self.end_headers()
self.wfile.write(b"Authorization failed! Please try again.")
def get_free_port():
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind(('', 0))
return s.getsockname()[1]
def main(): def main():
config = load_config() config = load_config()
calendar_config = config.get('calendar', {}) calendar_config = config.get('calendar', {})
@@ -77,39 +48,23 @@ def main():
print("6. Download the credentials and save as credentials.json") print("6. Download the credentials and save as credentials.json")
return return
# Get a free port for the local server
port = get_free_port()
redirect_uri = f'http://localhost:{port}'
# Create the flow using the client secrets file from the Google API Console # Create the flow using the client secrets file from the Google API Console
flow = InstalledAppFlow.from_client_secrets_file( flow = InstalledAppFlow.from_client_secrets_file(
creds_file, SCOPES, creds_file, SCOPES,
redirect_uri=redirect_uri redirect_uri='urn:ietf:wg:oauth:2.0:oob' # Use out-of-band flow for headless environment
) )
# Start local server to receive the OAuth callback
server = HTTPServer(('localhost', port), OAuthHandler)
server.auth_code = None
server_thread = threading.Thread(target=server.serve_forever)
server_thread.daemon = True
server_thread.start()
# Generate URL for authorization # Generate URL for authorization
auth_url, _ = flow.authorization_url(prompt='consent') auth_url, _ = flow.authorization_url(prompt='consent')
print("\nOpening your browser to authorize this application...") print("\nPlease visit this URL to authorize this application:")
webbrowser.open(auth_url) print(auth_url)
print("\nAfter authorizing, you will receive a code. Enter that code below:")
print("\nWaiting for authorization...") code = input("Enter the authorization code: ")
while server.auth_code is None:
pass
# Stop the server
server.shutdown()
server.server_close()
# Exchange the authorization code for credentials # Exchange the authorization code for credentials
flow.fetch_token(code=server.auth_code) flow.fetch_token(code=code)
creds = flow.credentials creds = flow.credentials
# Save the credentials # Save the credentials