Public/Get-PatPlaylist.ps1
|
function Get-PatPlaylist { <# .SYNOPSIS Retrieves playlists from a Plex server. .DESCRIPTION Gets a list of playlists from the Plex server. Can retrieve all playlists, filter by ID or name, and optionally include the items within each playlist. Only returns regular (non-smart) playlists by default. .PARAMETER PlaylistId The unique identifier of a specific playlist to retrieve. .PARAMETER PlaylistName The name of a specific playlist to retrieve. Supports tab completion. .PARAMETER IncludeItems When specified, also retrieves the items within each playlist. Items are returned in a nested 'Items' property on each playlist object. .PARAMETER ServerName The name of a stored server to use. Use Get-PatStoredServer to see available servers. This is more convenient than ServerUri as you don't need to remember the URI or token. .PARAMETER ServerUri The base URI of the Plex server (e.g., http://plex.example.com:32400). If not specified, uses the default stored server. .PARAMETER Token The Plex authentication token. Required when using -ServerUri to authenticate with the server. If not specified with -ServerUri, requests will fail. .EXAMPLE Get-PatPlaylist Retrieves all playlists from the default Plex server. .EXAMPLE Get-PatPlaylist -ServerName 'Home' Retrieves all playlists from the stored server named 'Home'. .EXAMPLE Get-PatPlaylist -PlaylistId 12345 Retrieves the playlist with the specified ID. .EXAMPLE Get-PatPlaylist -PlaylistName 'My Favorites' Retrieves the playlist named 'My Favorites'. .EXAMPLE Get-PatPlaylist -IncludeItems Retrieves all playlists with their items included. .EXAMPLE Get-PatPlaylist -PlaylistName 'Watch Later' -IncludeItems | Select-Object -ExpandProperty Items Retrieves only the items from the 'Watch Later' playlist. .OUTPUTS PlexAutomationToolkit.Playlist Objects with properties: - PlaylistId: Unique playlist identifier (ratingKey) - Title: Name of the playlist - Type: Playlist type (video, audio, photo) - ItemCount: Number of items in the playlist - Duration: Total duration in milliseconds - Smart: Whether this is a smart playlist - Composite: URI of the playlist composite image - ServerUri: The Plex server URI - Items: (Only with -IncludeItems) Array of playlist items #> [CmdletBinding(DefaultParameterSetName = 'All')] param ( [Parameter(Mandatory = $true, ParameterSetName = 'ById', ValueFromPipeline, ValueFromPipelineByPropertyName)] [ValidateRange(1, [int]::MaxValue)] [int] $PlaylistId, [Parameter(Mandatory = $true, ParameterSetName = 'ByName')] [ValidateNotNullOrEmpty()] [string] $PlaylistName, [Parameter(Mandatory = $false)] [switch] $IncludeItems, [Parameter(Mandatory = $false)] [string] $ServerName, [Parameter(Mandatory = $false)] [ValidateNotNullOrEmpty()] [ValidateScript({ Test-PatServerUri -Uri $_ })] [string] $ServerUri, [Parameter(Mandatory = $false)] [ValidateNotNullOrEmpty()] [string] $Token ) begin { try { $script:serverContext = Resolve-PatServerContext -ServerName $ServerName -ServerUri $ServerUri -Token $Token } catch { throw "Failed to resolve server: $($_.Exception.Message)" } $effectiveUri = $script:serverContext.Uri $headers = $script:serverContext.Headers } process { try { # Determine endpoint based on parameter set if ($PSCmdlet.ParameterSetName -eq 'ById') { $endpoint = "/playlists/$PlaylistId" Write-Verbose "Retrieving playlist $PlaylistId from $effectiveUri" } else { $endpoint = '/playlists' Write-Verbose "Retrieving all playlists from $effectiveUri" } $uri = Join-PatUri -BaseUri $effectiveUri -Endpoint $endpoint $result = Invoke-PatApi -Uri $uri -Headers $headers -ErrorAction 'Stop' # Handle empty response if (-not $result) { Write-Verbose "No playlists found" return } # Extract playlist data from Metadata array (both single and multiple queries return this structure) $playlistData = if ($result.Metadata) { $result.Metadata } else { @() } # Filter by name if specified if ($PSCmdlet.ParameterSetName -eq 'ByName') { $playlistData = $playlistData | Where-Object { $_.title -eq $PlaylistName } if (-not $playlistData) { throw "No playlist found with name '$PlaylistName'" } } # Filter out smart playlists (we only support dumb playlists) $playlistData = $playlistData | Where-Object { $_.smart -ne '1' -and $_.smart -ne 1 } # Transform each playlist into a structured object foreach ($playlist in $playlistData) { $playlistObj = [PSCustomObject]@{ PSTypeName = 'PlexAutomationToolkit.Playlist' PlaylistId = [int]$playlist.ratingKey Title = $playlist.title Type = $playlist.playlistType ItemCount = [int]$playlist.leafCount Duration = [long]$playlist.duration Smart = ($playlist.smart -eq '1' -or $playlist.smart -eq 1) Composite = $playlist.composite AddedAt = if ($playlist.addedAt) { [DateTimeOffset]::FromUnixTimeSeconds([long]$playlist.addedAt).LocalDateTime } else { $null } UpdatedAt = if ($playlist.updatedAt) { [DateTimeOffset]::FromUnixTimeSeconds([long]$playlist.updatedAt).LocalDateTime } else { $null } ServerUri = $effectiveUri } # Fetch items if requested if ($IncludeItems) { $itemsEndpoint = "/playlists/$($playlist.ratingKey)/items" $itemsUri = Join-PatUri -BaseUri $effectiveUri -Endpoint $itemsEndpoint try { $itemsResult = Invoke-PatApi -Uri $itemsUri -Headers $headers -ErrorAction 'Stop' $items = @() if ($itemsResult -and $itemsResult.Metadata) { $items = foreach ($item in $itemsResult.Metadata) { [PSCustomObject]@{ PSTypeName = 'PlexAutomationToolkit.PlaylistItem' PlaylistItemId = [int]$item.playlistItemID RatingKey = [int]$item.ratingKey Title = $item.title Type = $item.type Duration = [long]$item.duration AddedAt = if ($item.addedAt) { [DateTimeOffset]::FromUnixTimeSeconds([long]$item.addedAt).LocalDateTime } else { $null } PlaylistId = [int]$playlist.ratingKey ServerUri = $effectiveUri } } } Add-Member -InputObject $playlistObj -MemberType NoteProperty -Name 'Items' -Value $items } catch { Write-Warning "Failed to retrieve items for playlist '$($playlist.title)': $($_.Exception.Message)" Add-Member -InputObject $playlistObj -MemberType NoteProperty -Name 'Items' -Value @() } } $playlistObj } } catch { throw "Failed to retrieve playlists: $($_.Exception.Message)" } } } |