Ajout du binaire tesseract pour la reconnaissance OCR des PDF pour l'installation local

Correction d'un problème d'écrasement de BDD à la réinstallation
This commit is contained in:
2026-06-18 10:28:31 +02:00
parent f04ecf1021
commit 3cdfc5256b
8 changed files with 68 additions and 6 deletions

View File

@@ -70,6 +70,13 @@ jobs:
shell: pwsh shell: pwsh
run: choco install wixtoolset -y --no-progress run: choco install wixtoolset -y --no-progress
# Tesseract OCR : non preinstalle sur windows-latest. Requis pour que
# build-windows.ps1 embarque l'OCR des PDF scannes (sinon il skip en
# degradation gracieuse). Installe dans %ProgramFiles%\Tesseract-OCR.
- name: Install Tesseract OCR
shell: pwsh
run: choco install tesseract -y --no-progress
# Version de l'installeur = version du tag (push) OU de l'input (manuel). # Version de l'installeur = version du tag (push) OU de l'input (manuel).
# Sorties : version (numerique X.Y.Z pour le MSI), tag (vX.Y.Z[-beta]), # Sorties : version (numerique X.Y.Z pour le MSI), tag (vX.Y.Z[-beta]),
# isbeta (true/false) — independant du nom de ref (qui est une branche en manuel). # isbeta (true/false) — independant du nom de ref (qui est une branche en manuel).

View File

@@ -26,7 +26,7 @@ from app.infrastructure.ollama_model_installer import ensure_ollama_embedding_mo
app = FastAPI( app = FastAPI(
title="LoreMind Brain", title="LoreMind Brain",
description="Backend IA pour la génération de contenu narratif.", description="Backend IA pour la génération de contenu narratif.",
version="0.16.0", version="0.16.1",
) )
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)

View File

@@ -16,7 +16,21 @@ ailleurs, sous ~/.loremind/brain, pour y ecrire le dossier data/).
import os import os
import sys import sys
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) _HERE = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, _HERE)
# OCR : si un Tesseract est bundlé à côté (mode desktop), on y pointe pytesseract
# AVANT que l'app n'importe le pdf_extractor (qui détecte la version au chargement).
# tessdata (fra+eng) est embarqué dans tesseract/tessdata. Sans ce bloc, l'OCR
# reste désactivé en dégradation gracieuse (PDF born-digital OK, scans signalés).
_TESS = os.path.join(_HERE, "tesseract", "tesseract.exe")
if os.path.exists(_TESS):
os.environ.setdefault("TESSDATA_PREFIX", os.path.join(_HERE, "tesseract"))
try:
import pytesseract
pytesseract.pytesseract.tesseract_cmd = _TESS
except ImportError:
pass
import uvicorn # noqa: E402 import uvicorn # noqa: E402

View File

@@ -14,7 +14,7 @@
<groupId>com.loremind</groupId> <groupId>com.loremind</groupId>
<artifactId>loremind-core</artifactId> <artifactId>loremind-core</artifactId>
<version>0.16.0</version> <version>0.16.1</version>
<name>LoreMind Core</name> <name>LoreMind Core</name>
<description>Backend Core - Architecture Hexagonale</description> <description>Backend Core - Architecture Hexagonale</description>

View File

@@ -137,6 +137,27 @@ if (-not $SkipBrain) {
Copy-Item (Join-Path $BrainDir 'app') (Join-Path $BrainEmbed 'app') -Recurse Copy-Item (Join-Path $BrainDir 'app') (Join-Path $BrainEmbed 'app') -Recurse
Copy-Item (Join-Path $BrainDir 'run_local.py') (Join-Path $BrainEmbed 'run_local.py') Copy-Item (Join-Path $BrainDir 'run_local.py') (Join-Path $BrainEmbed 'run_local.py')
# e) Tesseract (OCR des PDF scannes). Pas de zip portable officiel : on COPIE
# l'install UB-Mannheim (tesseract.exe + DLL), prerequis a installer une
# fois via `choco install tesseract`. Langues fra+eng tirees de tessdata_fast
# (leger, coherent). Si Tesseract n'est pas installe -> skip gracieux :
# l'app reste fonctionnelle, seul l'OCR des scans manquera (cf. run_local.py
# + pdf_extractor.py qui detectent l'absence et degradent proprement).
$tessSrc = Join-Path $env:ProgramFiles 'Tesseract-OCR'
if (Test-Path (Join-Path $tessSrc 'tesseract.exe')) {
$tessDst = Join-Path $BrainEmbed 'tesseract'
Copy-Item $tessSrc $tessDst -Recurse
New-Item -ItemType Directory -Force -Path (Join-Path $tessDst 'tessdata') | Out-Null
foreach ($lang in @('fra','eng')) {
Invoke-WebRequest -UseBasicParsing `
-Uri "https://github.com/tesseract-ocr/tessdata_fast/raw/main/$lang.traineddata" `
-OutFile (Join-Path $tessDst "tessdata\$lang.traineddata")
}
Write-Ok "Tesseract bundle (OCR des scans actif)"
} else {
Write-Host " !! Tesseract introuvable ($tessSrc) -> OCR des scans NON bundle (degradation gracieuse). Pour l'activer : choco install tesseract" -ForegroundColor Yellow
}
Write-Ok "Brain prepare (brain/dist-embed : python embeddable + deps + sources)" Write-Ok "Brain prepare (brain/dist-embed : python embeddable + deps + sources)"
} else { Write-Step "Brain : saute (--SkipBrain)" } } else { Write-Step "Brain : saute (--SkipBrain)" }
@@ -183,6 +204,13 @@ New-Item -ItemType Directory -Force -Path $OutDir | Out-Null
# ne contient de virgule) sont bindes en List<String> par Spring. # ne contient de virgule) sont bindes en List<String> par Spring.
$brainCmd = '$APPDIR\brain\python\python.exe,$APPDIR\brain\run_local.py' $brainCmd = '$APPDIR\brain\python\python.exe,$APPDIR\brain\run_local.py'
# --win-upgrade-uuid : UUID STABLE du produit. Permet a Windows Installer de
# reconnaitre qu'une nouvelle version est une MISE A JOUR du meme produit -> upgrade
# en place propre (pas besoin de desinstaller avant, pas de doublon). Les donnees
# (base H2, images) vivent de toute facon dans ~/.loremind, HORS du dossier
# d'installation, donc jamais touchees par l'installeur.
# /!\ NE JAMAIS CHANGER cet UUID : le modifier casserait la chaine d'upgrade.
#
# Note : pas de --win-console (app de bureau). Les logs Spring/Brain peuvent # Note : pas de --win-console (app de bureau). Les logs Spring/Brain peuvent
# etre rediriges vers un fichier via une option ulterieure si besoin de debug. # etre rediriges vers un fichier via une option ulterieure si besoin de debug.
jpackage ` jpackage `
@@ -197,6 +225,7 @@ jpackage `
--java-options '-Dspring.profiles.active=local' ` --java-options '-Dspring.profiles.active=local' `
--java-options "-Dbrain.sidecar.command=$brainCmd" ` --java-options "-Dbrain.sidecar.command=$brainCmd" `
--win-per-user-install ` --win-per-user-install `
--win-upgrade-uuid 'a7c4e1d2-9b3f-4e6a-8d05-1f2c3b4a5e6d' `
--win-menu --win-menu-group 'LoreMind' ` --win-menu --win-menu-group 'LoreMind' `
--win-shortcut --win-dir-chooser --win-shortcut --win-dir-chooser

View File

@@ -34,6 +34,18 @@ server {
try_files $uri =404; try_files $uri =404;
} }
# Fichiers de traduction (assets/i18n/*.json) : nom STABLE (non hashe),
# donc JAMAIS caches — sinon le navigateur ressert un vieux fr.json apres une
# mise a jour et affiche des cles brutes (ex : settings.data.* en clair).
# Aligne sur le mode desktop (LocalWebConfig sert deja l'i18n en no-cache).
# ^~ : ce prefixe l'emporte sur la regex d'assets ci-dessous.
location ^~ /assets/i18n/ {
add_header Cache-Control "no-cache, no-store, must-revalidate" always;
add_header Pragma "no-cache" always;
expires 0;
try_files $uri =404;
}
# Assets Angular avec hash dans le nom (main.<hash>.js, etc.) : # Assets Angular avec hash dans le nom (main.<hash>.js, etc.) :
# immuables, peuvent etre caches longtemps. # immuables, peuvent etre caches longtemps.
location ~* \.(?:js|css|woff2?|ttf|svg|png|jpg|jpeg|webp|ico)$ { location ~* \.(?:js|css|woff2?|ttf|svg|png|jpg|jpeg|webp|ico)$ {

4
web/package-lock.json generated
View File

@@ -1,12 +1,12 @@
{ {
"name": "loremind-web", "name": "loremind-web",
"version": "0.16.0", "version": "0.16.1",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "loremind-web", "name": "loremind-web",
"version": "0.16.0", "version": "0.16.1",
"dependencies": { "dependencies": {
"@angular/animations": "^21.2.16", "@angular/animations": "^21.2.16",
"@angular/common": "^21.2.16", "@angular/common": "^21.2.16",

View File

@@ -1,6 +1,6 @@
{ {
"name": "loremind-web", "name": "loremind-web",
"version": "0.16.0", "version": "0.16.1",
"description": "LoreMind Frontend - Angular", "description": "LoreMind Frontend - Angular",
"scripts": { "scripts": {
"ng": "ng", "ng": "ng",