diff options
Diffstat (limited to 'src/lib/Media/Anime/Airing/Subtitled/match.ts')
| -rw-r--r-- | src/lib/Media/Anime/Airing/Subtitled/match.ts | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/src/lib/Media/Anime/Airing/Subtitled/match.ts b/src/lib/Media/Anime/Airing/Subtitled/match.ts index 1a0c6b2d..1bf31b6f 100644 --- a/src/lib/Media/Anime/Airing/Subtitled/match.ts +++ b/src/lib/Media/Anime/Airing/Subtitled/match.ts @@ -3,6 +3,7 @@ import type { Media } from '../../../../AniList/media'; import settings from '$stores/settings'; import type { SubsPlease } from '$lib/Media/Anime/Airing/Subtitled/subsPlease'; import levenshtein from 'fast-levenshtein'; +import stringSimilarity from 'string-similarity'; export interface Time { title: string; @@ -33,7 +34,7 @@ const secondsUntil = (targetTime: string, targetDay: string) => { const normalizeTitle = (title: string | null) => { return (title || '') .toLowerCase() - .replace(/season \d+|s\d+|\W/g, '') + .replace(/season \d+|s\d+/g, '') .replace(/\b(\d)(st|nd|rd|th)\b/g, '$1') .replace(/\b(part|pt)\b/gi, '') .trim(); @@ -67,14 +68,24 @@ export const findClosestMedia = (media: Media[], matchFor: string) => { if (!matchFor) return null; let bestFitMedia: Media | null = null; - let smallestDistance = Infinity; + let smallestDistance = -Infinity; media.forEach((m) => { - [m.title.romaji, m.title.english, ...m.synonyms].filter(Boolean).forEach((title) => { - const normalizedItemTitle = normalizeTitle(title); - const distance = levenshtein.get(normalizeTitle(matchFor), normalizedItemTitle); + const titles = [m.title.romaji, m.title.english, ...m.synonyms].filter(Boolean); + + titles.forEach((title) => { + const normalisedTitle = normalizeTitle(title); + const normalisedMatchFor = normalizeTitle(matchFor); + const distance = stringSimilarity.compareTwoStrings(normalisedMatchFor, normalisedTitle); - if (distance < smallestDistance && distance < Math.max(3, normalizedItemTitle.length * 0.4)) { + if ( + distance > smallestDistance && + (normalisedMatchFor + .split(' ') + .filter((word) => titles.some((title) => normalizeTitle(title).includes(word))).length >= + normalisedMatchFor.split(' ').length || + titles.some((title) => normalizeTitle(title).includes(normalisedMatchFor))) + ) { smallestDistance = distance; bestFitMedia = m; } |