diff --git a/PSConfluencePublisher/PSConfluencePublisher.psd1 b/PSConfluencePublisher/PSConfluencePublisher.psd1 index 9c1255a..9c57f25 100755 --- a/PSConfluencePublisher/PSConfluencePublisher.psd1 +++ b/PSConfluencePublisher/PSConfluencePublisher.psd1 @@ -63,7 +63,9 @@ RootModule = 'PSConfluencePublisher.psm1' 'PersonalAccessToken.psm1', 'Connection.psm1', 'Manifest.psm1', - 'Page.psm1' + 'Page.psm1', + 'PageMeta.psm1', + 'String.psm1' ) # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export. @@ -86,7 +88,7 @@ AliasesToExport = @() # List of all files packaged with this module FileList = @( - "./manifest.schema.json" + "manifest.schema.json" ) # Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell. diff --git a/PSConfluencePublisher/PSConfluencePublisher.psm1 b/PSConfluencePublisher/PSConfluencePublisher.psm1 index c7b163f..1136573 100755 --- a/PSConfluencePublisher/PSConfluencePublisher.psm1 +++ b/PSConfluencePublisher/PSConfluencePublisher.psm1 @@ -33,427 +33,3 @@ $ErrorActionPreference = "Stop" -function New-ConfluencePage -{ - <# - .SYNOPSIS - Add a confluence page - - .DESCRIPTION - - .EXAMPLE - Add-ConfluencePage - -Host 'confluence.contoso.com' ` - -Space 'TIARA' ` - -Title 'Testitest' ` - -Content @{} - #> - Param( - [Parameter(Mandatory)] [string] $Host, - # The name of the Confluence space to publish to - [Parameter(Mandatory)] [string] $Space, - # title of page to be published - [Parameter(Mandatory)] [string] $Title, - # content of page - [Parameter(Mandatory)] [string] $Content, - # parent page id - [Parameter()] [string] $Ancestor - ) - - Process - { - Assert-PersonalAccessToken $Host - - $transportBody = @{ - 'type' = 'page' - 'title' = $Title - 'space' = @{ - 'key' = $Space - } - 'body' = @{ - 'storage' = @{ - 'value' = $Content - 'representation' = 'storage' - } - } - } | ConvertTo-JSON - - Invoke-WebRequest ` - -Uri "https://${Host}/rest/api/content" ` - -Method 'Post' ` - -Headers @{ - 'Authorization' = "Bearer $([System.Net.NetworkCredential]::new('', $script:PATS[$Host_]).Password)" - } ` - -ContentType "application/json" ` - -Body $transportBody ` - -OutVariable rawResponse | Out-Null - } - - End - { - $response = ($rawResponse.Content | ConvertFrom-JSON) - - @{ - 'PageId' = $response.Id - 'Version' = $response.version | Select -ExpandProperty 'number' - } - } -} - - -function Update-Page -{ - <# - .SYNOPSIS - Add a confluence page - - .DESCRIPTION - - .EXAMPLE - Add-ConfluencePage - -Host 'confluence.contoso.com' ` - -Space 'TIARA' ` - -Title 'Testitest' ` - -Content @{} - #> - Param( - [Parameter(Mandatory)] [string] $Host, - # The page id of an existing page - [Parameter(Mandatory)] [string] $PageId, - # The name of the Confluence space to publish to - [Parameter(Mandatory)] [string] $Space, - # title of page to be published - [Parameter(Mandatory)] [string] $Title, - # version of content - [Parameter(Mandatory)] [int] $Version, - # content of page - [Parameter(Mandatory)] [string] $Content, - # parent page id - [Parameter()] [string] $Ancestor - ) - - Process - { - Assert-PersonalAccessToken $Host - - $transportBody = @{ - 'id' = $PageId - 'type' = 'page' - 'title' = $Title - 'space' = @{ - 'key' = $Space - } - 'body' = @{ - 'storage' = @{ - 'value' = $Content - 'representation' = 'storage' - } - } - 'version' = @{ - 'number' = $Version - } - } | ConvertTo-JSON - - Invoke-WebRequest ` - -Uri "https://${Host}/rest/api/content/$PageId" ` - -Method 'Put' ` - -Headers @{ - 'Authorization' = "Bearer $([System.Net.NetworkCredential]::new('', $script:PATS[$Host_]).Password)" - } ` - -ContentType "application/json" ` - -Body $transportBody ` - -OutVariable rawResponse | Out-Null - } - - End - { - $response = ($rawResponse.Content | ConvertFrom-JSON) - } -} - - -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)] [string] $CacheIndexFile - ) - - Process - { - if ($Title) - { - $cachedPageMeta = Get-CachedPageMeta ` - -Title $Title ` - -CacheIndexFile $CacheIndexFile - } - - if ($cachedPageMeta) - { - return $cachedPageMeta - } - - $escapedTitle = [uri]::EscapeDataString($Title) - - $query = "title=${escapedTitle}&spaceKey=${Space}&expand=history" - - Assert-PersonalAccessToken $Host - - Invoke-WebRequest ` - -Uri "https://${Host}/rest/api/content?$query" ` - -Method 'Get' ` - -Headers @{ - 'Authorization' = "Bearer $([System.Net.NetworkCredential]::new('', $script:PATS[$Host_]).Password)" - } ` - -OutVariable response - - $results = ($response.Content | ConvertFrom-JSON).results - - if ($results.Count -gt 1) - { - throw "more than one result for query: $query" - } - elseif ($results.Count -eq 1) - { - Register-PageMeta ` - -PageId $results[0].id ` - -Version ($results[0]._expandable | Select -ExpandProperty 'version') ` - -Title $Title ` - -CacheIndexFile $CacheIndexFile - } - } -} - - -function Register-PageMeta -{ - <# - .SYNOPSIS - Register a Confluence page's metadata in the local cache - - .DESCRIPTION - - .EXAMPLE - Add-ConfluencePage - -Host 'confluence.contoso.com' ` - -Space 'TIARA' ` - -Title 'Testitest' ` - -Content @{} - #> - Param( - [Parameter(Mandatory)] [string] $PageId, - [Parameter()] [int] $Version = 0, - [Parameter(Mandatory)] [string] $Title, - [Parameter()] [string] $ContentHash = '', - [Parameter(Mandatory)] [string] $CacheIndexFile - ) - - Process - { - try - { - $raw = Get-Content $CacheIndexFile - } - - catch - { - $raw = "{}" - } - - $data = $raw | ConvertFrom-JSON - - $data | Add-Member -Name $Title ` - -Value @{ - 'PageId' = $PageId - 'Version' = $Version - 'ContentHash' = $ContentHash - } ` - -MemberType NoteProperty ` - -Force - - Set-Content -Path $CacheIndexFile -Value ($data | ConvertTo-JSON) - - Write-Debug "indexed page id: $Title -> $PageId" - } -} - - -function Publish-Page -{ - Param( - # title of the page (used for manifest lookup) - [Parameter(Mandatory)] [string] $Title, - # hostname of Confluence instance - [Parameter(Mandatory)] [string] $Host, - # name of Confluence space - [Parameter(Mandatory)] [string] $Space, - # manifest object - [Parameter(Mandatory)] [PSObject] $Manifest - ) - - Begin - { - $pageMeta = Get-PageMeta ` - -Host $hostname ` - -Space $spaceName ` - -Title $Title ` - -Manifest $Manifest - } - - Process - { - if ($pageMeta.ContentHash -eq $_) - { - Write-Host "skipping (no changes): $Title" - - return - } - - $pageId = $pageMeta.PageId - - $path = Join-Path $basepath 'content' "$_" - - $pageContent = Get-Content $path | Out-String - - $prettyName = $Title - - if ($data.pages[$_].ancestor_id) - { - $ancestorTitle = $data.pages[$data.pages[$_].ancestor_id].title - - $ancestorPageMeta = Get-PageMeta ` - -Host $hostname ` - -Space $spaceName ` - -Title $ancestorTitle ` - -CacheIndexFile $cacheIndexFile - - if ($ancestorPageMeta) - { - $ancestorPageId = $ancestorPageMeta.PageId - } - - $prettyName += " [$ancestorPageId]" - } - - if (-Not $pageId) - { - Write-Host ("create ${_}: $prettyName") - - try { - $pageMeta = New-ConfluencePage ` - -Host $hostname ` - -Space $spaceName ` - -Title $pageTitle ` - -Content $pageContent ` - -Ancestor $ancestorPageId - } - - catch - { - Write-Host "error (skipping): $prettyName" - - return - } - - - Register-PageMeta ` - -PageId $pageMeta.PageId ` - -Version $pageMeta.Version ` - -Title $pageTitle ` - -ContentHash $_ ` - -CacheIndexFile $cacheIndexFile - } - else - { - Write-Host ("update ${_} (${pageId}): $prettyName") - - $version = $pageMeta.Version + 1 - - try - { - Update-Page ` - -Host $hostname ` - -PageId $pageId ` - -Space $spaceName ` - -Title $pageTitle ` - -Version $version ` - -Content $pageContent ` - -Ancestor $ancestorPageId - } - - catch - { - Write-Host "error (skipping): $prettyName" - - return - } - - Register-PageMeta ` - -PageId $pageMeta.PageId ` - -Version $version ` - -Title $pageTitle ` - -ContentHash $_ ` - -CacheIndexFile $cacheIndexFile - } - } -} - - -function Publish-All -{ - <# - .SYNOPSIS - 1. cast index hash table to array - 2. (quick) sort the array - - .EXAMPLE - Get-Help -Name Test-Help - - This shows the help for the example function. - #> - Param( - [Parameter(Mandatory, Position = 0)] [string] $Url, - [Parameter(Mandatory, Position = 1)] [string] $Manifest - ) - - Begin - { - $hostname = ([uri]$url).Host - - $spaceName = (Split-Path -Leaf (Split-Path $Url)) - - $ancestorName = Split-Path -Leaf $url - - $data = Get-Content -Raw $Manifest | ConvertFrom-JSON -AsHashtable - - $basepath = Split-Path $Manifest - - $cacheIndexFile = 'confluence-page-cache.json' - } - - Process - { - $data.pages.keys | ForEach-Object ` - { - - } - } -}