Fix correctness bugs found by code review

- matrix: drop cryptohelper LoginAs so device.json creds aren't
  invalidated on every restart by Init's re-login
- matrix: thread ctx through PostThreadedReply; bot dispatcher derives
  per-command ctx from app lifecycle so SIGTERM cancels in-flight work
- matrix: isTokenValid verifies /whoami user_id matches configured one
- matrix: loadDevice distinguishes missing file from corrupt parse;
  refuse to silently overwrite a corrupt device.json
- matrix: Start checks Syncer type assertion and returns error
- arr: parseLookup skips empty-title items and extracts existing id
- bot: skip Add when Result.Exists; reply "already in library"
This commit is contained in:
prosolis
2026-05-24 20:50:51 -07:00
parent 8c295d183b
commit 035089c159
5 changed files with 137 additions and 52 deletions

View File

@@ -19,11 +19,15 @@ import (
// Result is a single candidate returned by an *arr lookup. Title and Year
// are extracted for display; raw is the untouched JSON object used to build
// the Add payload.
// the Add payload. Exists is true when the *arr server already has this item
// in its library (lookup responses set "id" to a non-zero value in that case),
// so the bot can skip the Add and report 'already in library' instead of
// blindly re-POSTing.
type Result struct {
Title string
Year int
raw json.RawMessage
Title string
Year int
Exists bool
raw json.RawMessage
}
// Raw exposes the underlying lookup JSON; useful for tests and debugging.
@@ -105,10 +109,29 @@ func parseLookup(body []byte, titleField string) ([]Result, error) {
continue
}
var title string
_ = json.Unmarshal(meta[titleField], &title)
if raw, ok := meta[titleField]; ok && len(raw) > 0 {
_ = json.Unmarshal(raw, &title)
}
if title == "" {
// Skip items we can't display. The Add path would still POST the
// raw JSON, but the user reply would read "Added to Radarr:" with
// no title — worse than dropping the candidate.
continue
}
var year int
_ = json.Unmarshal(meta["year"], &year)
out = append(out, Result{Title: title, Year: year, raw: item})
if raw, ok := meta["year"]; ok && len(raw) > 0 {
_ = json.Unmarshal(raw, &year)
}
var existingID int
if raw, ok := meta["id"]; ok && len(raw) > 0 {
_ = json.Unmarshal(raw, &existingID)
}
out = append(out, Result{
Title: title,
Year: year,
Exists: existingID > 0,
raw: item,
})
}
return out, nil
}