diff --git a/backend/Dockerfile b/backend/Dockerfile index 41a4bf5..7deba3e 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -26,6 +26,23 @@ COPY requirements.txt . # Install Python dependencies in stages for better caching RUN pip install --no-cache-dir numpy==1.24.3 RUN pip install --no-cache-dir scipy==1.11.4 + +# Install Essentia - detect architecture and install appropriate wheel +RUN ARCH=$(uname -m) && \ + if [ "$ARCH" = "x86_64" ]; then \ + echo "Installing Essentia for x86_64..." && \ + pip install --no-cache-dir --trusted-host essentia.upf.edu \ + https://essentia.upf.edu/python-wheels/essentia-2.1_beta6.dev374-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl || \ + echo "Essentia installation failed, using fallback mode"; \ + elif [ "$ARCH" = "aarch64" ]; then \ + echo "Installing Essentia for aarch64..." && \ + pip install --no-cache-dir --trusted-host essentia.upf.edu \ + https://essentia.upf.edu/python-wheels/essentia-2.1_beta6.dev374-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl || \ + echo "Essentia installation failed, using fallback mode"; \ + else \ + echo "Unsupported architecture: $ARCH, using fallback mode"; \ + fi + RUN pip install --no-cache-dir -r requirements.txt # Copy application code diff --git a/backend/requirements.txt b/backend/requirements.txt index b352c1f..549f0ec 100644 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -15,12 +15,8 @@ soundfile==0.12.1 audioread==3.0.1 mutagen==1.47.0 -# Optional: Essentia for genre/mood/instrument classification -# Note: essentia-tensorflow not available on PyPI for all platforms -# Uncomment if you can install it (Linux x86_64 only): -# essentia==2.1b6.dev1110 -# For manual installation: pip install essentia -# Or build from source: https://github.com/MTG/essentia +# Essentia for genre/mood/instrument classification +# Note: Essentia is installed separately in Dockerfile from official wheels # Scientific Computing numpy==1.24.3 diff --git a/backend/src/alembic/versions/20251127_002_rename_metadata.py b/backend/src/alembic/versions/20251127_002_rename_metadata.py new file mode 100644 index 0000000..230b13c --- /dev/null +++ b/backend/src/alembic/versions/20251127_002_rename_metadata.py @@ -0,0 +1,37 @@ +"""Rename metadata to extra_metadata + +Revision ID: 002 +Revises: 001 +Create Date: 2025-11-27 + +""" +from typing import Sequence, Union + +from alembic import op +import sqlalchemy as sa + +# revision identifiers, used by Alembic. +revision: str = '002' +down_revision: Union[str, None] = '001' +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None + + +def upgrade() -> None: + # Check if column exists before renaming + op.execute(""" + DO $$ + BEGIN + IF EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_name='audio_tracks' AND column_name='metadata' + ) THEN + ALTER TABLE audio_tracks RENAME COLUMN metadata TO extra_metadata; + END IF; + END $$; + """) + + +def downgrade() -> None: + # Rename back to metadata + op.execute('ALTER TABLE audio_tracks RENAME COLUMN extra_metadata TO metadata') diff --git a/deploy.sh b/deploy.sh new file mode 100755 index 0000000..e89f8da --- /dev/null +++ b/deploy.sh @@ -0,0 +1,82 @@ +#!/bin/bash + +# Script de déploiement pour Audio Classifier +# Usage: ./deploy.sh [user@]hostname + +set -e + +if [ -z "$1" ]; then + echo "Usage: ./deploy.sh user@hostname" + echo "Exemple: ./deploy.sh root@mon-serveur.com" + exit 1 +fi + +SERVER=$1 +APP_NAME="audio-classifier" +REMOTE_DIR="~/$APP_NAME" + +echo "🚀 Déploiement de Audio Classifier sur $SERVER" +echo "" + +# 1. Vérifier la connexion SSH +echo "📡 Vérification de la connexion SSH..." +ssh $SERVER "echo '✅ Connexion SSH OK'" || exit 1 +echo "" + +# 2. Créer le dossier distant +echo "📁 Création du dossier distant $REMOTE_DIR..." +ssh $SERVER "mkdir -p $REMOTE_DIR" +echo "" + +# 3. Copier les fichiers +echo "📦 Transfert des fichiers..." +rsync -avz --progress \ + --exclude 'node_modules' \ + --exclude '.next' \ + --exclude '__pycache__' \ + --exclude '*.pyc' \ + --exclude '.git' \ + --exclude 'backend/models/*.pb' \ + ./ $SERVER:$REMOTE_DIR/ +echo "" + +# 4. Télécharger les modèles Essentia sur le serveur +echo "🤖 Téléchargement des modèles Essentia..." +ssh $SERVER "cd $REMOTE_DIR && bash scripts/download-essentia-models.sh" +echo "" + +# 5. Vérifier Docker +echo "🐳 Vérification de Docker..." +ssh $SERVER "command -v docker >/dev/null 2>&1" || { + echo "⚠️ Docker n'est pas installé sur le serveur." + echo "Installation de Docker..." + ssh $SERVER "curl -fsSL https://get.docker.com | sudo sh && sudo usermod -aG docker \$(whoami)" + echo "✅ Docker installé. Vous devrez peut-être vous reconnecter au serveur." +} + +ssh $SERVER "command -v docker-compose >/dev/null 2>&1 || command -v docker compose >/dev/null 2>&1" || { + echo "⚠️ Docker Compose n'est pas installé." + echo "Installation de Docker Compose..." + ssh $SERVER "sudo apt-get update && sudo apt-get install -y docker-compose-plugin" +} +echo "" + +# 6. Build et démarrage +echo "🔨 Build et démarrage de l'application..." +ssh $SERVER "cd $REMOTE_DIR && docker-compose down && docker-compose build && docker-compose up -d" +echo "" + +# 7. Vérifier le statut +echo "📊 Vérification du statut..." +sleep 5 +ssh $SERVER "cd $REMOTE_DIR && docker-compose ps" +echo "" + +echo "✅ Déploiement terminé !" +echo "" +echo "🌐 L'application devrait être accessible sur:" +echo " - Backend API: http://$SERVER:8000" +echo " - Frontend: http://$SERVER:3000" +echo "" +echo "📝 Pour voir les logs:" +echo " ssh $SERVER 'cd $REMOTE_DIR && docker-compose logs -f'" diff --git a/install-server.sh b/install-server.sh new file mode 100755 index 0000000..ce5a3a2 --- /dev/null +++ b/install-server.sh @@ -0,0 +1,136 @@ +#!/bin/bash + +# Script d'installation pour Audio Classifier sur serveur Linux +# À exécuter directement sur le serveur après avoir cloné le repo + +set -e + +echo "🚀 Installation de Audio Classifier" +echo "" + +# 1. Vérifier qu'on est dans le bon dossier +if [ ! -f "docker-compose.yml" ]; then + echo "❌ Erreur: Ce script doit être exécuté depuis la racine du projet" + echo "Usage: cd audio-classifier && bash install-server.sh" + exit 1 +fi + +# 2. Vérifier l'architecture +echo "🔍 Détection de l'architecture..." +ARCH=$(uname -m) +echo "Architecture détectée: $ARCH" +if [ "$ARCH" = "x86_64" ]; then + echo "✅ Architecture x86_64 - Parfait pour Essentia !" +elif [ "$ARCH" = "aarch64" ]; then + echo "⚠️ Architecture ARM64 - Essentia pourrait avoir des limitations" +else + echo "⚠️ Architecture non testée: $ARCH" +fi +echo "" + +# 3. Installer Docker si nécessaire +echo "🐳 Vérification de Docker..." +if ! command -v docker &> /dev/null; then + echo "Docker non trouvé. Installation..." + curl -fsSL https://get.docker.com | sudo sh + sudo usermod -aG docker $USER + echo "✅ Docker installé" + echo "⚠️ Vous devrez vous reconnecter pour utiliser Docker sans sudo" + echo "Commande: exit puis reconnectez-vous en SSH" +else + echo "✅ Docker déjà installé" +fi +echo "" + +# 4. Installer Docker Compose si nécessaire +echo "🐳 Vérification de Docker Compose..." +if ! command -v docker-compose &> /dev/null && ! docker compose version &> /dev/null 2>&1; then + echo "Docker Compose non trouvé. Installation..." + sudo apt-get update + sudo apt-get install -y docker-compose-plugin + echo "✅ Docker Compose installé" +else + echo "✅ Docker Compose déjà installé" +fi +echo "" + +# 5. Télécharger les modèles Essentia +echo "🤖 Téléchargement des modèles Essentia..." +if [ -f "scripts/download-essentia-models.sh" ]; then + bash scripts/download-essentia-models.sh + echo "✅ Modèles téléchargés" +else + echo "⚠️ Script de téléchargement non trouvé, les modèles seront téléchargés plus tard" +fi +echo "" + +# 6. Créer le fichier .env si nécessaire +if [ ! -f ".env" ]; then + echo "📝 Création du fichier .env..." + cat > .env << 'EOF' +# Database +POSTGRES_USER=audio_classifier +POSTGRES_PASSWORD=change_this_password +POSTGRES_DB=audio_classifier +DATABASE_URL=postgresql://audio_classifier:change_this_password@db:5432/audio_classifier + +# Backend +ESSENTIA_MODELS_PATH=/app/models + +# Frontend +NEXT_PUBLIC_API_URL=http://localhost:8000 +EOF + echo "✅ Fichier .env créé" + echo "⚠️ Pensez à modifier les mots de passe dans .env" +else + echo "✅ Fichier .env existe déjà" +fi +echo "" + +# 7. Arrêter les conteneurs existants +echo "🛑 Arrêt des conteneurs existants..." +docker-compose down 2>/dev/null || true +echo "" + +# 8. Build de l'application +echo "🔨 Build de l'application..." +docker-compose build +echo "✅ Build terminé" +echo "" + +# 9. Démarrer l'application +echo "🚀 Démarrage de l'application..." +docker-compose up -d +echo "" + +# 10. Attendre que les services démarrent +echo "⏳ Attente du démarrage des services..." +sleep 10 +echo "" + +# 11. Vérifier le statut +echo "📊 Statut des services:" +docker-compose ps +echo "" + +# 12. Vérifier Essentia +echo "🔍 Vérification d'Essentia..." +docker-compose logs backend | grep -i essentia | tail -3 +echo "" + +# 13. Afficher les informations finales +echo "✅ Installation terminée !" +echo "" +echo "🌐 Application accessible sur:" +SERVER_IP=$(hostname -I | awk '{print $1}') +echo " - Backend API: http://$SERVER_IP:8000" +echo " - API Docs: http://$SERVER_IP:8000/docs" +echo " - Frontend: http://$SERVER_IP:3000" +echo "" +echo "📝 Commandes utiles:" +echo " - Voir les logs: docker-compose logs -f" +echo " - Arrêter: docker-compose down" +echo " - Redémarrer: docker-compose restart" +echo "" +echo "🎵 Pour scanner vos fichiers audio:" +echo " docker-compose exec backend python -m src.cli.scanner /path/to/music"