PowerLFM.psm1
using namespace System.Management.Automation New-Variable -Name baseUrl -Value 'https://ws.audioscrobbler.com/2.0' function Add-LFMAlbumTag { # .ExternalHelp PowerLFM-help.xml [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $Album, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $Artist, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateCount(1, 10)] [string[]] $Tag ) begin { $apiParams = @{ 'method' = 'album.addTags' 'api_key' = $script:LFMConfig.ApiKey 'sk' = $script:LFMConfig.SessionKey } } process { $noCommonParams = Remove-CommonParameter $PSBoundParameters $apiSig = Get-LFMSignature -Method $apiParams.Method @noCommonParams $apiParams.Add('api_sig', $apiSig) $convertedParams = ConvertTo-LFMParameter $noCommonParams $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" } end { if ($PSCmdlet.ShouldProcess("Album: $Album", "Adding album tag: $Tag")) { try { $irm = Invoke-LFMApiUri -Uri $apiUrl -Method Post if ($irm.Lfm.Status -eq 'ok') {Write-Verbose "Tag: $Tag has been added"} } catch { throw $_ } } } } function Add-LFMArtistTag { # .ExternalHelp PowerLFM-help.xml [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [string] $Artist, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateCount(1, 10)] [string[]] $Tag ) begin { $apiParams = @{ 'method' = 'artist.addTags' 'api_key' = $script:LFMConfig.ApiKey 'sk' = $script:LFMConfig.SessionKey } } process { $noCommonParams = Remove-CommonParameter $PSBoundParameters $apiSig = Get-LFMSignature -Method $apiParams.Method @noCommonParams $apiParams.Add('api_sig', $apiSig) $convertedParams = ConvertTo-LFMParameter $noCommonParams $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" } end { if ($PSCmdlet.ShouldProcess("Artist: $Artist", "Adding artist tag: $Tag")) { try { $irm = Invoke-LFMApiUri -Uri $apiUrl -Method Post if ($irm.Lfm.Status -eq 'ok') {Write-Verbose "Tag: $Tag has been added"} } catch { throw $_ } } } } function Add-LFMConfiguration { # .ExternalHelp PowerLFM-help.xml [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $ApiKey, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $SessionKey, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $SharedSecret ) process { try { $keys = $PSBoundParameters.Keys.Where({$_ -in @('ApiKey', 'SessionKey', 'SharedSecret')}) foreach ($param in $keys) { $ssParams = @{ Name = "LFM$param" Secret = $PSBoundParameters[$param] Vault = 'BuiltInLocalVault' NoClobber = $true } try { $null = Get-Secret -Name "LFM$param" -ErrorAction Stop $message = "There is already a value present for $param, do you wish to update the value?" if ($PSCmdlet.ShouldProcess('BuiltInLocalVault', $message)) { $ssParams.Remove('NoClobber') Set-Secret @ssParams } } catch { Set-Secret @ssParams } } } catch { throw $_ } } } function Add-LFMTrackTag { # .ExternalHelp PowerLFM-help.xml [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $Track, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $Artist, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateCount(1, 10)] [string[]] $Tag ) begin { $apiParams = @{ 'method' = 'track.addTags' 'api_key' = $script:LFMConfig.ApiKey 'sk' = $script:LFMConfig.SessionKey } } process { $noCommonParams = Remove-CommonParameter $PSBoundParameters $apiSig = Get-LFMSignature -Method $apiParams.Method @noCommonParams $apiParams.Add('api_sig', $apiSig) $convertedParams = ConvertTo-LFMParameter $noCommonParams $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" } end { if ($PSCmdlet.ShouldProcess("Track: $Track", "Adding track tag: $Tag")) { try { $irm = Invoke-LFMApiUri -Uri $apiUrl -Method Post if ($irm.Lfm.Status -eq 'ok') {Write-Verbose "Tag: $Tag has been added"} } catch { throw $_ } } } } function Get-LFMAlbumInfo { # .ExternalHelp PowerLFM-help.xml [CmdletBinding(DefaultParameterSetName = 'album')] [OutputType('PowerLFM.Album.Info')] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName, Position = 0, ParameterSetName = 'album')] [ValidateNotNullOrEmpty()] [string] $Album, [Parameter(Mandatory, ValueFromPipelineByPropertyName, Position = 1, ParameterSetName = 'album')] [ValidateNotNullOrEmpty()] [string] $Artist, [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'id')] [ValidateNotNullOrEmpty()] [guid] $Id, [string] $UserName, [switch] $AutoCorrect ) begin { $apiParams = @{ 'method' = 'album.getInfo' 'api_key' = $script:LFMConfig.ApiKey 'format' = 'json' } } process { $noCommonParams = Remove-CommonParameter $PSBoundParameters $convertedParams = ConvertTo-LFMParameter $noCommonParams $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" } end { try { $irm = Invoke-LFMApiUri -Uri $apiUrl $tracks = foreach ($track in $irm.Album.Tracks.Track) { $trackInfo = [pscustomobject] @{ 'PSTypeName' = 'PowerLFM.Album.Track' 'Track' = $track.Name 'Duration' = [int] $track.Duration 'Url' = [uri] $track.Url } Write-Output $trackInfo } $tags = foreach ($tag in $irm.Album.Tags.Tag) { $tagInfo = [pscustomobject] @{ 'PSTypeName' = 'PowerLFM.Album.Tag' 'Tag' = $tag.Name 'Url' = [uri] $tag.Url } Write-Output $tagInfo } $albumInfo = @{ 'PSTypeName' = 'PowerLFM.Album.Info' 'Artist' = $irm.Album.Artist 'Album' = $irm.Album.Name 'Id' = $irm.Album.Mbid 'Listeners' = [int] $irm.Album.Listeners 'PlayCount' = [int] $irm.Album.PlayCount 'Url' = [uri] $irm.Album.Url 'Summary' = $irm.Album.Wiki.Summary 'Tracks' = $tracks 'Tags' = $tags } $userPlayCount = [int] $irm.Album.UserPlayCount if ($PSBoundParameters.ContainsKey('UserName')) { $albumInfo.Add('UserPlayCount', $userPlayCount) } $albumInfo = [pscustomobject] $albumInfo Write-Output $albumInfo } catch { throw $_ } } } function Get-LFMAlbumTag { # .ExternalHelp PowerLFM-help.xml [CmdletBinding(DefaultParameterSetName = 'album')] [OutputType('PowerLFM.Album.Tag')] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName, Position = 0, ParameterSetName = 'album')] [ValidateNotNullOrEmpty()] [string] $Album, [Parameter(Mandatory, ValueFromPipelineByPropertyName, Position = 1, ParameterSetName = 'album')] [ValidateNotNullOrEmpty()] [string] $Artist, [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'id')] [ValidateNotNullOrEmpty()] [guid] $Id, [string] $UserName, [switch] $AutoCorrect ) begin { $apiParams = @{ 'method' = 'album.getTags' 'api_key' = $script:LFMConfig.ApiKey 'sk' = $script:LFMConfig.SessionKey 'format' = 'json' } } process { $noCommonParams = Remove-CommonParameter $PSBoundParameters $convertedParams = ConvertTo-LFMParameter $noCommonParams $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" } end { try { $irm = Invoke-LFMApiUri -Uri $apiUrl foreach ($tag in $irm.Tags.Tag) { $tagInfo = [pscustomobject] @{ 'PSTypeName' = 'PowerLFM.Album.Tag' 'Tag' = $tag.Name 'Url' = [uri] $tag.Url } Write-Output $tagInfo } } catch { throw $_ } } } function Get-LFMAlbumTopTag { # .ExternalHelp PowerLFM-help.xml [CmdletBinding(DefaultParameterSetName = 'album')] [OutputType('PowerLFM.Album.Tag')] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName, Position = 0, ParameterSetName = 'album')] [ValidateNotNullOrEmpty()] [string] $Album, [Parameter(Mandatory, ValueFromPipelineByPropertyName, Position = 1, ParameterSetName = 'album')] [ValidateNotNullOrEmpty()] [string] $Artist, [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'id')] [ValidateNotNullOrEmpty()] [guid] $Id, [switch] $AutoCorrect ) begin { $apiParams = @{ 'method' = 'album.getTopTags' 'api_key' = $script:LFMConfig.ApiKey 'format' = 'json' } } process { $noCommonParams = Remove-CommonParameter $PSBoundParameters $convertedParams = ConvertTo-LFMParameter $noCommonParams $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" } end { try { $irm = Invoke-LFMApiUri -Uri $apiUrl foreach ($tag in $irm.TopTags.Tag) { $tagInfo = [pscustomobject] @{ 'PSTypeName' = 'PowerLFM.Album.Tag' 'Tag' = $tag.Name 'Url' = [uri] $tag.Url 'Match' = [int] $tag.Count } Write-Output $tagInfo } } catch { throw $_ } } } function Get-LFMArtistCorrection { # .ExternalHelp PowerLFM-help.xml [CmdletBinding()] [OutputType('PowerLFM.Artist.Correction')] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $Artist ) begin { $apiParams = @{ 'method' = 'artist.getCorrection' 'api_key' = $script:LFMConfig.ApiKey 'format' = 'json' } } process { $noCommonParams = Remove-CommonParameter $PSBoundParameters $convertedParams = ConvertTo-LFMParameter $noCommonParams $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" } end { try { $irm = Invoke-LFMApiUri -Uri $apiUrl $correction = $irm.Corrections.Correction.Artist $correctedArtistInfo = [pscustomobject] @{ 'PSTypeName' = 'PowerLFM.Artist.Correction' 'Artist' = $correction.Name 'Id' = $correction.Mbid 'Url' = [uri] $correction.Url } Write-Output $correctedArtistInfo } catch { throw $_ } } } function Get-LFMArtistInfo { # .ExternalHelp PowerLFM-help.xml [CmdletBinding(DefaultParameterSetName = 'artist')] [OutputType('PowerLFM.Artist.Info')] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName, Position = 0, ParameterSetName = 'artist')] [ValidateNotNullOrEmpty()] [string] $Artist, [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'id')] [ValidateNotNullOrEmpty()] [guid] $Id, [string] $UserName, [switch] $AutoCorrect ) begin { $apiParams = @{ 'method' = 'artist.getInfo' 'api_key' = $script:LFMConfig.ApiKey 'format' = 'json' } } process { $noCommonParams = Remove-CommonParameter $PSBoundParameters $convertedParams = ConvertTo-LFMParameter $noCommonParams $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" } end { try { $irm = Invoke-LFMApiUri -Uri $apiUrl $similarArtists = foreach ($similar in $irm.Artist.Similar.Artist) { $similarInfo = [pscustomobject] @{ 'PSTypeName' = 'PowerLFM.Artist.Similar' 'Artist' = $similar.Name 'Url' = [uri] $similar.Url } Write-Output $similarInfo } $tags = foreach ($tag in $irm.Artist.Tags.Tag) { $tagInfo = [pscustomobject] @{ 'PSTypeName' = 'PowerLFM.Artist.Tag' 'Tag' = $tag.Name 'Url' = [uri] $tag.Url } Write-Output $tagInfo } switch ($irm.Artist.OnTour) { '0' {$tour = 'No'} '1' {$tour = 'Yes'} } $artistInfo = @{ 'PSTypeName' = 'PowerLFM.Artist.Info' 'Artist' = $irm.Artist.Name 'Id' = $irm.Artist.Mbid 'Listeners' = [int] $irm.Artist.Stats.Listeners 'PlayCount' = [int] $irm.Artist.Stats.PlayCount 'OnTour' = $tour 'Url' = [uri] $irm.Artist.Url 'Summary' = $irm.Artist.Bio.Summary 'SimilarArtists' = $similarArtists 'Tags' = $tags } $userPlayCount = [int] $irm.Artist.Stats.UserPlayCount if ($PSBoundParameters.ContainsKey('UserName')) { $artistInfo.Add('UserPlayCount', $userPlayCount) } $artistInfo = [pscustomobject] $artistInfo Write-Output $artistInfo } catch { throw $_ } } } function Get-LFMArtistSimilar { # .ExternalHelp PowerLFM-help.xml [CmdletBinding(DefaultParameterSetName = 'artist')] [OutputType('PowerLFM.Artist.Similar')] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName, Position = 0, ParameterSetName = 'artist')] [ValidateNotNullOrEmpty()] [string] $Artist, [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'id')] [ValidateNotNullOrEmpty()] [guid] $Id, [int] $Limit, [switch] $AutoCorrect ) begin { $apiParams = @{ 'method' = 'artist.getSimilar' 'api_key' = $script:LFMConfig.ApiKey 'format' = 'json' } } process { $noCommonParams = Remove-CommonParameter $PSBoundParameters $convertedParams = ConvertTo-LFMParameter $noCommonParams $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" } end { try { $irm = Invoke-LFMApiUri -Uri $apiUrl foreach ($similar in $irm.SimilarArtists.Artist) { $similarInfo = [pscustomobject] @{ 'PSTypeName' = 'PowerLFM.Artist.Similar' 'Artist' = $similar.Name 'Id' = $similar.Mbid 'Url' = [uri] $similar.Url 'Match' = [math]::Round($similar.Match, 2) } Write-Output $similarInfo } } catch { throw $_ } } } function Get-LFMArtistTag { # .ExternalHelp PowerLFM-help.xml [CmdletBinding(DefaultParameterSetName = 'artist')] [OutputType('PowerLFM.Artist.Tag')] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName, Position = 0, ParameterSetName = 'artist')] [ValidateNotNullOrEmpty()] [string] $Artist, [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'id')] [ValidateNotNullOrEmpty()] [guid] $Id, [string] $UserName, [switch] $AutoCorrect ) begin { $apiParams = @{ 'method' = 'artist.getTags' 'api_key' = $script:LFMConfig.ApiKey 'sk' = $script:LFMConfig.SessionKey 'format' = 'json' } } process { $noCommonParams = Remove-CommonParameter $PSBoundParameters $convertedParams = ConvertTo-LFMParameter $noCommonParams $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" } end { try { $irm = Invoke-LFMApiUri -Uri $apiUrl foreach ($tag in $irm.Tags.Tag) { $tagInfo = [pscustomobject] @{ 'PSTypeName' = 'PowerLFM.Artist.Tag' 'Tag' = $tag.Name 'Url' = [uri] $tag.Url } Write-Output $tagInfo } } catch { throw $_ } } } function Get-LFMArtistTopAlbum { # .ExternalHelp PowerLFM-help.xml [CmdletBinding(DefaultParameterSetName = 'artist')] [OutputType('PowerLFM.Artist.Album')] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName, Position = 0, ParameterSetName = 'artist')] [ValidateNotNullOrEmpty()] [string] $Artist, [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'id')] [ValidateNotNullOrEmpty()] [guid] $Id, [Parameter()] [ValidateRange(1, 50)] [int] $Limit, [int] $Page, [switch] $AutoCorrect ) begin { $apiParams = @{ 'method' = 'artist.getTopAlbums' 'api_key' = $script:LFMConfig.ApiKey 'format' = 'json' } } process { $noCommonParams = Remove-CommonParameter $PSBoundParameters $convertedParams = ConvertTo-LFMParameter $noCommonParams $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" } end { try { $irm = Invoke-LFMApiUri -Uri $apiUrl foreach ($album in $irm.TopAlbums.Album) { $albumInfo = [pscustomobject] @{ 'PSTypeName' = 'PowerLFM.Artist.Album' 'Album' = $album.Name 'Id' = $album.Mbid 'Url' = [uri]$album.Url 'PlayCount' = [int] $album.PlayCount } Write-Output $albumInfo } } catch { throw $_ } } } function Get-LFMArtistTopTag { # .ExternalHelp PowerLFM-help.xml [CmdletBinding(DefaultParameterSetName = 'artist')] [OutputType('PowerLFM.Artist.Tag')] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName, Position = 0, ParameterSetName = 'artist')] [ValidateNotNullOrEmpty()] [string] $Artist, [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'id')] [ValidateNotNullOrEmpty()] [guid] $Id, [switch] $AutoCorrect ) begin { $apiParams = @{ 'method' = 'artist.getTopTags' 'api_key' = $script:LFMConfig.ApiKey 'format' = 'json' } } process { $noCommonParams = Remove-CommonParameter $PSBoundParameters $convertedParams = ConvertTo-LFMParameter $noCommonParams $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" } end { try { $irm = Invoke-LFMApiUri -Uri $apiUrl foreach ($tag in $irm.TopTags.Tag) { $tagInfo = [pscustomobject] @{ 'PSTypeName' = 'PowerLFM.Artist.Tag' 'Tag' = $tag.Name 'Url' = [uri] $tag.Url 'Match' = [int] $tag.Count } Write-Output $tagInfo } } catch { throw $_ } } } function Get-LFMArtistTopTrack { # .ExternalHelp PowerLFM-help.xml [CmdletBinding(DefaultParameterSetName = 'artist')] [OutputType('PowerLFM.Artist.Track')] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName, Position = 0, ParameterSetName = 'artist')] [ValidateNotNullOrEmpty()] [string] $Artist, [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'id')] [ValidateNotNullOrEmpty()] [guid] $Id, [Parameter()] [ValidateRange(1, 50)] [int] $Limit, [int] $Page, [switch] $AutoCorrect ) begin { $apiParams = @{ 'method' = 'artist.getTopTracks' 'api_key' = $script:LFMConfig.ApiKey 'format' = 'json' } } process { $noCommonParams = Remove-CommonParameter $PSBoundParameters $convertedParams = ConvertTo-LFMParameter $noCommonParams $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" } end { try { $irm = Invoke-LFMApiUri -Uri $apiUrl foreach ($track in $irm.TopTracks.Track) { $trackInfo = [pscustomobject] @{ 'PSTypeName' = 'PowerLFM.Artist.Track' 'Track' = $track.Name 'Id' = $track.Mbid 'Url' = [uri] $track.Url 'Listeners' = [int] $track.Listeners 'PlayCount' = [int] $track.PlayCount } Write-Output $trackInfo } } catch { throw $_ } } } function Get-LFMChartTopArtist { # .ExternalHelp PowerLFM-help.xml [CmdletBinding()] [OutputType('PowerLFM.Chart.TopArtists')] param ( [Parameter()] [ValidateRange(1, 119)] [int] $Limit, [int] $Page ) $apiParams = @{ 'method' = 'chart.getTopArtists' 'api_key' = $script:LFMConfig.ApiKey 'format' = 'json' } $noCommonParams = Remove-CommonParameter $PSBoundParameters $convertedParams = ConvertTo-LFMParameter $noCommonParams $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" try { $irm = Invoke-LFMApiUri -Uri $apiUrl foreach ($artist in $irm.Artists.Artist) { $artistInfo = [pscustomobject] @{ 'PSTypeName' = 'PowerLFM.Chart.TopArtists' 'Artist' = $artist.Name 'Id' = $artist.Mbid 'Url' = [uri] $artist.Url 'Listeners' = [int] $artist.Listeners 'PlayCount' = [int] $artist.PlayCount } Write-Output $artistInfo } } catch { throw $_ } } function Get-LFMChartTopTag { # .ExternalHelp PowerLFM-help.xml [CmdletBinding()] [OutputType('PowerLFM.Chart.TopTags')] param ( [Parameter()] [ValidateRange(1, 119)] [int] $Limit, [int] $Page ) $apiParams = @{ 'method' = 'chart.getTopTags' 'api_key' = $script:LFMConfig.ApiKey 'format' = 'json' } $noCommonParams = Remove-CommonParameter $PSBoundParameters $convertedParams = ConvertTo-LFMParameter $noCommonParams $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" try { $irm = Invoke-LFMApiUri -Uri $apiUrl foreach ($tag in $irm.Tags.Tag) { $tagInfo = [pscustomobject] @{ 'PSTypeName' = 'PowerLFM.Chart.TopTags' 'Tag' = ConvertTo-TitleCase -String $tag.Name 'Url' = [uri] $tag.Url 'Reach' = [int] $tag.Reach 'TotalTags' = [int] $tag.Taggings } Write-Output $tagInfo } } catch { throw $_ } } function Get-LFMChartTopTrack { # .ExternalHelp PowerLFM-help.xml [CmdletBinding()] [OutputType('PowerLFM.Chart.TopTracks')] param ( [Parameter()] [ValidateRange(1, 119)] [int] $Limit, [int] $Page ) $apiParams = @{ 'method' = 'chart.getTopTracks' 'api_key' = $script:LFMConfig.ApiKey 'format' = 'json' } $noCommonParams = Remove-CommonParameter $PSBoundParameters $convertedParams = ConvertTo-LFMParameter $noCommonParams $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" try { $irm = Invoke-LFMApiUri -Uri $apiUrl foreach ($track in $irm.Tracks.Track) { $trackInfo = [pscustomobject] @{ 'PSTypeName' = 'PowerLFM.Chart.TopTracks' 'Track' = $track.Name 'TrackId' = $track.Mbid 'TrackUrl' = [uri] $track.Url 'Artist' = $track.Artist.Name 'ArtistId' = $track.Artist.Mbid 'ArtistUrl' = [uri] $track.Artist.Url 'Duration' = [int] $track.Duration 'Listeners' = [int] $track.Listeners 'PlayCount' = [int] $track.PlayCount } Write-Output $trackInfo } } catch { throw $_ } } function Get-LFMConfiguration { # .ExternalHelp PowerLFM-help.xml [CmdletBinding()] param () try { $script:LFMConfig = [pscustomobject] @{ 'ApiKey' = Get-Secret -Name LFMApiKey -Vault BuiltInLocalVault -AsPlainText 'SessionKey' = Get-Secret -Name LFMSessionKey -Vault BuiltInLocalVault -AsPlainText 'SharedSecret' = Get-Secret -Name LFMSharedSecret -Vault BuiltInLocalVault -AsPlainText } Write-Verbose 'LFMConfig is loaded in to the session' } catch { throw $_ } } function Get-LFMGeoTopArtist { # .ExternalHelp PowerLFM-help.xml [CmdletBinding()] [OutputType('PowerLFM.Geo.TopArtists')] param ( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $Country, [Parameter()] [ValidateRange(1, 119)] [int] $Limit, [int] $Page ) begin { $apiParams = @{ 'method' = 'geo.getTopArtists' 'api_key' = $script:LFMConfig.ApiKey 'format' = 'json' } } process { $noCommonParams = Remove-CommonParameter $PSBoundParameters $convertedParams = ConvertTo-LFMParameter $noCommonParams $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" } end { try { $irm = Invoke-LFMApiUri -Uri $apiUrl foreach ($artist in $irm.TopArtists.Artist) { $artistInfo = [pscustomobject] @{ 'PSTypeName' = 'PowerLFM.Geo.TopArtists' 'Artist' = $artist.Name 'Id' = $artist.Mbid 'Url' = [uri] $artist.Url 'Listeners' = [int] $artist.Listeners } Write-Output $artistInfo } } catch { throw $_ } } } function Get-LFMGeoTopTrack { # .ExternalHelp PowerLFM-help.xml [CmdletBinding()] [OutputType('PowerLFM.Geo.TopTracks')] param ( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $Country, [Parameter(ValueFromPipelineByPropertyName)] [string] $City, [Parameter()] [ValidateRange(1, 119)] [int] $Limit, [int] $Page ) begin { $apiParams = @{ 'method' = 'geo.getTopTracks' 'api_key' = $script:LFMConfig.ApiKey 'format' = 'json' } } process { $noCommonParams = Remove-CommonParameter $PSBoundParameters $convertedParams = ConvertTo-LFMParameter $noCommonParams $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" } end { try { $irm = Invoke-LFMApiUri -Uri $apiUrl foreach ($track in $irm.Tracks.Track) { $trackInfo = [pscustomobject] @{ 'PSTypeName' = 'PowerLFM.Geo.TopTracks' 'Track' = $track.Name 'TrackId' = $track.Mbid 'TrackUrl' = [uri] $track.Url 'Artist' = $track.Artist.Name 'ArtistId' = $track.Artist.Mbid 'ArtistUrl' = [uri] $track.Artist.Url 'Rank' = [int] $track.'@attr'.Rank 'Listeners' = [int] $track.Listeners } Write-Output $trackInfo } } catch { throw $_ } } } function Get-LFMLibraryArtist { # .ExternalHelp PowerLFM-help.xml [CmdletBinding()] [OutputType('PowerLFM.Library.Artist')] param ( [Parameter(ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $UserName, [int] $Limit, [int] $Page ) begin { $apiParams = @{ 'method' = 'library.getArtists' 'api_key' = $script:LFMConfig.ApiKey 'sk' = $script:LFMConfig.SessionKey 'format' = 'json' } } process { $noCommonParams = Remove-CommonParameter $PSBoundParameters $convertedParams = ConvertTo-LFMParameter $noCommonParams $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" } end { try { $irm = Invoke-LFMApiUri -Uri $apiUrl foreach ($artist in $irm.Artists.Artist) { $artistInfo = [pscustomobject] @{ 'PSTypeName' = 'PowerLFM.Library.Artist' 'Artist' = $artist.Name 'PlayCount' = [int] $artist.PlayCount 'Url' = [uri] $artist.Url 'Id' = $artist.Mbid } Write-Output $artistInfo } } catch { throw $_ } } } function Get-LFMTagInfo { # .ExternalHelp PowerLFM-help.xml [CmdletBinding()] [OutputType('PowerLFM.Tag.Info')] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $Tag, [Parameter()] [string] $Language ) begin { $apiParams = @{ 'method' = 'tag.getInfo' 'api_key' = $script:LFMConfig.ApiKey 'format' = 'json' } } process { $noCommonParams = Remove-CommonParameter $PSBoundParameters $convertedParams = ConvertTo-LFMParameter $noCommonParams $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" } end { try { $irm = Invoke-LFMApiUri -Uri $apiUrl $tagInfo = [pscustomobject] @{ 'PSTypeName' = 'PowerLFM.Tag.Info' 'Tag' = $irm.Tag.Name 'Url' = [uri] "http://www.last.fm/tag/$Tag" -replace ' ', '+' 'Reach' = [int] $irm.Tag.Reach 'TotalTags' = [int] $irm.Tag.Total 'Summary' = $irm.Tag.Wiki.Summary } Write-Output $tagInfo } catch { throw $_ } } } function Get-LFMTagSimilar { # .ExternalHelp PowerLFM-help.xml [CmdletBinding()] [OutputType('PowerLFM.Tag.Similar')] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $Tag ) begin { $apiParams = @{ 'method' = 'tag.getSimilar' 'api_key' = $script:LFMConfig.ApiKey 'format' = 'json' } } process { $noCommonParams = Remove-CommonParameter $PSBoundParameters $convertedParams = ConvertTo-LFMParameter $noCommonParams $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" } end { try { $irm = Invoke-LFMApiUri -Uri $apiUrl $tagInfo = [pscustomobject] @{ 'PSTypeName' = 'PowerLFM.Tag.Similar' 'Tag' = $irm.Tag.Name 'Url' = [uri] $irm.Tag.Url } # This api method seems broken at the moment. # It does not return anything. Write-Output $tagInfo } catch { throw $_ } } } function Get-LFMTagTopAlbum { # .ExternalHelp PowerLFM-help.xml [CmdletBinding()] [OutputType('PowerLFM.Tag.TopAlbums')] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $Tag, [int] $Limit, [int] $Page ) begin { $apiParams = @{ 'method' = 'tag.getTopAlbums' 'api_key' = $script:LFMConfig.ApiKey 'format' = 'json' } } process { $noCommonParams = Remove-CommonParameter $PSBoundParameters $convertedParams = ConvertTo-LFMParameter $noCommonParams $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" } end { try { $irm = Invoke-LFMApiUri -Uri $apiUrl foreach ($album in $irm.Albums.Album) { $albumInfo = [pscustomobject] @{ 'PSTypeName' = 'PowerLFM.Tag.TopAlbums' 'Album' = $album.Name 'AlbumId' = $album.Mbid 'AlbumUrl' = [uri] $album.Url 'Artist' = $album.Artist.Name 'ArtistId' = $album.Artist.Mbid 'ArtistUrl' = [uri] $album.Artist.Url 'Rank' = [int] $album.'@attr'.Rank } Write-Output $albumInfo } } catch { throw $_ } } } function Get-LFMTagTopArtist { # .ExternalHelp PowerLFM-help.xml [CmdletBinding()] [OutputType('PowerLFM.Tag.TopArtists')] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $Tag, [int] $Limit, [int] $Page ) begin { $apiParams = @{ 'method' = 'tag.getTopArtists' 'api_key' = $script:LFMConfig.ApiKey 'format' = 'json' } } process { $noCommonParams = Remove-CommonParameter $PSBoundParameters $convertedParams = ConvertTo-LFMParameter $noCommonParams $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" } end { try { $irm = Invoke-LFMApiUri -Uri $apiUrl foreach ($artist in $irm.TopArtists.Artist) { $artistInfo = [pscustomobject] @{ 'PSTypeName' = 'PowerLFM.Tag.TopArtists' 'Artist' = $artist.Name 'ArtistId' = $artist.Mbid 'ArtistUrl' = [uri] $artist.Url 'Rank' = [int] $artist.'@attr'.Rank } Write-Output $artistInfo } } catch { throw $_ } } } function Get-LFMTagTopTag { # .ExternalHelp PowerLFM-help.xml [CmdletBinding()] [OutputType('PowerLFM.Tag.TopTags')] param () begin { $apiParams = @{ 'method' = 'tag.getTopTags' 'api_key' = $script:LFMConfig.ApiKey 'format' = 'json' } } process { $noCommonParams = Remove-CommonParameter $PSBoundParameters $convertedParams = ConvertTo-LFMParameter $noCommonParams $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" } end { try { $irm = Invoke-LFMApiUri -Uri $apiUrl foreach ($tag in $irm.TopTags.Tag) { $tagInfo = [pscustomobject] @{ 'PSTypeName' = 'PowerLFM.Tag.TopTags' 'Tag' = $tag.Name 'Count' = [int] $tag.Count 'Reach' = [int] $tag.Reach } Write-Output $tagInfo } } catch { throw $_ } } } function Get-LFMTagTopTrack { # .ExternalHelp PowerLFM-help.xml [CmdletBinding()] [OutputType('PowerLFM.Tag.TopTracks')] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $Tag, [int] $Limit, [int] $Page ) begin { $apiParams = @{ 'method' = 'tag.getTopTracks' 'api_key' = $script:LFMConfig.ApiKey 'format' = 'json' } } process { $noCommonParams = Remove-CommonParameter $PSBoundParameters $convertedParams = ConvertTo-LFMParameter $noCommonParams $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" } end { try { $irm = Invoke-LFMApiUri -Uri $apiUrl foreach ($track in $irm.Tracks.Track) { $trackInfo = [pscustomobject] @{ 'PSTypeName' = 'PowerLFM.Tag.TopTracks' 'Track' = $track.Name 'TrackId' = $track.Mbid 'TrackUrl' = [uri] $track.Url 'Artist' = $track.Artist.Name 'ArtistId' = $track.Artist.Mbid 'ArtistUrl' = [uri] $track.Artist.Url 'Rank' = [int] $track.'@attr'.Rank 'Duration' = [int] $track.Duration } Write-Output $trackInfo } } catch { throw $_ } } } function Get-LFMTagWeeklyChartList { # .ExternalHelp PowerLFM-help.xml [CmdletBinding()] [OutputType('PowerLFM.Tag.WeeklyChartList')] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $Tag ) begin { $apiParams = @{ 'method' = 'tag.getWeeklyChartList' 'api_key' = $script:LFMConfig.ApiKey 'format' = 'json' } } process { $noCommonParams = Remove-CommonParameter $PSBoundParameters $convertedParams = ConvertTo-LFMParameter $noCommonParams $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" } end { try { $irm = Invoke-LFMApiUri -Uri $apiUrl $chartList = $irm.WeeklyChartList.Chart.GetEnumerator() | Sort-Object {$_.From} -Descending foreach ($chart in $chartList) { $chartInfo = [pscustomobject] @{ 'PSTypeName' = 'PowerLFM.Tag.WeeklyChartList' 'StartDate' = $chart.From | ConvertFrom-UnixTime -Local 'EndDate' = $chart.To | ConvertFrom-UnixTime -Local } Write-Output $chartInfo } } catch { throw $_ } } } function Get-LFMTrackCorrection { # .ExternalHelp PowerLFM-help.xml [CmdletBinding()] [OutputType('PowerLFM.Track.Correction')] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $Track, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $Artist ) begin { $apiParams = @{ 'method' = 'track.getCorrection' 'api_key' = $script:LFMConfig.ApiKey 'format' = 'json' } } process { $noCommonParams = Remove-CommonParameter $PSBoundParameters $convertedParams = ConvertTo-LFMParameter $noCommonParams $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" } end { try { $irm = Invoke-LFMApiUri -Uri $apiUrl $correction = $irm.Corrections.Correction.Track $correctedTrackInfo = [pscustomobject] @{ 'PSTypeName' = 'PowerLFM.Track.Correction' 'Track' = $correction.Name 'TrackUrl' = [uri] $correction.Url 'Artist' = $correction.Artist.Name 'ArtistUrl' = [uri] $correction.Artist.Url 'ArtistId' = $correction.Artist.Mbid } Write-Output $correctedTrackInfo } catch { throw $_ } } } function Get-LFMTrackInfo { # .ExternalHelp PowerLFM-help.xml [CmdletBinding(DefaultParameterSetName = 'track')] [OutputType('PowerLFM.Track.Info')] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName, Position = 0, ParameterSetName = 'track')] [ValidateNotNullOrEmpty()] [string] $Track, [Parameter(Mandatory, ValueFromPipelineByPropertyName, Position = 1, ParameterSetName = 'track')] [ValidateNotNullOrEmpty()] [string] $Artist, [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'id')] [ValidateNotNullOrEmpty()] [guid] $Id, [string] $UserName, [switch] $AutoCorrect ) begin { $apiParams = @{ 'method' = 'track.getInfo' 'api_key' = $script:LFMConfig.ApiKey 'format' = 'json' } } process { $noCommonParams = Remove-CommonParameter $PSBoundParameters $convertedParams = ConvertTo-LFMParameter $noCommonParams $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" } end { try { $irm = Invoke-LFMApiUri -Uri $apiUrl $tags = foreach ($tag in $irm.Track.TopTags.Tag) { $tagInfo = [pscustomobject] @{ 'PSTypeName' = 'PowerLFM.Album.Tag' 'Tag' = $tag.Name 'Url' = [uri] $tag.Url } Write-Output $tagInfo } switch ($irm.Track.UserLoved) { '0' {$loved = 'No'} '1' {$loved = 'Yes'} } $trackInfo = @{ 'PSTypeName' = 'PowerLFM.Album.Info' 'Track' = $irm.Track.Name 'Artist' = $irm.Track.Artist.Name 'Album' = $irm.Track.Album.Title 'Id' = $irm.Track.Mbid 'Listeners' = [int] $irm.Track.Listeners 'PlayCount' = [int] $irm.Track.PlayCount 'Url' = [uri] $irm.Track.Url 'Tags' = $tags } $userPlayCount = [int] $irm.Track.UserPlayCount if ($PSBoundParameters.ContainsKey('UserName')) { $trackInfo.Add('UserPlayCount', $userPlayCount) $trackInfo.Add('Loved', $loved) } $trackInfo = [pscustomobject] $trackInfo Write-Output $trackInfo } catch { throw $_ } } } function Get-LFMTrackSimilar { # .ExternalHelp PowerLFM-help.xml [CmdletBinding(DefaultParameterSetName = 'track')] [OutputType('PowerLFM.Track.Similar')] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName, Position = 0, ParameterSetName = 'track')] [ValidateNotNullOrEmpty()] [string] $Track, [Parameter(Mandatory, ValueFromPipelineByPropertyName, Position = 1, ParameterSetName = 'track')] [ValidateNotNullOrEmpty()] [string] $Artist, [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'id')] [ValidateNotNullOrEmpty()] [guid] $Id, [int] $Limit = '5', [switch] $AutoCorrect ) begin { $apiParams = @{ 'method' = 'track.getSimilar' 'api_key' = $script:LFMConfig.ApiKey 'limit' = $Limit 'format' = 'json' } } process { $noCommonParams = Remove-CommonParameter $PSBoundParameters $convertedParams = ConvertTo-LFMParameter $noCommonParams $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" } end { try { $irm = Invoke-LFMApiUri -Uri $apiUrl foreach ($similar in $irm.SimilarTracks.Track) { $similarInfo = [pscustomobject] @{ 'PSTypeName' = 'PowerLFM.Track.Similar' 'Track' = $similar.Name 'Artist' = $similar.Artist.Name 'Id' = $similar.Mbid 'PlayCount' = [int] $similar.PlayCount 'Url' = [uri] $similar.Url 'Match' = [math]::Round($similar.Match, 2) } Write-Output $similarInfo } } catch { throw $_ } } } function Get-LFMTrackTag { # .ExternalHelp PowerLFM-help.xml [CmdletBinding(DefaultParameterSetName = 'track')] [OutputType('PowerLFM.Track.UserTag')] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName, Position = 0, ParameterSetName = 'track')] [ValidateNotNullOrEmpty()] [string] $Track, [Parameter(Mandatory, ValueFromPipelineByPropertyName, Position = 1, ParameterSetName = 'track')] [ValidateNotNullOrEmpty()] [string] $Artist, [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'id')] [ValidateNotNullOrEmpty()] [guid] $Id, [string] $UserName, [switch] $AutoCorrect ) begin { $apiParams = @{ 'method' = 'track.getTags' 'api_key' = $script:LFMConfig.ApiKey 'sk' = $script:LFMConfig.SessionKey 'format' = 'json' } } process { $noCommonParams = Remove-CommonParameter $PSBoundParameters $convertedParams = ConvertTo-LFMParameter $noCommonParams $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" } end { try { $irm = Invoke-LFMApiUri -Uri $apiUrl foreach ($tag in $irm.Tags.Tag) { $tagInfo = [pscustomobject] @{ 'PSTypeName' = 'PowerLFM.Track.Tag' 'Tag' = $tag.Name 'Url' = [uri] $tag.Url } Write-Output $tagInfo } } catch { throw $_ } } } function Get-LFMTrackTopTag { # .ExternalHelp PowerLFM-help.xml [CmdletBinding(DefaultParameterSetName = 'track')] [OutputType('PowerLFM.Track.TopTag')] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName, Position = 0, ParameterSetName = 'track')] [ValidateNotNullOrEmpty()] [string] $Track, [Parameter(Mandatory, ValueFromPipelineByPropertyName, Position = 1, ParameterSetName = 'track')] [ValidateNotNullOrEmpty()] [string] $Artist, [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'id')] [ValidateNotNullOrEmpty()] [guid] $Id, [switch] $AutoCorrect ) begin { $apiParams = @{ 'method' = 'track.getTopTags' 'api_key' = $script:LFMConfig.ApiKey 'format' = 'json' } } process { $noCommonParams = Remove-CommonParameter $PSBoundParameters $convertedParams = ConvertTo-LFMParameter $noCommonParams $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" } end { try { $irm = Invoke-LFMApiUri -Uri $apiUrl foreach ($tag in $irm.TopTags.Tag) { $tagInfo = [pscustomobject] @{ 'PSTypeName' = 'PowerLFM.Track.Tag' 'Tag' = $tag.Name 'Url' = [uri] $tag.Url 'Match' = [int] $tag.Count } Write-Output $tagInfo } } catch { throw $_ } } } function Get-LFMUserFriend { # .ExternalHelp PowerLFM-help.xml [CmdletBinding()] [OutputType('PowerLFM.User.Info')] param ( [Parameter(ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $UserName, [Parameter()] [ValidateRange(1, 50)] [int] $Limit, [int] $Page ) begin { $apiParams = @{ 'method' = 'user.getFriends' 'api_key' = $script:LFMConfig.ApiKey 'sk' = $script:LFMConfig.SessionKey 'format' = 'json' } } process { $noCommonParams = Remove-CommonParameter $PSBoundParameters $convertedParams = ConvertTo-LFMParameter $noCommonParams $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" } end { try { $irm = Invoke-LFMApiUri -Uri $apiUrl foreach ($friend in $irm.Friends.User) { $userInfo = @{ 'PSTypeName' = 'PowerLFM.User.Info' 'UserName' = $friend.Name 'RealName' = $friend.RealName 'Url' = [uri] $friend.Url 'Country' = $friend.Country 'Registered' = ConvertFrom-UnixTime -UnixTime $friend.Registered.UnixTime -Local 'PlayLists' = [int] $friend.PlayLists } $userInfo = [pscustomobject] $userInfo Write-Output $userInfo } } catch { throw $_ } } } function Get-LFMUserInfo { # .ExternalHelp PowerLFM-help.xml [CmdletBinding()] [OutputType('PowerLFM.User.Info')] param ( [Parameter(ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $UserName ) begin { $apiParams = @{ 'method' = 'user.GetInfo' 'api_key' = $script:LFMConfig.ApiKey 'sk' = $script:LFMConfig.SessionKey 'format' = 'json' } } process { $noCommonParams = Remove-CommonParameter $PSBoundParameters $convertedParams = ConvertTo-LFMParameter $noCommonParams $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" } end { try { $irm = Invoke-LFMApiUri -Uri $apiUrl $userInfo = [pscustomobject] @{ 'PSTypeName' = 'PowerLFM.User.Info' 'UserName' = $irm.User.Name 'RealName' = $irm.User.RealName 'Url' = [uri] $irm.User.Url 'Country' = $irm.User.Country 'Registered' = ConvertFrom-UnixTime -UnixTime $irm.User.Registered.UnixTime -Local 'PlayCount' = [int] $irm.User.PlayCount 'PlayLists' = [int] $irm.User.PlayLists } Write-Output $userInfo } catch { throw $_ } } } function Get-LFMUserLovedTrack { # .ExternalHelp PowerLFM-help.xml [CmdletBinding()] [OutputType('PowerLFM.User.Track')] param ( [Parameter(ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $UserName, [Parameter()] [ValidateRange(1, 50)] [int] $Limit, [int] $Page ) begin { $apiParams = @{ 'method' = 'user.getLovedTracks' 'api_key' = $script:LFMConfig.ApiKey 'sk' = $script:LFMConfig.SessionKey 'format' = 'json' } } process { $noCommonParams = Remove-CommonParameter $PSBoundParameters $convertedParams = ConvertTo-LFMParameter $noCommonParams $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" } end { try { $irm = Invoke-LFMApiUri -Uri $apiUrl foreach ($track in $irm.LovedTracks.Track) { $trackInfo = [pscustomobject] @{ 'PSTypeName' = 'PowerLFM.User.Track' 'Track' = $track.Name 'TrackUrl' = [uri] $track.Url 'TrackId' = $track.Mbid 'Artist' = $track.Artist.Name 'ArtistUrl' = [uri] $track.Artist.Url 'ArtistId' = $track.Artist.Mbid 'Date' = ConvertFrom-UnixTime -UnixTime $track.Date.Uts -Local } Write-Output $trackInfo } } catch { throw $_ } } } function Get-LFMUserPersonalTag { # .ExternalHelp PowerLFM-help.xml [CmdletBinding()] [OutputType('PowerLFM.User.PersonalTag')] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $Tag, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [ValidateSet('Artist', 'Album', 'Track')] [string] $TagType, [Parameter(ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $UserName, [Parameter()] [ValidateRange(1, 50)] [int] $Limit, [int] $Page ) begin { $apiParams = @{ 'method' = 'user.getPersonalTags' 'api_key' = $script:LFMConfig.ApiKey 'sk' = $script:LFMConfig.SessionKey 'format' = 'json' } } process { $noCommonParams = Remove-CommonParameter $PSBoundParameters $convertedParams = ConvertTo-LFMParameter $noCommonParams $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" } end { try { $irm = Invoke-LFMApiUri -Uri $apiUrl foreach ($userTag in $irm.Taggings.Artists.Artist) { $userTagInfo = [pscustomobject] @{ 'PSTypeName' = 'PowerLFM.User.PersonalTag' 'Artist' = $userTag.Name 'Id' = $userTag.Mbid 'Url' = [uri] $userTag.Url } Write-Output $userTagInfo } } catch { throw $_ } } } function Get-LFMUserRecentTrack { [CmdletBinding()] [OutputType('PowerLFM.User.RecentTrack')] param ( [Parameter(ValueFromPipelineByPropertyName)] [datetime] $StartDate, [Parameter(ValueFromPipelineByPropertyName)] [datetime] $EndDate, [Parameter(ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $UserName, [Parameter()] [ValidateRange(1, 50)] [int] $Limit, [int] $Page ) begin { $apiParams = @{ 'method' = 'user.getRecentTracks' 'api_key' = $script:LFMConfig.ApiKey 'sk' = $script:LFMConfig.SessionKey 'extended' = 1 'format' = 'json' } } process { $noCommonParams = Remove-CommonParameter $PSBoundParameters $convertedParams = ConvertTo-LFMParameter $noCommonParams $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" } end { try { $irm = Invoke-LFMApiUri -Uri $apiUrl $i = 0 foreach ($track in $irm.RecentTracks.Track) { switch ($track.Loved) { '0' {$loved = 'No'} '1' {$loved = 'Yes'} } $trackInfo = @{ 'PSTypeName' = 'PowerLFM.User.RecentTrack' 'Track' = $track.Name 'Artist' = $track.Artist.Name 'Album' = $track.Album.'#text' 'Loved' = $loved } $scrobbleTime = ConvertFrom-UnixTime -UnixTime $track.Date.Uts -Local switch ($track.'@attr'.NowPlaying) { $true {$trackInfo.Add('ScrobbleTime', 'Now Playing')} $null {$trackInfo.Add('ScrobbleTime', $scrobbleTime)} } # This prevents a track that is currently playing from being displayed when # an end date is specified because the tracks should only be in the past. if ($PSBoundParameters.ContainsKey('EndDate') -and $track.'@attr'.NowPlaying -eq 'true') { $trackInfo = $trackInfo[1] } # This prevents more tracks in the output than specified with the limit # parameter when a track is currently playing. Previously, if the limit # was set to two there would be three objects in the output including # the currently playing track. if ($irm.RecentTracks.Track[0].'@attr'.NowPlaying -and $PSBoundParameters.ContainsKey('Limit') -and $Limit -eq $i) { break } $i++ $trackInfo = [pscustomobject] $trackInfo Write-Output $trackInfo } } catch { throw $_ } } } function Get-LFMUserTopAlbum { # .ExternalHelp PowerLFM-help.xml [CmdletBinding()] [OutputType('PowerLFM.User.TopAlbum')] param ( [Parameter(ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $UserName, [Parameter()] [ValidateSet('Overall', '7 Days', '1 Month', '3 Months', '6 Months', '1 Year')] [string] $TimePeriod, [Parameter()] [ValidateRange(1, 50)] [int] $Limit, [int] $Page ) begin { $apiParams = @{ 'method' = 'user.getTopAlbums' 'api_key' = $script:LFMConfig.ApiKey 'sk' = $script:LFMConfig.SessionKey 'format' = 'json' } } process { $noCommonParams = Remove-CommonParameter $PSBoundParameters $convertedParams = ConvertTo-LFMParameter $noCommonParams $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" } end { try { $irm = Invoke-LFMApiUri -Uri $apiUrl foreach ($album in $irm.TopAlbums.Album) { $albumInfo = [pscustomobject] @{ 'PSTypeName' = 'PowerLFM.User.Album' 'Album' = $album.Name 'PlayCount' = [int] $album.PlayCount 'AlbumUrl' = [uri] $album.Url 'AlbumId' = $album.Mbid 'Artist' = $album.Artist.Name 'ArtistUrl' = [uri] $album.Artist.Url 'ArtistId' = $album.Artist.Mbid } Write-Output $albumInfo } } catch { throw $_ } } } function Get-LFMUserTopArtist { # .ExternalHelp PowerLFM-help.xml [CmdletBinding()] [OutputType('PowerLFM.User.TopArtist')] param ( [Parameter(ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $UserName, [Parameter()] [ValidateSet('Overall', '7 Days', '1 Month', '3 Months', '6 Months', '1 Year')] [string] $TimePeriod, [Parameter()] [ValidateRange(1, 50)] [int] $Limit, [int] $Page ) begin { $apiParams = @{ 'method' = 'user.getTopArtists' 'api_key' = $script:LFMConfig.ApiKey 'sk' = $script:LFMConfig.SessionKey 'format' = 'json' } } process { $noCommonParams = Remove-CommonParameter $PSBoundParameters $convertedParams = ConvertTo-LFMParameter $noCommonParams $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" } end { try { $irm = Invoke-LFMApiUri -Uri $apiUrl foreach ($artist in $irm.TopArtists.Artist) { $artistInfo = [pscustomobject] @{ 'PSTypeName' = 'PowerLFM.User.Artist' 'Artist' = $artist.Name 'PlayCount' = [int] $artist.PlayCount 'Url' = [uri] $artist.Url 'Id' = $artist.Mbid } Write-Output $artistInfo } } catch { throw $_ } } } function Get-LFMUserTopTag { # .ExternalHelp PowerLFM-help.xml [CmdletBinding()] [OutputType('PowerLFM.User.TopTag')] param ( [Parameter(ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $UserName, [int] $Limit ) begin { $apiParams = @{ 'method' = 'user.getTopTags' 'api_key' = $script:LFMConfig.ApiKey 'sk' = $script:LFMConfig.SessionKey 'format' = 'json' } } process { $noCommonParams = Remove-CommonParameter $PSBoundParameters $convertedParams = ConvertTo-LFMParameter $noCommonParams $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" } end { try { $irm = Invoke-LFMApiUri -Uri $apiUrl foreach ($tag in $irm.TopTags.Tag) { $tagInfo = [pscustomobject] @{ 'PSTypeName' = 'PowerLFM.User.TopTag' 'Tag' = $tag.Name 'TagUrl' = [uri] $tag.Url 'Count' = [int] $tag.Count } Write-Output $tagInfo } } catch { throw $_ } } } function Get-LFMUserTopTrack { # .ExternalHelp PowerLFM-help.xml [CmdletBinding()] [OutputType('PowerLFM.User.TopTrack')] param ( [Parameter()] [ValidateSet('Overall', '7 Days', '1 Month', '3 Months', '6 Months', '1 Year')] [string] $TimePeriod, [Parameter(ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $UserName, [Parameter()] [ValidateRange(1, 50)] [int] $Limit, [int] $Page ) begin { $apiParams = @{ 'method' = 'user.getTopTracks' 'api_key' = $script:LFMConfig.ApiKey 'sk' = $script:LFMConfig.SessionKey 'format' = 'json' } } process { $noCommonParams = Remove-CommonParameter $PSBoundParameters $convertedParams = ConvertTo-LFMParameter $noCommonParams $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" } end { try { $irm = Invoke-LFMApiUri -Uri $apiUrl foreach ($track in $irm.TopTracks.Track) { $trackInfo = [pscustomobject] @{ 'PSTypeName' = 'PowerLFM.User.TopTrack' 'Track' = $track.Name 'PlayCount' = [int] $track.PlayCount 'TrackUrl' = [uri] $track.Url 'TrackId' = $track.Mbid 'Artist' = $track.Artist.Name 'ArtistUrl' = [uri] $track.Artist.Url 'ArtistId' = $track.Artist.Mbid } Write-Output $trackInfo } } catch { throw $_ } } } function Get-LFMUserTrackScrobble { # .ExternalHelp PowerLFM-help.xml [CmdletBinding()] [OutputType('PowerLFM.User.TrackScrobble')] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $Track, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $Artist, [Parameter(ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $UserName, [Parameter()] [ValidateRange(1, 50)] [int] $Limit, [int] $Page ) begin { $apiParams = @{ 'method' = 'user.getTrackScrobbles' 'api_key' = $script:LFMConfig.ApiKey 'sk' = $script:LFMConfig.SessionKey 'format' = 'json' } } process { $noCommonParams = Remove-CommonParameter $PSBoundParameters $convertedParams = ConvertTo-LFMParameter $noCommonParams $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" } end { try { $irm = Invoke-LFMApiUri -Uri $apiUrl foreach ($scrobble in $irm.TrackScrobbles.Track) { $scrobbleInfo = [pscustomobject] @{ 'PSTypeName' = 'PowerLFM.User.TrackScrobble' 'Track' = $scrobble.Name 'TrackId' = $scrobble.Mbid 'TrackUrl' = $scrobble.Url 'Artist' = $scrobble.Artist.'#text' 'Album' = $scrobble.Album.'#text' 'Date' = ConvertFrom-UnixTime -UnixTime $scrobble.Date.Uts -Local } Write-Output $scrobbleInfo } } catch { throw $_ } } } function Get-LFMUserWeeklyAlbumChart { # .ExternalHelp PowerLFM-help.xml [CmdletBinding()] [OutputType('PowerLFM.User.WeeklyAlbumChart')] param ( [Parameter(ValueFromPipelineByPropertyName)] [datetime] $StartDate, [Parameter(ValueFromPipelineByPropertyName)] [datetime] $EndDate, [Parameter(ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $UserName ) begin { $apiParams = @{ 'method' = 'user.getWeeklyAlbumChart' 'api_key' = $script:LFMConfig.ApiKey 'sk' = $script:LFMConfig.SessionKey 'format' = 'json' } } process { $noCommonParams = Remove-CommonParameter $PSBoundParameters $convertedParams = ConvertTo-LFMParameter $noCommonParams $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" } end { try { $irm = Invoke-LFMApiUri -Uri $apiUrl foreach ($album in $irm.WeeklyAlbumChart.Album) { $albumInfo = [pscustomobject] @{ 'PSTypeName' = 'PowerLFM.User.WeeklyChartList' 'Album' = $album.Name 'Url' = [uri] $album.Url 'Id' = $album.Mbid 'Artist' = $album.Artist.'#text' 'ArtistId' = $album.Artist.Mbid 'PlayCount' = [int] $album.PlayCount 'StartDate' = ConvertFrom-UnixTime -UnixTime $irm.WeeklyAlbumChart.'@attr'.From -Local 'EndDate' = ConvertFrom-UnixTime -UnixTime $irm.WeeklyAlbumChart.'@attr'.To -Local } Write-Output $albumInfo } } catch { throw $_ } } } function Get-LFMUserWeeklyArtistChart { # .ExternalHelp PowerLFM-help.xml [CmdletBinding()] [OutputType('PowerLFM.User.WeeklyArtistChart')] param ( [Parameter(ValueFromPipelineByPropertyName)] [datetime] $StartDate, [Parameter(ValueFromPipelineByPropertyName)] [datetime] $EndDate, [Parameter(ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $UserName ) begin { $apiParams = @{ 'method' = 'user.getWeeklyArtistChart' 'api_key' = $script:LFMConfig.ApiKey 'sk' = $script:LFMConfig.SessionKey 'format' = 'json' } } process { $noCommonParams = Remove-CommonParameter $PSBoundParameters $convertedParams = ConvertTo-LFMParameter $noCommonParams $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" } end { try { $irm = Invoke-LFMApiUri -Uri $apiUrl foreach ($artist in $irm.WeeklyArtistChart.Artist) { $artistInfo = [pscustomobject] @{ 'PSTypeName' = 'PowerLFM.User.WeeklyArtistChart' 'Artist' = $artist.Name 'Url' = [uri] $artist.Url 'Id' = $artist.Mbid 'PlayCount' = [int] $artist.PlayCount 'StartDate' = ConvertFrom-UnixTime -UnixTime $irm.WeeklyArtistChart.'@attr'.From -Local 'EndDate' = ConvertFrom-UnixTime -UnixTime $irm.WeeklyArtistChart.'@attr'.To -Local } Write-Output $artistInfo } } catch { throw $_ } } } function Get-LFMUserWeeklyChartList { # .ExternalHelp PowerLFM-help.xml [CmdletBinding()] [OutputType('PowerLFM.User.WeeklyChartList')] param ( [Parameter(ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $UserName ) begin { $apiParams = @{ 'method' = 'user.getWeeklyChartList' 'api_key' = $script:LFMConfig.ApiKey 'sk' = $script:LFMConfig.SessionKey 'format' = 'json' } } process { $noCommonParams = Remove-CommonParameter $PSBoundParameters $convertedParams = ConvertTo-LFMParameter $noCommonParams $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" } end { try { $irm = Invoke-LFMApiUri -Uri $apiUrl $chartList = $irm.WeeklyChartList.Chart | Sort-Object -Property From -Descending foreach ($chart in $chartList) { $chartInfo = [pscustomobject] @{ 'PSTypeName' = 'PowerLFM.User.WeeklyChartList' 'StartDate' = $chart.From | ConvertFrom-UnixTime -Local 'EndDate' = $chart.To | ConvertFrom-UnixTime -Local } Write-Output $chartInfo } } catch { throw $_ } } } function Get-LFMUserWeeklyTrackChart { # .ExternalHelp PowerLFM-help.xml [CmdletBinding()] [OutputType('PowerLFM.User.WeeklyTrackChart')] param ( [Parameter(ValueFromPipelineByPropertyName)] [datetime] $StartDate, [Parameter(ValueFromPipelineByPropertyName)] [datetime] $EndDate, [Parameter(ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $UserName ) begin { $apiParams = @{ 'method' = 'user.getWeeklyTrackChart' 'api_key' = $script:LFMConfig.ApiKey 'sk' = $script:LFMConfig.SessionKey 'format' = 'json' } } process { $noCommonParams = Remove-CommonParameter $PSBoundParameters $convertedParams = ConvertTo-LFMParameter $noCommonParams $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" } end { try { $irm = Invoke-LFMApiUri -Uri $apiUrl foreach ($track in $irm.WeeklyTrackChart.Track) { $trackInfo = [pscustomobject] @{ 'PSTypeName' = 'PowerLFM.User.WeeklyTrackChart' 'Track' = $track.Name 'Url' = [uri] $track.Url 'Id' = $track.Mbid 'Artist' = $track.Artist.'#text' 'ArtistId' = $track.Artist.Mbid 'PlayCount' = [int] $track.PlayCount 'StartDate' = ConvertFrom-UnixTime -UnixTime $irm.WeeklyTrackChart.'@attr'.From -Local 'EndDate' = ConvertFrom-UnixTime -UnixTime $irm.WeeklyTrackChart.'@attr'.To -Local } Write-Output $trackInfo } } catch { throw $_ } } } function Remove-LFMAlbumTag { # .ExternalHelp PowerLFM-help.xml [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $Album, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $Artist, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $Tag ) begin { $apiParams = @{ 'method' = 'album.removeTag' 'api_key' = $script:LFMConfig.ApiKey 'sk' = $script:LFMConfig.SessionKey } } process { $noCommonParams = Remove-CommonParameter $PSBoundParameters $apiSig = Get-LFMSignature -Method $apiParams.Method @noCommonParams $apiParams.Add('api_sig', $apiSig) $convertedParams = ConvertTo-LFMParameter $noCommonParams $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" } end { if ($PSCmdlet.ShouldProcess("Album: $Album", "Removing album tag: $Tag")) { try { $irm = Invoke-LFMApiUri -Uri $apiUrl -Method Post if ($irm.Lfm.Status -eq 'ok') {Write-Verbose "Tag: $Tag has been removed"} } catch { throw $_ } } } } function Remove-LFMArtistTag { # .ExternalHelp PowerLFM-help.xml [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $Artist, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $Tag ) begin { $apiParams = @{ 'method' = 'artist.removeTag' 'api_key' = $script:LFMConfig.ApiKey 'sk' = $script:LFMConfig.SessionKey } } process { $noCommonParams = Remove-CommonParameter $PSBoundParameters $apiSig = Get-LFMSignature -Method $apiParams.Method @noCommonParams $apiParams.Add('api_sig', $apiSig) $convertedParams = ConvertTo-LFMParameter $noCommonParams $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" } end { if ($PSCmdlet.ShouldProcess("Artist: $Artist", "Removing artist tag: $Tag")) { try { $irm = Invoke-LFMApiUri -Uri $apiUrl -Method Post if ($irm.Lfm.Status -eq 'ok') {Write-Verbose "Tag: $Tag has been removed"} } catch { throw $_ } } } } function Remove-LFMConfiguration { # .ExternalHelp PowerLFM-help.xml [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')] param () process { try { $secrets = Get-SecretInfo -Name LFM* -Vault BuiltInLocalVault foreach ($secret in $secrets) { if ($PSCmdlet.ShouldProcess('BuiltInLocalVault', "Removing secret: $($secret.Name)")) { Remove-Secret -Name $secret.Name -Vault BuiltInLocalVault -Verbose } } } catch { throw $_ } } } function Remove-LFMTrackTag { # .ExternalHelp PowerLFM-help.xml [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $Track, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $Artist, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $Tag ) begin { $apiParams = @{ 'method' = 'track.removeTag' 'api_key' = $script:LFMConfig.ApiKey 'sk' = $script:LFMConfig.SessionKey } } process { $noCommonParams = Remove-CommonParameter $PSBoundParameters $apiSig = Get-LFMSignature -Method $apiParams.Method @noCommonParams $apiParams.Add('api_sig', $apiSig) $convertedParams = ConvertTo-LFMParameter $noCommonParams $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" } end { if ($PSCmdlet.ShouldProcess("Track: $Track", "Removing track tag: $Tag")) { try { $irm = Invoke-LFMApiUri -Uri $apiUrl -Method Post if ($irm.Lfm.Status -eq 'ok') {Write-Verbose "Tag: $Tag has been removed"} } catch { throw $_ } } } } function Request-LFMSession { # .ExternalHelp PowerLFM-help.xml [CmdletBinding()] [OutputType('System.String')] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $ApiKey, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $Token, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $SharedSecret ) process { $apiParams = @{ 'method' = 'auth.getSession' 'api_key' = $ApiKey 'token' = $Token 'format' = 'json' } $noCommonParams = Remove-CommonParameter $PSBoundParameters $apiSig = Get-LFMSignature -Method $apiParams.Method @noCommonParams $apiParams.Add('api_sig', $apiSig) $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" try { $irm = Invoke-LFMApiUri -Uri $apiUrl $obj = [pscustomobject] @{ 'ApiKey' = $ApiKey 'SessionKey' = $irm.Session.Key 'SharedSecret' = $SharedSecret } Write-Output $obj } catch { throw $_ } } } function Request-LFMToken { # .ExternalHelp PowerLFM-help.xml [CmdletBinding()] [OutputType('System.String')] param ( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string] $ApiKey, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string] $SharedSecret ) $apiParams = @{ 'method' = 'auth.getToken' 'api_key' = $ApiKey 'format' = 'json' } $noCommonParams = Remove-CommonParameter $PSBoundParameters $apiSig = Get-LFMSignature -Method $apiParams.Method @noCommonParams $apiParams.Add('api_sig', $apiSig) $query = New-LFMApiQuery $apiParams $apiUrl = "$baseUrl/?$query" try { Write-Verbose "Requesting token from $baseUrl" $token = (Invoke-LFMApiUri -Uri $apiUrl).Token Write-Verbose "Authorizing application with requested token on account" Show-LFMAuthWindow -Url "http://www.last.fm/api/auth/?api_key=$ApiKey&token=$token" $obj = [pscustomobject] @{ 'ApiKey' = $ApiKey 'Token' = $token 'SharedSecret' = $SharedSecret } Write-Output $obj } catch { throw $_ } } function Search-LFMAlbum { # .ExternalHelp PowerLFM-help.xml [CmdletBinding()] [OutputType('PowerLFM.Album.Search')] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $Album, [ValidateRange(1, 50)] [int] $Limit, [int] $Page ) begin { $apiParams = @{ 'method' = 'album.search' 'api_key' = $script:LFMConfig.ApiKey 'format' = 'json' } } process { $noCommonParams = Remove-CommonParameter $PSBoundParameters $convertedParams = ConvertTo-LFMParameter $noCommonParams $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" } end { try { $irm = Invoke-LFMApiUri -Uri $apiUrl foreach ($match in $irm.Results.AlbumMatches.Album) { $matchInfo = [pscustomobject] @{ 'PSTypeName' = 'PowerLFM.Album.Search' 'Album' = $match.Name 'Artist' = $match.Artist 'Id' = $match.Mbid 'Url' = [uri] $match.Url } Write-Output $matchInfo } } catch { throw $_ } } } function Search-LFMArtist { # .ExternalHelp PowerLFM-help.xml [CmdletBinding()] [OutputType('PowerLFM.Artist.Search')] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $Artist, [Parameter()] [ValidateRange(1, 50)] [int] $Limit, [int] $Page ) begin { $apiParams = @{ 'method' = 'artist.search' 'api_key' = $script:LFMConfig.ApiKey 'format' = 'json' } } process { $noCommonParams = Remove-CommonParameter $PSBoundParameters $convertedParams = ConvertTo-LFMParameter $noCommonParams $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" } end { try { $irm = Invoke-LFMApiUri -Uri $apiUrl foreach ($match in $irm.Results.ArtistMatches.Artist) { $matchInfo = [pscustomobject] @{ 'PSTypeName' = 'PowerLFM.Artist.Search' 'Artist' = $match.Name 'Id' = $match.Mbid 'Listeners' = [int] $match.Listeners 'Url' = [uri] $match.Url } Write-Output $matchInfo } } catch { throw $_ } } } function Search-LFMTrack { # .ExternalHelp PowerLFM-help.xml [CmdletBinding()] [OutputType('PowerLFM.Track.Search')] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $Track, [ValidateRange(1, 50)] [int] $Limit, [int] $Page ) begin { $apiParams = @{ 'method' = 'track.search' 'api_key' = $script:LFMConfig.ApiKey 'format' = 'json' } } process { $noCommonParams = Remove-CommonParameter $PSBoundParameters $convertedParams = ConvertTo-LFMParameter $noCommonParams $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" } end { try { $irm = Invoke-LFMApiUri -Uri $apiUrl foreach ($match in $irm.Results.TrackMatches.Track) { $matchInfo = [pscustomobject] @{ 'PSTypeName' = 'PowerLFM.Track.Search' 'Track' = $match.Name 'Artist' = $match.Artist 'Id' = $match.Mbid 'Listeners' = [int] $match.Listeners 'Url' = [uri] $match.Url } Write-Output $matchInfo } } catch { throw $_ } } } function Set-LFMTrackLove { # .ExternalHelp PowerLFM-help.xml [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $Artist, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $Track ) begin { $apiParams = @{ 'method' = 'track.love' 'api_key' = $script:LFMConfig.ApiKey 'sk' = $script:LFMConfig.SessionKey } } process { $noCommonParams = Remove-CommonParameter $PSBoundParameters $apiSig = Get-LFMSignature -Method $apiParams.Method @noCommonParams $apiParams.Add('api_sig', $apiSig) $convertedParams = ConvertTo-LFMParameter $noCommonParams $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" } end { if ($PSCmdlet.ShouldProcess("Track: $Track", "Adding love")) { try { $irm = Invoke-LFMApiUri -Uri $apiUrl -Method Post if ($irm.Lfm.Status -eq 'ok') {Write-Verbose "Track: $Track has been loved"} } catch { throw $_ } } } } function Set-LFMTrackNowPlaying { # .ExternalHelp PowerLFM-help.xml [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium')] [OutputType('PowerLFM.Track.NowPlaying')] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $Track, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $Artist, [Parameter(ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $Album, [Parameter(ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [guid] $Id, [Parameter(ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [int] $Duration, [Parameter()] [switch] $PassThru ) begin { $apiParams = @{ 'method' = 'track.updateNowPlaying' 'api_key' = $script:LFMConfig.ApiKey 'sk' = $script:LFMConfig.SessionKey 'format' = 'json' } } process { $noCommonParams = Remove-CommonParameter $PSBoundParameters $apiSig = Get-LFMSignature -Method $apiParams.Method @noCommonParams $apiParams.Add('api_sig', $apiSig) $convertedParams = ConvertTo-LFMParameter $noCommonParams $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" } end { if ($PSCmdlet.ShouldProcess("Track: $Track", "Setting track to now playing")) { try { $irm = Invoke-LFMApiUri -Uri $apiUrl -Method Post $code = Get-LFMIgnoredMessage -Code $irm.NowPlaying.IgnoredMessage.Code if ($code.Code -ne 0) { throw "Request has been filtered because of bad meta data. $($code.Message)." } if ($PassThru) { [pscustomobject] @{ PSTypeName = 'PowerLFM.Track.NowPlaying' Artist = $irm.NowPlaying.Artist.'#text' Album = $irm.NowPlaying.Album.'#text' Track = $irm.NowPlaying.Track.'#text' } } } catch { throw $_ } } } } function Set-LFMTrackScrobble { # .ExternalHelp PowerLFM-help.xml [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium')] [OutputType('PowerLFM.Track.Scrobble')] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $Artist, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $Track, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [datetime] $Timestamp, [Parameter(ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $Album, [Parameter(ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [guid] $Id, [Parameter(ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [int] $TrackNumber, [Parameter(ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [int] $Duration, [Parameter()] [switch] $PassThru ) begin { $apiParams = @{ 'method' = 'track.scrobble' 'api_key' = $script:LFMConfig.ApiKey 'sk' = $script:LFMConfig.SessionKey 'format' = 'json' } } process { $noCommonParams = Remove-CommonParameter $PSBoundParameters $apiSig = Get-LFMSignature -Method $apiParams.Method @noCommonParams $apiParams.Add('api_sig', $apiSig) $convertedParams = ConvertTo-LFMParameter $noCommonParams $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" } end { if ($PSCmdlet.ShouldProcess("Track: $Track", "Setting track to now playing")) { try { $irm = Invoke-LFMApiUri -Uri $apiUrl -Method Post $code = Get-LFMIgnoredMessage -Code $irm.Scrobbles.Scrobble.IgnoredMessage.Code if ($code.Code -ne 0) { throw "Request has been filtered because of bad meta data. $($code.Message)." } if ($PassThru) { [pscustomobject] @{ PSTypeName = 'PowerLFM.Track.Scrobble' Artist = $irm.Scrobbles.Scrobble.Artist.'#text' Album = $irm.Scrobbles.Scrobble.Album.'#text' Track = $irm.Scrobbles.Scrobble.Track.'#text' } } } catch { throw $_ } } } } function Set-LFMTrackUnlove { # .ExternalHelp PowerLFM-help.xml [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $Artist, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string] $Track ) begin { $apiParams = @{ 'method' = 'track.unlove' 'api_key' = $script:LFMConfig.ApiKey 'sk' = $script:LFMConfig.SessionKey } } process { $noCommonParams = Remove-CommonParameter $PSBoundParameters $apiSig = Get-LFMSignature -Method $apiParams.Method @noCommonParams $apiParams.Add('api_sig', $apiSig) $convertedParams = ConvertTo-LFMParameter $noCommonParams $query = New-LFMApiQuery ($convertedParams + $apiParams) $apiUrl = "$baseUrl/?$query" } end { if ($PSCmdlet.ShouldProcess("Track: $Track", "Removing love")) { try { $irm = Invoke-LFMApiUri -Uri $apiUrl -Method Post if ($irm.Lfm.Status -eq 'ok') {Write-Verbose "Track: $Track has been unloved"} } catch { throw $_ } } } } function ConvertFrom-UnixTime { [CmdletBinding()] [OutputType('System.DateTime')] param ( [Parameter(Mandatory, ValueFromPipeline)] [double] $UnixTime, [switch] $Local ) begin { [datetime] $epoch = '1/1/1970 00:00:00' $utcOffset = Get-Date -UFormat %Z } process { $time = $epoch.AddSeconds($UnixTime) if ($PSBoundParameters.ContainsKey('Local')) { Write-Output $time.AddHours($utcOffset) } else { Write-Output $time } } } function ConvertTo-LFMParameter { param ( [psobject] $InputObject ) $lfmParameter = @{ 'Album' = 'album' 'Artist' = 'artist' 'AutoCorrect' = 'autocorrect' 'City' = 'location' 'Country' = 'country' 'Duration' = 'duration' 'EndDate' = 'to' 'Id' = 'mbid' 'Language' = 'lang' 'Limit' = 'limit' 'Page' = 'page' 'StartDate' = 'from' 'Tag' = 'tag' 'TagType' = 'taggingtype' 'TimePeriod' = 'period' 'Timestamp' = 'timestamp' 'Track' = 'track' 'UserName' = 'user' 'Token' = 'token' 'ApiKey' = 'api_key' } $period = @{ 'Overall' = 'overall' '7 Days' = '7day' '1 Month' = '1month' '3 Months' = '3month' '6 Months' = '6month' '1 Year' = '12month' } $callingCommand = (Get-PSCallStack)[-2].Command if ($callingCommand -like 'Get-LFM*Info') { $lfmParameter['Username'] = 'username' } if ($callingCommand -like 'Add-LFM*Tag') { $lfmParameter['Tag'] = 'tags' } if ($InputObject.ContainsKey('Timestamp')) { $InputObject['Timestamp'] = (ConvertTo-UnixTime -Date $Timestamp) } if ($InputObject.ContainsKey('StartDate')) { $InputObject['StartDate'] = (ConvertTo-UnixTime -Date $StartDate) } if ($InputObject.ContainsKey('EndDate')) { $InputObject['EndDate'] = (ConvertTo-UnixTime -Date $EndDate) } if ($InputObject.ContainsKey('TimePeriod')) { $InputObject['TimePeriod'] = $period[$InputObject['TimePeriod']] } $null = if ($InputObject.ContainsKey('Method')) { $InputObject.Remove('Method') } $null = If ($InputObject.ContainsKey('SharedSecret')) { $InputObject.Remove('SharedSecret') } $null = If ($InputObject.ContainsKey('PassThru')) { $InputObject.Remove('PassThru') } $hash = @{ } foreach ($key in $InputObject.Keys) { $hash.Add($lfmParameter[$key], $InputObject[$key]) } Write-Output $hash } function ConvertTo-TitleCase { [CmdletBinding()] [OutputType('System.String')] param ( [Parameter(Mandatory, ValueFromPipeline)] [string[]] $String ) process { (Get-Culture).TextInfo.ToTitleCase($String) } } function ConvertTo-UnixTime { [CmdletBinding()] [OutputType('System.TimeSpan')] param ( [Parameter(Mandatory, ValueFromPipeline)] [datetime] $Date ) begin { [datetime] $epoch = '1/1/1970 00:00:00' } process { if ($Date.Kind -eq 'Local') { $Date = $Date.ToUniversalTime() } (New-TimeSpan -Start $epoch -End $Date).TotalSeconds } } function Get-LFMIgnoredMessage { param ( [int] $Code ) $ignoredCode = @{ 0 = 'None (the request passed all filters)' 1 = 'Filtered artist' 2 = 'Filtered track' 3 = 'Timestamp too far in the past' 4 = 'Timestamp too far in the future' 5 = 'Max daily scrobbles exceeded' } [pscustomobject] @{ Code = $Code Message = $ignoredCode[$Code] } } function Get-LFMSignature { [OutputType('System.String')] param ( [Parameter(Mandatory)] [ValidateSet('album.addTags','album.removeTag', 'artist.addTags','artist.removeTag', 'auth.getToken','auth.getSession', 'track.addTags','track.removeTag', 'track.love','track.unlove', 'track.updateNowPlaying', 'track.scrobble')] [string] $Method, [string] $Album, [string] $Artist, [string[]] $Tag, [string] $Track, [datetime] $Timestamp, [int] $TrackNumber, [int] $Duration, [guid] $Id, [switch] $Passthru, [string] $ApiKey, [string] $SharedSecret, [string] $Token ) $sigParams = @{ 'method' = $Method 'api_key' = $script:LFMConfig.ApiKey 'sk' = $script:LFMConfig.SessionKey } $convertedParams = ConvertTo-LFMParameter $PSBoundParameters if ($PSBoundParameters.ContainsKey('ApiKey')) { $sigParams.Remove('api_key') $sigParams.Remove('sk') $query = New-LFMApiQuery ($convertedParams + $sigParams) Get-Md5Hash -String "$query$($SharedSecret)" Write-Verbose "$query$($SharedSecret)" } else { $query = New-LFMApiQuery ($convertedParams + $sigParams) Get-Md5Hash -String "$query$($script:LFMConfig.SharedSecret)" Write-Verbose "$query$($script:LFMConfig.SharedSecret)" } } function Get-Md5Hash { [CmdletBinding()] param ( [Parameter()] [string] $String ) $md5 = New-Object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider $utf8 = New-Object -TypeName System.Text.UTF8Encoding $hash = ([System.BitConverter]::ToString($md5.ComputeHash($utf8.GetBytes($String)))) -replace '-' Write-Output $hash } function Invoke-LFMApiUri { [CmdletBinding()] param ( [uri] $Uri, [ValidateSet('Get', 'Post')] [string] $Method = 'Get' ) try { # If Invoke-RestMethod returns, say HTTP 403, it will cause a terminating # error and drop down in to the catch block. In most other cases if a bad # request is made it will actually return a JSON object with the error. $irm = Invoke-RestMethod -Method $Method -Uri $Uri -ErrorAction Stop # Api call could return an object with an error code as shown below. This # will account for that and throw the object down to the catch block. # error message links # ----- ------- ----- # 6 Album not found {} if ($irm.Error) { throw $irm } Write-Output $irm } catch { $response = if ($null -ne $_.ErrorDetails) { if ($_.ErrorDetails.Message | Test-Json) { $_.ErrorDetails.Message | ConvertFrom-Json } else { $_.ErrorDetails.Message } $errorId = 'PowerLFM.WebResponseException' $errorCategory = 'InvalidOperation' } else { $_.TargetObject $errorId = 'PowerLFM.ResourceNotFound' $errorCategory = 'ObjectNotFound' } $messagePart1 = '. Run Get-LFMConfiguration if token and session keys have already been requested.' $messagePart2 = 'This is not a valid request.' # Constructing error message from response object. # Capitalizing first letter in sentence. $responseMessage = [char]::ToUpper($response.Message[0]) + $response.Message.Substring(1) if ($responseMessage -like 'Invalid API key*') {$errorMessage = $responseMessage + $messagePart1} else {$errorMessage = "$messagePart2 $responseMessage."} $PSCmdlet.ThrowTerminatingError([ErrorRecord]::new( $errorMessage, $errorId, $errorCategory, $MyInvocation.MyCommand.Name )) } } function New-LFMApiQuery { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] param ( [psobject] $InputObject ) if ((Get-PSCallStack)[1].Command -like '*Signature') { $keyValues = $InputObject.GetEnumerator() | Sort-Object Key | ForEach-Object { "$($_.Key)$($_.Value)" } $query = $keyValues -join '' } else { $keyValues = $InputObject.GetEnumerator() | ForEach-Object { "$($_.Key)=$($_.Value)" } $query = $keyValues -join '&' } Write-Output $query } function Remove-CommonParameter { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] param ( [psobject] $InputObject ) $commonParams = [System.Management.Automation.PSCmdlet]::CommonParameters + [System.Management.Automation.PSCmdlet]::OptionalCommonParameters $keysToRemove = $InputObject.Keys.Where({ $_ -in $commonParams }) $null = $keysToRemove | ForEach-Object { $InputObject.Remove($_) } Write-Output $InputObject } function Show-LFMAuthWindow { [CmdletBinding()] param ( [Parameter(Mandatory)] [uri] $Url ) Add-Type -AssemblyName System.Windows.Forms $form = New-Object -TypeName System.Windows.Forms.Form -Property @{ Width = 516 Height = 638 StartPosition = 1 FormBorderStyle = 'Fixed3D' MinimizeBox = $false MaximizeBox = $false ShowIcon = $false } $web = New-Object -TypeName System.Windows.Forms.WebBrowser -Property @{ Width = 500 Height = 600 ScrollBarsEnabled = $false Url = $Url } $docComp = { $uri = $web.Url.AbsoluteUri if ($uri -cmatch '/None') { $form.Close() } } $web.ScriptErrorsSuppressed = $true $web.Add_DocumentCompleted($docComp) $form.Controls.Add($web) $form.Activate() $null = $form.ShowDialog() } function Test-Json { param ( [Parameter(Mandatory, ValueFromPipeline)] [string] $Json ) process { $result = $true try { $null = [Newtonsoft.Json.Linq.JObject]::Parse($Json) } catch { $result = $false } Write-Output $result } } |