inkscape.isoCoucheGreyScale/deploy.ps1
2026-10-04 23:13:07 +02:00

203 lines
8.2 KiB
PowerShell

<#
.SYNOPSIS
Déploie l'extension « Iso-couches par nuances de gris » dans Inkscape.
.DESCRIPTION
Copie gray_iso_layers.inx, gray_iso_layers.py, gray_iso_layers_core.py, le schéma de l'onglet
« Help » (images\parameters_en.png), celui de l'onglet « Depth » (images\depth_en.png) et les traductions
compilées (locale\<langue>\LC_MESSAGES\grayisolayers.mo) dans un
sous-dossier dédié du répertoire des extensions utilisateur d'Inkscape
(Inkscape explore récursivement ce répertoire). Refuse de s'exécuter si
Inkscape est ouvert : les extensions ne sont chargées qu'au démarrage.
.PARAMETER ExtensionsDir
Répertoire des extensions Inkscape. Par défaut : %APPDATA%\inkscape\extensions
.PARAMETER FolderName
Nom du sous-dossier de l'extension. Par défaut : GrayIsoLayers
.PARAMETER Depth
Installe aussi de quoi calculer les cartes de profondeur, dans
%LOCALAPPDATA%\GrayIsoLayers : un environnement Python (onnxruntime-directml,
numpy, pillow) et les deux modèles (MiDaS small, Depth Anything V2 Small,
environ 165 Mo à télécharger). Le Python d'Inkscape ne peut pas charger
onnxruntime : il faut un Python 3 installé sur la machine.
.PARAMETER Python
Python qui crée l'environnement de -Depth. Par défaut : « python » du PATH,
sinon le lanceur « py ». À indiquer si le Python trouvé est trop récent
pour onnxruntime.
.PARAMETER Uninstall
Supprime le sous-dossier de l'extension au lieu de le créer, ainsi que
%LOCALAPPDATA%\GrayIsoLayers (environnement, modèles, cache).
.PARAMETER Force
Déploie même si Inkscape est en cours d'exécution.
.EXAMPLE
.\deploy.ps1
.\deploy.ps1 -Depth
.\deploy.ps1 -Uninstall
.\deploy.ps1 -FolderName 'autre-nom'
#>
[CmdletBinding()]
param(
[string] $ExtensionsDir = (Join-Path $env:APPDATA 'inkscape\extensions'),
[string] $FolderName = 'GrayIsoLayers',
[switch] $Depth,
[string] $Python,
[switch] $Uninstall,
[switch] $Force
)
$ErrorActionPreference = 'Stop'
$files = @('gray_iso_layers.inx', 'gray_iso_layers.py', 'gray_iso_layers_core.py',
'gray_iso_layers_depth.py', 'depth_estimate.py', 'images\parameters_en.png',
'images\depth_en.png')
$localeDir = 'locale'
$source = $PSScriptRoot
$destination = Join-Path $ExtensionsDir $FolderName
# Cartes de profondeur : environnement Python, modèles et cache, hors du
# dossier des extensions (Inkscape le parcourt en entier au démarrage).
# Mêmes noms que dans gray_iso_layers_depth.py.
$dataDir = Join-Path $env:LOCALAPPDATA 'GrayIsoLayers'
$packages = @('onnxruntime-directml', 'numpy', 'pillow')
$models = [ordered]@{
'midas_v21_small_256.onnx' = 'https://github.com/isl-org/MiDaS/releases/download/v2_1/model-small.onnx'
'depth_anything_v2_small.onnx' = 'https://huggingface.co/onnx-community/depth-anything-v2-small/resolve/main/onnx/model.onnx'
}
# --- Inkscape doit être fermé : les extensions sont lues au démarrage ---------
$running = Get-Process -Name 'inkscape' -ErrorAction SilentlyContinue
if ($running -and -not $Force) {
Write-Error "Inkscape est ouvert. Fermez-le puis relancez le script (ou utilisez -Force)."
exit 1
}
# --- Désinstallation ---------------------------------------------------------
if ($Uninstall) {
if (Test-Path -LiteralPath $destination) {
Remove-Item -LiteralPath $destination -Recurse -Force
Write-Host "Supprimé : $destination" -ForegroundColor Green
}
else {
Write-Host "Rien à supprimer : $destination n'existe pas." -ForegroundColor Yellow
}
if (Test-Path -LiteralPath $dataDir) {
Remove-Item -LiteralPath $dataDir -Recurse -Force
Write-Host "Supprimé : $dataDir" -ForegroundColor Green
}
exit 0
}
# --- Vérification des sources ------------------------------------------------
$missing = $files | Where-Object { -not (Test-Path -LiteralPath (Join-Path $source $_)) }
if (-not (Test-Path -LiteralPath (Join-Path $source $localeDir))) {
$missing = @($missing) + "$localeDir\ (lancer : python i18n.py)"
}
if ($missing) {
Write-Error "Fichier(s) introuvable(s) dans $source : $($missing -join ', ')"
exit 1
}
# --- Copie -------------------------------------------------------------------
if (-not (Test-Path -LiteralPath $destination)) {
New-Item -ItemType Directory -Path $destination -Force | Out-Null
Write-Host "Dossier créé : $destination"
}
foreach ($file in $files) {
$from = Join-Path $source $file
$to = Join-Path $destination $file
$action = if (Test-Path -LiteralPath $to) { 'remplacé' } else { 'copié ' }
New-Item -ItemType Directory -Path (Split-Path $to) -Force | Out-Null
Copy-Item -LiteralPath $from -Destination $to -Force
Write-Host " $action $file"
}
# Traductions : le dossier est remplacé en entier (langue retirée => supprimée)
$localeTo = Join-Path $destination $localeDir
if (Test-Path -LiteralPath $localeTo) {
Remove-Item -LiteralPath $localeTo -Recurse -Force
}
Copy-Item -LiteralPath (Join-Path $source $localeDir) -Destination $localeTo -Recurse
$languages = Get-ChildItem -LiteralPath $localeTo -Directory | ForEach-Object Name
Write-Host " copié $localeDir\ ($($languages -join ', '))"
# Le cache Python d'une version précédente peut masquer les fichiers copiés
$pycache = Join-Path $destination '__pycache__'
if (Test-Path -LiteralPath $pycache) {
Remove-Item -LiteralPath $pycache -Recurse -Force
}
# --- Cartes de profondeur ----------------------------------------------------
if ($Depth) {
Write-Host ""
Write-Host "Cartes de profondeur : $dataDir"
$venvPython = Join-Path $dataDir 'venv\Scripts\python.exe'
if (-not (Test-Path -LiteralPath $venvPython)) {
# « python » avant le lanceur « py » : ce dernier prend la version la
# plus récente, parfois une préversion pour laquelle onnxruntime
# n'est pas encore publié.
$command = @()
if ($Python) {
$command = @($Python)
}
elseif (Get-Command python -ErrorAction SilentlyContinue) {
$command = @((Get-Command python).Source)
}
elseif (Get-Command py -ErrorAction SilentlyContinue) {
$command = @((Get-Command py).Source, '-3')
}
if ($command.Count -eq 0) {
Write-Error "Aucun Python 3 trouvé (python ou py) : installez-le depuis python.org, ou indiquez-le avec -Python."
exit 1
}
$arguments = @($command | Select-Object -Skip 1) + @('-m', 'venv', (Join-Path $dataDir 'venv'))
& $command[0] $arguments
if ($LASTEXITCODE -ne 0 -or -not (Test-Path -LiteralPath $venvPython)) {
Write-Error "Création de l'environnement Python impossible avec $($command -join ' ')."
exit 1
}
Write-Host " créé venv\"
}
& $venvPython -m pip install --quiet --disable-pip-version-check --upgrade @packages
if ($LASTEXITCODE -ne 0) {
Write-Error "Installation de $($packages -join ', ') impossible."
exit 1
}
Write-Host " installé $($packages -join ', ')"
$modelsDir = Join-Path $dataDir 'models'
New-Item -ItemType Directory -Path $modelsDir -Force | Out-Null
foreach ($name in $models.Keys) {
$to = Join-Path $modelsDir $name
if (Test-Path -LiteralPath $to) {
Write-Host " présent models\$name"
continue
}
# Téléchargement dans un fichier provisoire : un modèle tronqué par une
# coupure ne passe pas pour un modèle installé.
$partial = "$to.part"
$previous = $ProgressPreference
$ProgressPreference = 'SilentlyContinue' # la barre ralentit beaucoup PowerShell 5.1
try {
Invoke-WebRequest -Uri $models[$name] -OutFile $partial -UseBasicParsing
}
finally {
$ProgressPreference = $previous
}
Move-Item -LiteralPath $partial -Destination $to -Force
$size = [math]::Round((Get-Item -LiteralPath $to).Length / 1MB)
Write-Host " téléchargé models\$name ($size Mo)"
}
}
Write-Host ""
Write-Host "Extension déployée dans $destination" -ForegroundColor Green
Write-Host "Redémarrez Inkscape, puis : Extensions > AlexDesign > Iso-couches par nuances de gris..."