GW2.PS.API-ConfigManagement.psm1
$MyPublisher = "SMFX" $MyModuleName = "GW2.PS" $ReservedSettings = @( #'DefaultProfile', 'Module', 'Publisher', 'Cache', 'LiteDB', 'Profiles' ) Function ConfigPath { <# .SYNOPSIS Return the path to the configuration file; might depend on platform. #> If ($IsWindows) { "$env:AppData\$MyPublisher\$MyModuleName.xml" } elseif ($IsMacOS) { "~/Library/Application Support/$MyPublisher/$MyModuleName.xml" } else { "$PSScriptRoot/Data/$MyModuleName.xml" } } Function BasicProfile { <# .SYNOPSIS Provide standard template structure for a profile #> [CmdletBinding()] param([string]$Name) [ordered]@{ "GW2Profile" = $Name "APIKey" = $null } } Function LoadConfig { <# .SYNOPSIS Load details from configuration file .DESCRIPTION Import configuration details from file system and generate a default template if not available. #> [CmdletBinding()] param([switch]$PassThru) Process { If (-not (Test-Path (ConfigPath))) { IF (-not (Test-Path (Split-Path (ConfigPath) -Parent))) { $Null = mkdir (Split-Path (ConfigPath) -Parent) } $BasicConfig = [ordered]@{ 'Module' = $MyModuleName 'Publisher' = $MyPublisher 'Cache' = (New-GW2CacheSettings) 'LiteDB' = (New-GW2LiteDBSettings) #'Table' = (New-GW2TableAPISettings) #Not yet published 'DefaultProfile' = "Default" 'Profiles' = @{ 'Default' = BasicProfile -Name "Default" } } #$BasicConfig | ConvertTo-Json | Set-Content -Path (ConfigPath) $BasicConfig | Save-GW2Config } #$ConfigValue = (Get-Content (ConfigPath) | ConvertFrom-Json ) $ConfigValue = Import-Clixml (ConfigPath) Set-Variable -Name 'ModConfig' -Scope Global -Value $ConfigValue -Option ReadOnly -Force If ($PassThru) { $ConfigValue } } } Function Get-GW2DefaultProfile { <# .SYNOPSIS Return the name of the current default #> $ModConfig.DefaultProfile } Function Save-GW2Config { <# .SYNOPSIS Export settings to configuration file #> [CmdletBinding()] param( [parameter(ValueFromPipeline)] $InputObject ) Process { #$InputObject | ConvertTo-Json | Set-Content (ConfigPath) $InputObject | Export-Clixml -Path (ConfigPath) } } Function Set-GW2ConfigValue { <# .SYNOPSIS Set a value for the configuration .DESCRIPTION Will store a value in a profile unless -Section indicates otherwise. If no profile or system is specified, it store in the default profile. #> [CmdletBinding()] param( [parameter(ValueFromPipelineByPropertyName)] [string]$Name, [parameter(ValueFromPipeline, ValueFromPipelineByPropertyName)] $Value, [parameter(ValueFromPipelineByPropertyName)] [string]$GW2Profile = (Get-GW2DefaultProfile), [parameter(ValueFromPipelineByPropertyName)] [ValidateSet("Profile","System","Cache","LiteDB")] [string]$Section="Profile" ) Begin { $TempConfig = LoadConfig -PassThru } Process { switch ($Section) { "System" { If ($Name -notin $ReservedSettings) { $TempConfig.$Name = $Value } } "Cache" { If (-not ($TempConfig.Cache)) { $TempConfig.Cache = (New-GW2CacheSettings) } $TempConfig.Cache.$Name = $Value } "LiteDB" { If (-not ($TempConfig.LiteDB)) { $TempConfig.LiteDB = (New-GW2LiteDBSettings) } $TempConfig.LiteDB.$Name = $Value } default { If (-not ($TempConfig.Profiles.containsKey($GW2Profile))) { $TempConfig.Profiles.$GW2Profile = BasicProfile -Name $GW2Profile } $TempConfig.Profiles.$GW2Profile.$Name = $Value } } } End { $TempConfig | Save-GW2Config LoadConfig } } Function Set-GW2DefaultProfile { <# .SYNOPSIS Set the default profile name #> [CmdletBinding()] param() DynamicParam { CommonGW2APIParameters } Begin { $CommParams = CommonGW2APIParameters } Process { ForEach ($Comm in ($CommParams.Keys)) { Set-Variable -Name $Comm -Value ($PSBoundParameters.$Comm) -Scope 0 If (-not [string]::IsNullOrEmpty((Get-Variable -Name $Comm))) { Set-Variable -Name $Comm -Value $CommParams.$Comm.Value -Scope 0 } } If ($GW2Profile) { Write-Debug "Setting default profile to $GW2Profile" Set-GW2ConfigValue -Section System -Name DefaultProfile -Value $GW2Profile } } } Function NewGW2Function { param( [string]$Base, [string[]]$Subsection ) $FunctionSections = ForEach ($Section in (@($Base) + $Subsection)) { If (-not [string]::IsNullOrEmpty($Section)) { ($Section.Substring(0, 1).ToUpper() + $Section.Substring(1).ToLower()) -replace "s$", "" } } If ($FunctionSections.count -gt 1) { $FinalSection = $FunctionSections[-1] } else { $FinalSection = $FunctionSections } $FunctionString = "Get-GW2$($FunctionSections -join '')" -replace ":id","" $URIStub = ((@($Base) + $Subsection) -join "/").ToLower() @" Function $FunctionString { <# .SYNOPSIS Get the $URIStub from Guild Wars 2 API #> [cmdletbinding()] param() DynamicParam { CommonGW2APIParameters -IDType "$FinalSection" } Process { `$APIEndpoint = "$URIStub" Get-GW2APIValue -APIValue `$APIEndpoint @PSBoundParameters } } "@ } Function BuildGW2Functions { [cmdletbinding(DefaultParameterSetName="WebBase")] param( [parameter(ParameterSetName="WebBase")] $Bases = ((Get-GW2Base) -replace "^/v2/", "" ), [parameter(ParameterSetName="MissingAPIs",Mandatory)] [switch]$Missing, [parameter(ParameterSetName="MissingAPIs")] [string]$MissingPath="C:\Repo\SmFx\GW2\PoShGW2\Module\GW2.PS\missingAPIs.txt" ) Process { if ($Missing) { $MissingBases=Get-Content $MissingPath BuildGW2Functions -Bases $MissingBases } else { ForEach ($Base in $Bases) { $Sections = $Base -split '/' $Root = $Sections[0] If ($Sections.Length -gt 1) { $Subs = $Sections[1..($Sections.Length - 1)] } else { $Subs = $null } NewGW2Function -Base $Root -Subsection $Subs | Set-Clipboard Write-Host "Function for $base on clipboard" Pause } } } } Function CommonGW2APIParameters { <# .SYNOPSIS Create standard, dynamic parameters for GW2 functions. .DESCRIPTION This will create standard parameters for GW2 functions to provide values such as GW2Profile, ID, and other attributes .PARAMETER IDType Specifies that function calling this uses ID parameters #> param([string]$IDType, [switch]$IDMandatory) $RuntimeParamDic = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $StandardProps = @('Mandatory', 'ValueFromPipelineByPropertyName', 'ValueFromPipeline', 'ParameterSetName', 'Position') $Attrib = [ordered]@{ 'GW2Profile' = @{ 'AttribType' = [string] 'Mandatory' = $false 'ValueFromPipelineByPropertyName' = $true 'Position' = 1 'ValidSet' = ([string[]]($ModConfig.Profiles.Keys)) 'DefaultValue' = (Get-GW2DefaultProfile) } 'Online' = @{ 'AttribType' = [switch] 'Mandatory' = $false 'Position' = 2 'DefaultValue' = (-not ((Get-GW2DefaultUseCache) -or (Get-GW2DefaultUseDB))) } 'UseCache' = @{ 'AttribType' = [switch] 'Mandatory' = $false 'Position' = 3 'DefaultValue' = ((-not $Online ) -and (Get-GW2DefaultUseCache)) } 'UseDB' = @{ 'AttribType' = [switch] 'Mandatory' = $false 'Position' = 3 'DefaultValue' = ((-not $Online) -and (Get-GW2DefaultUseDB)) } } If ($IDType -or $IDMandatory) { $Attrib.ID = @{ 'AttribType' = [string] 'Mandatory' = $IDMandatory 'ValueFromPipelineByPropertyName' = $true 'ValueFromPipeline' = $true 'Position' = 0 'Alias' = @('ids','name') } If ($IDType -ne 'id') { $Attrib.ID.'Alias' += "$($IDType)ID" } } ForEach ($AttribName in $Attrib.Keys) { #[string]$AttribName = $Key.ToString() $ThisAttrib = New-Object System.Management.Automation.ParameterAttribute ForEach ($Prop in $StandardProps) { If ($null -ne $Attrib.$AttribName.$Prop) { $ThisAttrib.$Prop = $Attrib.$AttribName.$Prop } } $ThisCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute] $ThisCollection.Add($ThisAttrib) If ($Attrib.$AttribName.ValidSet) { $ThisValidation = New-Object System.Management.Automation.ValidateSetAttribute($Attrib.$AttribName.ValidSet) $ThisCollection.Add($ThisValidation) } if ($Attrib.$AttribName.Alias) { $ThisAlias = New-Object -Type ` System.Management.Automation.AliasAttribute -ArgumentList @($Attrib.$AttribName.Alias) $ThisCollection.Add($ThisAlias) } $ThisRuntimeParam = New-Object System.Management.Automation.RuntimeDefinedParameter($AttribName, $Attrib.$AttribName.AttribType, $ThisCollection) If ($Attrib.$AttribName.DefaultValue) { $ThisRuntimeParam.Value = $Attrib.$AttribName.DefaultValue } $RuntimeParamDic.Add($AttribName, $ThisRuntimeParam) } return $RuntimeParamDic } Function Get-GW2ConfigValue { <# .SYNOPSIS Set a value for the configuration .DESCRIPTION Will store a value in a profile unless -Section indicates otherwise. If no profile or system is specified, it store in the default profile. #> [CmdletBinding()] param( [parameter(ValueFromPipelineByPropertyName)] [string]$Name, [parameter(ValueFromPipelineByPropertyName)] [string]$GW2Profile = (Get-GW2DefaultProfile), [parameter(ValueFromPipelineByPropertyName)] [ValidateSet("Profile","System","Cache","LiteDB")] [string]$Section="Profile" ) Begin { $TempConfig = $ModConfig #LoadConfig -PassThru } Process { switch ($Section) { "System" { If ($Name -notin $ReservedSettings) { return $TempConfig.$Name } } "Cache" { return $TempConfig.Cache.$Name } "LiteDB" { return $TempConfig.LiteDB.$Name } default { return $TempConfig.Profiles.$GW2Profile.$Name } } } } Function Get-GW2DefaultUseCache { If ((Get-Module -Name 'GW2.PS.Cache' -ListAvailable)) { Write-Output ($true -eq (Get-GW2ConfigValue -Section Cache -Name 'UseCache')) } else { Write-Output $false } } Function Get-GW2DefaultUseDB { If ((Get-Module -Name 'GW2.PS.LiteDB') -or (Get-Module -Name 'GW2.PS.LiteDB' -ListAvailable)) { Write-Output ($true -eq (Get-GW2ConfigValue -Section LiteDB -Name 'UseDB')) } else { Write-Output $false } } LoadConfig |