Murad Jabir 1 éve
szülő
commit
7b86d1dc1c
5 módosított fájl, 379 hozzáadás és 44 törlés
  1. 63 0
      AUTHENTICATION_SETUP.md
  2. 186 0
      PROXY_SETUP.md
  3. 12 36
      auth.py
  4. 7 8
      main.py
  5. 111 0
      proxy_config.py

+ 63 - 0
AUTHENTICATION_SETUP.md

@@ -0,0 +1,63 @@
+# Authentication Setup
+
+The YouTube Predownloader now uses simplified OAuth authentication for accessing your personal YouTube subscriptions.
+
+## Setup Instructions
+
+### 1. Get Google API Credentials
+
+1. Go to the [Google Cloud Console](https://console.cloud.google.com/)
+2. Create a new project or select an existing one
+3. Enable the **YouTube Data API v3**
+4. Go to **Credentials** → **Create Credentials** → **OAuth 2.0 Client ID**
+5. Choose **Desktop Application**
+6. Download the credentials as `client_secret.json`
+7. Place the file in your project directory
+
+### 2. Authenticate
+
+Run the interactive authentication:
+```bash
+python3 auth.py --interactive
+```
+
+This will:
+- Open a browser window
+- Ask you to sign in to Google
+- Request permission to access your YouTube data
+- Save the authentication token for future use
+
+### 3. Verify Authentication
+
+Test that authentication is working:
+```bash
+python3 -c "from auth import get_token_non_interactive; print('✅ Auth working' if get_token_non_interactive() else '❌ Auth failed')"
+```
+
+## Files
+
+- `client_secret.json` - Your OAuth credentials (keep private)
+- `youtube_token.pickle` - Saved authentication token (auto-generated)
+
+## Troubleshooting
+
+### Token Expired
+If you see authentication errors, re-run:
+```bash
+python3 auth.py --interactive
+```
+
+### Missing Permissions
+Make sure you granted permission to access your YouTube data during authentication.
+
+### No Subscriptions Found
+If you get 0 subscriptions, ensure:
+1. You're signed in to the correct Google account
+2. That account has YouTube subscriptions
+3. Authentication completed successfully
+
+## Security Notes
+
+- Keep `client_secret.json` private (add to .gitignore)
+- The `youtube_token.pickle` file contains your access token
+- Tokens expire and will be automatically refreshed when needed

+ 186 - 0
PROXY_SETUP.md

@@ -0,0 +1,186 @@
+# Proxy Configuration for YouTube Predownloader
+
+The YouTube Predownloader now supports SOCKS5, HTTP, and HTTPS proxies for all download operations, with special support for PIA (Private Internet Access) SOCKS5 proxies.
+
+## Supported Proxy Types
+
+1. **PIA SOCKS5 Proxy** (Integrated configuration)
+2. **SOCKS5 Proxy** (General)
+3. **HTTP Proxy**
+4. **HTTPS Proxy**
+
+## Configuration Methods
+
+### Method 1: PIA Configuration File (Recommended for PIA users)
+
+1. Edit `proxy_config.py` and set your PIA credentials:
+
+```python
+# PIA SOCKS5 Proxy Server Details
+PROXY_ADDRESS = "proxy-nl.privateinternetaccess.com"  # Choose your server
+PROXY_PORT = 1080
+PROXY_USER = "your_pia_username"  # Your actual PIA username
+PROXY_PASS = "your_pia_password"  # Your actual PIA password
+```
+
+2. Available PIA servers:
+   - Netherlands: `proxy-nl.privateinternetaccess.com`
+   - US East: `proxy-us-east.privateinternetaccess.com`
+   - US West: `proxy-us-west.privateinternetaccess.com`
+   - UK: `proxy-uk.privateinternetaccess.com`
+   - Germany: `proxy-de.privateinternetaccess.com`
+   - Canada: `proxy-ca.privateinternetaccess.com`
+   - Australia: `proxy-au.privateinternetaccess.com`
+
+3. Test your configuration:
+```bash
+python3 proxy_config.py
+python3 test_proxy.py
+```
+
+### Method 2: Environment Variables
+
+Set environment variables before running the script:
+
+```bash
+# SOCKS5 Proxy (highest priority)
+export SOCKS5_PROXY="socks5://username:password@proxy.example.com:1080"
+
+# HTTP Proxy (medium priority)
+export HTTP_PROXY="http://proxy.example.com:8080"
+
+# HTTPS Proxy (lowest priority)
+export HTTPS_PROXY="https://proxy.example.com:8080"
+
+# Then run the script
+python3 main.py
+```
+
+### Method 3: Direct Code Configuration
+
+Edit the proxy configuration section in `main.py`:
+
+```python
+# Override all other configurations
+HTTP_PROXY = "http://proxy.example.com:8080"
+HTTPS_PROXY = "https://proxy.example.com:8080"
+SOCKS5_PROXY = "socks5://127.0.0.1:1080"
+```
+
+## Priority Order
+
+The script uses proxies in this priority order:
+1. **PIA Configuration** (`proxy_config.py` if configured)
+2. **SOCKS5_PROXY** (environment variable)
+3. **HTTP_PROXY** (environment variable)
+4. **HTTPS_PROXY** (environment variable)
+5. **Direct connection** (no proxy)
+
+## Examples
+
+### Using PIA SOCKS5 Proxy
+1. Edit `proxy_config.py`:
+```python
+PROXY_ADDRESS = "proxy-us-east.privateinternetaccess.com"
+PROXY_USER = "p1234567"
+PROXY_PASS = "your_password"
+```
+
+2. Run the downloader:
+```bash
+python3 main.py
+```
+
+### Using Tor SOCKS5 Proxy
+```bash
+export SOCKS5_PROXY="socks5://127.0.0.1:9050"
+python3 main.py
+```
+
+### Using SSH SOCKS5 Tunnel
+```bash
+# Create SSH SOCKS5 tunnel
+ssh -D 1080 -C -N user@your-server.com &
+
+# Configure and run
+export SOCKS5_PROXY="socks5://127.0.0.1:1080"
+python3 main.py
+```
+
+### Using HTTP Proxy with Authentication
+```bash
+export HTTP_PROXY="http://username:password@proxy.example.com:8080"
+python3 main.py
+```
+
+## Testing Proxy Configuration
+
+### Test PIA Configuration
+```bash
+# Test PIA proxy settings
+python3 proxy_config.py
+
+# Comprehensive proxy test
+python3 test_proxy.py
+```
+
+The script will log the active proxy configuration on startup:
+
+```
+2025-08-31 10:30:15 - INFO - PIA SOCKS5 Proxy: proxy-nl.privateinternetaccess.com:1080 (user: p1234567)
+```
+
+During downloads, you'll see:
+```
+2025-08-31 10:30:30 - INFO - 🌐 Using PIA SOCKS5 proxy: proxy-nl.privateinternetaccess.com:1080
+```
+
+## Troubleshooting
+
+### Common Issues
+
+1. **Proxy not working**: Check if the proxy server is running and accessible
+2. **Authentication errors**: Ensure username/password are correctly encoded in the URL
+3. **Slow downloads**: SOCKS5 proxies may add latency depending on the route
+
+### Testing Proxy Connectivity
+
+Test your proxy with yt-dlp directly:
+
+```bash
+# Test PIA proxy (replace with your credentials)
+yt-dlp --proxy socks5://username:password@proxy-nl.privateinternetaccess.com:1080 --simulate "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
+
+# Test SOCKS5 proxy
+yt-dlp --proxy socks5://127.0.0.1:1080 --simulate "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
+
+# Test HTTP proxy
+yt-dlp --proxy http://proxy.example.com:8080 --simulate "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
+```
+
+## Disabling Proxy
+
+To disable proxy usage:
+
+```bash
+# Remove environment variables
+unset SOCKS5_PROXY
+unset HTTP_PROXY
+unset HTTPS_PROXY
+
+# Disable PIA configuration in proxy_config.py
+python3 main.py
+```
+
+Or rename/delete the proxy configuration file:
+```bash
+mv proxy_config.py proxy_config.py.disabled
+python3 main.py
+```
+
+## Security Notes
+
+- Always use HTTPS URLs when possible
+- Be cautious with proxy authentication credentials in environment variables
+- Consider using encrypted proxy protocols like SOCKS5 over SSH tunnels
+- Test proxy configuration before running long download sessions

+ 12 - 36
auth.py

@@ -1,6 +1,5 @@
 from google_auth_oauthlib.flow import InstalledAppFlow
 from google.auth.transport.requests import Request
-from google.oauth2 import service_account
 import os
 import pickle
 import json
@@ -8,28 +7,6 @@ import json
 # OAuth 2.0 scopes
 SCOPES = ["https://www.googleapis.com/auth/youtube.readonly"]
 
-def get_service_account_token():
-    """Authenticate using service account (no user interaction needed)."""
-    service_account_file = "service_account.json"
-    
-    if not os.path.exists(service_account_file):
-        print(f"Service account file {service_account_file} not found.")
-        print("To use service account authentication:")
-        print("1. Go to Google Cloud Console")
-        print("2. Navigate to IAM & Admin > Service Accounts")
-        print("3. Create a new service account")
-        print("4. Download the JSON key file as 'service_account.json'")
-        return None
-    
-    try:
-        creds = service_account.Credentials.from_service_account_file(
-            service_account_file, scopes=SCOPES)
-        print("Service account authentication successful!")
-        return creds
-    except Exception as e:
-        print(f"Service account authentication failed: {e}")
-        return None
-
 def get_token_interactive():
     """Perform OAuth authentication with user interaction."""
     creds = None
@@ -65,37 +42,36 @@ def get_token_interactive():
     return creds
 
 def get_token_non_interactive():
-    """Try non-interactive authentication methods first."""
-    # Try service account first
-    creds = get_service_account_token()
-    if creds:
-        return creds
-    
-    # Try existing saved token
+    """Try to use existing saved OAuth token."""
     token_file = "youtube_token.pickle"
+    
     if os.path.exists(token_file):
         try:
             with open(token_file, "rb") as token:
                 creds = pickle.load(token)
             
             if creds and creds.valid:
-                print("Using existing valid token.")
+                print("Using existing valid OAuth token.")
                 return creds
             elif creds and creds.expired and creds.refresh_token:
                 try:
                     creds.refresh(Request())
-                    print("Token refreshed successfully!")
+                    print("OAuth token refreshed successfully!")
                     # Save refreshed token
                     with open(token_file, "wb") as token:
                         pickle.dump(creds, token)
                     return creds
                 except Exception as e:
-                    print(f"Token refresh failed: {e}")
+                    print(f"OAuth token refresh failed: {e}")
         except Exception as e:
-            print(f"Error loading saved token: {e}")
+            print(f"Error loading saved OAuth token: {e}")
+    
+    print("No valid OAuth token found.")
+    print("Run: python3 auth.py --interactive to authenticate.")
+    return None
     
-    print("No valid non-interactive authentication method available.")
-    print("Run with --interactive flag or set up service account authentication.")
+    print("No valid non-interactive OAuth token available.")
+    print("Run: python3 auth.py --interactive to authenticate.")
     return None
 
 def get_token():

+ 7 - 8
main.py

@@ -14,7 +14,7 @@ from googleapiclient.discovery import build
 import subprocess
 from google.auth.transport.requests import Request
 import sys
-from auth import get_token, get_token_non_interactive, get_service_account_token
+from auth import get_token, get_token_non_interactive
 
 # Home Assistant Integration
 try:
@@ -51,7 +51,7 @@ DAYS_TO_KEEP = 10  # Delete videos older than 10 days
 TOKEN_FILE = "youtube_token.pickle"  # Token file from the OAuth script
 EXIT_TIME = dt_time(6, 0)  # Exit the script at 06:00
 POPULAR_VIDEOS_MAX_RESULTS = 10  # Number of popular videos to fetch (you can change this)
-REGION_CODES = ["US", "GB", "LU", "LK"]  # Regions to fetch popular videos from
+REGION_CODES = ["LK"]  # Regions to fetch popular videos from
 
 # Logging Configuration
 LOG_DIR = "logs"
@@ -236,20 +236,19 @@ def update_yt_dlp():
         raise
 
 def authenticate_youtube_api():
-    """Authenticate using our enhanced auth system (tries non-interactive first)."""
+    """Authenticate using OAuth token."""
     logger = logging.getLogger(__name__)
-    logger.info("Attempting non-interactive authentication...")
+    logger.info("Attempting OAuth authentication...")
     
     # Try non-interactive authentication first
     creds = get_token_non_interactive()
     
     if not creds:
-        logger.error("Non-interactive authentication failed.")
+        logger.error("OAuth authentication failed.")
         logger.info("You need to run: python3 auth.py --interactive")
-        logger.info("Or set up service account authentication.")
-        raise Exception("Authentication failed. No valid credentials available.")
+        raise Exception("Authentication failed. No valid OAuth credentials available.")
     
-    logger.info("Authentication successful!")
+    logger.info("OAuth authentication successful!")
     
     # Build the YouTube API client
     youtube = build("youtube", "v3", credentials=creds)

+ 111 - 0
proxy_config.py

@@ -0,0 +1,111 @@
+# PIA (Private Internet Access) SOCKS5 Proxy Configuration
+# Replace these values with your actual PIA credentials and preferred server
+
+# PIA SOCKS5 Proxy Server Details
+# You can find the full list of PIA SOCKS5 servers at:
+# https://www.privateinternetaccess.com/helpdesk/guides/desktop/linux/linux-openvpn-socks-proxy
+
+# Common PIA SOCKS5 servers:
+PROXY_ADDRESS = "proxy-nl.privateinternetaccess.com"  # Netherlands server
+# PROXY_ADDRESS = "proxy-us-east.privateinternetaccess.com"  # US East
+# PROXY_ADDRESS = "proxy-us-west.privateinternetaccess.com"  # US West
+# PROXY_ADDRESS = "proxy-uk.privateinternetaccess.com"      # UK
+# PROXY_ADDRESS = "proxy-de.privateinternetaccess.com"      # Germany
+# PROXY_ADDRESS = "proxy-ca.privateinternetaccess.com"      # Canada
+# PROXY_ADDRESS = "proxy-au.privateinternetaccess.com"      # Australia
+
+PROXY_PORT = 1080  # Standard SOCKS5 port for PIA
+
+# Your PIA credentials
+# IMPORTANT: Replace these with your actual PIA username and password
+PROXY_USER = "x7652327"  # Replace with your PIA username
+PROXY_PASS = "XEf6mg5zFK"  # Replace with your PIA password
+
+# Alternative servers by region (uncomment and use as needed):
+SERVERS = {
+    "netherlands": "proxy-nl.privateinternetaccess.com",
+    "us_east": "proxy-us-east.privateinternetaccess.com", 
+    "us_west": "proxy-us-west.privateinternetaccess.com",
+    "uk": "proxy-uk.privateinternetaccess.com",
+    "germany": "proxy-de.privateinternetaccess.com",
+    "canada": "proxy-ca.privateinternetaccess.com",
+    "australia": "proxy-au.privateinternetaccess.com",
+    "japan": "proxy-jp.privateinternetaccess.com",
+    "singapore": "proxy-sg.privateinternetaccess.com"
+}
+
+def get_proxy_url():
+    """Generate the complete SOCKS5 proxy URL with authentication."""
+    if PROXY_USER and PROXY_PASS and PROXY_ADDRESS:
+        return f"socks5://{PROXY_USER}:{PROXY_PASS}@{PROXY_ADDRESS}:{PROXY_PORT}"
+    elif PROXY_ADDRESS:
+        return f"socks5://{PROXY_ADDRESS}:{PROXY_PORT}"
+    else:
+        return None
+
+def get_proxy_info():
+    """Get proxy configuration information."""
+    return {
+        "address": PROXY_ADDRESS,
+        "port": PROXY_PORT,
+        "username": PROXY_USER,
+        "password": PROXY_PASS,
+        "url": get_proxy_url()
+    }
+
+# Test connectivity function
+def test_proxy_connectivity():
+    """Test if the proxy configuration is working."""
+    import subprocess
+    import sys
+    
+    proxy_url = get_proxy_url()
+    if not proxy_url:
+        print("❌ No proxy configuration found")
+        return False
+    
+    print(f"🧪 Testing PIA SOCKS5 proxy: {PROXY_ADDRESS}:{PROXY_PORT}")
+    print(f"👤 Username: {PROXY_USER}")
+    
+    try:
+        # Test with a simple curl command
+        test_cmd = [
+            "curl", "--socks5", f"{PROXY_USER}:{PROXY_PASS}@{PROXY_ADDRESS}:{PROXY_PORT}",
+            "--connect-timeout", "10",
+            "--max-time", "15",
+            "https://ipinfo.io/ip"
+        ]
+        
+        result = subprocess.run(test_cmd, capture_output=True, text=True, timeout=20)
+        
+        if result.returncode == 0:
+            ip = result.stdout.strip()
+            print(f"✅ Proxy is working! External IP: {ip}")
+            return True
+        else:
+            print(f"❌ Proxy test failed: {result.stderr.strip()}")
+            return False
+            
+    except subprocess.TimeoutExpired:
+        print("⏰ Proxy test timed out")
+        return False
+    except FileNotFoundError:
+        print("⚠️ curl not found, cannot test proxy connectivity")
+        return False
+    except Exception as e:
+        print(f"💥 Error testing proxy: {e}")
+        return False
+
+if __name__ == "__main__":
+    print("PIA SOCKS5 Proxy Configuration")
+    print("=" * 40)
+    
+    info = get_proxy_info()
+    print(f"Address: {info['address']}")
+    print(f"Port: {info['port']}")
+    print(f"Username: {info['username']}")
+    print(f"Password: {'*' * len(info['password']) if info['password'] else 'Not set'}")
+    print(f"Full URL: {info['url']}")
+    
+    print("\n" + "=" * 40)
+    test_proxy_connectivity()