Skip to content

Commit c1ded37

Browse files
Fix Jellyfin to use path-specific scanning instead of full library refresh (#7)
1 parent 6370cbb commit c1ded37

2 files changed

Lines changed: 44 additions & 14 deletions

File tree

main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -708,7 +708,7 @@ async def test_connection(
708708
headers = {"X-Plex-Token": token}
709709
elif type.lower() == "jellyfin":
710710
test_url = f"{url}/System/Info/Public"
711-
headers = {"X-MediaBrowser-Token": api_key}
711+
headers = {"Authorization": f'MediaBrowser Token="{api_key}"'}
712712
elif type.lower() == "emby":
713713
test_url = f"{url}/Library/SelectableMediaFolders"
714714
headers = {"X-MediaBrowser-Token": api_key}

media_server_service.py

Lines changed: 43 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -115,17 +115,34 @@ def __init__(self, **kwargs):
115115
self.type = "jellyfin"
116116

117117
async def scan_path(self, path: str) -> Dict[str, Any]:
118-
"""Scan a path in Jellyfin"""
118+
"""Scan a specific path in Jellyfin using the Media/Updated endpoint.
119+
120+
This uses the /Library/Media/Updated endpoint which notifies Jellyfin
121+
about changes to specific paths, rather than triggering a full library scan.
122+
"""
119123
headers = {
120-
"X-MediaBrowser-Token": self.api_key
124+
"Authorization": f'MediaBrowser Token="{self.api_key}"',
125+
"Content-Type": "application/json"
121126
}
122-
123-
# Trigger library scan
124-
scan_url = urljoin(self.url, "/Library/Refresh")
127+
128+
# Use /Library/Media/Updated endpoint for path-specific scanning
129+
scan_url = urljoin(self.url, "/Library/Media/Updated")
130+
131+
payload = {
132+
"Updates": [
133+
{
134+
"Path": path,
135+
"UpdateType": "Modified"
136+
}
137+
]
138+
}
139+
140+
logger.debug(f"Scanning Jellyfin path: {path}")
141+
125142
async with aiohttp.ClientSession() as session:
126-
async with session.post(scan_url, headers=headers, timeout=30) as response:
143+
async with session.post(scan_url, headers=headers, json=payload, timeout=30) as response:
127144
response.raise_for_status()
128-
return {"message": "Scan initiated"}
145+
return {"status": "success", "message": f"Scan initiated for path: {path}"}
129146

130147
class EmbyServer(MediaServerBase):
131148
def __init__(self, **kwargs):
@@ -305,15 +322,28 @@ async def _scan_plex(self, server: PlexServer, path: str, library_type: str) ->
305322

306323
async def _scan_jellyfin(self, server: JellyfinServer, path: str) -> Dict[str, Any]:
307324
headers = {
308-
"X-MediaBrowser-Token": server.api_key
325+
"Authorization": f'MediaBrowser Token="{server.api_key}"',
326+
"Content-Type": "application/json"
309327
}
310-
311-
# Trigger library scan
312-
scan_url = urljoin(server.url, "/Library/Refresh")
328+
329+
# Use /Library/Media/Updated endpoint for path-specific scanning
330+
scan_url = urljoin(server.url, "/Library/Media/Updated")
331+
332+
payload = {
333+
"Updates": [
334+
{
335+
"Path": path,
336+
"UpdateType": "Modified"
337+
}
338+
]
339+
}
340+
341+
logger.debug(f"Scanning Jellyfin path: {path}")
342+
313343
async with aiohttp.ClientSession() as session:
314-
async with session.post(scan_url, headers=headers, timeout=30) as response:
344+
async with session.post(scan_url, headers=headers, json=payload, timeout=30) as response:
315345
response.raise_for_status()
316-
return {"message": "Scan initiated"}
346+
return {"status": "success", "message": f"Scan initiated for path: {path}"}
317347

318348
async def _scan_emby(self, server: EmbyServer, path: str) -> Dict[str, Any]:
319349
headers = {

0 commit comments

Comments
 (0)