53 lines
1.4 KiB
JavaScript
53 lines
1.4 KiB
JavaScript
import { createReadStream, statSync } from 'node:fs';
|
|
import { createInterface } from 'node:readline';
|
|
import { IMDB_RATINGS } from '../config.js';
|
|
|
|
let cache = null;
|
|
let cacheMtime = 0;
|
|
|
|
export async function loadRatings(filePath = IMDB_RATINGS) {
|
|
const map = new Map();
|
|
const stream = createReadStream(filePath, { encoding: 'utf8' });
|
|
const rl = createInterface({ input: stream, crlfDelay: Infinity });
|
|
let first = true;
|
|
for await (const line of rl) {
|
|
if (first) {
|
|
first = false;
|
|
continue;
|
|
}
|
|
if (!line) continue;
|
|
const tab1 = line.indexOf('\t');
|
|
if (tab1 < 0) continue;
|
|
const tab2 = line.indexOf('\t', tab1 + 1);
|
|
if (tab2 < 0) continue;
|
|
const id = line.slice(0, tab1);
|
|
const rating = line.slice(tab1 + 1, tab2);
|
|
const votes = line.slice(tab2 + 1);
|
|
map.set(id, [rating, votes]);
|
|
}
|
|
return map;
|
|
}
|
|
|
|
export async function getRatings() {
|
|
try {
|
|
const st = statSync(IMDB_RATINGS);
|
|
if (cache && st.mtimeMs === cacheMtime) return cache;
|
|
cache = await loadRatings(IMDB_RATINGS);
|
|
cacheMtime = st.mtimeMs;
|
|
return cache;
|
|
} catch (err) {
|
|
if (cache) return cache;
|
|
throw err;
|
|
}
|
|
}
|
|
|
|
export function lookupRating(map, imdbId) {
|
|
if (!imdbId) return { rating: 0, votes: 0 };
|
|
const row = map.get(imdbId);
|
|
if (!row) return { rating: 0, votes: 0 };
|
|
return {
|
|
rating: parseFloat(row[0]) || 0,
|
|
votes: parseInt(row[1], 10) || 0,
|
|
};
|
|
}
|