PSWebToolbox.psm1

function Format-AtomFeed {
    param (
        $Feed
    )
    $Entries = foreach ($Entry in $Feed) {
        [PSCustomObject][ordered] @{
            #PostID = $Entry."post-id".InnerText
            ID = $Entry.id
            Title = $Entry.title
            Link = $Entry.link
            PublishDate = if ($Entry.published -is [DateTime]) { [DateTime] $Entry.published } else { $Entry.published }
            #Creator = $Entry.Creator.'#cdata-section'
            #Categories = $Entry.Category.'#cdata-section' -join ',' # actually for Wordpress it's a mix of Category/Tags
            #isPermaLink = $Entry.Guid.isPermaLink
            #LinkPerm = $Entry.Guid.'#text'
            #Description = $Entry.description.'#cdata-section'
            #Content = ($Entry.encoded.'#cdata-section' -replace '<[^>]+>', '')
        }
    }
    return $Entries
}
function Format-RSSFeed {
    [CmdletBinding()]
    param (
        [System.Collections.IList] $Feed
    )
    $Entries = foreach ($Entry in $Feed) {
        if ($Entry.link -like '*#*') {
            $Link = ($Entry.link).Split('#')[0]
        } else {
            $Link = $Entry.link
        }
        [PSCustomObject] @{
            Title = $Entry.title
            Link = $Link

            PublishDate = try { [DateTime] $Entry.pubDate } catch { $Entry.pubDate } ;
            Creator = $Entry.Creator.'#cdata-section'
            Categories = ($Entry.Category.'#cdata-section' | Sort-Object -Unique) -join ',' # actually for Wordpress it's a mix of Category/Tags
            LinkPerm = $Entry.Guid.'#text'
            Description = ConvertFrom-HTML -HTML ((($Entry.description.'#cdata-section') -split '<p>', 0, 'SimpleMatch,IgnoreCase')[1]) -RemoveTags
            IsPermaLink = $Entry.Guid.isPermaLink
        }
    }
    return $Entries
}
function Get-RSSFeed {
    [CmdletBinding(DefaultParameterSetName = 'Count')]
    param(
        [Parameter(ValueFromPipeline)][System.Uri[]] $Url,
        [Parameter(ParameterSetName = 'Count')][int] $Count = 10,
        [Parameter(ParameterSetName = 'All')] [switch] $All,
        [switch] $CategoriesOnly
    )
    Begin {
        if ($All) {
            $Count = 999999999
        }
        $Feed = [System.Collections.Generic.List[Object]]::new()
    }
    Process {
        [int] $CurrentCount = 0

        [int] $PageCount = 1
        foreach ($_ in $Url) {
            [System.Uri] $BuildURL = "$_"

            $Output = while ($true) {
                Write-Verbose "Get-Feed - Count: $($CurrentCount) Expected Count: $Count URL: $BuildURL"
                try {
                    [Array] $Data = Invoke-RestMethod -Uri $BuildURL -Verbose:$false
                    $CurrentCount = $CurrentCount + $Data.Count
                } catch {
                    $ErrorMessage = $_.Exception.Message -replace "`n", " " -replace "`r", " "
                    if ($PageCount -eq 1) {
                        #
                        Write-Warning "Get-Feed - Url: $_ CurrentUrl: $BuildURL Error: $ErrorMessage"
                    } else {
                        # Basically means end of feed for /?paged if it's more then 1 page being fed
                        # Especially for -All switch
                    }
                    break;
                }
                # return Data
                $Data

                # Verify if we're ok to close or not
                if ($CurrentCount -ge $Count) {
                    # if count is defined return only defined count
                    break
                }
                $PageCount++
                $BuildURL = "$Url/?paged=$PageCount"
            }
            if ($Output.Count -ge $Count) {
                $Output = $Output | Select-Object -First $Count
            }
            $Feed.AddRange($Output)
        }
    }
    End {
        $Value = Format-RSSFeed -Feed $Feed
        if ($CategoriesOnly) {
            return $Value.Categories -Split ',' | Group-Object -NoElement | Sort-Object Count -Descending
        } else {
            Write-Verbose "Get-RssFeed - Returning $($Value.Count) articles"
            return $Value
        }
    }
}


Export-ModuleMember `
    -Function @('Get-RSSFeed') `
    -Alias @()