Functions/GenXdev.AI/EnsureFaceRecognition.ps1
################################################################################ <# .SYNOPSIS Ensures Docker Desktop and Face Recognition service are installed and running. .DESCRIPTION This function sets up and manages a face recognition service using Docker. It ensures that Docker Desktop is installed, builds or uses an existing face recognition Docker image, and runs the service in a container. The service uses a specified directory to store face images for recognition. .PARAMETER PathToFaces The path to the directory where face images are stored. If not specified, defaults to "$env:USERPROFILE\Pictures\Faces". .PARAMETER Force If specified, forces rebuilding of Docker image and removing existing data. .EXAMPLE EnsureFaceRecognition .EXAMPLE EnsureFaceRecognition -PathToFaces "C:\MyFaces" -Force #> function EnsureFaceRecognition { [CmdletBinding()] param( ######################################################################## [Parameter( Position = 0, Mandatory = $false, HelpMessage = "Path to store face images for recognition" )] [string] $PathToFaces = $null, ######################################################################## [Parameter( Mandatory = $false, HelpMessage = "Force rebuild of Docker image and remove existing data" )] [switch] $Force ) begin { # set default path for faces if not provided if ([string]::IsNullOrWhiteSpace($PathToFaces)) { $PathToFaces = "$($env:USERPROFILE)\Pictures\Faces" }######################################################################## <# .SYNOPSIS Checks if the WinGet PowerShell module is installed. .DESCRIPTION Attempts to import the Microsoft.WinGet.Client module and verifies its presence. .EXAMPLE IsWinGetInstalled #> function IsWinGetInstalled { # attempt to load the winget module silently Microsoft.PowerShell.Core\Import-Module "Microsoft.WinGet.Client" ` -ErrorAction SilentlyContinue # verify if module was loaded successfully $module = Microsoft.PowerShell.Core\Get-Module "Microsoft.WinGet.Client" ` -ErrorAction SilentlyContinue return $null -ne $module } ######################################################################## <# .SYNOPSIS Installs the WinGet PowerShell module. .DESCRIPTION Installs and imports the Microsoft.WinGet.Client module for package management. .EXAMPLE InstallWinGet #> function InstallWinGet { # install and import winget module with force to ensure success Microsoft.PowerShell.Utility\Write-Verbose "Installing WinGet PowerShell client..." $null = PowerShellGet\Install-Module "Microsoft.WinGet.Client" ` -Force ` -AllowClobber # load the newly installed module Microsoft.PowerShell.Core\Import-Module "Microsoft.WinGet.Client" } } process { # store current path to restore it later $previousPath = (Microsoft.PowerShell.Management\Get-Location).Path # define path for face recognition module files $modulesPath = GenXdev.FileSystem\Expand-Path ` "$($env:APPDATA)\GenXdev\GenXdev.AI\Modules\FaceRecognition" GenXdev.AI\EnsureDockerDesktop # Check if Docker image exists $imageExists = docker images facerec_service --format "{{.Repository}}" 2>$null if ($Force -and $imageExists) { Microsoft.PowerShell.Utility\Write-Verbose "Removing existing Docker image due to -Force flag..." docker rmi facerec_service -f wsl --shutdown GenXdev.FileSystem\Remove-AllItems $PathToFaces $imageExists = $null } if (-not $imageExists) { # create modules directory if it doesn't exist $null = mkdir $modulesPath -ErrorAction SilentlyContinue Microsoft.PowerShell.Management\Push-Location $modulesPath try { GenXdev.AI\EnsureGithubCLIInstalled # check if repository already exists if ([System.IO.Directory]::Exists("$modulesPath\face_recognition")) { if ($Force) { Microsoft.PowerShell.Utility\Write-Verbose "Updating face recognition repository..." Microsoft.PowerShell.Management\Push-Location .\face_recognition try { git pull origin master } finally { Microsoft.PowerShell.Management\Pop-Location } } } else { Microsoft.PowerShell.Utility\Write-Verbose "Cloning face recognition repository..." git clone https://github.com/JanLoebel/face_recognition.git } Microsoft.PowerShell.Management\Set-Location .\face_recognition Microsoft.PowerShell.Utility\Write-Verbose "Building Docker image for face recognition service..." $buildResult = docker build -t facerec_service . 2>&1 # check if build was successful if ($LASTEXITCODE -ne 0) { Microsoft.PowerShell.Utility\Write-Error "Docker build failed with exit code $LASTEXITCODE" Microsoft.PowerShell.Utility\Write-Error ("Build output: $buildResult") throw "Failed to build facerec_service Docker image" } # verify image was created successfully $imageExists = docker images facerec_service --format "{{.Repository}}" 2>$null if (-not $imageExists) { throw "facerec_service image was not created successfully" } Microsoft.PowerShell.Utility\Write-Verbose "✅ Docker image 'facerec_service' built successfully" } catch { Microsoft.PowerShell.Utility\Write-Error "Error setting up face recognition: $_" throw } finally { Microsoft.PowerShell.Management\Pop-Location } } else { Microsoft.PowerShell.Management\Push-Location $modulesPath Microsoft.PowerShell.Management\Set-Location .\face_recognition } $PathToFaces = GenXdev.FileSystem\Expand-Path $PathToFaces -CreateDirectory # convert windows path to docker volume mount format $dockerPath = $PathToFaces if ($dockerPath -match '^[A-Za-z]:') { # convert C:\path\to\folder to /c/path/to/folder for Docker $driveLetter = $dockerPath[0].ToString().ToLower() $pathWithoutDrive = $dockerPath.Substring(2).Replace('\', '/') $dockerPath = "/$driveLetter$pathWithoutDrive" } # define container name for consistent reference $containerName = "facerec_service_container" # check if container exists (running or stopped) $existingContainer = docker ps -a --filter "name=^${containerName}$" ` --format "{{.ID}}" if ($existingContainer) { # check if container is running $runningContainer = docker ps --filter "name=^${containerName}$" ` --format "{{.ID}}" if ($runningContainer) { Microsoft.PowerShell.Utility\Write-Verbose "facerec_service container is already running." } else { # start existing container Microsoft.PowerShell.Utility\Write-Verbose "Starting existing face recognition container..." docker start $containerName Microsoft.PowerShell.Utility\Start-Sleep -Seconds 2 } } else { # create and start new container Microsoft.PowerShell.Utility\Write-Verbose "Creating and starting face recognition container..." docker run -d --name $containerName -p 8080:8080 ` -v "${dockerPath}:/root/faces" facerec_service Microsoft.PowerShell.Utility\Start-Sleep -Seconds 2 }# set api base url for service communication $script:ApiBaseUrl = "http://127.0.0.1:8080" Microsoft.PowerShell.Utility\Write-Verbose "Face recognition service should be ready at $script:ApiBaseUrl" # uncomment this block to enable service readiness check } end { # restore original location Microsoft.PowerShell.Management\Set-Location $previousPath } } ################################################################################ |