import os import requests import schedule import time import base64 from datetime import datetime from flask import Flask, Response from threading import Thread # Configuration ENCODED_SOURCE_URL = os.environ.get('ENCODED_SOURCE_URL', '') # Fallback to a direct URL if no encoded URL is provided SOURCE_URL = base64.b64decode(ENCODED_SOURCE_URL).decode('utf-8') if ENCODED_SOURCE_URL else os.environ.get('SOURCE_URL', 'http://example.com/source.m3u8') PORT = int(os.environ.get('PORT', 8000)) M3U8_DIR = '/m3u8' LOCAL_FILE_PATH = os.path.join(M3U8_DIR, 'playlist.m3u8') # Set a long timeout (10 minutes) for downloading large M3U8 files DOWNLOAD_TIMEOUT = 600 # seconds app = Flask(__name__) def download_m3u8(): """Download the M3U8 file from the source URL""" try: # Ensure the directory exists os.makedirs(M3U8_DIR, exist_ok=True) print(f"{datetime.now()} - Downloading M3U8 from source (timeout: {DOWNLOAD_TIMEOUT}s)") response = requests.get(SOURCE_URL, timeout=DOWNLOAD_TIMEOUT) if response.status_code == 200: with open(LOCAL_FILE_PATH, 'wb') as f: f.write(response.content) print(f"{datetime.now()} - M3U8 file downloaded successfully to {LOCAL_FILE_PATH}") return True else: print(f"{datetime.now()} - Failed to download M3U8. Status code: {response.status_code}") return False except requests.exceptions.Timeout: print(f"{datetime.now()} - Timeout error: The request took longer than {DOWNLOAD_TIMEOUT} seconds") return False except Exception as e: print(f"{datetime.now()} - Error downloading M3U8: {str(e)}") return False @app.route('/playlist.m3u8') def serve_playlist(): """Serve the M3U8 file""" try: with open(LOCAL_FILE_PATH, 'rb') as f: content = f.read() return Response(content, mimetype='application/vnd.apple.mpegurl') except Exception as e: return str(e), 500 @app.route('/health') def health_check(): """Health check endpoint""" if os.path.exists(LOCAL_FILE_PATH): return "OK", 200 else: return "Playlist not available", 503 def schedule_downloads(): """Schedule the M3U8 download to run at midnight every day""" schedule.every().day.at("00:00").do(download_m3u8) while True: schedule.run_pending() time.sleep(60) # Check every minute def main(): """Main function to start the application""" print(f"{datetime.now()} - Starting IPTV Filter service") # Initial download if not download_m3u8(): print("Initial download failed. Retrying in 30 seconds...") time.sleep(30) if not download_m3u8(): print("Second attempt failed. Starting server anyway...") # Start the scheduler in a separate thread scheduler_thread = Thread(target=schedule_downloads) scheduler_thread.daemon = True scheduler_thread.start() # Start the Flask app print(f"{datetime.now()} - Starting web server on port {PORT}") app.run(host='0.0.0.0', port=PORT) if __name__ == '__main__': main()