Public/Add-SpotifyTracks.ps1
<# .SYNOPSIS Adds songs to your Spotify liked tracks .DESCRIPTION Accepts a list of tracks from a CSV or from another cmdlet in this module, searches for those songs on Spotify, and adds them to your Spotify liked tracks if found. .PARAMETER Tracks Mutually exclusive with InputFile. An array of SpotifyTracks, as generated by another cmdlet in this module, such as Get-TracksFromFolder or Get-SpotifyTracks. .PARAMETER InputFile Mutually exclusive with Tracks. The Path to a CSV file containing a list of tracks, where each track has values for three columns: name (song name), artists (a comma-separated list of artist names), and album (album name). .PARAMETER ClientId Optional. The ClientId of the app you registered in the Spotify developer portal. See the 'Authentication' section at https://github.com/niwamo/SpotifyUtils .PARAMETER RedirectURI Optional. The redirect URI used for OAuth authentication. Must match what is configured in the Spotify developer protal. See the 'Authentication' section at https://github.com/niwamo/SpotifyUtils .PARAMETER ConfigFile Optional. The path to a JSON configuration file containing 'ClientId' and 'RedirectURI' properties. See the 'Authentication' section at https://github.com/niwamo/SpotifyUtils .EXAMPLE Add-SpotifyTracks -Tracks $(Get-TracksFromFolder -Path ~\Songs) #> function Add-SpotifyTracks { [CmdletBinding()] param ( [Parameter(Mandatory=$false, ValueFromPipeline=$true)] [Object[]] $Tracks, [ValidateScript({ Test-Path $_ })] [Parameter(Mandatory=$false)] [string] $InputFile, [Parameter(Mandatory=$false)] [string] $ClientId, [Parameter(Mandatory=$false)] [string] $RedirectURI, [ValidateScript({Test-Path $_})] [Parameter(Mandatory=$false)] [string] $ConfigFile ) begin { Set-StrictMode -Version 1.0 $ErrorActionPreference = 'Stop' $inputData = [System.Collections.ArrayList]::new() } process { if (!$Tracks -and !$InputFile) { throw "Either 'Tracks' or 'InputFile' required" } elseif ($Tracks) { $inputData.AddRange([array] $Tracks) | Out-Null } elseif ($InputFile.Substring($InputFile.Length-3, 3) -ne 'csv') { throw 'Only CSV files are supported for InputFile' } else { Write-Debug "Importing tracks from CSV" $inputData = Import-Csv -Path $InputFile } } end { Write-Debug ( "Received $($inputData.Count) tracks to add" ) $tracks = ConvertTo-SpotifyTrack -Tracks $inputData # authorization $TokenParams = @{ Scopes = @('user-library-modify') } foreach ($param in @('ClientId', 'RedirectURI', 'ConfigFile')) { if ($PSBoundParameters.ContainsKey($param)) { $TokenParams.Add($param, $PSBoundParameters.TryGetValue($param)) } } try { $token = Get-SpotifyToken @TokenParams } catch { Write-Error ( "There was a problem authenticating to the Spotify API.`n" + "Please review the Authentication section at https://github.com/niwamo/SpotifyUtils.`n" + "Error message: " + $_.Exception.Message ) } $headers = @{ Authorization = "Bearer $token" } ########################## # Region: Add Tracks # ########################## $missing = [System.Collections.ArrayList]::new() foreach ($song in $tracks) { Write-Debug "Trying to add $($song.name) by $($song.artists[0])" # https://stackoverflow.com/questions/73680222 $uri = "$($script:SEARCH_URI)?type=track&q=artist:""$($song.artists[0])"" track:""$($song.name)""" $results = (Invoke-WebRequest -Uri $uri -Headers $headers).Content | ConvertFrom-Json $top = $results.tracks.items[0] Write-Debug "top: $($top | ConvertTo-Json -Depth 5)" if ($top.name -eq $song.name -and $top.artists[0].name -eq $song.artists[0]) { $params = @{ URI = "$script:MYTRACKS_URI" Method = 'Put' ContentType = 'application/json' Body = "{""ids"":[""$($top.id)""]}" Headers = $headers } Write-Debug "params: $($params | ConvertTo-Json -Depth 5)" Invoke-WebRequest @params | Out-Null Write-Debug "Added $($song.name)" } else { Write-Debug "Could not find $($song.name)" $missing.Add($song) | Out-Null } [System.Threading.Thread]::Sleep($script:API_DELAY) } if ($missing.Count) { Write-Warning "Failed to add $($missing.Count) tracks, returning them in an array" return $missing } } } |