Spaces:
Paused
Paused
const fs = require('fs'); | |
const path = require('path'); | |
const axios = require('axios'); | |
const { cacheDb } = require('./db'); | |
const log = require('./logger'); | |
const baseUrl = process.env.BASE_URL || 'http://localhost:7000'; | |
const DEFAULT_CATALOG_CACHE_DURATION = process.env.CATALOG_CONTENT_CACHE_DURATION || '3d'; | |
const DEFAULT_RPDB_POSTER_CACHE_DURATION = process.env.RPDB_POSTER_CACHE_DURATION || '3d'; | |
const posterDirectory = path.join(__dirname, '../../db/rpdbPosters'); | |
if (!fs.existsSync(posterDirectory)) { | |
fs.mkdirSync(posterDirectory, { recursive: true }); | |
} | |
const formatFileName = (posterId) => { | |
return posterId.replace(/[^a-zA-Z0-9-_]/g, '_'); | |
}; | |
const cacheDurationToSeconds = (duration) => { | |
const match = duration.match(/^(\d+)([dh])$/); | |
if (!match) throw new Error('Invalid cache duration format'); | |
const [ , value, unit ] = match; | |
const number = parseInt(value, 10); | |
switch (unit) { | |
case 'd': return number * 86400; | |
case 'h': return number * 3600; | |
default: throw new Error('Invalid cache duration unit'); | |
} | |
}; | |
const setCatalogCache = (key, value, duration = DEFAULT_CATALOG_CACHE_DURATION, page = 1, skip = 0, genre = null, year = null, rating = null, mediaType = null) => { | |
try { | |
genre = genre === null ? "undefined" : genre; | |
year = year === null ? "undefined" : year; | |
rating = rating === null ? "undefined" : rating; | |
const durationInSeconds = cacheDurationToSeconds(duration); | |
const expireTime = Math.floor(Date.now() / 1000) + durationInSeconds; | |
const query = `INSERT OR REPLACE INTO cache (key, value, timestamp, page, skip, genre, year, rating, mediaType) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`; | |
cacheDb.run(query, [key, JSON.stringify(value), expireTime, page, skip, genre, year, rating, mediaType], (err) => { | |
if (err) { | |
log.error(`Failed to set cache for key ${key}: ${err.message}`); | |
} else { | |
log.debug(`Cache set for key ${key} with duration ${duration}`); | |
} | |
}); | |
} catch (error) { | |
log.error(`Error in setting cache: ${error.message}`); | |
} | |
}; | |
const getCatalogCache = (key, cacheDuration = DEFAULT_CATALOG_CACHE_DURATION) => { | |
const cacheDurationInSeconds = cacheDurationToSeconds(cacheDuration); | |
return new Promise((resolve, reject) => { | |
cacheDb.get( | |
`SELECT value, timestamp, page, skip, genre, year, rating, mediaType FROM cache WHERE key = ?`, | |
[key], | |
(err, row) => { | |
if (err) { | |
log.error(`Error retrieving cache for key ${key}: ${err.message}`); | |
return reject(err); | |
} | |
if (!row) { | |
log.debug(`Cache miss for key ${key}`); | |
return resolve(null); | |
} | |
const isCacheValid = (Date.now() / 1000 - row.timestamp) < cacheDurationInSeconds; | |
if (isCacheValid) { | |
log.debug(`Cache hit for key ${key}`); | |
resolve({ | |
value: JSON.parse(row.value), | |
page: row.page, | |
skip: row.skip, | |
genre: row.genre, | |
year: row.year, | |
rating: row.rating, | |
mediaType: row.mediaType | |
}); | |
} else { | |
log.debug(`Cache expired for key ${key}`); | |
resolve(null); | |
} | |
} | |
); | |
}); | |
}; | |
const getCachedPoster = async (posterId) => { | |
const formattedPosterId = formatFileName(posterId); | |
const filePath = path.join(posterDirectory, `${formattedPosterId}.jpg`); | |
const cacheDurationInSeconds = cacheDurationToSeconds(DEFAULT_RPDB_POSTER_CACHE_DURATION); | |
if (fs.existsSync(filePath)) { | |
const stats = fs.statSync(filePath); | |
const fileAgeInSeconds = (Date.now() - stats.mtimeMs) / 1000; | |
if (fileAgeInSeconds < cacheDurationInSeconds) { | |
const posterUrl = `${baseUrl}/poster/${formattedPosterId}.jpg`; | |
log.debug(`Cache hit for poster id ${posterId}, serving from ${posterUrl}`); | |
return { poster_url: posterUrl }; | |
} else { | |
log.debug(`Cache expired for poster id ${posterId}`); | |
fs.unlinkSync(filePath); // Supprimer le fichier expiré | |
} | |
} else { | |
log.debug(`Cache miss for poster id ${posterId}`); | |
} | |
return null; | |
}; | |
const setCachedPoster = async (posterId, posterUrl) => { | |
const formattedPosterId = formatFileName(posterId); | |
const filePath = path.join(posterDirectory, `${formattedPosterId}.jpg`); | |
try { | |
const response = await axios.get(posterUrl, { responseType: 'arraybuffer' }); | |
fs.writeFileSync(filePath, response.data); | |
log.debug(`Poster id ${posterId} cached at ${filePath}`); | |
} catch (error) { | |
log.error(`Error caching poster id ${posterId} from URL ${posterUrl}: ${error.message}`); | |
throw error; | |
} | |
}; | |
module.exports = { | |
setCatalogCache, | |
getCatalogCache, | |
setCachedPoster, | |
getCachedPoster | |
}; | |