diff --git a/.forgejo/workflows/generate-m3u.yml b/.forgejo/workflows/generate-m3u.yml index 51ab05e..2f7436a 100644 --- a/.forgejo/workflows/generate-m3u.yml +++ b/.forgejo/workflows/generate-m3u.yml @@ -1,16 +1,4 @@ name: Generate M3U Playlist - Enhanced Country Detection - -on: - push: - branches: - - main - workflow_dispatch: - -jobs: - build-and-organize: - runs-on: ubuntu-22.04 - name: Generate M3U Playlist with Auto-Organization - on: push: branches: @@ -26,24 +14,21 @@ jobs: steps: - name: Checkout Repository uses: actions/checkout@v4 - + - name: Setup Python uses: actions/setup-python@v4 with: python-version: '3.11' - + - name: Configure Git run: | git config --local user.email "actions@forgejo.plainrock127.xyz" git config --local user.name "IPTV Playlist Bot" - + - name: Create Required Directories run: | echo "πŸ—οΈ Setting up directory structure..." - mkdir -p reports/daily - mkdir -p reports/archive - mkdir -p backups - mkdir -p logs + mkdir -p reports/daily reports/archive backups logs echo "βœ… Directory structure created" - name: Install Python Dependencies @@ -59,7 +44,6 @@ jobs: if [ -f bulk_import.m3u ]; then LINES=$(wc -l < bulk_import.m3u) echo "πŸ“Ί Found bulk_import.m3u with $LINES lines" - # Show first few lines for debugging echo "πŸ“„ First 10 lines of import file:" head -10 bulk_import.m3u @@ -73,13 +57,10 @@ jobs: run: | echo "πŸš€ Starting playlist generation..." cd scripts - # Make the script executable chmod +x generate_playlist.py - # Run the main script with enhanced logging python3 generate_playlist.py 2>&1 | tee ../logs/generation.log - if [ $? -eq 0 ]; then echo "βœ… Playlist generation completed successfully" else @@ -92,19 +73,16 @@ jobs: - name: Validate Generated Files run: | echo "πŸ” Validating generated files..." - # Check if playlist was generated if [ -f playlist.m3u ]; then CHANNELS=$(grep -c "^#EXTINF" playlist.m3u || echo "0") echo "βœ… Generated playlist.m3u with $CHANNELS channels" - # Show playlist statistics GROUPS=$(grep -o 'group-title="[^"]*"' playlist.m3u | sort -u | wc -l || echo "0") echo "πŸ“Š Organized into $GROUPS groups" else echo "⚠️ No playlist.m3u generated" fi - # Check channels.txt if [ -f channels.txt ]; then CHANNEL_BLOCKS=$(grep -c "^Stream name =" channels.txt || echo "0") @@ -118,21 +96,21 @@ jobs: echo "πŸ“Š Creating comprehensive report..." DATE=$(date +%Y%m%d_%H%M%S) REPORT="reports/daily/report_$DATE.md" - + echo "# πŸ“Ί IPTV Playlist Generation Report" > "$REPORT" echo "**Generated:** $(date)" >> "$REPORT" echo "" >> "$REPORT" - + # Playlist statistics if [ -f playlist.m3u ]; then CHANNELS=$(grep -c "^#EXTINF" playlist.m3u || echo "0") GROUPS=$(grep -o 'group-title="[^"]*"' playlist.m3u | sort -u | wc -l || echo "0") - + echo "## πŸ“Š Statistics" >> "$REPORT" echo "- **Total Channels:** $CHANNELS" >> "$REPORT" echo "- **Country Groups:** $GROUPS" >> "$REPORT" echo "" >> "$REPORT" - + # List top 10 groups echo "## 🌍 Top Channel Groups" >> "$REPORT" grep -o 'group-title="[^"]*"' playlist.m3u | sed 's/group-title="//;s/"//' | sort | uniq -c | sort -nr | head -10 | while read count group; do @@ -141,11 +119,11 @@ jobs: else echo "## ⚠️ No playlist generated" >> "$REPORT" fi - + echo "" >> "$REPORT" echo "---" >> "$REPORT" echo "*Report generated automatically by Forgejo Actions*" >> "$REPORT" - + echo "βœ… Report created: $REPORT" - name: Health Check (Optional) @@ -159,26 +137,34 @@ jobs: fi - name: Cleanup and Archive - run: - steps: - - name: Checkout Repository - uses: actions/checkout@v4 - - - name: Setup Python - uses: actions/setup-python@v4 - with: - python-version: '3.11' - - - name: Configure Git run: | - git config --local user.email "actions@forgejo.plainrock127.xyz" - git config --local user.name "IPTV Playlist Bot" - - - name: Create Required Directories - run: | - echo "πŸ—οΈ Setting up directories..." - mkdir -p reports/daily reports/archive backups logs - echo "βœ… Directories created" + echo "🧹 Running cleanup and archiving tasks..." + + # Clean Old Reports + echo "Cleaning old daily reports..." + REPORT_DIR="reports/daily" + if [ -d "$REPORT_DIR" ]; then + cd "$REPORT_DIR" + if ls *.md >/dev/null 2>&1; then + COUNT=$(ls *.md | wc -l) + echo "Found $COUNT reports" + if [ "$COUNT" -gt 3 ]; then + echo "Removing excess reports..." + ls -t *.md | tail -n +4 | xargs rm -f + echo "Cleanup done" + fi + else + echo "No reports to clean in $REPORT_DIR" + fi + cd - > /dev/null # Go back to original directory + else + echo "Daily reports directory $REPORT_DIR not found." + fi + + # Reset Import File + echo "Resetting bulk_import.m3u..." + echo '#EXTM3U' > bulk_import.m3u + echo "Import file reset" - name: Create Country Fix Script run: | @@ -189,10 +175,8 @@ jobs: import re import shutil from datetime import datetime - def detect_country_enhanced(channel_name, epg_id="", logo_url="", stream_url=""): text = f"{channel_name} {epg_id} {logo_url} {stream_url}".lower() - # EPG ID suffix detection (highest priority) if ".ca" in epg_id.lower(): return "πŸ‡¨πŸ‡¦ Canada" @@ -206,9 +190,7 @@ def detect_country_enhanced(channel_name, epg_id="", logo_url="", stream_url="") return "πŸ‡¦πŸ‡Ί Australia" elif ".jp" in epg_id.lower(): return "πŸ‡―πŸ‡΅ Japan" - channel_lower = channel_name.lower() - # Specific fixes for misclassified channels if any(x in channel_lower for x in ["tsn 1", "tsn 2", "tsn 3", "tsn 4", "tsn 5", "cbc news toronto"]): return "πŸ‡¨πŸ‡¦ Canada" @@ -222,7 +204,6 @@ def detect_country_enhanced(channel_name, epg_id="", logo_url="", stream_url="") return "πŸ‡΅πŸ‡­ Philippines" if "animax" in channel_lower: return "πŸ‡―πŸ‡΅ Japan" - # Platform-based detection if "pluto.tv" in text or "images.pluto.tv" in text: pluto_overrides = { @@ -233,10 +214,8 @@ def detect_country_enhanced(channel_name, epg_id="", logo_url="", stream_url="") if pattern in channel_lower: return country return "πŸ‡ΊπŸ‡Έ United States" - if "plex.tv" in text: return "πŸ‡ΊπŸ‡Έ United States" - # Country pattern matching patterns = { "πŸ‡ΊπŸ‡Έ United States": ["usa", "us ", "america", "cbs", "nbc", "abc", "fox", "espn", "cnn", "amc", "mtv", "comedy central", "nickelodeon", "disney", "hgtv", "syfy", "bravo", "tlc", "lifetime", "paramount", "weather channel", "tmz", "wgn"], @@ -255,87 +234,65 @@ def detect_country_enhanced(channel_name, epg_id="", logo_url="", stream_url="") "πŸ‡²πŸ‡½ Mexico": ["mexico", "mexican", "televisa", "tv azteca"], "πŸ‡·πŸ‡Ί Russia": ["russia", "russian", "ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ", "россия", "Π½Ρ‚Π²"] } - for country, keywords in patterns.items(): if any(keyword in text for keyword in keywords): return country - return "🌍 International" - def fix_channels(): backup_name = f"channels_backup_{datetime.now().strftime('%Y%m%d_%H%M%S')}.txt" shutil.copy2("channels.txt", backup_name) print(f"πŸ“‹ Created backup: {backup_name}") - with open("channels.txt", 'r', encoding='utf-8') as f: content = f.read() - blocks = content.split('\n\n') fixed_channels = [] changes_made = 0 country_stats = {} - for block in blocks: if not block.strip(): continue - lines = block.strip().split('\n') channel_data = {} - for line in lines: if '=' in line: key, value = line.split('=', 1) channel_data[key.strip()] = value.strip() - if not channel_data: continue - current_group = channel_data.get('Group', 'Uncategorized') stream_name = channel_data.get('Stream name', '') epg_id = channel_data.get('EPG id', '') logo = channel_data.get('Logo', '') stream_url = channel_data.get('Stream URL', '') - detected_country = detect_country_enhanced(stream_name, epg_id, logo, stream_url) - if current_group != detected_country: print(f"πŸ”„ Fix: '{stream_name}' {current_group} β†’ {detected_country}") channel_data['Group'] = detected_country changes_made += 1 - country_stats[channel_data['Group']] = country_stats.get(channel_data['Group'], 0) + 1 - fixed_block = [] for key in ['Group', 'Stream name', 'Logo', 'EPG id', 'Stream URL']: fixed_block.append(f"{key} = {channel_data.get(key, '')}") - fixed_channels.append('\n'.join(fixed_block)) - with open("channels.txt", 'w', encoding='utf-8') as f: f.write('\n\n'.join(fixed_channels)) - print(f"βœ… Changes made: {changes_made}") print(f"πŸ“Ί Total channels: {len(fixed_channels)}") - # Show top countries sorted_countries = sorted(country_stats.items(), key=lambda x: x[1], reverse=True) print("🌍 Top Countries:") for country, count in sorted_countries[:10]: percentage = (count / len(fixed_channels) * 100) if len(fixed_channels) > 0 else 0 print(f" {country}: {count} ({percentage:.1f}%)") - # Calculate success rate unclassified = country_stats.get('Uncategorized', 0) + country_stats.get('🌍 International', 0) success_rate = ((len(fixed_channels) - unclassified) / len(fixed_channels) * 100) if len(fixed_channels) > 0 else 0 print(f"🎯 Detection Success Rate: {success_rate:.1f}%") - return len(fixed_channels), changes_made - if __name__ == "__main__": total, changes = fix_channels() print(f"πŸŽ‰ Country fix completed! {changes} channels reclassified.") EOF - chmod +x country_fix.py echo "βœ… Country fix script created" @@ -343,7 +300,6 @@ EOF run: | echo "πŸ”§ Running enhanced country classification fix..." python3 country_fix.py - if [ $? -eq 0 ]; then echo "βœ… Country classification fix completed successfully" else @@ -354,41 +310,30 @@ EOF - name: Generate Enhanced M3U Playlist run: | echo "πŸ“Ί Generating enhanced M3U playlist..." - - python3 -c " -import sys + python3 -c "import sys print('πŸš€ Generating M3U from fixed channels...') - # Read channels.txt with open('channels.txt', 'r', encoding='utf-8') as f: content = f.read() - blocks = content.split('\n\n') - # Generate M3U with open('playlist.m3u', 'w', encoding='utf-8') as f: f.write('#EXTM3U\n') - valid_channels = 0 - for block in blocks: if not block.strip(): continue - lines = block.strip().split('\n') channel_data = {} - for line in lines: if '=' in line: key, value = line.split('=', 1) channel_data[key.strip()] = value.strip() - stream_name = channel_data.get('Stream name', '') group = channel_data.get('Group', '') logo = channel_data.get('Logo', '') epg_id = channel_data.get('EPG id', '') url = channel_data.get('Stream URL', '') - if stream_name and url: f.write(f'#EXTINF:-1 group-title=\"{group}\"') if logo: @@ -398,14 +343,11 @@ with open('playlist.m3u', 'w', encoding='utf-8') as f: f.write(f',{stream_name}\n') f.write(f'{url}\n') valid_channels += 1 - -print(f'βœ… Generated playlist.m3u with {valid_channels} channels') -" +print(f'βœ… Generated playlist.m3u with {valid_channels} channels')" - name: Validate Results and Generate Report run: | echo "πŸ” Validating results..." - if [ -f channels.txt ]; then CHANNEL_COUNT=$(grep -c "^Stream name =" channels.txt || echo "0") echo "βœ… channels.txt: $CHANNEL_COUNT channels" @@ -413,7 +355,6 @@ print(f'βœ… Generated playlist.m3u with {valid_channels} channels') echo "❌ channels.txt not found" exit 1 fi - if [ -f playlist.m3u ]; then PLAYLIST_COUNT=$(grep -c "^#EXTINF" playlist.m3u || echo "0") echo "βœ… playlist.m3u: $PLAYLIST_COUNT channels" @@ -421,11 +362,11 @@ print(f'βœ… Generated playlist.m3u with {valid_channels} channels') echo "❌ playlist.m3u not found" exit 1 fi - + # Generate comprehensive report DATE=$(date +%Y%m%d_%H%M%S) REPORT="reports/daily/enhanced_report_$DATE.md" - + echo "# 🌍 Enhanced Country Detection Report" > "$REPORT" echo "**Generated:** $(date)" >> "$REPORT" echo "" >> "$REPORT" @@ -433,7 +374,7 @@ print(f'βœ… Generated playlist.m3u with {valid_channels} channels') echo "- **Total Channels:** $CHANNEL_COUNT" >> "$REPORT" echo "- **Playlist Channels:** $PLAYLIST_COUNT" >> "$REPORT" echo "" >> "$REPORT" - + # Count countries in playlist if [ -f playlist.m3u ]; then echo "## 🌍 Country Distribution" >> "$REPORT" @@ -441,11 +382,9 @@ print(f'βœ… Generated playlist.m3u with {valid_channels} channels') echo "- **$country:** $count channels" >> "$REPORT" done fi - echo "" >> "$REPORT" echo "---" >> "$REPORT" echo "*Enhanced country detection with 99%+ accuracy*" >> "$REPORT" - echo "πŸ“Š Report created: $REPORT" - name: Commit Enhanced Results @@ -467,7 +406,8 @@ print(f'βœ… Generated playlist.m3u with {valid_channels} channels') - name: Final Summary run: | echo "πŸŽ‰ ENHANCED COUNTRY DETECTION COMPLETE!" - echo "=" * 50 + # Fixed the echo syntax for repeating characters + echo "==================================================" if [ -f playlist.m3u ]; then CHANNELS=$(grep -c "^#EXTINF" playlist.m3u || echo "0") COUNTRIES=$(grep -o 'group-title="[^"]*"' playlist.m3u | sed 's/group-title="//;s/"//' | sort -u | wc -l || echo "0") @@ -476,4 +416,4 @@ print(f'βœ… Generated playlist.m3u with {valid_channels} channels') echo "🌍 Canadian, US, UK, Philippines channels now correctly classified" fi echo "πŸ“‹ Backup files created for safety" - echo "πŸ“Š Detailed reports available in reports/daily/" \ No newline at end of file + echo "πŸ“Š Detailed reports available in reports/daily/"