This commit is contained in:
shafat420
2025-11-13 09:53:33 +06:00
parent 4361d9040e
commit 609c35033b
3 changed files with 49 additions and 78 deletions

114
mapper.js
View File

@@ -1,73 +1,33 @@
const axios = require('axios');
// Common headers for API requests
const getCommonHeaders = () => ({
'Accept': 'application/json, text/plain, */*',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36',
'x-site': 'anicrush',
'Referer': 'https://anicrush.to/',
'Origin': 'https://anicrush.to',
'sec-fetch-site': 'same-site',
'sec-fetch-mode': 'cors',
'sec-fetch-dest': 'empty'
});
// Minimal GraphQL query for AniList (title, format, year only)
const ANILIST_QUERY = `
query ($id: Int) {
Media(id: $id, type: ANIME) {
id
title {
romaji
english
native
}
synonyms
format
seasonYear
}
}`;
// Function to calculate string similarity using Levenshtein distance
function calculateLevenshteinSimilarity(str1, str2) {
if (!str1 || !str2) return 0;
str1 = str1.toLowerCase();
str2 = str2.toLowerCase();
const matrix = Array(str2.length + 1).fill(null)
.map(() => Array(str1.length + 1).fill(null));
const axios = require('axios');
const stringSimilarity = require('string-similarity');
for (let i = 0; i <= str1.length; i++) matrix[0][i] = i;
for (let j = 0; j <= str2.length; j++) matrix[j][0] = j;
// Common headers for API requests
const getCommonHeaders = () => ({
'Accept': 'application/json, text/plain, */*',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36',
'x-site': 'anicrush',
'Referer': 'https://anicrush.to/',
'Origin': 'https://anicrush.to',
'sec-fetch-site': 'same-site',
'sec-fetch-mode': 'cors',
'sec-fetch-dest': 'empty'
});
for (let j = 1; j <= str2.length; j++) {
for (let i = 1; i <= str1.length; i++) {
const indicator = str1[i - 1] === str2[j - 1] ? 0 : 1;
matrix[j][i] = Math.min(
matrix[j][i - 1] + 1,
matrix[j - 1][i] + 1,
matrix[j - 1][i - 1] + indicator
);
}
// Minimal GraphQL query for AniList (title, format, year only)
const ANILIST_QUERY = `
query ($id: Int) {
Media(id: $id, type: ANIME) {
id
title {
romaji
english
native
}
const maxLength = Math.max(str1.length, str2.length);
if (maxLength === 0) return 100;
return ((maxLength - matrix[str2.length][str1.length]) / maxLength) * 100;
}
// Function to calculate word-based similarity
function calculateWordSimilarity(str1, str2) {
if (!str1 || !str2) return 0;
const words1 = str1.toLowerCase().split(/\s+/).filter(Boolean);
const words2 = str2.toLowerCase().split(/\s+/).filter(Boolean);
const commonWords = words1.filter(word => words2.includes(word));
const totalUniqueWords = new Set([...words1, ...words2]).size;
return (commonWords.length / totalUniqueWords) * 100;
}
synonyms
format
seasonYear
}
}`;
// Function to normalize title for comparison
function normalizeTitle(title) {
@@ -177,13 +137,13 @@ async function getEpisodeList(movieId) {
}
}
// Function to calculate overall similarity between titles
// Function to calculate similarity between titles using string-similarity library
function calculateTitleSimilarity(title1, title2) {
const levenshteinSim = calculateLevenshteinSimilarity(title1, title2);
const wordSim = calculateWordSimilarity(title1, title2);
// Weight the similarities (favoring word-based matching for titles)
return (levenshteinSim * 0.4) + (wordSim * 0.6);
if (!title1 || !title2) return 0;
return stringSimilarity.compareTwoStrings(
title1.toLowerCase(),
title2.toLowerCase()
) * 100; // Convert to percentage
}
// Function to find best match between AniList and anicrush results
@@ -217,11 +177,13 @@ function findBestMatch(anilistData, anicrushResults) {
typePenalty = 15; // small penalty instead of skip
}
const resultTitles = [result.name, result.name_english].filter(Boolean).map(normalizeTitle);
const resultTitles = [result.name, result.name_english].filter(Boolean);
for (const aTitle of anilistTitles) {
for (const rTitle of resultTitles) {
const score = calculateTitleSimilarity(aTitle, rTitle);
const similarity = calculateTitleSimilarity(aTitle, rTitle);
const score = Math.max(0, similarity - typePenalty);
if (score > highestScore) {
highestScore = score;
bestMatch = result;
@@ -230,7 +192,7 @@ function findBestMatch(anilistData, anicrushResults) {
}
}
return highestScore >= 25 ? bestMatch : null; // accept if 25%+ similarity
return highestScore >= 60 ? bestMatch : null; // Increased threshold to 60% for better accuracy
}
// Alias for compatibility

10
package-lock.json generated
View File

@@ -13,7 +13,8 @@
"cors": "^2.8.5",
"crypto": "^1.0.1",
"dotenv": "^16.3.1",
"express": "^4.18.2"
"express": "^4.18.2",
"string-similarity": "^4.0.4"
},
"devDependencies": {
"nodemon": "^3.0.2"
@@ -1530,6 +1531,13 @@
"node": ">= 0.8"
}
},
"node_modules/string-similarity": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/string-similarity/-/string-similarity-4.0.4.tgz",
"integrity": "sha512-/q/8Q4Bl4ZKAPjj8WerIBJWALKkaPRfrvhfF8k/B23i4nzrlRj2/go1m90In7nG/3XDSbOo0+pu6RvCTM9RGMQ==",
"deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.",
"license": "ISC"
},
"node_modules/supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",

View File

@@ -17,7 +17,8 @@
"cors": "^2.8.5",
"crypto": "^1.0.1",
"dotenv": "^16.3.1",
"express": "^4.18.2"
"express": "^4.18.2",
"string-similarity": "^4.0.4"
},
"devDependencies": {
"nodemon": "^3.0.2"