| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- from google_auth_oauthlib.flow import InstalledAppFlow
- from google.auth.transport.requests import Request
- import os
- import pickle
- import requests
- import logging
- from pathlib import Path
- # OAuth 2.0 scopes
- SCOPES = ["https://www.googleapis.com/auth/youtube.readonly"]
- # Configure logging
- logger = logging.getLogger(__name__)
- def get_token():
- """Perform OAuth authentication and save the token."""
- creds = None
- # The token file to save credentials
- token_file = "youtube_token.pickle"
- # Check if token file exists
- if os.path.exists(token_file):
- with open(token_file, "rb") as token:
- creds = pickle.load(token)
- # If no valid credentials, authenticate user
- 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=8080)
- # Save the credentials to a file
- with open(token_file, "wb") as token:
- pickle.dump(creds, token)
- print(f"Token saved to {token_file}")
- else:
- print("Token already exists and is valid.")
-
- return creds
- def create_cookies_from_token(output_file="youtube_cookies.txt"):
- """Create a cookies file using the OAuth token for yt-dlp authentication."""
- try:
- # Get valid credentials
- creds = get_token()
- if not creds:
- logger.error("No valid credentials available")
- return False
-
- # Create a session with the OAuth token
- session = requests.Session()
-
- # Add authorization header
- headers = {
- 'Authorization': f'Bearer {creds.token}',
- 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
- }
- session.headers.update(headers)
-
- # Make a request to YouTube to establish session
- try:
- response = session.get('https://www.youtube.com/', timeout=30)
- if response.status_code == 200:
- logger.info("Successfully authenticated with YouTube using OAuth token")
-
- # Extract cookies from the session
- cookies_content = "# Netscape HTTP Cookie File\n# Generated from OAuth token\n\n"
-
- for cookie in session.cookies:
- # Convert cookie to Netscape format
- domain = cookie.domain if cookie.domain else '.youtube.com'
- flag = 'TRUE' if domain.startswith('.') else 'FALSE'
- path = cookie.path if cookie.path else '/'
- secure = 'TRUE' if cookie.secure else 'FALSE'
- expires = str(int(cookie.expires)) if cookie.expires else '0'
-
- cookies_content += f"{domain}\t{flag}\t{path}\t{secure}\t{expires}\t{cookie.name}\t{cookie.value}\n"
-
- # Add essential YouTube cookies if they're missing
- essential_cookies = [
- ('.youtube.com', 'TRUE', '/', 'FALSE', '0', 'PREF', 'f1=50000000&hl=en'),
- ('.youtube.com', 'TRUE', '/', 'FALSE', '0', 'CONSENT', 'YES+'),
- ]
-
- for domain, flag, path, secure, expires, name, value in essential_cookies:
- if name not in [c.name for c in session.cookies]:
- cookies_content += f"{domain}\t{flag}\t{path}\t{secure}\t{expires}\t{name}\t{value}\n"
-
- # Write cookies file
- with open(output_file, 'w') as f:
- f.write(cookies_content)
-
- logger.info(f"Cookies file created: {output_file}")
- return True
- else:
- logger.error(f"Failed to authenticate with YouTube: {response.status_code}")
- return False
-
- except requests.RequestException as e:
- logger.error(f"Error making request to YouTube: {e}")
- return False
-
- except Exception as e:
- logger.error(f"Error creating cookies from token: {e}")
- return False
- def get_oauth_headers():
- """Get OAuth authorization headers for API requests."""
- try:
- creds = get_token()
- if not creds or not creds.valid:
- return None
-
- return {
- 'Authorization': f'Bearer {creds.token}',
- 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36'
- }
- except Exception as e:
- logger.error(f"Error getting OAuth headers: {e}")
- return None
- if __name__ == "__main__":
- import sys
-
- # Set up logging
- logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
-
- if "--create-cookies" in sys.argv:
- # Create cookies file from OAuth token
- output_file = "youtube_cookies.txt"
- if "--output" in sys.argv:
- output_idx = sys.argv.index("--output") + 1
- if output_idx < len(sys.argv):
- output_file = sys.argv[output_idx]
-
- print("Creating cookies file from OAuth token...")
- success = create_cookies_from_token(output_file)
- if success:
- print(f"✅ Cookies file created successfully: {output_file}")
- print("This file can now be used with yt-dlp for authentication")
- else:
- print("❌ Failed to create cookies file")
- sys.exit(1)
- else:
- # Default behavior - just get/refresh token
- creds = get_token()
- if creds:
- print("✅ OAuth token is valid and ready")
- print("💡 To create cookies for yt-dlp, run: python3 auth.py --create-cookies")
- else:
- print("❌ Failed to get valid OAuth token")
- sys.exit(1)
|