Private/ConvertFrom-StoreHtml.ps1
|
function ConvertFrom-StoreHtml { <# .SYNOPSIS Parses the HTML table returned by the store.rg-adguard.net API into structured objects. .PARAMETER Html Raw HTML string from Invoke-StoreAPI. .PARAMETER Channel The ring that was queried, attached to every output object. #> [CmdletBinding()] [OutputType([PSCustomObject])] param( [Parameter(Mandatory, ValueFromPipeline)] [ValidateNotNullOrEmpty()] [string]$Html, [Parameter(Mandatory)] [string]$Channel ) process { # Extract every <tr>...</tr> block. $rowPattern = '(?is)<tr[^>]*>(.*?)</tr>' $rowMatches = [regex]::Matches($Html, $rowPattern) if ($rowMatches.Count -eq 0) { Write-Warning "ConvertFrom-StoreHtml: No table rows found in response for channel $Channel." return } # Pattern for a data row. Header rows won't have an <a> with href. $cellPattern = '(?is)<td[^>]*>\s*<a\s+href="(?<url>[^"]+)"[^>]*>(?<name>[^<]+)</a>\s*</td>' + '\s*<td[^>]*>(?<expire>[^<]*)</td>' + '\s*<td[^>]*>(?<sha1>[^<]*)</td>' + '\s*<td[^>]*>(?<size>[^<]*)</td>' $parsed = 0 foreach ($row in $rowMatches) { $inner = $row.Groups[1].Value if ($inner -match $cellPattern) { $parsed++ $name = [System.Net.WebUtility]::HtmlDecode($Matches['name']).Trim() $url = [System.Net.WebUtility]::HtmlDecode($Matches['url']).Trim() $expire = [System.Net.WebUtility]::HtmlDecode($Matches['expire']).Trim() $sha1 = [System.Net.WebUtility]::HtmlDecode($Matches['sha1']).Trim() $size = [System.Net.WebUtility]::HtmlDecode($Matches['size']).Trim() # Skip rows with invalid download URLs. if ([string]::IsNullOrWhiteSpace($url) -or $url -notmatch '^https?://') { Write-Verbose "Skipping row with invalid URL: $url" continue } [PSCustomObject]@{ PSTypeName = 'WinStoreRip.PackageInfo' Name = $name URL = $url ExpireTime = $expire SHA1 = $sha1 Size = $size Channel = $Channel } } } if ($parsed -eq 0) { Write-Warning "ConvertFrom-StoreHtml: Table rows found but none matched expected structure. The API format may have changed." } else { Write-Verbose "Parsed $parsed package(s) from $Channel channel." } } } |