mirror of
https://github.com/gesellix/Bose-SoundTouch.git
synced 2026-08-19 09:06:14 +00:00
fix(bmx): emit BMX-relative playback hrefs in TuneIn nav/search results
The b95bdae split changed BmxPlayback.Href to raw `Tune.ashx?id=…` URLs,
which the speaker's BMX module fetches directly — failing `IsItBose`,
sending no auth, and getting 401 from radiotime. Restore the v0.85.0
shape (`/v1/playback/{station|episodes}/{id}`) so playback flows back
through HandleTuneInPlayback. Also restore play-link emission for Topic
search results (single podcast episodes); `Tune.ashx?id=t<N>` accepts
them like station IDs, so the same path works.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
68760a8977
commit
882d0633fb
+10
-36
@@ -277,7 +277,7 @@ func tuneInNavigatePlayItem(item map[string]interface{}) models.BmxNavItem {
|
||||
Subtitle: subtitle,
|
||||
Links: &models.Links{
|
||||
BmxPlayback: &models.Link{
|
||||
Href: TuneInStream(stationID, ""),
|
||||
Href: fmt.Sprintf("/v1/playback/station/%s", stationID),
|
||||
Type: "stationurl",
|
||||
},
|
||||
},
|
||||
@@ -373,10 +373,11 @@ func tuneInSearchSection(item map[string]interface{}, idx int, query, layout str
|
||||
}
|
||||
|
||||
switch typeStr {
|
||||
case "Station", "PlayItem":
|
||||
case "Station", "PlayItem", "Topic":
|
||||
// Topics are single podcast episodes (t<N>) — Tune.ashx
|
||||
// accepts them just like station IDs, so the same play-link
|
||||
// shape works.
|
||||
section.Items = append(section.Items, tuneInSearchPlayItem(cm))
|
||||
case "Topic":
|
||||
section.Items = append(section.Items, tuneInSearchTopic(cm))
|
||||
case "Program", "Profile":
|
||||
section.Items = append(section.Items, tuneInSearchProfile(cm, name))
|
||||
}
|
||||
@@ -412,43 +413,13 @@ func tuneInSearchPlayItem(item map[string]interface{}) models.BmxNavItem {
|
||||
Subtitle: subtitle,
|
||||
Links: &models.Links{
|
||||
BmxPlayback: &models.Link{
|
||||
Href: TuneInStream(stationID, ""),
|
||||
Href: fmt.Sprintf("/v1/playback/station/%s", stationID),
|
||||
Type: "stationurl",
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func tuneInSearchTopic(item map[string]interface{}) models.BmxNavItem {
|
||||
name, _ := item["Title"].(string)
|
||||
if name == "" {
|
||||
name, _ = item["text"].(string)
|
||||
}
|
||||
|
||||
image, _ := item["Image"].(string)
|
||||
if image == "" {
|
||||
image, _ = item["image"].(string)
|
||||
}
|
||||
|
||||
subtitle, _ := item["Subtitle"].(string)
|
||||
if subtitle == "" {
|
||||
subtitle, _ = item["subtext"].(string)
|
||||
}
|
||||
|
||||
href, _ := item["URL"].(string)
|
||||
|
||||
return models.BmxNavItem{
|
||||
Name: name,
|
||||
ImageUrl: image,
|
||||
Subtitle: subtitle,
|
||||
Links: &models.Links{
|
||||
BmxNavigate: &models.Link{
|
||||
Href: "/v1/navigate/" + base64.RawURLEncoding.EncodeToString([]byte(tuneInRenderJSONURI(href))),
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func tuneInSearchProfile(item map[string]interface{}, _ string) models.BmxNavItem {
|
||||
profileName, _ := item["Title"].(string)
|
||||
if profileName == "" {
|
||||
@@ -481,13 +452,16 @@ func tuneInSearchProfile(item map[string]interface{}, _ string) models.BmxNavIte
|
||||
// Artists/Stations/etc are typically navigated first.
|
||||
if typeStr, _ := item["Type"].(string); typeStr == "Program" {
|
||||
if guideID, _ := item["GuideId"].(string); guideID != "" {
|
||||
encodedName := base64.URLEncoding.EncodeToString([]byte(profileName))
|
||||
playbackHref := fmt.Sprintf("/v1/playback/episodes/%s?encoded_name=%s", guideID, encodedName)
|
||||
|
||||
return models.BmxNavItem{
|
||||
Name: profileName,
|
||||
ImageUrl: image,
|
||||
Subtitle: subtitle,
|
||||
Links: &models.Links{
|
||||
BmxPlayback: &models.Link{
|
||||
Href: TuneInStream(guideID, "") + "&encoded_name=" + url.QueryEscape(profileName),
|
||||
Href: playbackHref,
|
||||
Type: "tracklisturl",
|
||||
},
|
||||
BmxNavigate: &models.Link{
|
||||
|
||||
Reference in New Issue
Block a user