Match Jellyfin punctuation variants using provider metadata and strict fallback
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import re
|
||||
from typing import Any, Dict, Optional
|
||||
import httpx
|
||||
import time
|
||||
@@ -192,15 +193,27 @@ class JellyfinClient(ApiClient):
|
||||
"SearchTerm": term,
|
||||
"IncludeItemTypes": ",".join(item_types or []),
|
||||
"Recursive": "true",
|
||||
"Fields": "Path,MediaSources",
|
||||
"Fields": "Path,MediaSources,ProviderIds,OriginalTitle,SortName",
|
||||
"Limit": limit,
|
||||
}
|
||||
headers = self._emby_headers()
|
||||
try:
|
||||
async with httpx.AsyncClient(timeout=10.0) as client:
|
||||
response = await client.get(url, headers=headers, params=params)
|
||||
response.raise_for_status()
|
||||
result = response.json()
|
||||
normalized = ' '.join(re.sub(r"[^\w\s]", ' ', term, flags=re.UNICODE).split())
|
||||
terms = list(dict.fromkeys([term, normalized]))
|
||||
if normalized != term and normalized.split():
|
||||
terms.append(max(normalized.split(), key=len))
|
||||
items = {}
|
||||
for search_term in dict.fromkeys(terms):
|
||||
if not search_term:
|
||||
continue
|
||||
response = await client.get(url, headers=headers, params={**params, "SearchTerm": search_term})
|
||||
response.raise_for_status()
|
||||
payload = response.json()
|
||||
for item in payload.get('Items', []):
|
||||
if isinstance(item, dict) and item.get('Id'):
|
||||
items[item['Id']] = item
|
||||
result = {'Items': list(items.values()), 'TotalRecordCount': len(items)}
|
||||
duration_ms = round((time.perf_counter() - started_at) * 1000, 2)
|
||||
finish_remote_call(
|
||||
operation_event_id,
|
||||
|
||||
@@ -137,12 +137,10 @@ def jellyfin_item_matches_request(
|
||||
request_provider_ids = extract_request_provider_ids(request_payload or {})
|
||||
item_provider_ids = extract_request_provider_ids(item)
|
||||
|
||||
provider_priority = ("tmdb", "tvdb", "imdb")
|
||||
for key in provider_priority:
|
||||
request_id = request_provider_ids.get(key)
|
||||
item_id = item_provider_ids.get(key)
|
||||
if request_id and item_id and request_id == item_id:
|
||||
return True
|
||||
shared = set(request_provider_ids) & set(item_provider_ids)
|
||||
if shared:
|
||||
# Conflicting metadata must never fall through to title matching.
|
||||
return all(request_provider_ids[key] == item_provider_ids[key] for key in shared)
|
||||
|
||||
request_title = _normalize_media_title(title)
|
||||
if not request_title:
|
||||
@@ -169,11 +167,6 @@ def jellyfin_item_matches_request(
|
||||
if request_title in item_titles:
|
||||
return True
|
||||
|
||||
if request_type == RequestType.tv:
|
||||
for candidate in item_titles:
|
||||
if candidate and (candidate.startswith(request_title) or request_title.startswith(candidate)):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user