backend
This commit is contained in:
parent
1fb8a56cf0
commit
0f271fa47a
@ -33,16 +33,52 @@ function generateFolderHash() {
|
|||||||
return crypto.randomBytes(16).toString('hex')
|
return crypto.randomBytes(16).toString('hex')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fonction pour obtenir le type MIME à partir de l'extension
|
||||||
|
function getMimeType(ext) {
|
||||||
|
const mimeTypes = {
|
||||||
|
'.pdf': 'application/pdf',
|
||||||
|
'.jpg': 'image/jpeg',
|
||||||
|
'.jpeg': 'image/jpeg',
|
||||||
|
'.png': 'image/png',
|
||||||
|
'.tiff': 'image/tiff'
|
||||||
|
}
|
||||||
|
return mimeTypes[ext.toLowerCase()] || 'application/octet-stream'
|
||||||
|
}
|
||||||
|
|
||||||
// Fonction pour créer la structure de dossiers
|
// Fonction pour créer la structure de dossiers
|
||||||
function createFolderStructure(folderHash) {
|
function createFolderStructure(folderHash) {
|
||||||
const folderPath = path.join('uploads', folderHash)
|
console.log(`[FOLDER] Création de la structure pour le hash: ${folderHash}`)
|
||||||
const cachePath = path.join('cache', folderHash)
|
console.log(`[FOLDER] Répertoire de travail: ${process.cwd()}`)
|
||||||
|
|
||||||
|
// Créer les dossiers racines s'ils n'existent pas
|
||||||
|
const uploadsDir = 'uploads'
|
||||||
|
const cacheDir = 'cache'
|
||||||
|
|
||||||
|
console.log(`[FOLDER] Vérification de l'existence de ${uploadsDir}: ${fs.existsSync(uploadsDir)}`)
|
||||||
|
console.log(`[FOLDER] Vérification de l'existence de ${cacheDir}: ${fs.existsSync(cacheDir)}`)
|
||||||
|
|
||||||
|
if (!fs.existsSync(uploadsDir)) {
|
||||||
|
fs.mkdirSync(uploadsDir, { recursive: true })
|
||||||
|
console.log(`[FOLDER] Dossier racine créé: ${uploadsDir}`)
|
||||||
|
}
|
||||||
|
if (!fs.existsSync(cacheDir)) {
|
||||||
|
fs.mkdirSync(cacheDir, { recursive: true })
|
||||||
|
console.log(`[FOLDER] Dossier racine créé: ${cacheDir}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const folderPath = path.join(uploadsDir, folderHash)
|
||||||
|
const cachePath = path.join(cacheDir, folderHash)
|
||||||
|
|
||||||
|
console.log(`[FOLDER] Chemin du dossier uploads: ${folderPath}`)
|
||||||
|
console.log(`[FOLDER] Chemin du dossier cache: ${cachePath}`)
|
||||||
|
|
||||||
if (!fs.existsSync(folderPath)) {
|
if (!fs.existsSync(folderPath)) {
|
||||||
fs.mkdirSync(folderPath, { recursive: true })
|
fs.mkdirSync(folderPath, { recursive: true })
|
||||||
|
console.log(`[FOLDER] Dossier uploads créé: ${folderPath}`)
|
||||||
}
|
}
|
||||||
if (!fs.existsSync(cachePath)) {
|
if (!fs.existsSync(cachePath)) {
|
||||||
fs.mkdirSync(cachePath, { recursive: true })
|
fs.mkdirSync(cachePath, { recursive: true })
|
||||||
|
console.log(`[FOLDER] Dossier cache créé: ${cachePath}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
return { folderPath, cachePath }
|
return { folderPath, cachePath }
|
||||||
@ -52,7 +88,7 @@ function createFolderStructure(folderHash) {
|
|||||||
function saveJsonCacheInFolder(folderHash, fileHash, result) {
|
function saveJsonCacheInFolder(folderHash, fileHash, result) {
|
||||||
const { cachePath } = createFolderStructure(folderHash)
|
const { cachePath } = createFolderStructure(folderHash)
|
||||||
const cacheFile = path.join(cachePath, `${fileHash}.json`)
|
const cacheFile = path.join(cachePath, `${fileHash}.json`)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
fs.writeFileSync(cacheFile, JSON.stringify(result, null, 2))
|
fs.writeFileSync(cacheFile, JSON.stringify(result, null, 2))
|
||||||
console.log(`[CACHE] Résultat sauvegardé dans le dossier ${folderHash}: ${fileHash}`)
|
console.log(`[CACHE] Résultat sauvegardé dans le dossier ${folderHash}: ${fileHash}`)
|
||||||
@ -67,7 +103,7 @@ function saveJsonCacheInFolder(folderHash, fileHash, result) {
|
|||||||
function getJsonCacheFromFolder(folderHash, fileHash) {
|
function getJsonCacheFromFolder(folderHash, fileHash) {
|
||||||
const cachePath = path.join('cache', folderHash)
|
const cachePath = path.join('cache', folderHash)
|
||||||
const cacheFile = path.join(cachePath, `${fileHash}.json`)
|
const cacheFile = path.join(cachePath, `${fileHash}.json`)
|
||||||
|
|
||||||
if (fs.existsSync(cacheFile)) {
|
if (fs.existsSync(cacheFile)) {
|
||||||
try {
|
try {
|
||||||
const data = fs.readFileSync(cacheFile, 'utf8')
|
const data = fs.readFileSync(cacheFile, 'utf8')
|
||||||
@ -88,10 +124,10 @@ function listFolderResults(folderHash) {
|
|||||||
if (!fs.existsSync(cachePath)) {
|
if (!fs.existsSync(cachePath)) {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
const files = fs.readdirSync(cachePath)
|
const files = fs.readdirSync(cachePath)
|
||||||
const results = []
|
const results = []
|
||||||
|
|
||||||
for (const file of files) {
|
for (const file of files) {
|
||||||
if (file.endsWith('.json')) {
|
if (file.endsWith('.json')) {
|
||||||
const fileHash = path.basename(file, '.json')
|
const fileHash = path.basename(file, '.json')
|
||||||
@ -104,7 +140,7 @@ function listFolderResults(folderHash) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return results
|
return results
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1075,8 +1111,12 @@ app.delete('/api/cache/:hash', (req, res) => {
|
|||||||
// Route pour créer un nouveau dossier
|
// Route pour créer un nouveau dossier
|
||||||
app.post('/api/folders', (req, res) => {
|
app.post('/api/folders', (req, res) => {
|
||||||
try {
|
try {
|
||||||
|
console.log('[FOLDER] Début de la création d\'un nouveau dossier')
|
||||||
const folderHash = generateFolderHash()
|
const folderHash = generateFolderHash()
|
||||||
createFolderStructure(folderHash)
|
console.log(`[FOLDER] Hash généré: ${folderHash}`)
|
||||||
|
|
||||||
|
const result = createFolderStructure(folderHash)
|
||||||
|
console.log(`[FOLDER] Structure créée:`, result)
|
||||||
|
|
||||||
console.log(`[FOLDER] Nouveau dossier créé: ${folderHash}`)
|
console.log(`[FOLDER] Nouveau dossier créé: ${folderHash}`)
|
||||||
|
|
||||||
@ -1099,9 +1139,9 @@ app.get('/api/folders/:folderHash/results', (req, res) => {
|
|||||||
try {
|
try {
|
||||||
const { folderHash } = req.params
|
const { folderHash } = req.params
|
||||||
const results = listFolderResults(folderHash)
|
const results = listFolderResults(folderHash)
|
||||||
|
|
||||||
console.log(`[FOLDER] Résultats récupérés pour le dossier ${folderHash}: ${results.length} fichiers`)
|
console.log(`[FOLDER] Résultats récupérés pour le dossier ${folderHash}: ${results.length} fichiers`)
|
||||||
|
|
||||||
res.json({
|
res.json({
|
||||||
success: true,
|
success: true,
|
||||||
folderHash,
|
folderHash,
|
||||||
@ -1122,18 +1162,18 @@ app.get('/api/folders/:folderHash/files/:fileHash', (req, res) => {
|
|||||||
try {
|
try {
|
||||||
const { folderHash, fileHash } = req.params
|
const { folderHash, fileHash } = req.params
|
||||||
const folderPath = path.join('uploads', folderHash)
|
const folderPath = path.join('uploads', folderHash)
|
||||||
|
|
||||||
if (!fs.existsSync(folderPath)) {
|
if (!fs.existsSync(folderPath)) {
|
||||||
return res.status(404).json({ success: false, error: 'Dossier non trouvé' })
|
return res.status(404).json({ success: false, error: 'Dossier non trouvé' })
|
||||||
}
|
}
|
||||||
|
|
||||||
const files = fs.readdirSync(folderPath)
|
const files = fs.readdirSync(folderPath)
|
||||||
const targetFile = files.find(file => file.startsWith(fileHash))
|
const targetFile = files.find(file => file.startsWith(fileHash))
|
||||||
|
|
||||||
if (!targetFile) {
|
if (!targetFile) {
|
||||||
return res.status(404).json({ success: false, error: 'Fichier non trouvé' })
|
return res.status(404).json({ success: false, error: 'Fichier non trouvé' })
|
||||||
}
|
}
|
||||||
|
|
||||||
const filePath = path.join(folderPath, targetFile)
|
const filePath = path.join(folderPath, targetFile)
|
||||||
res.sendFile(path.resolve(filePath))
|
res.sendFile(path.resolve(filePath))
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -1150,17 +1190,17 @@ app.post('/api/folders/default', async (req, res) => {
|
|||||||
try {
|
try {
|
||||||
const folderHash = generateFolderHash()
|
const folderHash = generateFolderHash()
|
||||||
const { folderPath, cachePath } = createFolderStructure(folderHash)
|
const { folderPath, cachePath } = createFolderStructure(folderHash)
|
||||||
|
|
||||||
console.log(`[FOLDER] Création du dossier par défaut: ${folderHash}`)
|
console.log(`[FOLDER] Création du dossier par défaut: ${folderHash}`)
|
||||||
|
|
||||||
// Charger les fichiers de test dans le dossier
|
// Charger les fichiers de test dans le dossier
|
||||||
const testFilesDir = path.join(__dirname, '..', 'test-files')
|
const testFilesDir = path.join(__dirname, '..', 'test-files')
|
||||||
if (fs.existsSync(testFilesDir)) {
|
if (fs.existsSync(testFilesDir)) {
|
||||||
const testFiles = fs.readdirSync(testFilesDir)
|
const testFiles = fs.readdirSync(testFilesDir)
|
||||||
const supportedFiles = testFiles.filter(file =>
|
const supportedFiles = testFiles.filter(file =>
|
||||||
['.pdf', '.jpg', '.jpeg', '.png', '.tiff'].includes(path.extname(file).toLowerCase())
|
['.pdf', '.jpg', '.jpeg', '.png', '.tiff'].includes(path.extname(file).toLowerCase())
|
||||||
)
|
)
|
||||||
|
|
||||||
for (const testFile of supportedFiles) {
|
for (const testFile of supportedFiles) {
|
||||||
const sourcePath = path.join(testFilesDir, testFile)
|
const sourcePath = path.join(testFilesDir, testFile)
|
||||||
const fileBuffer = fs.readFileSync(sourcePath)
|
const fileBuffer = fs.readFileSync(sourcePath)
|
||||||
@ -1168,21 +1208,48 @@ app.post('/api/folders/default', async (req, res) => {
|
|||||||
const ext = path.extname(testFile)
|
const ext = path.extname(testFile)
|
||||||
const newFileName = `${fileHash}${ext}`
|
const newFileName = `${fileHash}${ext}`
|
||||||
const destPath = path.join(folderPath, newFileName)
|
const destPath = path.join(folderPath, newFileName)
|
||||||
|
|
||||||
// Copier le fichier
|
// Copier le fichier
|
||||||
fs.copyFileSync(sourcePath, destPath)
|
fs.copyFileSync(sourcePath, destPath)
|
||||||
|
|
||||||
// Traiter le fichier et sauvegarder le résultat
|
// Traiter le fichier et sauvegarder le résultat
|
||||||
try {
|
try {
|
||||||
const result = await processDocument(fileBuffer, newFileName, testFile)
|
console.log(`[FOLDER] Traitement de ${testFile}...`)
|
||||||
saveJsonCacheInFolder(folderHash, fileHash, result)
|
|
||||||
console.log(`[FOLDER] Fichier de test traité: ${testFile} -> ${fileHash}`)
|
// Simuler un objet req.file pour la logique existante
|
||||||
|
const mockFile = {
|
||||||
|
path: destPath,
|
||||||
|
originalname: testFile,
|
||||||
|
mimetype: getMimeType(ext)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extraction de texte selon le type de fichier
|
||||||
|
let ocrResult = null
|
||||||
|
if (ext.toLowerCase() === '.pdf') {
|
||||||
|
ocrResult = await extractTextFromPdf(destPath)
|
||||||
|
} else if (['.jpg', '.jpeg', '.png', '.tiff'].includes(ext.toLowerCase())) {
|
||||||
|
ocrResult = await extractTextFromImage(destPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ocrResult && ocrResult.text) {
|
||||||
|
// Extraction des entités
|
||||||
|
const entities = extractEntitiesFromText(ocrResult.text)
|
||||||
|
|
||||||
|
// Génération du résultat au format standard
|
||||||
|
const result = generateStandardJSON(mockFile, ocrResult, entities, 0)
|
||||||
|
|
||||||
|
// Sauvegarde dans le cache du dossier
|
||||||
|
saveJsonCacheInFolder(folderHash, fileHash, result)
|
||||||
|
console.log(`[FOLDER] Fichier de test traité: ${testFile} -> ${fileHash}`)
|
||||||
|
} else {
|
||||||
|
console.warn(`[FOLDER] Aucun texte extrait de ${testFile}`)
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn(`[FOLDER] Erreur lors du traitement de ${testFile}:`, error.message)
|
console.warn(`[FOLDER] Erreur lors du traitement de ${testFile}:`, error.message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
res.json({
|
res.json({
|
||||||
success: true,
|
success: true,
|
||||||
folderHash,
|
folderHash,
|
||||||
@ -1211,6 +1278,7 @@ app.listen(PORT, () => {
|
|||||||
console.log(`📡 API disponible sur: http://localhost:${PORT}/api`)
|
console.log(`📡 API disponible sur: http://localhost:${PORT}/api`)
|
||||||
console.log(`🏥 Health check: http://localhost:${PORT}/api/health`)
|
console.log(`🏥 Health check: http://localhost:${PORT}/api/health`)
|
||||||
console.log(`📁 Test files: http://localhost:${PORT}/api/test-files`)
|
console.log(`📁 Test files: http://localhost:${PORT}/api/test-files`)
|
||||||
|
console.log(`📂 Répertoire de travail: ${process.cwd()}`)
|
||||||
})
|
})
|
||||||
|
|
||||||
module.exports = app
|
module.exports = app
|
||||||
|
|||||||
@ -38,7 +38,7 @@ import { Layout } from '../components/Layout'
|
|||||||
export default function ExtractionView() {
|
export default function ExtractionView() {
|
||||||
const dispatch = useAppDispatch()
|
const dispatch = useAppDispatch()
|
||||||
const { folderResults, currentResultIndex } = useAppSelector((state) => state.document)
|
const { folderResults, currentResultIndex } = useAppSelector((state) => state.document)
|
||||||
|
|
||||||
const [currentIndex, setCurrentIndex] = useState(currentResultIndex)
|
const [currentIndex, setCurrentIndex] = useState(currentResultIndex)
|
||||||
|
|
||||||
// Utiliser les résultats du dossier pour la navigation
|
// Utiliser les résultats du dossier pour la navigation
|
||||||
@ -94,23 +94,23 @@ export default function ExtractionView() {
|
|||||||
<Typography variant="h4" gutterBottom>
|
<Typography variant="h4" gutterBottom>
|
||||||
Résultats d'extraction
|
Résultats d'extraction
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|
||||||
{/* Navigation */}
|
{/* Navigation */}
|
||||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 2, mb: 3 }}>
|
<Box sx={{ display: 'flex', alignItems: 'center', gap: 2, mb: 3 }}>
|
||||||
<IconButton
|
<IconButton
|
||||||
onClick={goToPrevious}
|
onClick={goToPrevious}
|
||||||
disabled={!hasPrev}
|
disabled={!hasPrev}
|
||||||
color="primary"
|
color="primary"
|
||||||
>
|
>
|
||||||
<NavigateBefore />
|
<NavigateBefore />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
|
|
||||||
<Typography variant="body1" sx={{ flexGrow: 1, textAlign: 'center' }}>
|
<Typography variant="body1" sx={{ flexGrow: 1, textAlign: 'center' }}>
|
||||||
Document {currentIndex + 1} sur {folderResults.length}
|
Document {currentIndex + 1} sur {folderResults.length}
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|
||||||
<IconButton
|
<IconButton
|
||||||
onClick={goToNext}
|
onClick={goToNext}
|
||||||
disabled={!hasNext}
|
disabled={!hasNext}
|
||||||
color="primary"
|
color="primary"
|
||||||
>
|
>
|
||||||
@ -141,18 +141,18 @@ export default function ExtractionView() {
|
|||||||
<Typography variant="h6">
|
<Typography variant="h6">
|
||||||
{extraction.document.fileName}
|
{extraction.document.fileName}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Chip
|
<Chip
|
||||||
label={extraction.document.mimeType}
|
label={extraction.document.mimeType}
|
||||||
size="small"
|
size="small"
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
/>
|
/>
|
||||||
<Chip
|
<Chip
|
||||||
label={`${(extraction.document.fileSize / 1024 / 1024).toFixed(2)} MB`}
|
label={`${(extraction.document.fileSize / 1024 / 1024).toFixed(2)} MB`}
|
||||||
size="small"
|
size="small"
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<Box sx={{ display: 'flex', gap: 1, flexWrap: 'wrap' }}>
|
<Box sx={{ display: 'flex', gap: 1, flexWrap: 'wrap' }}>
|
||||||
<Chip
|
<Chip
|
||||||
icon={<Language />}
|
icon={<Language />}
|
||||||
|
|||||||
59
test-folders.js
Normal file
59
test-folders.js
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
const crypto = require('crypto');
|
||||||
|
|
||||||
|
// Fonction pour générer un hash de dossier
|
||||||
|
function generateFolderHash() {
|
||||||
|
return crypto.randomBytes(16).toString('hex');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fonction pour créer la structure de dossiers
|
||||||
|
function createFolderStructure(folderHash) {
|
||||||
|
console.log(`[FOLDER] Création de la structure pour le hash: ${folderHash}`);
|
||||||
|
console.log(`[FOLDER] Répertoire de travail: ${process.cwd()}`);
|
||||||
|
|
||||||
|
// Créer les dossiers racines s'ils n'existent pas
|
||||||
|
const uploadsDir = 'uploads';
|
||||||
|
const cacheDir = 'cache';
|
||||||
|
|
||||||
|
console.log(`[FOLDER] Vérification de l'existence de ${uploadsDir}: ${fs.existsSync(uploadsDir)}`);
|
||||||
|
console.log(`[FOLDER] Vérification de l'existence de ${cacheDir}: ${fs.existsSync(cacheDir)}`);
|
||||||
|
|
||||||
|
if (!fs.existsSync(uploadsDir)) {
|
||||||
|
fs.mkdirSync(uploadsDir, { recursive: true });
|
||||||
|
console.log(`[FOLDER] Dossier racine créé: ${uploadsDir}`);
|
||||||
|
}
|
||||||
|
if (!fs.existsSync(cacheDir)) {
|
||||||
|
fs.mkdirSync(cacheDir, { recursive: true });
|
||||||
|
console.log(`[FOLDER] Dossier racine créé: ${cacheDir}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const folderPath = path.join(uploadsDir, folderHash);
|
||||||
|
const cachePath = path.join(cacheDir, folderHash);
|
||||||
|
|
||||||
|
console.log(`[FOLDER] Chemin du dossier uploads: ${folderPath}`);
|
||||||
|
console.log(`[FOLDER] Chemin du dossier cache: ${cachePath}`);
|
||||||
|
|
||||||
|
if (!fs.existsSync(folderPath)) {
|
||||||
|
fs.mkdirSync(folderPath, { recursive: true });
|
||||||
|
console.log(`[FOLDER] Dossier uploads créé: ${folderPath}`);
|
||||||
|
}
|
||||||
|
if (!fs.existsSync(cachePath)) {
|
||||||
|
fs.mkdirSync(cachePath, { recursive: true });
|
||||||
|
console.log(`[FOLDER] Dossier cache créé: ${cachePath}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return { folderPath, cachePath };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test
|
||||||
|
console.log('=== Test de création de dossier ===');
|
||||||
|
const folderHash = generateFolderHash();
|
||||||
|
console.log(`Hash généré: ${folderHash}`);
|
||||||
|
|
||||||
|
const result = createFolderStructure(folderHash);
|
||||||
|
console.log('Résultat:', result);
|
||||||
|
|
||||||
|
console.log('\n=== Vérification des dossiers créés ===');
|
||||||
|
console.log('Dossiers uploads:', fs.readdirSync('uploads'));
|
||||||
|
console.log('Dossiers cache:', fs.readdirSync('cache'));
|
||||||
Loading…
x
Reference in New Issue
Block a user