mirror of
https://git.nadeko.net/Mystique/MystiquePlus.git
synced 2025-03-15 12:17:50 +01:00
214 lines
No EOL
7.1 KiB
JavaScript
214 lines
No EOL
7.1 KiB
JavaScript
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
// Define cultural groups by country with more precise matching
|
|
const culturalGroups = {
|
|
anglosphere: [
|
|
'united kingdom', 'uk', 'great britain', 'britain',
|
|
'england', 'scotland', 'wales', 'northern ireland',
|
|
'^united states$', '^usa$', '^us$', '^america$',
|
|
'^canada$',
|
|
'^australia$',
|
|
'^new zealand$',
|
|
'^ireland$'
|
|
],
|
|
francophone: [
|
|
'^france$', '^belgium$', '^switzerland$', '^quebec$', '^monaco$',
|
|
'^luxembourg$', '^haiti$', '^ivory coast$', '^senegal$', '^cameroon$'
|
|
],
|
|
hispanic: [
|
|
'^spain$', '^mexico$', '^argentina$', '^chile$', '^colombia$', '^peru$',
|
|
'^venezuela$', '^ecuador$', '^guatemala$', '^cuba$', '^dominican republic$',
|
|
'^honduras$', '^el salvador$', '^nicaragua$', '^costa rica$', '^panama$',
|
|
'^bolivia$', '^paraguay$', '^uruguay$', 'latin america'
|
|
],
|
|
lusophone: [
|
|
'^portugal$', '^brazil$', '^angola$', '^mozambique$',
|
|
'^cape verde$', '^guinea-bissau$', '^sao tome and principe$'
|
|
],
|
|
arabic: [
|
|
'saudi arabia', 'egypt', 'uae', 'united arab emirates', 'qatar',
|
|
'kuwait', 'oman', 'bahrain', 'yemen', 'iraq', 'syria',
|
|
'jordan', 'lebanon', 'palestine', 'libya', 'tunisia',
|
|
'algeria', 'morocco', 'sudan'
|
|
],
|
|
germanosphere: [
|
|
'^germany$', '^austria$', '^switzerland$', '^luxembourg$', '^liechtenstein$'
|
|
],
|
|
slavic: [
|
|
'^russia$', '^ukraine$', '^belarus$', '^poland$', '^czech republic$',
|
|
'^slovakia$', '^serbia$', '^croatia$', '^bosnia$', '^montenegro$',
|
|
'^slovenia$', '^bulgaria$', '^north macedonia$'
|
|
],
|
|
sinosphere: [
|
|
'^china$', 'hong kong', '^taiwan$', '^singapore$', '^macau$'
|
|
],
|
|
indosphere: [
|
|
'^india$', '^pakistan$', '^bangladesh$', '^nepal$', '^sri lanka$',
|
|
'^bhutan$', '^maldives$'
|
|
],
|
|
turkic: [
|
|
'^turkey$', '^azerbaijan$', '^uzbekistan$', '^kazakhstan$',
|
|
'^kyrgyzstan$', '^turkmenistan$'
|
|
],
|
|
nordic: [
|
|
'^sweden$', '^norway$', '^denmark$', '^finland$', '^iceland$',
|
|
'faroe islands', '^greenland$'
|
|
],
|
|
baltic: [
|
|
'^estonia$', '^latvia$', '^lithuania$'
|
|
],
|
|
hellenic: [
|
|
'^greece$', '^cyprus$'
|
|
],
|
|
benelux: [
|
|
'^netherlands$', '^belgium$', '^luxembourg$'
|
|
],
|
|
persian: [
|
|
'^iran$', '^afghanistan$', '^tajikistan$'
|
|
],
|
|
malaysphere: [
|
|
'^malaysia$', '^brunei$', '^indonesia$'
|
|
],
|
|
korean: [
|
|
'south korea', 'korea', 'north korea'
|
|
],
|
|
japanese: [
|
|
'^japan$'
|
|
],
|
|
vietnamese: [
|
|
'^vietnam$'
|
|
],
|
|
thai: [
|
|
'^thailand$'
|
|
]
|
|
};
|
|
|
|
function getCulturalGroup(channelInfo) {
|
|
// Look specifically for group-title (country information)
|
|
const groupMatch = channelInfo.match(/group-title="([^"]*)"/) || [];
|
|
const groupTitle = (groupMatch[1] || '').toLowerCase();
|
|
|
|
// Check if the country belongs to any cultural group
|
|
for (const [group, countries] of Object.entries(culturalGroups)) {
|
|
// Use exact matching with RegExp
|
|
if (countries.some(country => {
|
|
// If the country pattern starts with ^, use it as a RegExp
|
|
if (country.startsWith('^')) {
|
|
const regex = new RegExp(country, 'i');
|
|
return regex.test(groupTitle);
|
|
}
|
|
// Otherwise, use includes for flexible matching (for multi-word countries)
|
|
return groupTitle.includes(country);
|
|
})) {
|
|
return group;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
function splitByCulturalGroup(filePath) {
|
|
const content = fs.readFileSync(filePath, 'utf8');
|
|
const lines = content.split('\n');
|
|
|
|
// Create cultural groups directory
|
|
const groupsDir = path.join(path.dirname(filePath), 'cultural-groups');
|
|
if (!fs.existsSync(groupsDir)) {
|
|
fs.mkdirSync(groupsDir);
|
|
}
|
|
|
|
// Get existing cultural group files
|
|
const existingFiles = fs.readdirSync(groupsDir)
|
|
.filter(file => file.endsWith('.m3u'))
|
|
.map(file => file.toLowerCase());
|
|
|
|
const groups = {};
|
|
|
|
// Verify M3U header
|
|
const header = lines[0];
|
|
if (!header.startsWith('#EXTM3U')) {
|
|
throw new Error('Invalid M3U file: Missing #EXTM3U header');
|
|
}
|
|
|
|
// Process the file line by line to handle multi-line entries
|
|
let currentCulturalGroup = null;
|
|
let currentEntry = [];
|
|
let isInEntry = false;
|
|
|
|
for (let i = 1; i < lines.length; i++) {
|
|
const line = lines[i].trim();
|
|
if (!line) continue;
|
|
|
|
if (line.startsWith('#EXTINF')) {
|
|
// Start of a new entry
|
|
isInEntry = true;
|
|
currentEntry = [line];
|
|
|
|
// Determine cultural group
|
|
currentCulturalGroup = getCulturalGroup(line);
|
|
} else if (isInEntry) {
|
|
// Add the line to the current entry
|
|
currentEntry.push(line);
|
|
|
|
// If this is a URL line (doesn't start with #), this completes the entry
|
|
if (!line.startsWith('#')) {
|
|
// Add all lines of the entry to the appropriate cultural group
|
|
if (currentCulturalGroup) {
|
|
if (!groups[currentCulturalGroup]) {
|
|
groups[currentCulturalGroup] = ['#EXTM3U'];
|
|
}
|
|
groups[currentCulturalGroup].push(...currentEntry);
|
|
}
|
|
|
|
// Reset for the next entry
|
|
isInEntry = false;
|
|
currentEntry = [];
|
|
currentCulturalGroup = null;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Get list of current cultural group files
|
|
const currentGroupFiles = Object.keys(groups).map(groupTitle =>
|
|
`${groupTitle.toLowerCase()}.m3u`
|
|
);
|
|
|
|
// Remove obsolete files
|
|
existingFiles.forEach(existingFile => {
|
|
if (!currentGroupFiles.includes(existingFile)) {
|
|
const fileToRemove = path.join(groupsDir, existingFile);
|
|
fs.unlinkSync(fileToRemove);
|
|
console.log(`Removed obsolete cultural group playlist: ${existingFile}`);
|
|
}
|
|
});
|
|
|
|
// Write cultural group files
|
|
Object.entries(groups).forEach(([groupTitle, groupLines]) => {
|
|
const groupFilePath = path.join(groupsDir, `${groupTitle.toLowerCase()}.m3u`);
|
|
fs.writeFileSync(groupFilePath, groupLines.join('\n') + '\n');
|
|
console.log(`Created/updated cultural group playlist: ${groupFilePath}`);
|
|
});
|
|
|
|
// Generate summary - count entries properly by counting #EXTINF lines
|
|
const summary = Object.entries(groups).map(([group, lines]) => {
|
|
const channelCount = lines.filter(line => line.startsWith('#EXTINF')).length;
|
|
return `${group}: ${channelCount} channels`;
|
|
});
|
|
|
|
console.log('\nCultural group split summary:');
|
|
console.log(summary.join('\n'));
|
|
}
|
|
|
|
const filePath = process.argv[2];
|
|
if (!filePath) {
|
|
console.error('Please provide the path to the M3U file');
|
|
process.exit(1);
|
|
}
|
|
|
|
try {
|
|
splitByCulturalGroup(filePath);
|
|
} catch (error) {
|
|
console.error('Error splitting M3U file:', error.message);
|
|
process.exit(1);
|
|
} |