feat(api): support Prime Video scraping and provider-aware metadata

This commit is contained in:
2026-03-01 01:08:25 +03:00
parent 74348f224d
commit c0e62e778c
11 changed files with 515 additions and 166 deletions

View File

@@ -3,19 +3,35 @@ import { env } from '../config/env.js';
import { emitCacheEvent } from '../config/socket.js';
import logger from '../utils/logger.js';
import type { GetInfoResponse, CacheEntry } from '../types/index.js';
import { parseSupportedContentUrl } from '../utils/contentUrl.js';
/**
* Cache key prefix for Netflix content
* Cache key prefix for scraped content
*/
const CACHE_PREFIX = 'netflix:content:';
const CACHE_PREFIX = 'content:';
/**
* Generate cache key from URL
*/
function getCacheKey(url: string): string {
// Use URL hash or title ID as key
const titleId = url.match(/\/title\/(\d+)/)?.[1] || url;
return `${CACHE_PREFIX}${titleId}`;
const parsed = parseSupportedContentUrl(url);
if (parsed) {
return `${CACHE_PREFIX}${parsed.provider}:${parsed.id}`;
}
return `${CACHE_PREFIX}url:${encodeURIComponent(url)}`;
}
function normalizeCachedResponse(url: string, data: GetInfoResponse): GetInfoResponse {
if (data.provider === 'netflix' || data.provider === 'primevideo') {
return data;
}
return {
...data,
provider: parseSupportedContentUrl(url)?.provider ?? 'netflix',
};
}
/**
@@ -39,7 +55,7 @@ export class CacheService {
logger.debug('Cache hit', { url });
const entry: CacheEntry<GetInfoResponse> = JSON.parse(cached);
return entry.data;
return normalizeCachedResponse(url, entry.data);
} catch (error) {
logger.error('Cache get error', {
url,
@@ -57,7 +73,7 @@ export class CacheService {
const ttl = env.REDIS_TTL_SECONDS;
const entry: CacheEntry<GetInfoResponse> = {
data,
data: normalizeCachedResponse(url, data),
cachedAt: Date.now(),
ttl,
};
@@ -137,7 +153,7 @@ export class CacheService {
}
/**
* Clear all Netflix content cache
* Clear all scraped content cache
*/
static async clearAll(): Promise<void> {
try {