fix: tautulli — entry_id collision on missing ts, token settings, test coverage

This commit is contained in:
pyr0ball 2026-05-13 19:04:07 -07:00
parent b61a85dc62
commit 72800332c9
4 changed files with 16 additions and 2 deletions

View file

@ -82,7 +82,8 @@ def parse_webhook(
ingest_time = now_iso() ingest_time = now_iso()
severity = _severity(action) severity = _severity(action)
matched = apply_patterns(text, compiled_patterns) matched = apply_patterns(text, compiled_patterns)
entry_id = make_entry_id(source_id, 0, str(raw_ts) + text) id_ts = str(raw_ts) if raw_ts else ingest_time
entry_id = make_entry_id(source_id, 0, id_ts + text)
return RetrievedEntry( return RetrievedEntry(
entry_id=entry_id, entry_id=entry_id,

View file

@ -141,6 +141,7 @@ class SettingsBody(BaseModel):
llm_url: str | None = None llm_url: str | None = None
llm_model: str | None = None llm_model: str | None = None
llm_api_key: str | None = None llm_api_key: str | None = None
tautulli_token: str | None = None
severity_overrides: list[SeverityOverride] | None = None severity_overrides: list[SeverityOverride] | None = None
@ -338,6 +339,8 @@ def patch_settings(body: SettingsBody) -> dict:
prefs["llm_model"] = body.llm_model prefs["llm_model"] = body.llm_model
if body.llm_api_key is not None: if body.llm_api_key is not None:
prefs["llm_api_key"] = body.llm_api_key prefs["llm_api_key"] = body.llm_api_key
if body.tautulli_token is not None:
prefs["tautulli_token"] = body.tautulli_token
if body.severity_overrides is not None: if body.severity_overrides is not None:
prefs["severity_overrides"] = [o.model_dump() for o in body.severity_overrides] prefs["severity_overrides"] = [o.model_dump() for o in body.severity_overrides]
_save_prefs(prefs) _save_prefs(prefs)

View file

@ -43,7 +43,7 @@ http://<turnstone-host>:8534/turnstone/api/ingest/tautulli
``` ```
Replace `<turnstone-host>` with the hostname or IP of the machine running Replace `<turnstone-host>` with the hostname or IP of the machine running
Turnstone. If Turnstone is behind a reverse proxy, use the proxy URL instead. Turnstone. (8534 is the default port; adjust if you're using a reverse proxy or changed the port)
## Optional token authentication ## Optional token authentication

View file

@ -147,6 +147,16 @@ class TestTextFormat:
entry = parse_webhook(_STOP_PAYLOAD, []) entry = parse_webhook(_STOP_PAYLOAD, [])
assert entry.text.startswith("[plex:stop]") assert entry.text.startswith("[plex:stop]")
def test_pause_action(self):
payload = {**_STOP_PAYLOAD, "action": "pause", "timestamp": "1747195600", "session_key": "pause01"}
entry = parse_webhook(payload, [])
assert entry.text.startswith("[plex:pause]")
def test_resume_action(self):
payload = {**_STOP_PAYLOAD, "action": "resume", "timestamp": "1747195700", "session_key": "resume01"}
entry = parse_webhook(payload, [])
assert entry.text.startswith("[plex:resume]")
def test_tv_episode_formats_show_and_title(self): def test_tv_episode_formats_show_and_title(self):
entry = parse_webhook(_ERROR_PAYLOAD, []) entry = parse_webhook(_ERROR_PAYLOAD, [])
assert '"Oshi no Ko — Episode 7"' in entry.text assert '"Oshi no Ko — Episode 7"' in entry.text