fix(print): detect generic doc names (Печать документа) + integrate email collector into deploy

Print document naming:
- Add Test-IsGenericDocumentName() to detect placeholder names like
  'Печать документа', 'Print Document', 'Remote Downlevel Document', etc.
- Add Test-NeedsBetterDocumentName() that combines mojibake, generic and
  numeric-only checks into a single gate for PrintService event log fallback
- Replace Test-LooksLikeMojibakeQuestionMarks with Test-NeedsBetterDocumentName
  in Win32_PrintJob polling and Get-PrintServiceDocumentFallback

Email collector deployment integration:
- Ansible: add email-outbound-collector.ps1 to deploy_aw_windows.yml file list
- Ansible: add aw_windows_email_collector_enabled/mode vars
- InnoSetup: add email-outbound-collector.ps1 to [Files] section
- Common module: add EmailCollectorScript to Copy-ActivityWatchCollectorAssets,
  New-ActivityWatchDeploymentConfig, launch-watchers script
- Deploy scripts: pass EmailCollectorScript through pipeline
- Deployment configs: add emailCollectorScript path
- Sync all changes to install-kit copy

Co-Authored-By: Fashion Lisa <igor04091968@gmail.com>
This commit is contained in:
Devin AI
2026-05-04 18:07:14 +00:00
co-authored by Fashion Lisa
parent bfee99d679
commit a35a8a51bd
19 changed files with 383 additions and 52 deletions
@@ -1,4 +1,4 @@
[CmdletBinding()]
[CmdletBinding()]
param(
[string]$ConfigPath = 'C:\ProgramData\ActivityWatch\deployment-config.json',
[string]$ServerHost,
@@ -516,6 +516,35 @@ function Test-LooksLikeMojibakeQuestionMarks {
return $Value -match '\?{2,}'
}
function Test-IsGenericDocumentName {
param([AllowNull()][string]$Value)
if ([string]::IsNullOrWhiteSpace($Value)) { return $true }
$generic = @(
'^\s*Печать документа\s*$',
'^\s*Print Document\s*$',
'^\s*Document\s*$',
'^\s*Документ\s*$',
'^\s*Remote Downlevel Document\s*$',
'^\s*Local Downlevel Document\s*$',
'^\s*Untitled\s*$',
'^\s*Без имени\s*$',
'^\s*Без названия\s*$'
)
foreach ($pattern in $generic) {
if ($Value -match $pattern) { return $true }
}
return $false
}
function Test-NeedsBetterDocumentName {
param([AllowNull()][string]$Value)
if ([string]::IsNullOrWhiteSpace($Value)) { return $true }
if (Test-LooksLikeMojibakeQuestionMarks -Value $Value) { return $true }
if (Test-IsGenericDocumentName -Value $Value) { return $true }
if ($Value -match '^[0-9]+$') { return $true }
return $false
}
function Normalize-OwnerForMatch {
param([AllowNull()][string]$Value)
if ([string]::IsNullOrWhiteSpace($Value)) { return '' }
@@ -602,7 +631,7 @@ function Get-PrintServiceDocumentFallback {
)
$preferred = [string]$EventSummary.DocumentName
if (-not (Test-LooksLikeMojibakeQuestionMarks -Value $preferred) -and $preferred -notmatch '^[0-9]+$') {
if (-not (Test-NeedsBetterDocumentName -Value $preferred)) {
return $preferred
}
@@ -615,17 +644,13 @@ function Get-PrintServiceDocumentFallback {
if ($candidate -eq $preferred) { continue }
if ($Owner -and $candidate -like "*$Owner*") { continue }
if ($PrinterName -and $candidate -like "*$PrinterName*") { continue }
if (Test-LooksLikeMojibakeQuestionMarks -Value $candidate) { continue }
if (Test-NeedsBetterDocumentName -Value $candidate) { continue }
if ($candidate -match '[\\/:]' -and $candidate -match '\.[A-Za-z0-9]{1,8}$') {
$pathCandidates.Add($candidate)
continue
}
if ($candidate -match '^[0-9]+$') {
continue
}
$textCandidates.Add($candidate)
}
@@ -828,7 +853,7 @@ while ($true) {
$owner = [string]$job.Owner
$documentNameOriginal = $documentName
if (Test-LooksLikeMojibakeQuestionMarks -Value $documentName) {
if (Test-NeedsBetterDocumentName -Value $documentName) {
$eventDocumentName = Get-BetterDocumentNameFromPrintServiceEvents -Owner $owner -PrinterName $printerName
if ($eventDocumentName) {
$documentName = $eventDocumentName