Fall back to OMDb demo on rate limits
This commit is contained in:
1 parent
4f78883f0b
commit
dfe3955604
2 files changed
+28
-5
No files matched your search
+13
-2
@@ -4,6 +4,9 @@ import type { MediaDetails } from '#lib/media/types';
|
|||||||
const cacheDuration = 24 * 60 * 60 * 1000;
|
const cacheDuration = 24 * 60 * 60 * 1000;
|
||||||
const imdbIdPattern = /tt\d+/;
|
const imdbIdPattern = /tt\d+/;
|
||||||
const missingValue = 'N/A';
|
const missingValue = 'N/A';
|
||||||
|
const omdbUrl = 'https://www.omdbapi.com/';
|
||||||
|
const omdbDemoUrl = 'http://www.omdbapi.com/demo.aspx/';
|
||||||
|
const rateLimitedStatus = 401;
|
||||||
|
|
||||||
interface OmdbResponse {
|
interface OmdbResponse {
|
||||||
Response: 'True' | 'False';
|
Response: 'True' | 'False';
|
||||||
@@ -35,13 +38,21 @@ function toMediaDetails(result: OmdbResponse): MediaDetails {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function requestOmdb(imdbId: string): Promise<Response> {
|
||||||
|
const params = new URLSearchParams({ apikey: OMDB_API_KEY ?? '', i: imdbId, plot: 'short' });
|
||||||
|
const response = await fetch(`${omdbUrl}?${params}`);
|
||||||
|
if (response.status !== rateLimitedStatus) return response;
|
||||||
|
|
||||||
|
const demoParams = new URLSearchParams({ i: imdbId, token: 'demo' });
|
||||||
|
return fetch(`${omdbDemoUrl}?${demoParams}`);
|
||||||
|
}
|
||||||
|
|
||||||
async function fetchDetails(imdbId: string): Promise<MediaDetails | null> {
|
async function fetchDetails(imdbId: string): Promise<MediaDetails | null> {
|
||||||
const cached = detailsCache.get(imdbId);
|
const cached = detailsCache.get(imdbId);
|
||||||
if (cached && Date.now() - cached.fetchedAt < cacheDuration) return cached.details;
|
if (cached && Date.now() - cached.fetchedAt < cacheDuration) return cached.details;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const params = new URLSearchParams({ apikey: OMDB_API_KEY ?? '', i: imdbId, plot: 'short' });
|
const response = await requestOmdb(imdbId);
|
||||||
const response = await fetch(`https://www.omdbapi.com/?${params}`);
|
|
||||||
if (!response.ok) throw new Error(`OMDb returned ${response.status}`);
|
if (!response.ok) throw new Error(`OMDb returned ${response.status}`);
|
||||||
|
|
||||||
const result: OmdbResponse = await response.json();
|
const result: OmdbResponse = await response.json();
|
||||||
|
|||||||
+15
-3
@@ -1,6 +1,7 @@
|
|||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
import urllib.error
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
import urllib.request
|
import urllib.request
|
||||||
|
|
||||||
@@ -8,6 +9,9 @@ from jsonfile import PROJECT_ROOT
|
|||||||
|
|
||||||
IMDB_ID_PATTERN = re.compile(r"tt\d{7,9}")
|
IMDB_ID_PATTERN = re.compile(r"tt\d{7,9}")
|
||||||
ENV_FILE = PROJECT_ROOT / ".env"
|
ENV_FILE = PROJECT_ROOT / ".env"
|
||||||
|
OMDB_URL = "https://www.omdbapi.com/"
|
||||||
|
OMDB_DEMO_URL = "http://www.omdbapi.com/demo.aspx/"
|
||||||
|
RATE_LIMITED_STATUS = 401
|
||||||
|
|
||||||
|
|
||||||
def imdb_id(text: str) -> str | None:
|
def imdb_id(text: str) -> str | None:
|
||||||
@@ -31,14 +35,22 @@ def omdb_api_key() -> str | None:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def request_json(url: str, parameters: dict) -> dict:
|
||||||
|
with urllib.request.urlopen(f"{url}?{urllib.parse.urlencode(parameters)}", timeout=10) as response:
|
||||||
|
return json.load(response)
|
||||||
|
|
||||||
|
|
||||||
def lookup(identifier: str) -> dict | None:
|
def lookup(identifier: str) -> dict | None:
|
||||||
api_key = omdb_api_key()
|
api_key = omdb_api_key()
|
||||||
if not api_key:
|
if not api_key:
|
||||||
return None
|
return None
|
||||||
query = urllib.parse.urlencode({"apikey": api_key, "i": identifier})
|
|
||||||
try:
|
try:
|
||||||
with urllib.request.urlopen(f"https://www.omdbapi.com/?{query}", timeout=10) as response:
|
try:
|
||||||
result = json.load(response)
|
result = request_json(OMDB_URL, {"apikey": api_key, "i": identifier})
|
||||||
|
except urllib.error.HTTPError as error:
|
||||||
|
if error.code != RATE_LIMITED_STATUS:
|
||||||
|
raise
|
||||||
|
result = request_json(OMDB_DEMO_URL, {"i": identifier, "token": "demo"})
|
||||||
except (OSError, ValueError):
|
except (OSError, ValueError):
|
||||||
return None
|
return None
|
||||||
return result if result.get("Response") == "True" else None
|
return result if result.get("Response") == "True" else None
|
||||||
Reference in new issue
Block a user