diff --git a/app.go b/app.go index 030de2a..c0d5dea 100644 --- a/app.go +++ b/app.go @@ -85,6 +85,42 @@ func containsStreamingURL(body []byte) bool { return isStreamingURL(trimmedBody) } +func containsLRCLIBResults(body []byte) bool { + trimmedBody := strings.TrimSpace(string(body)) + if trimmedBody == "" { + return false + } + + var searchResults []map[string]interface{} + if err := json.Unmarshal(body, &searchResults); err == nil { + return len(searchResults) > 0 + } + + var exactResult map[string]interface{} + if err := json.Unmarshal(body, &exactResult); err == nil { + return len(exactResult) > 0 + } + + return false +} + +func containsMusicBrainzResults(body []byte) bool { + trimmedBody := strings.TrimSpace(string(body)) + if trimmedBody == "" { + return false + } + + var payload struct { + Count int `json:"count"` + Recordings []json.RawMessage `json:"recordings"` + } + if err := json.Unmarshal(body, &payload); err != nil { + return false + } + + return payload.Count > 0 || len(payload.Recordings) > 0 +} + func isStreamingURL(raw string) bool { candidate := strings.TrimSpace(raw) if candidate == "" { @@ -948,6 +984,10 @@ func (a *App) CheckAPIStatus(apiType string, apiURL string) bool { checkURL = fmt.Sprintf("%s/api/track/360735657?quality=27", apiURL) } else if apiType == "amazon" { checkURL = fmt.Sprintf("%s/status", apiURL) + } else if apiType == "lrclib" { + checkURL = fmt.Sprintf("%s/api/search?artist_name=Adele&track_name=Hello", strings.TrimRight(apiURL, "/")) + } else if apiType == "musicbrainz" { + checkURL = fmt.Sprintf("%s/ws/2/recording?query=%s&fmt=json&limit=1", strings.TrimRight(apiURL, "/"), url.QueryEscape(`recording:"Hello" AND artist:"Adele"`)) } else { checkURL = apiURL } @@ -958,6 +998,7 @@ func (a *App) CheckAPIStatus(apiType string, apiURL string) bool { return false, err } req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36") + req.Header.Set("Accept", "application/json") maxRetries := 3 for i := 0; i < maxRetries; i++ { @@ -981,7 +1022,15 @@ func (a *App) CheckAPIStatus(apiType string, apiURL string) bool { return true, nil } - if apiType != "amazon" && apiType != "qobuz" && apiType != "qbz" && statusCode == 200 { + if apiType == "lrclib" && statusCode == 200 && containsLRCLIBResults(body) { + return true, nil + } + + if apiType == "musicbrainz" && statusCode == 200 && containsMusicBrainzResults(body) { + return true, nil + } + + if apiType != "amazon" && apiType != "qobuz" && apiType != "qbz" && apiType != "lrclib" && apiType != "musicbrainz" && statusCode == 200 { return true, nil } } diff --git a/frontend/src/assets/icons/amazon-music.png b/frontend/src/assets/icons/amazon-music.png deleted file mode 100644 index 92d42cf..0000000 Binary files a/frontend/src/assets/icons/amazon-music.png and /dev/null differ diff --git a/frontend/src/assets/icons/amzn.png b/frontend/src/assets/icons/amzn.png new file mode 100644 index 0000000..e138846 Binary files /dev/null and b/frontend/src/assets/icons/amzn.png differ diff --git a/frontend/src/assets/icons/lrclib.png b/frontend/src/assets/icons/lrclib.png new file mode 100644 index 0000000..ac3e5e7 Binary files /dev/null and b/frontend/src/assets/icons/lrclib.png differ diff --git a/frontend/src/assets/icons/musicbrainz_d.png b/frontend/src/assets/icons/musicbrainz_d.png new file mode 100644 index 0000000..7467b95 Binary files /dev/null and b/frontend/src/assets/icons/musicbrainz_d.png differ diff --git a/frontend/src/assets/icons/musicbrainz_l.png b/frontend/src/assets/icons/musicbrainz_l.png new file mode 100644 index 0000000..1b864f7 Binary files /dev/null and b/frontend/src/assets/icons/musicbrainz_l.png differ diff --git a/frontend/src/assets/icons/qbz.png b/frontend/src/assets/icons/qbz.png new file mode 100644 index 0000000..a6eb75e Binary files /dev/null and b/frontend/src/assets/icons/qbz.png differ diff --git a/frontend/src/assets/icons/qobuz.png b/frontend/src/assets/icons/qobuz.png deleted file mode 100644 index d4a3be1..0000000 Binary files a/frontend/src/assets/icons/qobuz.png and /dev/null differ diff --git a/frontend/src/assets/icons/songlink.ico b/frontend/src/assets/icons/songlink.ico deleted file mode 100644 index 4fdec81..0000000 Binary files a/frontend/src/assets/icons/songlink.ico and /dev/null differ diff --git a/frontend/src/assets/icons/songlink_d.png b/frontend/src/assets/icons/songlink_d.png new file mode 100644 index 0000000..b988734 Binary files /dev/null and b/frontend/src/assets/icons/songlink_d.png differ diff --git a/frontend/src/assets/icons/songlink_l.png b/frontend/src/assets/icons/songlink_l.png new file mode 100644 index 0000000..fd0cb1a Binary files /dev/null and b/frontend/src/assets/icons/songlink_l.png differ diff --git a/frontend/src/assets/icons/songstats.png b/frontend/src/assets/icons/songstats.png index fc8a223..ae111fc 100644 Binary files a/frontend/src/assets/icons/songstats.png and b/frontend/src/assets/icons/songstats.png differ diff --git a/frontend/src/assets/icons/tidal.png b/frontend/src/assets/icons/tidal.png deleted file mode 100644 index 141e014..0000000 Binary files a/frontend/src/assets/icons/tidal.png and /dev/null differ diff --git a/frontend/src/assets/icons/tidal_d.png b/frontend/src/assets/icons/tidal_d.png new file mode 100644 index 0000000..4760bfa Binary files /dev/null and b/frontend/src/assets/icons/tidal_d.png differ diff --git a/frontend/src/assets/icons/tidal_l.png b/frontend/src/assets/icons/tidal_l.png new file mode 100644 index 0000000..7397386 Binary files /dev/null and b/frontend/src/assets/icons/tidal_l.png differ diff --git a/frontend/src/components/ApiStatusTab.tsx b/frontend/src/components/ApiStatusTab.tsx index d1bb34f..674ccd4 100644 --- a/frontend/src/components/ApiStatusTab.tsx +++ b/frontend/src/components/ApiStatusTab.tsx @@ -1,6 +1,6 @@ import { Button } from "@/components/ui/button"; import { RefreshCw, CheckCircle2, XCircle, Loader2 } from "lucide-react"; -import { TidalIcon, QobuzIcon, AmazonIcon } from "./PlatformIcons"; +import { TidalIcon, QobuzIcon, AmazonIcon, LrclibIcon, MusicBrainzIcon } from "./PlatformIcons"; import { useApiStatus } from "@/hooks/useApiStatus"; export function ApiStatusTab() { const { sources, statuses, isCheckingAll, refreshAll } = useApiStatus(); @@ -12,12 +12,12 @@ export function ApiStatusTab() { -
{source.name}