Files
providers/.github/scripts/url-checker.js
2025-04-18 20:30:06 +05:30

176 lines
5.5 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const fs = require('fs');
const axios = require('axios');
const FILE_PATH = 'modflix.json';
// Read the modflix.json file
function readModflixJson() {
try {
const data = fs.readFileSync(FILE_PATH, 'utf8');
return JSON.parse(data);
} catch (error) {
console.error(`Error reading ${FILE_PATH}:`, error);
process.exit(1);
}
}
// Extract domain (origin) from URL
function getDomain(url) {
try {
const urlObj = new URL(url);
return urlObj.origin;
} catch (error) {
console.error(`Error parsing URL ${url}:`, error);
return url;
}
}
// Extract ONLY the path from the original URL
function getOriginalPath(url) {
try {
const urlObj = new URL(url);
return urlObj.pathname + urlObj.search + urlObj.hash;
} catch (error) {
console.error(`Error extracting path from ${url}:`, error);
return '';
}
}
// Check URL and return new URL if domain redirected
async function checkUrl(url) {
const originalUrl = url;
try {
// Set timeout to 10 seconds to avoid hanging
const response = await axios.head(url, {
maxRedirects: 0,
timeout: 10000,
validateStatus: status => true
});
// If status is 200, no change needed
if (response.status === 200) {
console.log(`${url} is valid (200 OK)`);
return null;
} else if (response.status >= 300 && response.status < 400) {
// Handle redirects
const newLocation = response.headers.location;
if (newLocation) {
// If it's a relative redirect, construct the full URL
let fullRedirectUrl = newLocation;
if (!newLocation.startsWith('http')) {
const baseUrl = new URL(url);
fullRedirectUrl = new URL(newLocation, baseUrl.origin).toString();
}
console.log(`🔄 ${url} redirects to ${fullRedirectUrl}`);
// IMPORTANT: Only extract the domain/origin from the redirect URL
const newDomain = getDomain(fullRedirectUrl);
// Get the ORIGINAL path from the modflix.json URL (might be empty, might have trailing slash)
const originalPath = getOriginalPath(originalUrl);
// Combine new domain with original path
const finalUrl = newDomain + originalPath;
// Log the change
console.log(`Will update to: ${finalUrl} (new domain + original path)`);
return finalUrl;
}
} else {
console.log(`⚠️ ${url} returned status ${response.status}`);
}
} catch (error) {
// Try GET request if HEAD fails
try {
const response = await axios.get(url, {
maxRedirects: 0,
timeout: 10000,
validateStatus: status => true
});
if (response.status === 200) {
console.log(`${url} is valid (200 OK)`);
return null;
} else if (response.status >= 300 && response.status < 400) {
// Handle redirects
const newLocation = response.headers.location;
if (newLocation) {
console.log(`🔄 ${url} redirects to ${newLocation}`);
let fullRedirectUrl = newLocation;
if (!newLocation.startsWith('http')) {
const baseUrl = new URL(url);
fullRedirectUrl = new URL(newLocation, baseUrl.origin).toString();
}
// IMPORTANT: Only extract the domain/origin
const newDomain = getDomain(fullRedirectUrl);
// Keep ORIGINAL path
const originalPath = getOriginalPath(originalUrl);
// Combine new domain with original path
const finalUrl = newDomain + originalPath;
console.log(`Will update to: ${finalUrl} (new domain + original path)`);
return finalUrl;
}
} else {
console.log(`⚠️ ${url} returned status ${response.status}`);
}
} catch (getError) {
if (getError.response) {
console.log(`⚠️ ${url} returned status ${getError.response.status}`);
} else if (getError.code === 'ECONNABORTED') {
console.log(`${url} request timed out`);
} else if (getError.code === 'ENOTFOUND') {
console.log(`${url} domain not found`);
} else {
console.log(`❌ Error checking ${url}: ${getError.message}`);
}
}
}
// Return null if no change or error
return null;
}
// Main function
async function main() {
const providers = readModflixJson();
let hasChanges = false;
// Process each provider
for (const [key, provider] of Object.entries(providers)) {
const url = provider.url;
console.log(`Checking ${provider.name} (${url})...`);
try {
const newUrl = await checkUrl(url);
if (newUrl && newUrl !== url) {
provider.url = newUrl;
hasChanges = true;
console.log(`Updated ${provider.name} URL from ${url} to ${newUrl}`);
}
} catch (error) {
console.log(`❌ Error processing ${url}: ${error.message}`);
}
}
// Write changes back to file if needed
if (hasChanges) {
fs.writeFileSync(FILE_PATH, JSON.stringify(providers, null, 2));
console.log(`✅ Updated ${FILE_PATH} with new URLs`);
} else {
console.log(` No changes needed for ${FILE_PATH}`);
}
}
// Execute main function with error handling
main().catch(error => {
console.error('Unhandled error:', error);
process.exit(1);
});