live / src /drive_uploader.py
ayush77uh's picture
SECURITY: Remove full credential logging
0301023
Raw
History Blame Contribute Delete
3.85 kB
"""
Google Drive Auto-Uploader using OAuth2 refresh token.
Works with personal Google accounts (not just Workspace).
"""
import os
import json
from google.oauth2.credentials import Credentials
from google.auth.transport.requests import Request
from googleapiclient.discovery import build
from googleapiclient.http import MediaFileUpload
# Scopes required for Drive upload
SCOPES = ['https://www.googleapis.com/auth/drive']
def get_drive_service():
"""
Creates a Google Drive API service using OAuth2 refresh token.
Requires 3 env vars: GOOGLE_OAUTH_CLIENT_ID, GOOGLE_OAUTH_CLIENT_SECRET, GOOGLE_DRIVE_REFRESH_TOKEN
"""
client_id = os.getenv("GOOGLE_OAUTH_CLIENT_ID", "").strip()
client_secret = os.getenv("GOOGLE_OAUTH_CLIENT_SECRET", "").strip()
refresh_token = os.getenv("GOOGLE_DRIVE_REFRESH_TOKEN", "").strip()
if not all([client_id, client_secret, refresh_token]):
missing = []
if not client_id: missing.append("GOOGLE_OAUTH_CLIENT_ID")
if not client_secret: missing.append("GOOGLE_OAUTH_CLIENT_SECRET")
if not refresh_token: missing.append("GOOGLE_DRIVE_REFRESH_TOKEN")
print(f"ERROR: Missing env vars: {', '.join(missing)}", flush=True)
return None
# Debug: Print first few chars to verify (Don't log full secrets!)
print(f"DEBUG: Client ID: {client_id[:5]}... (len={len(client_id)})", flush=True)
print(f"DEBUG: Client Secret: {client_secret[:3]}... (len={len(client_secret)})", flush=True)
print(f"DEBUG: Refresh Token: {refresh_token[:5]}... (len={len(refresh_token)})", flush=True)
try:
creds = Credentials(
token=None,
refresh_token=refresh_token,
client_id=client_id,
client_secret=client_secret,
token_uri="https://oauth2.googleapis.com/token",
scopes=SCOPES
)
# Refresh the access token
creds.refresh(Request())
service = build('drive', 'v3', credentials=creds)
print("βœ… Google Drive connected (OAuth2)!", flush=True)
return service
except Exception as e:
print(f"❌ Failed to connect to Google Drive: {e}", flush=True)
return None
def upload_to_drive(file_path, folder_id=None):
"""
Uploads a file to Google Drive using the user's own account.
Args:
file_path: Path to the file to upload
folder_id: Google Drive folder ID
Returns:
The file URL on Google Drive, or None if upload failed
"""
if not folder_id:
folder_id = os.getenv("GOOGLE_DRIVE_FOLDER_ID")
if not folder_id:
print("ERROR: GOOGLE_DRIVE_FOLDER_ID not set!", flush=True)
return None
service = get_drive_service()
if not service:
return None
filename = os.path.basename(file_path)
file_size_mb = os.path.getsize(file_path) / (1024 * 1024)
print(f"πŸ“€ Uploading {filename} ({file_size_mb:.1f} MB) to Google Drive...", flush=True)
file_metadata = {
'name': filename,
'parents': [folder_id]
}
media = MediaFileUpload(
file_path,
mimetype='video/mp4',
resumable=True,
chunksize=10 * 1024 * 1024 # 10MB chunks
)
try:
file = service.files().create(
body=file_metadata,
media_body=media,
fields='id, webViewLink'
).execute()
file_id = file.get('id')
file_link = file.get('webViewLink', f"https://drive.google.com/file/d/{file_id}/view")
print(f"βœ… Upload SUCCESS: {filename}", flush=True)
print(f"πŸ“Ž Link: {file_link}", flush=True)
return file_link
except Exception as e:
print(f"❌ Upload FAILED: {e}", flush=True)
return None