|
- param(
- [Parameter(Mandatory = $true)][int]$TemplateId,
- [string]$ConfigPath = (Join-Path (Split-Path -Parent $PSScriptRoot) 'config.ini'),
- [string]$OutputRoot = (Join-Path (Split-Path -Parent $PSScriptRoot) 'temp\previews')
- )
-
- $ErrorActionPreference = 'Stop'
- . (Join-Path $PSScriptRoot 'template-common.ps1')
- if ($TemplateId -lt 1) { throw 'TemplateId must be positive' }
- $context = Get-MailContext -ConfigPath $ConfigPath
- $connection = Open-MailDatabase $context
- try {
- $command = $connection.CreateCommand()
- $command.CommandText = 'SELECT [HtmlContent],[ContentHash],[ValidationStatus] FROM [TemplateVersion] WHERE [Id]=?'
- $null = $command.Parameters.Add('id', [System.Data.OleDb.OleDbType]::Integer)
- $command.Parameters[0].Value = $TemplateId
- $reader = $command.ExecuteReader()
- try {
- if (-not $reader.Read()) { throw "Template ID $TemplateId was not found" }
- $html = [string]$reader.GetValue(0)
- $hash = [string]$reader.GetValue(1)
- if ([string]$reader.GetValue(2) -ne 'validated' -or
- (Get-HashHex ([System.Text.Encoding]::UTF8.GetBytes($html))) -ne $hash) {
- throw 'Template validation or content hash failed'
- }
- }
- finally { $reader.Close() }
- $document = [xml]$html
- Assert-TemplateNode $document.DocumentElement
- $previewPath = Join-Path $OutputRoot ([guid]::NewGuid().ToString('N'))
- $null = New-Item -ItemType Directory -Path $previewPath -Force
- $command = $connection.CreateCommand()
- $command.CommandText = 'SELECT [OriginalRelativePath],[ContentType],[ContentHash],[SnapshotBytes],[ContentId] FROM [TemplateImage] WHERE [TemplateVersionId]=? ORDER BY [Id]'
- $null = $command.Parameters.Add('id', [System.Data.OleDb.OleDbType]::Integer)
- $command.Parameters[0].Value = $TemplateId
- $reader = $command.ExecuteReader()
- try {
- $index = 0
- while ($reader.Read()) {
- $index++
- $bytes = [byte[]]$reader.GetValue(3)
- if ((Get-HashHex $bytes) -ne [string]$reader.GetValue(2)) { throw 'Stored image hash failed' }
- $type = [string]$reader.GetValue(1)
- $ext = switch ($type) { 'image/png' { 'png' } 'image/jpeg' { 'jpg' } 'image/gif' { 'gif' } default { throw 'Unsupported stored image type' } }
- $name = "image-$index.$ext"
- [System.IO.File]::WriteAllBytes((Join-Path $previewPath $name), $bytes)
- $cid = 'cid:' + [string]$reader.GetValue(4)
- $found = $false
- foreach ($node in $document.GetElementsByTagName('img')) {
- if ($node.GetAttribute('src') -eq $cid) { $node.SetAttribute('src', $name); $found = $true }
- }
- if (-not $found) { throw 'Stored image is not referenced by the template' }
- }
- }
- finally { $reader.Close() }
- foreach ($node in $document.GetElementsByTagName('img')) {
- if ($node.GetAttribute('src').StartsWith('cid:')) { throw 'Template image snapshot is missing' }
- }
- $file = Join-Path $previewPath 'preview.html'
- [System.IO.File]::WriteAllText($file, $document.OuterXml, (New-Object System.Text.UTF8Encoding($false)))
- Write-Output $file
- }
- finally { $connection.Dispose() }
|