#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ DIGI Online - Cookie-Based Extractor Generează playlist folosind cookies extrase din browser """ import requests import json import sys from datetime import datetime class DigiOnlineCookie: def __init__(self, cookies_dict): self.base_url = "https://www.digionline.ro" self.api_url = "https://www.digionline.ro/api" self.session = requests.Session() # Setează cookies for key, value in cookies_dict.items(): self.session.cookies.set(key, value, domain='.digionline.ro') # Headers self.session.headers.update({ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36', 'Accept': 'application/json, text/plain, */*', 'Accept-Language': 'en-US,en;q=0.9,ro;q=0.8', 'Referer': 'https://www.digionline.ro/', 'Origin': 'https://www.digionline.ro' }) self.channels = [] def get_channels(self): """Obține lista de canale disponibile""" print("\n📺 Obținere listă canale...") # Încearcă mai multe endpoint-uri endpoints = [ f"{self.base_url}/api/v1/channels", f"{self.base_url}/api/channels", f"{self.base_url}/api/channel/list", f"{self.api_url}/v1/channels", f"{self.api_url}/channels" ] for endpoint in endpoints: try: print(f" 🔍 Încerc: {endpoint}") response = self.session.get(endpoint, timeout=10) if response.status_code == 200: try: data = response.json() # Încearcă diferite structuri de răspuns if isinstance(data, list): self.channels = data elif 'data' in data: self.channels = data['data'] elif 'channels' in data: self.channels = data['channels'] elif 'items' in data: self.channels = data['items'] if self.channels: print(f"✅ {len(self.channels)} canale găsite!") return True except json.JSONDecodeError: continue except Exception as e: continue print("❌ Nu s-au putut obține canalele din API!") return False def get_stream_url(self, channel_id, channel_name): """Obține URL-ul de stream pentru un canal""" # Încearcă mai multe endpoint-uri pentru stream endpoints = [ f"{self.base_url}/api/v1/stream/{channel_id}", f"{self.base_url}/api/stream/start/{channel_id}", f"{self.base_url}/api/stream/{channel_id}", f"{self.api_url}/v1/stream/{channel_id}", f"{self.api_url}/stream/{channel_id}" ] for endpoint in endpoints: try: response = self.session.get(endpoint, timeout=10) if response.status_code == 200: data = response.json() # Caută URL-ul în diferite locații if 'stream_url' in data: return data['stream_url'] elif 'url' in data: return data['url'] elif 'data' in data: if isinstance(data['data'], dict): if 'stream_url' in data['data']: return data['data']['stream_url'] elif 'url' in data['data']: return data['data']['url'] except Exception: continue return None def generate_playlist_from_known_channels(self, output_file="digi_authenticated.m3u"): """Generează playlist cu canale cunoscute DIGI""" print(f"\n📝 Generare playlist cu canale DIGI cunoscute...") # Lista de canale DIGI cunoscute known_channels = [ {"id": "digi24", "name": "Digi 24", "logo": "https://raw.githubusercontent.com/staycanuca/plugin.video.digi-online/master/resources/media/Digi24.png", "category": "Știri"}, {"id": "digisport1", "name": "Digi Sport 1", "logo": "https://raw.githubusercontent.com/staycanuca/plugin.video.digi-online/master/resources/media/DigiSport1.png", "category": "Sport"}, {"id": "digisport2", "name": "Digi Sport 2", "logo": "https://raw.githubusercontent.com/staycanuca/plugin.video.digi-online/master/resources/media/DigiSport2.png", "category": "Sport"}, {"id": "digisport3", "name": "Digi Sport 3", "logo": "https://raw.githubusercontent.com/staycanuca/plugin.video.digi-online/master/resources/media/DigiSport3.png", "category": "Sport"}, {"id": "digisport4", "name": "Digi Sport 4", "logo": "https://raw.githubusercontent.com/staycanuca/plugin.video.digi-online/master/resources/media/DigiSport4.png", "category": "Sport"}, {"id": "digiworld", "name": "Digi World", "logo": "https://raw.githubusercontent.com/staycanuca/plugin.video.digi-online/master/resources/media/DigiWorld.png", "category": "Documentare"}, {"id": "digianimalworld", "name": "Digi Animal World", "logo": "https://raw.githubusercontent.com/staycanuca/plugin.video.digi-online/master/resources/media/DigiAnimalWorld.png", "category": "Documentare"}, {"id": "digilife", "name": "Digi Life", "logo": "https://raw.githubusercontent.com/staycanuca/plugin.video.digi-online/master/resources/media/DigiLife.png", "category": "Lifestyle"}, {"id": "filmnow", "name": "Film Now", "logo": "https://raw.githubusercontent.com/staycanuca/plugin.video.digi-online/master/resources/media/FilmNow.png", "category": "Filme"}, ] try: with open(output_file, 'w', encoding='utf-8') as f: # Header M3U f.write("#EXTM3U\n\n") f.write("# ========================================\n") f.write("# PLAYLIST DIGI ONLINE - AUTENTIFICAT (COOKIES)\n") f.write(f"# Generat: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n") f.write("# ========================================\n\n") processed = 0 # Încearcă să obții canale din API if self.channels: print(f"\n📡 Procesare {len(self.channels)} canale din API...") for channel in self.channels: channel_id = channel.get('id') or channel.get('channelId') channel_name = channel.get('name') or channel.get('title') channel_logo = channel.get('logo') or channel.get('image') or '' category = channel.get('category') or 'General' if not channel_id or not channel_name: continue print(f" 📡 {channel_name}...", end='') stream_url = self.get_stream_url(channel_id, channel_name) if stream_url: f.write(f'#EXTINF:-1 tvg-id="{channel_id}" tvg-name="{channel_name}" ') f.write(f'tvg-logo="{channel_logo}" group-title="{category}",{channel_name}\n') f.write(f'{stream_url}\n\n') processed += 1 print(" ✅") else: print(" ❌") else: # Folosește canale cunoscute print(f"\n📡 Procesare canale DIGI cunoscute...") for channel in known_channels: print(f" 📡 {channel['name']}...", end='') stream_url = self.get_stream_url(channel['id'], channel['name']) if stream_url: f.write(f'#EXTINF:-1 tvg-id="{channel["id"]}" tvg-name="{channel["name"]}" ') f.write(f'tvg-logo="{channel["logo"]}" group-title="{channel["category"]}",{channel["name"]}\n') f.write(f'{stream_url}\n\n') processed += 1 print(" ✅") else: print(" ❌") # Footer f.write("# ========================================\n") f.write(f"# Total canale procesate: {processed}\n") f.write("# ========================================\n") if processed > 0: print(f"\n✅ Playlist generat cu succes!") print(f"📁 Fișier: {output_file}") print(f"📺 Canale funcționale: {processed}") return True else: print(f"\n❌ Nu s-au putut obține URL-uri de stream!") print(f"💡 Cookies-urile ar putea fi invalide sau expirate.") return False except Exception as e: print(f"❌ Eroare la generare playlist: {e}") return False def main(): """Funcția principală""" print("=" * 70) print("🎬 DIGI ONLINE - COOKIE EXTRACTOR") print("=" * 70) print() print("📋 Introdu cookies-urile extrase din browser:") print("⚠️ Ai nevoie de: DOSESSV3PRI și deviceId") print() dosess = input("🍪 DOSESSV3PRI: ").strip() if not dosess: print("❌ Cookie-ul DOSESSV3PRI este obligatoriu!") sys.exit(1) device_id = input("🍪 deviceId (opțional, apasă Enter pentru skip): ").strip() print("\n" + "=" * 70) # Creează dicționarul de cookies cookies_dict = { 'DOSESSV3PRI': dosess } if device_id: cookies_dict['deviceId'] = device_id # Creează instanța cu cookies digi = DigiOnlineCookie(cookies_dict) # Încearcă să obții lista de canale digi.get_channels() # Generează playlist-ul output_file = "digi_authenticated.m3u" if digi.generate_playlist_from_known_channels(output_file): print("\n" + "=" * 70) print("🎉 SUCCES!") print("=" * 70) print(f"\n📁 Playlist generat: {output_file}") print(f"📺 Folosește acest fișier în Dispatcharr/Jellyfin/VLC") print(f"\n💡 TIP: Cookies-urile expiră după câteva ore.") print(f" Rulează din nou scriptul cu cookies noi când expiră.\n") else: print("\n❌ Eroare la generare playlist!") sys.exit(1) if __name__ == "__main__": try: main() except KeyboardInterrupt: print("\n\n⚠️ Întrerupt de utilizator!") sys.exit(0) except Exception as e: print(f"\n❌ Eroare neașteptată: {e}") import traceback traceback.print_exc() sys.exit(1)