network.ps1

#using namespace System.Collections.Generic

### Includes:
. "$PSScriptRoot\cache.ps1"

### Variables:
$network_stat = [pscustomobject]@{
  ReadFromCacheCount = 0
  InvokeWebRequestCount = 0
}

### Functions:

function Combine-Url {
  [CmdletBinding()]
  param (
    [Parameter(Mandatory = $true)]
    [string[]]$Segments,
    [switch]$KeepTrailingSlash
  )
  # Write-Verbose "Combine-Url: args[$($Segments.Length)]: [$($Segments -join " ; ")]"
  $trailing_slash = if ($KeepTrailingSlash -and ($Segments[-1].EndsWith('/'))) { '/' } else { '' }
  $result = (@($Segments | % { "$_".Trim().Trim('/') } | ? { $_ }) -join '/') + $trailing_slash
  return $result
}


function Get-UrlContent {
  [CmdletBinding()]
  param (
    [Parameter(Mandatory = $true)]
    [string]$Url,
    [ValidateSet('JSON', 'Text', IgnoreCase = $true)]
    [string]$ResponseType = 'JSON',
    [hashtable]$Headers = @{ },
    [System.Collections.Specialized.OrderedDictionary]$Query = @{ }
    # [hashtable]$Query = @{ }
    # [switch]$Cache
  )
  
  Write-Verbose "Get-UrlContent: begin"
  Write-Verbose "Get-UrlContent: ErrorActionPreference: '$ErrorActionPreference'"
  Write-Verbose "Get-UrlContent: Url: '$Url'"
  Write-Verbose "Get-UrlContent: ResponseType: '$ResponseType'"
  # Write-Verbose "Get-UrlContent: Query: '$Query'"
  
  $config = Get-Config
  $cache_enabled = Parse-Bool $config.Cache.Enabled
  Write-Verbose "Get-UrlContent: cache_enabled: $cache_enabled"
  
  $ext = if ($ResponseType -eq 'JSON') {
    'json'
  } elseif ($ResponseType -eq 'Text') {
    'txt'
  } else {
    ''
  }
  
  $query_str = if ($Query -and $Query.Count) {
    '?' + (@($Query.GetEnumerator() | ? { $_.Value } | % { "$($_.Key)=$($_.Value)" }) -join '&')
  } else {
    ''
  }
  Write-Verbose "Get-UrlContent: query_str: '$query_str'"
  
  $full_url = $Url + $query_str
  Write-Verbose "Get-UrlContent: full URL: '$full_url'"
  
  $cache_key = $full_url
  
  if ($cache_enabled) {
    $cache_result = Read-TextFromCache -Key $cache_key -FileExtension $ext
    if ($cache_result) {
      Write-Verbose "Get-UrlContent: result obtained from cache"
      $network_stat.ReadFromCacheCount++
      if ($ResponseType -eq 'JSON') {
        $result = ConvertFrom-Json -InputObject $cache_result
        $props = @(Get-Member -InputObject $result -MemberType Properties | select -ExpandProperty Name)
        # if ($result.count -and $result.value) {
        if (('count' -in $props) -and ('value' -in $props)) {
          Write-Verbose "result(1): [$result]"
          return $result.value
        }
        Write-Verbose "result(2): [$result]"
        return $result
        
      } elseif ($ResponseType -eq 'Text') {
        Write-Verbose "result(3): [$cache_result]"
        return $cache_result
        
      } else {
        throw "Invalid response type '$ResponseType'"
      }
    } else {
      Write-Verbose "Get-UrlContent: result not found in cache"
    }
  }
  
  $params = @{ }
  
# Get-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState -ErrorAction 'SilentlyContinue'
  # Write-Host "`r`n*** Function Name:" -ForegroundColor 'White'
# try {
  # Write-Host ("Parameters:`r`n" + (New-Object "PSObject" -Property $PSBoundParameters | fl * | Out-String).Trim()) -ForegroundColor 'Cyan'
    
    Write-Verbose "Get-UrlContent: invoke web request to get result"
    
    ### ���������� -ErrorAction, ������� � try-catch:
    $response = Invoke-WebRequest -Uri $full_url -Headers $Headers @params
    $network_stat.InvokeWebRequestCount++
    if ($cache_enabled) {
      Save-TextToCache -Key $cache_key -Text $response.Content -FileExtension $ext
    }
    
    if ($ResponseType -eq 'JSON') {
      $result = ConvertFrom-Json -InputObject $response.Content
      $props = @(Get-Member -InputObject $result -MemberType Properties | select -ExpandProperty Name)
      # if ($result.count -and $result.value) {
      if (('count' -in $props) -and ('value' -in $props)) {
        return $result.value
      }
      return $result
      
    } elseif ($ResponseType -eq 'Text') {
      return $response.Content
      
    } else {
      throw "Invalid response type '$ResponseType'"
    }
    
# } catch {
# if ($ErrorActionPreference -eq 'Stop') {
# throw
# } elseif ($ErrorActionPreference -ne 'SilentlyContinue') {
# Write-Host ($_ | fl * -Force | Out-String).Trim() -ForegroundColor 'Red'
# Write-Host ("Parameters:`r`n" + (New-Object "PSObject" -Property $PSBoundParameters | fl * | Out-String).Trim()) -ForegroundColor 'Cyan'
# }
# }
}

function Show-NetworkStat() {
  Write-Host "`r`n=== NETWORK STATISTICS ==="
  Write-Host ($network_stat | fl * | Out-String).Trim()
}