psconfluencepublisher/tools/PageMeta.psm1

200 lines
5.3 KiB
PowerShell
Executable file

#!/usr/bin/env pwsh
$ErrorActionPreference = "Stop"
function Get-PageMetaCache
{
<#
.SYNOPSIS
Get a locally indexed/cached Confluence page id
.EXAMPLE
Get-PageMetaCache `
-Title 'Page Title' `
-Manifest @() `
-Index @{}
.NOTES
To test or not to test, that is the question... Since the
`Test-JSON` cmdlet requires serialized JSON, but we are working with
the deserialized Hashtable, it's too computationally intense to
always test the input upon every call. We therefore only make sure,
that correct data is written to the filesystem. For the rest, each
function is responsible for themself (learned that that's a valid
reflexive pronoun today 🤓).
This function is lucky to get this note, because it's at the top 💯.
Of course this applies to every function.
#>
Param(
[Parameter(Mandatory)] [string] $Title,
[Parameter(Mandatory)] [Array] $Manifest,
[Parameter()] [Collections.Hashtable] $Index
)
Process
{
If ($Index -And $Manifest.Count -gt 0 -And $Manifest[$Index.$Title])
{
$Manifest[$Index.$Title]
}
Else
{
For ($i = 0; $i -lt $Manifest.Count; $i += 1)
{
If ($Manifest[$i].Title -eq $Title)
{
$Manifest[$i]
break
}
}
}
}
}
function Get-PageMeta
{
<#
.SYNOPSIS
Get a Confluence page id
.DESCRIPTION
First, tries to retrieve from local page id index (cache) through
the local alias. If no cache hit, then polls the Confluence
instance host for the id by providing a space key and page title.
.EXAMPLE
Get-PageMeta `
-Host 'confluence.contoso.com' `
-Title 'Testitest' `
-Space 'TIARA' `
-CacheIndexFile 'confluence-page-cache.json'
#>
Param(
[Parameter(Mandatory)] [string] $Host,
[Parameter(Mandatory)] [string] $Title,
[Parameter(Mandatory)] [string] $Space,
[Parameter(Mandatory)] [Array] $Manifest,
[Parameter()] [Collections.Hashtable] $Index
)
Begin
{
$pageMeta = Get-PageMetaCache `
-Title $Title `
-Manifest $Manifest `
-Index $Index
}
Process
{
If ($pageMeta -And $pageMeta.Id)
{
$pageMeta
return
}
$escapedTitle = [Uri]::EscapeDataString($Title)
#TODO: move this to a separate function
$query = "title=${escapedTitle}&spaceKey=${Space}&expand=history"
Invoke-WebRequest `
-Uri "https://${Host}/rest/api/content?$query" `
-Method 'Get' `
-Headers @{
'Authorization' = "Bearer $(Get-PersonalAccessToken $Host)"
} `
-OutVariable response | Out-Null
$results = ($response.Content | ConvertFrom-JSON).results
if ($results.Count -gt 1)
{
throw "more than one result for query: $query"
}
elseif ($results.Count -eq 1)
{
Update-PageMeta `
-Id $results[0].id `
-Version ($results[0]._expandable | Select -ExpandProperty 'version') `
-Title $Title `
-Manifest $Manifest
}
}
}
function Update-PageMeta
{
<#
.SYNOPSIS
Register a Confluence page's metadata in the local cache
.DESCRIPTION
Synchronizes the locally cached page metadata (in manifest) with the
data stored by the Confluence instance. Therefore it is required to
supply a page id, since this is the reference linking the locally
cached page to a published instance of a page.
.EXAMPLE
Update-PageMeta `
-Title 'foobar' `
-PageId 'pageId' `
-Version 9001 `
-AncestorTitle 'ancestorTitle' `
-Hash 'hash' `
-Manifest $mockManifest
#>
Param(
[Parameter(Mandatory)] [String] $Title,
# remote Confluence page instance id
[Parameter(Mandatory)] [String] $Id,
[Parameter()] [Int] $Version,
[Parameter()] [String] $AncestorTitle,
[Parameter()] [String] $Hash,
[Parameter(Mandatory)] [Array] $Manifest,
[Parameter()] [Collections.Hashtable] $Index
)
Process
{
$pageMeta = Get-PageMetaCache `
-Title $Title `
-Manifest $Manifest `
-Index $Index
If (-Not $pageMeta)
{
throw "page titled `$Title` not indexed in Manifest."
}
$pageMeta.Id = $Id
If ($Version)
{
$pageMeta.Version = $Version
}
If ($AncestorTitle)
{
$pageMeta.AncestorTitle = $AncestorTitle
}
# if content didn't update, hash stays the same
If ($Hash)
{
$pageMeta.Hash = $Hash
}
Write-Debug "register: $Title -> $PageId"
$pageMeta
}
}