fix(rt-ratings): add roman numeral search support (#334)

* Add Roman Numeral Support
This commit is contained in:
grokdesigns
2026-01-10 12:12:48 -07:00
committed by GitHub
parent 5e33c6167d
commit 7b2187108d
+136
View File
@@ -79,6 +79,83 @@ class RottenTomatoes extends ExternalAPI {
);
}
/**
* Convert Roman numerals to Arabic numerals in a string
*/
private convertRomanToArabic(str: string): string {
const romanMap: Record<string, number> = {
I: 1,
II: 2,
III: 3,
IV: 4,
V: 5,
VI: 6,
VII: 7,
VIII: 8,
IX: 9,
X: 10,
XI: 11,
XII: 12,
XIII: 13,
XIV: 14,
XV: 15,
XVI: 16,
XVII: 17,
XVIII: 18,
XIX: 19,
XX: 20,
};
let result = str;
// Match Roman numerals with word boundaries
const romanRegex = /\b(X{0,2})(IX|IV|V?I{0,3})\b/gi;
result = result.replace(romanRegex, (match) => {
const upper = match.toUpperCase();
return romanMap[upper] !== undefined ? romanMap[upper].toString() : match;
});
return result;
}
/**
* Convert Arabic numerals to Roman numerals in a string
*/
private convertArabicToRoman(str: string): string {
const arabicMap: [number, string][] = [
[20, 'XX'],
[19, 'XIX'],
[18, 'XVIII'],
[17, 'XVII'],
[16, 'XVI'],
[15, 'XV'],
[14, 'XIV'],
[13, 'XIII'],
[12, 'XII'],
[11, 'XI'],
[10, 'X'],
[9, 'IX'],
[8, 'VIII'],
[7, 'VII'],
[6, 'VI'],
[5, 'V'],
[4, 'IV'],
[3, 'III'],
[2, 'II'],
[1, 'I'],
];
let result = str;
// Match 1-20 as standalone numbers or at end of string
result = result.replace(/\b([1-9]|1[0-9]|20)\b/g, (match) => {
const num = parseInt(match);
const found = arabicMap.find(([n]) => n === num);
return found ? found[1] : match;
});
return result;
}
/**
* Search the RT algolia api for the movie title
*
@@ -151,6 +228,26 @@ class RottenTomatoes extends ExternalAPI {
);
}
// 6. Try Roman numeral conversion in both directions
if (!movie) {
const nameWithArabic = this.convertRomanToArabic(nameLower);
const nameWithRoman = this.convertArabicToRoman(nameLower);
movie = contentResults.hits.find((movie) => {
const titleLower = movie.title.toLowerCase();
const titleWithArabic = this.convertRomanToArabic(titleLower);
const titleWithRoman = this.convertArabicToRoman(titleLower);
return (
Math.abs(movie.releaseYear - year) <= 1 &&
(titleWithArabic === nameWithArabic ||
titleWithRoman === nameWithRoman ||
titleLower === nameWithArabic ||
titleLower === nameWithRoman)
);
});
}
if (!movie) {
return null;
}
@@ -246,11 +343,50 @@ class RottenTomatoes extends ExternalAPI {
(series) => series.title.toLowerCase() === nameLower
);
}
// 6. Try Roman numeral conversion in both directions
if (!tvshow) {
const nameWithArabic = this.convertRomanToArabic(nameLower);
const nameWithRoman = this.convertArabicToRoman(nameLower);
tvshow = contentResults.hits.find((series) => {
const titleLower = series.title.toLowerCase();
const titleWithArabic = this.convertRomanToArabic(titleLower);
const titleWithRoman = this.convertArabicToRoman(titleLower);
return (
Math.abs(series.releaseYear - year) <= 1 &&
(titleWithArabic === nameWithArabic ||
titleWithRoman === nameWithRoman ||
titleLower === nameWithArabic ||
titleLower === nameWithRoman)
);
});
}
} else {
// If no year provided, use exact case-insensitive title match
tvshow = contentResults.hits.find(
(series) => series.title.toLowerCase() === nameLower
);
// Try Roman numeral conversion if no exact match
if (!tvshow) {
const nameWithArabic = this.convertRomanToArabic(nameLower);
const nameWithRoman = this.convertArabicToRoman(nameLower);
tvshow = contentResults.hits.find((series) => {
const titleLower = series.title.toLowerCase();
const titleWithArabic = this.convertRomanToArabic(titleLower);
const titleWithRoman = this.convertArabicToRoman(titleLower);
return (
titleWithArabic === nameWithArabic ||
titleWithRoman === nameWithRoman ||
titleLower === nameWithArabic ||
titleLower === nameWithRoman
);
});
}
}
if (!tvshow) {