6.9 KiB
Executable File
Feature: Import USB avec sélection de périphérique
Vue d'ensemble
Implémentation complète de l'import USB avec détection automatique, sélection par boutons radio, et stockage du CLI formaté en markdown.
Flow utilisateur
Étape 1 : Instructions et saisie CLI
- Utilisateur clique sur "Importer USB"
- Popup 1 s'affiche avec :
- Commande
lsusb -vavec bouton Copier - Zone de texte pour coller la sortie
- Boutons Annuler et Importer
- Commande
Étape 2 : Sélection du périphérique
-
Backend détecte tous les périphériques (lignes commençant par "Bus")
-
Popup 2 s'affiche avec :
- Liste des périphériques détectés
- Boutons radio (un seul sélectionnable à la fois)
- Bouton Finaliser (désactivé par défaut)
-
Utilisateur sélectionne UN périphérique → bouton Finaliser s'active
-
Utilisateur clique sur Finaliser
Étape 3 : Pré-remplissage et création
-
Backend extrait et filtre le CLI pour ce périphérique
-
Formate le CLI en markdown :
# Sortie lsusb -v Bus 002 Device 003[sortie filtrée]
-
Pré-remplit le formulaire avec :
nom,marque,modele,numero_serietype_principal,sous_type(chargés depuis YAML)cli(markdown formaté)caracteristiques_specifiques(vendor_id, product_id, etc.)
-
Utilisateur complète et enregistre
Fichiers modifiés
Backend
1. Database Schema
-
backend/app/models/peripheral.py:124cli = Column(Text) # Sortie CLI (lsusb -v) filtrée -
backend/app/schemas/peripheral.py:50cli: Optional[str] = None # Sortie CLI (lsusb -v) filtrée
2. Parsers
backend/app/utils/lsusb_parser.py(NOUVEAU)detect_usb_devices()- Détecte lignes "Bus"extract_device_section()- Filtre pour un périphériqueparse_device_info()- Parse les infos détaillées
3. API Endpoints
backend/app/api/endpoints/peripherals.py:665POST /peripherals/import/usb-cli/detect- Détecte périphériquesPOST /peripherals/import/usb-cli/extract- Extrait périphérique sélectionnéGET /peripherals/config/types- Charge types depuis YAML
4. Configuration
config/peripheral_types.yaml:115- Ajout type
usb_wifi(Adaptateur WiFi USB)
- Ajout type
Frontend
1. HTML
frontend/peripherals.html:250-318- Popup step 1 : Instructions + commande + zone texte
- Popup step 2 : Liste avec radio buttons
2. CSS
frontend/css/peripherals.css:540-666.import-instructions- Boîte d'instructions.command-box- Affichage commande avec bouton copier.btn-copy- Bouton copier stylisé.usb-devices-list- Liste périphériques.usb-device-item- Item cliquable avec radio
3. JavaScript
frontend/js/peripherals.jscopyUSBCommand()- Copie commande dans presse-papiersdetectUSBDevices()- Appelle API detectselectUSBDevice()- Active bouton FinaliserimportSelectedUSBDevice()- Import finalloadPeripheralTypesFromAPI()- Charge types depuis YAML
Endpoints API
1. Détection périphériques
POST /api/peripherals/import/usb-cli/detect
Content-Type: multipart/form-data
Parameters:
lsusb_output: string (sortie complète lsusb -v)
Response:
{
"success": true,
"devices": [
{
"bus_line": "Bus 002 Device 003: ID 0781:55ab ...",
"bus": "002",
"device": "003",
"id": "0781:55ab",
"vendor_id": "0x0781",
"product_id": "0x55ab",
"description": "SanDisk Corp. ..."
}
],
"total_devices": 5
}
2. Extraction périphérique
POST /api/peripherals/import/usb-cli/extract
Content-Type: multipart/form-data
Parameters:
lsusb_output: string
bus: string (ex: "002")
device: string (ex: "003")
Response (nouveau):
{
"success": true,
"already_exists": false,
"suggested_peripheral": {
"nom": "SanDisk 3.2Gen1",
"type_principal": "USB",
"sous_type": "Clé USB",
"marque": "SanDisk",
"modele": "3.2Gen1",
"numero_serie": "...",
"cli": "# Sortie lsusb -v\n\nBus 002 Device 003\n\n```\n...\n```",
"caracteristiques_specifiques": {
"vendor_id": "0x0781",
"product_id": "0x55ab",
...
}
}
}
Response (existant):
{
"success": true,
"already_exists": true,
"existing_peripheral_id": 42,
"existing_peripheral": { ... }
}
3. Types de périphériques
GET /api/peripherals/config/types
Response:
{
"success": true,
"types": {
"USB": ["Clavier", "Souris", "Hub", "Clé USB", "Webcam", "Adaptateur WiFi", "Autre"],
"Bluetooth": ["Clavier", "Souris", "Audio", "Autre"],
"Réseau": ["Wi-Fi", "Ethernet", "Autre"],
...
},
"full_types": [ ... ] // Données complètes du YAML
}
Migration base de données
Colonnes ajoutées à la table peripherals :
description(TEXT) - Description courtesynthese(TEXT) - Synthèse markdown complètecli(TEXT) - Sortie CLI formatée en markdown
Migration exécutée automatiquement au démarrage du backend.
Chargement dynamique des types
Les sous-types sont maintenant chargés depuis le YAML via l'API :
- Frontend appelle
/api/peripherals/config/types - Backend lit
config/peripheral_types.yaml - Frontend met en cache et affiche dans dropdown
- Fallback sur hardcodé si API échoue
Avantage : Ajouter un type dans le YAML suffit, pas besoin de modifier le JS !
Format CLI stocké
# Sortie lsusb -v
Bus 002 Device 003
Bus 002 Device 003: ID 0781:55ab SanDisk Corp. Cruzer Blade Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 3.20 bDeviceClass 0 ...
Détection de doublons
Basée sur vendor_id + product_id :
- Si existe déjà → propose de voir la fiche
- Sinon → pré-remplit formulaire
Tests
Pour tester l'import USB complet :
# 1. Obtenir la sortie lsusb
lsusb -v > /tmp/lsusb_output.txt
# 2. Dans l'interface :
- Cliquer "Importer USB"
- Copier la commande avec le bouton
- Coller le contenu de /tmp/lsusb_output.txt
- Cliquer "Importer"
- Sélectionner un périphérique avec le bouton radio
- Cliquer "Finaliser"
- Vérifier le pré-remplissage du formulaire
- Enregistrer
Améliorations futures possibles
- Prévisualisation CLI dans la fiche périphérique avec coloration syntaxique
- Export CLI depuis une fiche existante
- Comparaison de deux CLI (avant/après)
- Historique des CLI (tracking modifications matériel)
- Import batch : sélectionner plusieurs périphériques à la fois
Notes techniques
- Radio buttons utilisés pour sélection unique (pas checkboxes)
- Bouton Finaliser désactivé jusqu'à sélection
- CLI formaté en markdown pour meilleure lisibilité
- Cache des types pour performance
- Gestion erreurs complète avec messages utilisateur