Compare commits

23 Commits

Author SHA1 Message Date
8man 11b0fc424d Update modflix.json 2026-06-19 14:11:41 +05:30
GitHub Actions b5e0532875 Update provider URLs [skip ci] 2026-06-18 01:01:48 +00:00
8man d2d835ed65 Update modflix.json 2026-06-16 17:11:40 +05:30
8man d6d5e2e902 Update modflix.json 2026-06-15 21:17:29 +05:30
GitHub Actions 1e01c32f33 Update provider URLs [skip ci] 2026-06-13 01:01:04 +00:00
GitHub Actions e8870b383e Update provider URLs [skip ci] 2026-06-08 01:00:34 +00:00
GitHub Actions 6386c0b02f Update provider URLs [skip ci] 2026-06-07 00:59:47 +00:00
GitHub Actions 0b12d095a5 Update provider URLs [skip ci] 2026-06-04 01:05:44 +00:00
GitHub Actions dd4e468991 Update provider URLs [skip ci] 2026-06-01 01:00:32 +00:00
8man 129f671ae2 Update modflix.json 2026-05-29 11:15:54 +05:30
GitHub Actions 53d12fe6a1 Update provider URLs [skip ci] 2026-05-22 00:53:39 +00:00
8man 48f1e3472d Update modflix.json 2026-05-13 21:52:05 +05:30
8man cb9cb22c70 Update modflix.json 2026-05-11 21:42:17 +05:30
8man 38fd128eaa Handle blocked responses when final URL resolves elsewhere 2026-05-11 17:51:39 +05:30
8man bfe80ce95a Show URL checker output directly in Actions logs 2026-05-11 17:33:56 +05:30
8man 55d79974db Add verbose logging for URL checks 2026-05-11 17:24:11 +05:30
8man 68dd646b90 Use browser headers and follow redirects for URL updates 2026-05-11 17:03:27 +05:30
8man 1d39a56cc0 Improve URL checker with browser headers and redirect detection 2026-05-11 16:48:14 +05:30
8man 0081034e35 Update modflix.json 2026-05-11 16:25:01 +05:30
GitHub Actions a3be4c3f10 Update provider URLs [skip ci] 2026-05-11 00:51:08 +00:00
8man 5bf0d4418e Update modflix.json 2026-05-09 16:04:00 +05:30
GitHub Actions 8c3b254d05 Update provider URLs [skip ci] 2026-05-07 00:46:47 +00:00
GitHub Actions bc7989ed11 Update provider URLs [skip ci] 2026-05-05 00:44:53 +00:00
3 changed files with 244 additions and 215 deletions
+95 -72
View File
@@ -4,6 +4,17 @@ const axios = require('axios');
const FILE_PATH = 'modflix.json'; const FILE_PATH = 'modflix.json';
const updatedProviders = []; // Track updated providers for Discord notification const updatedProviders = []; // Track updated providers for Discord notification
const DEFAULT_HEADERS = {
'User-Agent':
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0 Safari/537.36',
Accept:
'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
'Accept-Language': 'en-US,en;q=0.9',
'Accept-Encoding': 'gzip, deflate, br',
Connection: 'keep-alive',
'Upgrade-Insecure-Requests': '1'
};
// Read the modflix.json file // Read the modflix.json file
function readModflixJson() { function readModflixJson() {
try { try {
@@ -31,103 +42,115 @@ function hasTrailingSlash(url) {
return url.endsWith('/') && !url.endsWith('://'); return url.endsWith('/') && !url.endsWith('://');
} }
// Check URL and return new URL if domain redirected function getFinalUrl(response, originalUrl) {
return (
response?.request?.res?.responseUrl ||
response?.request?._redirectable?._currentUrl ||
response?.config?.url ||
originalUrl
);
}
function normalizeOrigin(url) {
try {
return new URL(url).origin;
} catch {
return url;
}
}
async function requestUrl(method, url) {
return axios({
method,
url,
maxRedirects: 5,
timeout: 10000,
validateStatus: status => true,
headers: DEFAULT_HEADERS
});
}
function logVerboseResult(url, response, finalUrl) {
const status = response?.status ?? 'unknown';
const locationHeader = response?.headers?.location;
console.log(
`${url} -> status=${status} final=${finalUrl}` +
(locationHeader ? ` location=${locationHeader}` : '')
);
}
function shouldUpdateFromFinalUrl(originalUrl, finalUrl) {
const originalDomain = getDomain(originalUrl);
const finalDomain = getDomain(finalUrl);
return finalDomain && finalDomain !== originalDomain;
}
// Check URL and return new URL if domain redirected or resolved elsewhere
async function checkUrl(url) { async function checkUrl(url) {
try { try {
// Set timeout to 10 seconds to avoid hanging const response = await requestUrl('get', url);
const response = await axios.head(url, { const finalUrl = getFinalUrl(response, url);
maxRedirects: 0, logVerboseResult(url, response, finalUrl);
timeout: 10000,
validateStatus: status => true if (shouldUpdateFromFinalUrl(url, finalUrl)) {
}); const updatedUrl = normalizeOrigin(finalUrl) + (hasTrailingSlash(url) ? '/' : '');
console.log(`🔄 ${url} resolved to ${finalUrl}`);
console.log(`Will update to: ${updatedUrl} (preserved trailing slash: ${hasTrailingSlash(url)})`);
return updatedUrl;
}
// If status is 200, no change needed
if (response.status === 200) { if (response.status === 200) {
console.log(`${url} is valid (200 OK)`); console.log(`${url} is valid (200 OK)`);
return null; return null;
} else if (response.status >= 300 && response.status < 400) { }
// Handle redirects
if (response.status >= 300 && response.status < 400) {
const newLocation = response.headers.location; const newLocation = response.headers.location;
if (newLocation) { if (newLocation) {
// If it's a relative redirect, construct the full URL
let fullRedirectUrl = newLocation; let fullRedirectUrl = newLocation;
if (!newLocation.startsWith('http')) { if (!newLocation.startsWith('http')) {
const baseUrl = new URL(url); const baseUrl = new URL(url);
fullRedirectUrl = new URL(newLocation, baseUrl.origin).toString(); fullRedirectUrl = new URL(newLocation, baseUrl.origin).toString();
} }
if (shouldUpdateFromFinalUrl(url, fullRedirectUrl)) {
const newDomain = normalizeOrigin(fullRedirectUrl);
const needsTrailingSlash = hasTrailingSlash(url);
const finalUrlForUpdate = newDomain + (needsTrailingSlash ? '/' : '');
console.log(`🔄 ${url} redirects to ${fullRedirectUrl}`); console.log(`🔄 ${url} redirects to ${fullRedirectUrl}`);
console.log(
// Get the new domain `Will update to: ${finalUrlForUpdate} (preserved trailing slash: ${needsTrailingSlash})`
const newDomain = getDomain(fullRedirectUrl); );
return finalUrlForUpdate;
// Check if original URL had a trailing slash }
const needsTrailingSlash = hasTrailingSlash(url); }
// Create new URL: new domain + trailing slash if the original had one
let finalUrl = newDomain;
if (needsTrailingSlash) {
finalUrl += '/';
} }
console.log(`Will update to: ${finalUrl} (preserved trailing slash: ${needsTrailingSlash})`);
return finalUrl;
}
} else {
console.log(`⚠️ ${url} returned status ${response.status}`); console.log(`⚠️ ${url} returned status ${response.status}`);
}
} catch (error) { } catch (error) {
// Try GET request if HEAD fails if (error.response) {
try { const finalUrl = getFinalUrl(error.response, url);
const response = await axios.get(url, { logVerboseResult(url, error.response, finalUrl);
maxRedirects: 0,
timeout: 10000,
validateStatus: status => true
});
if (response.status === 200) { // If the request resolves to a different origin even with a non-2xx status,
console.log(`${url} is valid (200 OK)`); // use that as an update signal. This keeps existing behavior intact while
return null; // allowing sites that block HEAD/GET with 403 but still resolve elsewhere.
} else if (response.status >= 300 && response.status < 400) { if (shouldUpdateFromFinalUrl(url, finalUrl)) {
// Handle redirects const updatedUrl = normalizeOrigin(finalUrl) + (hasTrailingSlash(url) ? '/' : '');
const newLocation = response.headers.location; console.log(`🔄 ${url} resolved to ${finalUrl}`);
if (newLocation) { console.log(
console.log(`🔄 ${url} redirects to ${newLocation}`); `Will update to: ${updatedUrl} (preserved trailing slash: ${hasTrailingSlash(url)})`
);
let fullRedirectUrl = newLocation; return updatedUrl;
if (!newLocation.startsWith('http')) {
const baseUrl = new URL(url);
fullRedirectUrl = new URL(newLocation, baseUrl.origin).toString();
} }
// Get the new domain console.log(`⚠️ ${url} returned status ${error.response.status}`);
const newDomain = getDomain(fullRedirectUrl); } else if (error.code === 'ECONNABORTED') {
// Check if original URL had a trailing slash
const needsTrailingSlash = hasTrailingSlash(url);
// Create new URL: new domain + trailing slash if the original had one
let finalUrl = newDomain;
if (needsTrailingSlash) {
finalUrl += '/';
}
console.log(`Will update to: ${finalUrl} (preserved trailing slash: ${needsTrailingSlash})`);
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`); console.log(`${url} request timed out`);
} else if (getError.code === 'ENOTFOUND') { } else if (error.code === 'ENOTFOUND') {
console.log(`${url} domain not found`); console.log(`${url} domain not found`);
} else { } else {
console.log(`❌ Error checking ${url}: ${getError.message}`); console.log(`❌ Error checking ${url}: ${error.message}`);
}
} }
} }
+11 -5
View File
@@ -27,21 +27,27 @@ jobs:
- name: Run URL checker - name: Run URL checker
id: url_checker id: url_checker
shell: bash
run: | run: |
# Run the URL checker and save output set -o pipefail
node .github/scripts/url-checker.js > checker_output.log 2>&1 # Run the URL checker and show output in the job logs while also saving it
node .github/scripts/url-checker.js 2>&1 | tee checker_output.log
# Check if there are updated providers # Check if there are updated providers
if grep -q "### UPDATED_PROVIDERS_START ###" checker_output.log; then if grep -q "### UPDATED_PROVIDERS_START ###" checker_output.log; then
echo "CHANGES_DETECTED=true" >> $GITHUB_ENV echo "CHANGES_DETECTED=true" >> "$GITHUB_ENV"
# Extract only the updated provider lines between the markers # Extract only the updated provider lines between the markers
sed -n '/### UPDATED_PROVIDERS_START ###/,/### UPDATED_PROVIDERS_END ###/p' checker_output.log | sed -n '/### UPDATED_PROVIDERS_START ###/,/### UPDATED_PROVIDERS_END ###/p' checker_output.log | \
grep -v "###" > updated_providers.txt grep -v "###" > updated_providers.txt
else else
echo "CHANGES_DETECTED=false" >> $GITHUB_ENV echo "CHANGES_DETECTED=false" >> "$GITHUB_ENV"
fi fi
echo "--- checker_output.log ---"
cat checker_output.log
echo "--- end checker_output.log ---"
- name: Commit changes if any - name: Commit changes if any
run: | run: |
git config --global user.name "GitHub Actions" git config --global user.name "GitHub Actions"
+14 -14
View File
@@ -9,11 +9,11 @@
}, },
"Topmovies": { "Topmovies": {
"name": "Topmovies", "name": "Topmovies",
"url": "https://moviesleech.link" "url": "https://moviesleech.bar"
}, },
"UhdMovies": { "UhdMovies": {
"name": "UhdMovies", "name": "UhdMovies",
"url": "https://uhdmovies.pink" "url": "https://uhdmovies.food"
}, },
"filepress": { "filepress": {
"name": "filepress", "name": "filepress",
@@ -21,23 +21,23 @@
}, },
"Vega": { "Vega": {
"name": "vegamovies", "name": "vegamovies",
"url": "https://vegamovies.vodka" "url": "https://vegamovies.mq"
}, },
"lux": { "lux": {
"name": "luxmovies", "name": "luxmovies",
"url": "https://rogmovies.blog" "url": "https://rogmovies.work"
}, },
"drive": { "drive": {
"name": "moviesDrive", "name": "moviesDrive",
"url": "https://new2.moviesdrives.my/" "url": "https://new3.moviesdrives.my/"
}, },
"multi": { "multi": {
"name": "multimovies", "name": "multimovies",
"url": "https://multimovies.autos" "url": "https://multimovies.fyi"
}, },
"w4u": { "w4u": {
"name": "world4ufree", "name": "world4ufree",
"url": "https://world4ufree.tw" "url": "https://world4ufree.cl"
}, },
"extra": { "extra": {
"name": "extraMovies", "name": "extraMovies",
@@ -45,11 +45,11 @@
}, },
"hdhub": { "hdhub": {
"name": "hdhub4u", "name": "hdhub4u",
"url": "https://new4.hdhub4u.fo" "url": "https://new1.hdhub4u.cl"
}, },
"kat": { "kat": {
"name": "katmovieshd", "name": "katmovieshd",
"url": "https://katmoviehd.pictures" "url": "https://new1.katmoviehd.cymru"
}, },
"dc": { "dc": {
"name": "dramacool", "name": "dramacool",
@@ -141,11 +141,11 @@
}, },
"4khdhub": { "4khdhub": {
"name": "4khdhub", "name": "4khdhub",
"url": "https://4khdhub.dad" "url": "https://4khdhub.one"
}, },
"moviezwap": { "moviezwap": {
"name": "moviezwap", "name": "moviezwap",
"url": "https://www.moviezwap.date/" "url": "https://www.moviezwap.onl/"
}, },
"9xflix": { "9xflix": {
"name": "9xflix", "name": "9xflix",
@@ -173,7 +173,7 @@
}, },
"movies4u": { "movies4u": {
"name": "movies4u", "name": "movies4u",
"url": "https://movies4u.vg" "url": "https://movies4u.as"
}, },
"joya9tv": { "joya9tv": {
"name": "joya9tv1", "name": "joya9tv1",
@@ -181,10 +181,10 @@
}, },
"skymovieshd": { "skymovieshd": {
"name": "skyMovesHd", "name": "skyMovesHd",
"url": "https://skymovieshd.fast" "url": "https://skymovieshd.spot"
}, },
"1cinevood": { "1cinevood": {
"name": "cinewood", "name": "cinewood",
"url": "https://proxy01.cvproxy.workers.dev" "url": "https://1cinevood.in"
} }
} }