Public/Search-SpotifyTrack.ps1
|
<# .SYNOPSIS Search Spotify for a track by artist and title .DESCRIPTION Queries the Spotify search API for a track by artist name and title. Returns a single best match by default. Use -Limit 5 or -Limit 10 to retrieve a short list, and add -Interactive to pick one from that list in the terminal. If the search returns no results, use -TopTracksOnNoMatch to fall back to the artist's top 3 tracks on Spotify instead. .PARAMETER Artist The artist name to search for. .PARAMETER Title The track title to search for. .PARAMETER Limit Number of results to return. Allowed values: 1 (default), 5, 10. With -Limit 1 (the default), the top match is returned directly. .PARAMETER Interactive When combined with -Limit 5 or -Limit 10, displays a numbered list and prompts for a selection. Returns a single SpotifyTrack. .PARAMETER TopTracksOnNoMatch When the artist+title search returns no results, fall back to the artist's top 3 tracks on Spotify and return those instead. .PARAMETER ClientId Optional. The ClientId of the app you registered in the Spotify developer portal. .PARAMETER RedirectURI Optional. The redirect URI used for OAuth authentication. .PARAMETER ConfigFile Optional. The path to a JSON configuration file containing 'ClientId' and 'RedirectURI' properties. .EXAMPLE Search-SpotifyTrack -Artist "Radiohead" -Title "Creep" .EXAMPLE Search-SpotifyTrack -Artist "Radiohead" -Title "Creep" -Limit 5 .EXAMPLE $track = Search-SpotifyTrack -Artist "Radiohead" -Title "Creep" -Limit 10 -Interactive Add-SpotifyPlaylistTracks -PlaylistId $pl.id -TrackUris $track.uri .EXAMPLE Search-SpotifyTrack -Artist "Radiohead" -Title "TypoInTitle" -TopTracksOnNoMatch #> function Search-SpotifyTrack { [CmdletBinding()] param ( [Parameter(Mandatory=$true)] [string] $Artist, [Parameter(Mandatory=$true)] [string] $Title, [ValidateSet(1, 5, 10)] [Parameter(Mandatory=$false)] [int] $Limit = 1, [Parameter(Mandatory=$false)] [switch] $Interactive, [Parameter(Mandatory=$false)] [switch] $TopTracksOnNoMatch, [Parameter(Mandatory=$false)] [string] $ClientId, [Parameter(Mandatory=$false)] [string] $RedirectURI, [ValidateScript({Test-Path $_})] [Parameter(Mandatory=$false)] [string] $ConfigFile ) Set-StrictMode -Version 1.0 $ErrorActionPreference = 'Stop' $TokenParams = @{ Scopes = @('user-library-read') } foreach ($param in @('ClientId', 'RedirectURI', 'ConfigFile')) { if ($PSBoundParameters.ContainsKey($param)) { $TokenParams.Add($param, $PSBoundParameters[$param]) } } $token = Get-SpotifyToken @TokenParams $headers = @{ Authorization = "Bearer $token" } $q = [uri]::EscapeDataString("artist:`"$Artist`" track:`"$Title`"") $uri = "$script:SEARCH_URI`?type=track&q=$q&limit=$Limit" $response = ( Invoke-SpotifyRequest -Uri $uri -Headers $headers ).Content | ConvertFrom-Json $items = $response.tracks.items if (!$items -or $items.Count -eq 0) { if (!$TopTracksOnNoMatch) { Write-Warning "No results found for '$Title' by '$Artist'" return } Write-Warning "No results found for '$Title' by '$Artist' — falling back to top tracks" $artistQ = [uri]::EscapeDataString("artist:`"$Artist`"") [System.Threading.Thread]::Sleep($script:API_DELAY) $fallbackResponse = ( Invoke-SpotifyRequest -Uri "$script:SEARCH_URI`?type=track&q=$artistQ&limit=3" -Headers $headers ).Content | ConvertFrom-Json $items = $fallbackResponse.tracks.items if (!$items -or $items.Count -eq 0) { Write-Warning "No tracks found for artist '$Artist'" return } } $tracks = ConvertTo-SpotifyTrack -Tracks $items if ($Limit -eq 1 -or $tracks.Count -eq 1) { return $tracks[0] } if ($Interactive) { for ($i = 0; $i -lt $tracks.Count; $i++) { $t = $tracks[$i] Write-Host ("[{0}] {1} — {2} ({3})" -f ($i + 1), $t.artists[0], $t.name, $t.album) } $raw = Read-Host "Select (1-$($tracks.Count))" $idx = [int]$raw - 1 if ($idx -lt 0 -or $idx -ge $tracks.Count) { throw "Invalid selection '$raw'" } return $tracks[$idx] } return $tracks } |