Mystique/.forgejo/scripts/readme-m3u.js
mxnticek 0b37740c66 Update .forgejo/scripts/readme-m3u.js
somebody gonna hate me for sure, but i have edited this with ai for some part because i had no idea how to implement if else statement in this code... lmao
2025-06-14 23:16:16 +02:00

160 lines
No EOL
7.3 KiB
JavaScript

const fs = require('fs');
const path = require('path');
function updateReadme(m3uPath, additionalM3uFiles = []) {
// Get directories for both types of groups
const countriesDir = path.join(path.dirname(m3uPath), 'countries');
const culturalDir = path.join(path.dirname(m3uPath), 'cultural-groups');
const groups = {
countries: {},
cultural: {}
};
// Read the main M3U to get original group names and channel counts
const content = fs.readFileSync(m3uPath, 'utf8');
const lines = content.split('\n');
let totalChannels = 0;
lines.forEach(line => {
if (line.startsWith('#EXTINF')) {
totalChannels++;
const groupMatch = line.match(/group-title="([^"]*)"/);
const groupTitle = groupMatch ? groupMatch[1] : 'Unknown';
groups.countries[groupTitle] = (groups.countries[groupTitle] || 0) + 1;
}
});
// Process additional M3U files
const additionalPlaylists = [];
additionalM3uFiles.forEach(filePath => {
if (fs.existsSync(filePath)) {
const additionalContent = fs.readFileSync(filePath, 'utf8');
const additionalLines = additionalContent.split('\n');
const channelCount = additionalLines.filter(line => line.startsWith('#EXTINF')).length;
const fileName = path.basename(filePath);
additionalPlaylists.push({
name: fileName,
displayName: fileName.replace('.m3u', '').replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase()),
channels: channelCount,
path: fileName
});
} else {
console.warn(`Warning: Additional M3U file not found: ${filePath}`);
}
});
// Get cultural group counts
if (fs.existsSync(culturalDir)) {
fs.readdirSync(culturalDir)
.filter(file => file.endsWith('.m3u'))
.forEach(file => {
const culturalContent = fs.readFileSync(path.join(culturalDir, file), 'utf8');
const culturalLines = culturalContent.split('\n');
const channelCount = culturalLines.filter(line => line.startsWith('#EXTINF')).length;
const groupName = file.replace('.m3u', '');
groups.cultural[groupName] = channelCount;
});
}
// Build README content
let readmeContent = '# Mystique\n\n';
// Add description and features
readmeContent += '## About\n\n';
readmeContent += 'Mystique provides a curated collection of IPTV channels from around the world. ';
readmeContent += 'The channels are organized by both countries and cultural groups for easy access.\n\n';
// Add usage section
readmeContent += '## Usage\n\n';
readmeContent += '1. **Complete Playlist**: Use the main `mystique.m3u` file for access to all channels\n';
if (additionalPlaylists.length > 0) {
readmeContent += '2. **Additional Collections**: Specialized playlists for specific content types (Can be Radios, etc.)\n';
readmeContent += '3. **Country-Specific**: Individual country playlists are available in the `countries/` directory\n';
readmeContent += '4. **Cultural Groups**: Cultural/linguistic group playlists are available in the `cultural-groups/` directory\n';
} else {
readmeContent += '2. **Country-Specific**: Individual country playlists are available in the `countries/` directory\n';
readmeContent += '3. **Cultural Groups**: Cultural/linguistic group playlists are available in the `cultural-groups/` directory\n';
}
readmeContent += '\n';
// Add statistics
const totalAdditionalChannels = additionalPlaylists.reduce((sum, playlist) => sum + playlist.channels, 0);
readmeContent += '## Statistics\n\n';
readmeContent += `- Total Channels: ${totalChannels}\n`;
if (totalAdditionalChannels > 0) {
readmeContent += `- Additional Collections: ${totalAdditionalChannels} channels\n`;
}
readmeContent += `- Countries Available: ${Object.keys(groups.countries).length}\n`;
readmeContent += `- Cultural Groups: ${Object.keys(groups.cultural).length}\n\n`;
// Add playlists table
readmeContent += '## Available Playlists\n\n';
readmeContent += '| Playlist | Channels | Link |\n';
readmeContent += '|----------|-----------|------|\n';
// Add main playlist
const mainPlaylistName = path.basename(m3uPath);
readmeContent += `| **Complete (All channels)** | ${totalChannels} | [${mainPlaylistName}](${mainPlaylistName}) |\n`;
// Add additional playlists
if (additionalPlaylists.length > 0) {
readmeContent += '| **───────── Additional Collections ─────────** | | |\n';
additionalPlaylists.forEach(playlist => {
readmeContent += `| ${playlist.displayName} | ${playlist.channels} | [${playlist.name}](${playlist.path}) |\n`;
});
}
// Add countries
readmeContent += '| **───────── Countries ─────────** | | |\n';
const sortedCountryGroups = Object.entries(groups.countries).sort((a, b) => a[0].localeCompare(b[0]));
sortedCountryGroups.forEach(([groupName, channelCount]) => {
const safeGroupName = groupName.replace(/[^a-z0-9]/gi, '_').toLowerCase();
readmeContent += `| ${groupName} | ${channelCount} | [${safeGroupName}.m3u](countries/${safeGroupName}.m3u) |\n`;
});
// Add cultural groups
if (Object.keys(groups.cultural).length > 0) {
readmeContent += '| **───────── Cultural Groups ─────────** | | |\n';
const sortedCulturalGroups = Object.entries(groups.cultural).sort((a, b) => a[0].localeCompare(b[0]));
sortedCulturalGroups.forEach(([groupName, channelCount]) => {
const displayName = groupName
.split('-')
.map(word => word.charAt(0).toUpperCase() + word.slice(1))
.join(' ');
readmeContent += `| ${displayName} | ${channelCount} | [${groupName}.m3u](cultural-groups/${groupName}.m3u) |\n`;
});
}
// Add note about legal usage
readmeContent += '\n## Legal Notice\n\n';
readmeContent += 'This playlist is a collection of publicly available IPTV streams. ';
readmeContent += 'Please check your local laws regarding IPTV streaming before using this playlist.\n';
const readmePath = path.join(path.dirname(m3uPath), 'README.md');
fs.writeFileSync(readmePath, readmeContent);
console.log('README.md has been updated with comprehensive playlist information');
if (additionalPlaylists.length > 0) {
console.log(`Added ${additionalPlaylists.length} additional playlist(s):`);
additionalPlaylists.forEach(playlist => {
console.log(` - ${playlist.displayName}: ${playlist.channels} channels`);
});
}
}
const filePath = process.argv[2];
const additionalFiles = process.argv.slice(3); // Get all additional arguments
if (!filePath) {
console.error('Please provide the path to mystique.m3u');
console.error('Usage: node readme-m3u.js mystique.m3u [additional_file1.m3u] [additional_file2.m3u] ...');
process.exit(1);
}
try {
updateReadme(filePath, additionalFiles);
} catch (error) {
console.error('Error updating README:', error.message);
process.exit(1);
}