my-private-iptv-m3u/scripts/generate_playlist.py

116 lines
4.1 KiB
Python
Raw Normal View History

2025-06-27 23:26:06 +02:00
#!/usr/bin/env python3
"""
2025-06-27 23:39:12 +02:00
IPTV Playlist Generator - Main Script (Scripts Folder Version)
2025-06-27 23:26:06 +02:00
Modular design for better maintainability and easier development.
"""
import logging
2025-06-27 16:34:52 +02:00
import os
2025-06-27 23:39:12 +02:00
import sys
2025-06-27 17:36:03 +02:00
from datetime import datetime
2025-06-27 16:34:52 +02:00
2025-06-27 23:39:12 +02:00
# Add parent directory to path so we can import from scripts
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
2025-06-27 23:26:06 +02:00
# Import our modular components
2025-06-27 23:39:12 +02:00
from config_manager import ConfigManager
from channel_processor import ChannelProcessor
from file_manager import FileManager
from playlist_builder import PlaylistBuilder
from health_checker import HealthChecker
from report_generator import ReportGenerator
2025-06-27 23:26:06 +02:00
def setup_logging():
"""Setup comprehensive logging."""
logging.basicConfig(
level=logging.INFO,
format='[%(asctime)s] %(levelname)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S',
handlers=[
logging.FileHandler('playlist_update.log', encoding='utf-8'),
logging.StreamHandler()
]
)
2025-06-27 16:34:52 +02:00
2025-06-27 23:26:06 +02:00
def generate_playlist():
"""Main playlist generation function - coordinates all modules."""
2025-06-27 19:20:53 +02:00
try:
2025-06-27 23:26:06 +02:00
setup_logging()
logging.info("Starting modular playlist generation...")
# Initialize all modules
config = ConfigManager()
file_manager = FileManager(config)
processor = ChannelProcessor(config)
builder = PlaylistBuilder(config)
health_checker = HealthChecker(config)
report_gen = ReportGenerator(config)
# Clear log file
if os.path.exists('playlist_update.log'):
open('playlist_update.log', 'w').close()
# Statistics tracking
stats = {
'total_channels': 0,
'valid_channels': 0,
'duplicates_removed': 0,
'imported_channels': 0,
'countries_detected': 0,
'country_distribution': {}
2025-06-27 19:20:53 +02:00
}
2025-06-27 20:06:47 +02:00
2025-06-27 23:26:06 +02:00
# Step 1: Create backup
file_manager.create_backup('channels.txt')
2025-06-27 20:06:47 +02:00
2025-06-27 23:26:06 +02:00
# Step 2: Clean existing corrupted entries
processor.clean_corrupted_channels()
2025-06-27 20:06:47 +02:00
2025-06-27 23:26:06 +02:00
# Step 3: Force update existing channels with new country detection
processor.update_existing_channels_with_country_detection()
2025-06-27 18:45:55 +02:00
2025-06-27 23:26:06 +02:00
# Step 4: Process imports
imported_channels = processor.process_import()
stats['imported_channels'] = len(imported_channels)
logging.info(f"Import returned {len(imported_channels)} channels")
2025-06-27 19:20:53 +02:00
2025-06-27 23:26:06 +02:00
# Step 5: Load all channels
all_channels = file_manager.load_all_channels()
stats['total_channels'] = len(all_channels)
2025-06-27 16:34:52 +02:00
2025-06-27 23:26:06 +02:00
# Step 6: Remove duplicates
unique_channels = processor.remove_duplicates_optimized(all_channels)
stats['duplicates_removed'] = len(all_channels) - len(unique_channels)
2025-06-27 20:00:13 +02:00
2025-06-27 23:26:06 +02:00
# Step 7: Sort channels
if config.settings.get('sort_channels', True):
unique_channels.sort(key=lambda x: (x.get('Group', '').lower(), x.get('Stream name', '').lower()))
2025-06-27 20:06:47 +02:00
2025-06-27 23:26:06 +02:00
# Step 8: Health check (optional)
health_results = {}
if config.settings.get('enable_health_check', False):
health_results = health_checker.batch_health_check(unique_channels)
2025-06-27 20:06:47 +02:00
2025-06-27 23:26:06 +02:00
# Step 9: Generate M3U playlist
valid_channels, country_stats = builder.generate_m3u(unique_channels)
stats['valid_channels'] = valid_channels
stats['country_distribution'] = country_stats
stats['countries_detected'] = len(country_stats)
2025-06-27 20:00:13 +02:00
2025-06-27 23:26:06 +02:00
# Step 10: Generate report
report_gen.save_report(stats, health_results)
2025-06-27 18:36:13 +02:00
2025-06-27 23:26:06 +02:00
logging.info(f"Playlist generation complete: {valid_channels} channels across {len(country_stats)} countries")
logging.info(f"Top countries: {dict(list(sorted(country_stats.items(), key=lambda x: x[1], reverse=True))[:5])}")
2025-06-27 18:36:13 +02:00
2025-06-27 23:26:06 +02:00
return True
2025-06-27 18:36:13 +02:00
2025-06-27 16:34:52 +02:00
except Exception as e:
2025-06-27 23:26:06 +02:00
logging.error(f"Fatal error in playlist generation: {e}")
2025-06-27 23:39:12 +02:00
import traceback
logging.error(traceback.format_exc())
2025-06-27 23:26:06 +02:00
return False
2025-06-27 16:34:52 +02:00
if __name__ == "__main__":
2025-06-27 23:26:06 +02:00
success = generate_playlist()
exit(0 if success else 1)