# Nouvelle fonctionnalité : Import de fichiers .md ## Résumé Un nouveau bouton "Importer .md" a été ajouté au module Périphériques pour permettre l'import automatique de spécifications de périphériques depuis des fichiers Markdown. ## Fichiers créés/modifiés ### Backend **Nouveau :** - `backend/app/utils/md_parser.py` - Parser markdown (300+ lignes) **Modifié :** - `backend/app/api/endpoints/peripherals.py` - Ajout endpoint `/api/peripherals/import/markdown` ### Frontend **Modifié :** - `frontend/peripherals.html` - Nouveau bouton + modal import .md - `frontend/js/peripherals.js` - Fonctions `showImportMDModal()` et `importMarkdown()` - `frontend/css/peripherals.css` - Styles pour la preview de fichier ### Documentation **Créé :** - `docs/IMPORT_MARKDOWN.md` - Guide complet d'utilisation **Modifié :** - `MODULE_PERIPHERIQUES_RESUME.md` - Ajout de la fonctionnalité - `CHANGELOG.md` - Mise à jour avec import .md ## Utilisation rapide ### 1. Interface web ``` 1. Ouvrir http://localhost:8087/peripherals.html 2. Cliquer sur "Importer .md" 3. Sélectionner un fichier .md (ex: fichier_usb/ID_0781_55ab.md) 4. Cliquer sur "Importer" 5. Le formulaire se pré-remplit automatiquement 6. Compléter et enregistrer ``` ### 2. API directe ```bash curl -X POST http://localhost:8007/api/peripherals/import/markdown \ -F "file=@fichier_usb/ID_0781_55ab.md" ``` ## Formats supportés ### Format simple (minimal) ```markdown # USB Device ID 0b05_17cb ## Description Broadcom BCM20702A0 – Bluetooth USB (ASUS) ``` **Extraction automatique :** - Vendor ID et Product ID depuis le titre/nom de fichier - Nom du périphérique depuis la description - Type déduit (Bluetooth) - Marque extraite (ASUS) ### Format détaillé (complet) ```markdown # USB Device Specification — ID 0781:55ab ## Identification - **Vendor ID**: 0x0781 (SanDisk Corp.) - **Product ID**: 0x55ab - **Commercial name**: SanDisk 3.2 Gen1 USB Flash Drive - **Serial number**: 040123d4... ## USB Characteristics - **USB version**: USB 3.2 Gen 1 - **Negotiated speed**: 5 Gb/s - **Max power draw**: 896 mA ## Device Class - **Interface class**: 08 — Mass Storage - **Subclass**: 06 — SCSI transparent command set ## Classification Summary **Category**: USB Mass Storage Device **Subcategory**: USB 3.x Flash Drive ``` **Extraction complète :** - Tous les champs du format simple - Numéro de série - Caractéristiques USB (version, vitesse, alimentation) - Classe USB et protocole - Catégorie fonctionnelle - Notes sur rôle, performance, etc. ## Tests ### Fichiers de test disponibles Dans le dossier `fichier_usb/` : ```bash # Format simple fichier_usb/ID_0b05_17cb.md # Bluetooth ASUS fichier_usb/ID_046d_c52b.md # Logitech Unifying fichier_usb/ID_148f_7601.md # Adaptateur WiFi # Format détaillé fichier_usb/id_0781_55_ab.md # SanDisk USB 3.2 (2079 lignes) ``` ### Test rapide **Via interface :** ```bash # 1. Démarrer l'application docker compose up -d # 2. Ouvrir navigateur http://localhost:8087/peripherals.html # 3. Tester import - Cliquer "Importer .md" - Sélectionner fichier_usb/ID_0b05_17cb.md - Vérifier pré-remplissage du formulaire ``` **Via API :** ```bash # Test import simple curl -X POST http://localhost:8007/api/peripherals/import/markdown \ -F "file=@fichier_usb/ID_0b05_17cb.md" | jq # Test import détaillé curl -X POST http://localhost:8007/api/peripherals/import/markdown \ -F "file=@fichier_usb/id_0781_55_ab.md" | jq ``` ## Détection automatique Le parser détecte automatiquement : | Dans la description | Type assigné | Sous-type | |---------------------|--------------|-----------| | souris, mouse | USB | Souris | | clavier, keyboard | USB | Clavier | | wifi, wireless | WiFi | Adaptateur WiFi | | bluetooth | Bluetooth | Adaptateur Bluetooth | | usb flash, clé usb | USB | Clé USB | | dongle | USB | Dongle | **Marques détectées :** Logitech, SanDisk, Ralink, Broadcom, ASUS, Realtek, TP-Link, Intel, Samsung, Kingston, Corsair ## Données extraites ### Champs de base - `nom` - Nom commercial ou description - `type_principal` - Type (USB, Bluetooth, WiFi...) - `sous_type` - Sous-type (Souris, Clavier, Clé USB...) - `marque` - Marque du fabricant - `modele` - Modèle - `numero_serie` - Numéro de série - `description` - Description complète - `notes` - Notes techniques et recommandations ### Caractéristiques spécifiques (JSON) Stockées dans `caracteristiques_specifiques` : ```json { "vendor_id": "0x0781", "product_id": "0x55ab", "usb_version": "USB 3.2 Gen 1", "usb_speed": "5 Gb/s", "bcdUSB": "3.20", "max_power": "896 mA", "interface_class": "08", "interface_class_name": "Mass Storage", "category": "USB Mass Storage Device", "subcategory": "USB 3.x Flash Drive" } ``` ## Gestion d'erreurs | Erreur | Code | Message | |--------|------|---------| | Fichier non .md | 400 | Only markdown (.md) files are supported | | Encodage invalide | 400 | File encoding error. Please ensure the file is UTF-8 encoded | | Format invalide | 400 | Failed to parse markdown file: ... | ## Workflow complet ### Cas 1 : Périphérique nouveau (n'existe pas) ``` 1. Utilisateur : Clique "Importer .md" 2. Frontend : Affiche modal avec file input 3. Utilisateur : Sélectionne fichier .md 4. Frontend : Affiche preview (nom + taille) 5. Utilisateur : Clique "Importer" 6. Frontend : Envoie FormData à /api/peripherals/import/markdown 7. Backend : Parse le markdown avec md_parser.py 8. Backend : Extrait vendor_id, product_id, nom, marque, etc. 9. Backend : Vérifie si existe déjà (vendor_id + product_id) 10. Backend : Retourne JSON avec already_exists=false + suggested_peripheral 11. Frontend : Ferme modal import 12. Frontend : Ouvre modal ajout avec formulaire 13. Frontend : Pré-remplit tous les champs du formulaire 14. Utilisateur : Vérifie, complète (prix, localisation, photos) 15. Utilisateur : Enregistre 16. Frontend : POST /api/peripherals 17. Backend : Crée le périphérique dans peripherals.db 18. Frontend : Affiche succès et recharge la liste ``` ### Cas 2 : Périphérique déjà existant (doublon détecté) ``` 1. Utilisateur : Clique "Importer .md" 2. Frontend : Affiche modal avec file input 3. Utilisateur : Sélectionne fichier .md (ex: ID_0781_55ab.md) 4. Frontend : Affiche preview (nom + taille) 5. Utilisateur : Clique "Importer" 6. Frontend : Envoie FormData à /api/peripherals/import/markdown 7. Backend : Parse le markdown avec md_parser.py 8. Backend : Extrait vendor_id=0x0781, product_id=0x55ab 9. Backend : Vérifie si existe déjà → TROUVÉ ! 10. Backend : Retourne JSON avec already_exists=true + existing_peripheral 11. Frontend : Ferme modal import 12. Frontend : Affiche dialog de confirmation : "Ce périphérique existe déjà dans la base de données: Nom: SanDisk USB Flash Drive Marque: SanDisk Modèle: 3.2Gen1 Quantité: 2 Voulez-vous voir ce périphérique?" 13a. Si OUI : Redirige vers peripheral-detail.html?id=X 13b. Si NON : Affiche message "Import annulé - le périphérique existe déjà" ``` ## Intégration avec import USB Le module propose maintenant **deux méthodes d'import** : ### Import USB (`lsusb -v`) - ✅ Pour périphériques **actuellement connectés** - ✅ Données **en temps réel** du système - ✅ Détection automatique de tous les détails USB ### Import Markdown (.md) - ✅ Pour périphériques **déconnectés ou stockés** - ✅ Spécifications **pré-documentées** - ✅ Import **en lot** de fiches techniques - ✅ **Détection de doublons** (vendor_id + product_id) - ✅ Historique et documentation ## API Endpoint ``` POST /api/peripherals/import/markdown Content-Type: multipart/form-data Parameters: file: UploadFile (required) - Fichier .md Response 200 (nouveau périphérique): { "success": true, "already_exists": false, "filename": "ID_0781_55ab.md", "parsed_data": { ... }, "suggested_peripheral": { "nom": "...", "type_principal": "...", ... } } Response 200 (périphérique existant): { "success": true, "already_exists": true, "existing_peripheral_id": 42, "existing_peripheral": { "id": 42, "nom": "SanDisk USB Flash Drive", "type_principal": "USB", "marque": "SanDisk", "modele": "3.2Gen1", "quantite_totale": 2, "quantite_disponible": 1 }, "filename": "ID_0781_55ab.md", "message": "Un périphérique avec vendor_id=0x0781 et product_id=0x55ab existe déjà" } Response 400: { "detail": "Error message" } ``` ## Fichiers source | Fichier | Lignes | Description | |---------|--------|-------------| | `backend/app/utils/md_parser.py` | ~300 | Parser markdown principal | | `backend/app/api/endpoints/peripherals.py` | +70 | Endpoint API | | `frontend/peripherals.html` | +30 | Modal HTML | | `frontend/js/peripherals.js` | +75 | Handler JavaScript | | `frontend/css/peripherals.css` | +30 | Styles preview | | `docs/IMPORT_MARKDOWN.md` | ~400 | Documentation complète | **Total :** ~900 lignes de code ajoutées ## Documentation Pour plus de détails, voir : - **Guide complet** : [docs/IMPORT_MARKDOWN.md](docs/IMPORT_MARKDOWN.md) - **Spécifications** : [MODULE_PERIPHERIQUES_RESUME.md](MODULE_PERIPHERIQUES_RESUME.md) - **Changelog** : [CHANGELOG.md](CHANGELOG.md) --- **Développé avec Claude Code** - 2025-12-30