#!/bin/bash set -e # --- НАСТРОЙКИ (ПРОВЕРЬТЕ ПЕРЕД ЗАПУСКОМ) --- EMOTION_HOST="192.168.254.37" EMOTION_PORT="8001" PROCESSOR_PORT="8003" DB_HOST="192.168.254.35" DB_PORT="5432" DB_NAME="asr_db" DB_USER="asr_user" DB_PASSWORD="poluyan77" # --- КОНЕЦ НАСТРОЕК --- echo "=== 1. Установка базовых пакетов ===" sudo apt update sudo apt install -y python3 python3-pip python3-venv ffmpeg git echo "=== 2. Создание проекта и виртуального окружения ===" sudo mkdir -p /opt/emotion sudo chown root:root /opt/emotion cd /opt/emotion python3 -m venv venv source venv/bin/activate echo "=== 3. Установка Python-пакетов ===" pip install torch==2.5.1 torchaudio==2.5.1 --index-url https://download.pytorch.org/whl/cpu pip install fastapi uvicorn python-multipart transformers psycopg2-binary requests echo "=== 4. Создание сервера эмоций (server_text_final.py) ===" sudo tee /opt/emotion/server_text_final.py << 'EOF' from fastapi import FastAPI, Form from fastapi.responses import JSONResponse from transformers import pipeline app = FastAPI(title="Text Emotion Recognition API") print("Загрузка модели...") classifier = pipeline("text-classification", model="Aniemore/rubert-tiny2-russian-emotion-detection") print("Модель загружена") emotions_map = { "neutral": "нейтрально", "happy": "радость", "sadness": "грусть", "sad": "грусть", "anger": "злость", "angry": "злость", "fear": "страх", "surprise": "удивление", "surprised": "удивление", "disgust": "отвращение" } @app.post("/analyze") async def analyze_emotion(text: str = Form(...)): try: result = classifier(text)[0] emotion = emotions_map.get(result['label'], result['label']) confidence = result['score'] return {"status": "ok", "emotion": emotion, "confidence": confidence} except Exception as e: return JSONResponse(status_code=500, content={"error": str(e)}) @app.get("/health") async def health(): return {"status": "ok"} if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=8001) EOF echo "=== 5. Создание фонового процессора эмоций (emotion_processor.py) ===" sudo tee /opt/emotion/emotion_processor.py << 'EOF' #!/usr/bin/env python3 import psycopg2 import time import requests from datetime import datetime DB_CONFIG = { "host": "192.168.254.35", "port": 5432, "database": "asr_db", "user": "asr_user", "password": "poluyan77" } def log(msg): print(f"[{datetime.now()}] {msg}") def process_pending_calls(): conn = psycopg2.connect(**DB_CONFIG) cursor = conn.cursor() cursor.execute(""" SELECT c.id, t.full_text FROM calls c JOIN transcriptions t ON t.call_id = c.id LEFT JOIN auto_tags at ON at.call_id = c.id AND at.tag_name LIKE 'эмоция_%' WHERE at.id IS NULL AND t.full_text IS NOT NULL AND t.full_text != '' LIMIT 10 """) calls = cursor.fetchall() if not calls: cursor.close() conn.close() return 0 log(f"Найдено звонков без эмоций: {len(calls)}") for call_id, full_text in calls: try: response = requests.post('http://localhost:8001/analyze', data={'text': full_text}, timeout=10) if response.status_code == 200: result = response.json() emotion = result.get('emotion') confidence = result.get('confidence') if emotion: cursor.execute(""" INSERT INTO auto_tags (call_id, tag_name, confidence) VALUES (%s, %s, %s) """, (call_id, f"эмоция_{emotion}", confidence)) conn.commit() log(f"✅ Звонок {call_id}: эмоция {emotion} ({confidence:.2f})") else: log(f"⚠️ Звонок {call_id}: ошибка HTTP {response.status_code}") except Exception as e: log(f"❌ Звонок {call_id}: ошибка {e}") finally: time.sleep(0.5) cursor.close() conn.close() return len(calls) if __name__ == "__main__": log("Emotion processor started") while True: count = process_pending_calls() if count == 0: time.sleep(60) else: time.sleep(5) EOF echo "=== 6. Создание командного сервера (command_server.py) ===" sudo tee /opt/emotion/command_server.py << 'EOF' #!/usr/bin/env python3 import sys import os import json import http.server import threading sys.path.insert(0, '/opt/emotion') # Простая функция загрузки имён def load_operator_names(): import psycopg2 DB_CONFIG = {"host": "192.168.254.35", "port": 5432, "database": "asr_db", "user": "asr_user", "password": "poluyan77"} try: conn = psycopg2.connect(**DB_CONFIG) cursor = conn.cursor() cursor.execute("SELECT name FROM operator_names ORDER BY name") rows = cursor.fetchall() cursor.close() conn.close() return [row[0] for row in rows] except Exception as e: print(f"Ошибка: {e}") return [] def reload_operator_names(): global _operator_names_cache _operator_names_cache = load_operator_names() return _operator_names_cache _operator_names_cache = load_operator_names() class CommandHandler(http.server.SimpleHTTPRequestHandler): def do_POST(self): if self.path == '/reload-names': try: names = reload_operator_names() self.send_response(200) self.send_header('Content-type', 'application/json') self.end_headers() self.wfile.write(json.dumps({"status": "ok", "count": len(names)}).encode()) print(f"🔄 Кэш имён операторов обновлён, загружено {len(names)} имён") except Exception as e: self.send_response(500) self.end_headers() self.wfile.write(json.dumps({"status": "error", "error": str(e)}).encode()) else: self.send_response(404) self.end_headers() def log_message(self, format, *args): pass def start_command_server(port=8003): server = http.server.HTTPServer(('0.0.0.0', port), CommandHandler) print(f"🚀 Командный сервер запущен на порту {port}") server.serve_forever() if __name__ == "__main__": start_command_server() EOF echo "=== 7. Создание systemd сервисов ===" sudo tee /etc/systemd/system/emotion-api.service << 'EOF' [Unit] Description=Text Emotion Recognition API After=network.target [Service] Type=simple User=root WorkingDirectory=/opt/emotion Environment="PATH=/opt/emotion/venv/bin" ExecStart=/opt/emotion/venv/bin/python /opt/emotion/server_text_final.py Restart=always RestartSec=10 [Install] WantedBy=multi-user.target EOF sudo tee /etc/systemd/system/emotion-processor.service << 'EOF' [Unit] Description=Emotion Processor (background) After=network.target [Service] Type=simple User=root WorkingDirectory=/opt/emotion Environment="PATH=/opt/emotion/venv/bin" ExecStart=/opt/emotion/venv/bin/python /opt/emotion/emotion_processor.py Restart=always RestartSec=10 [Install] WantedBy=multi-user.target EOF sudo tee /etc/systemd/system/emotion-command.service << 'EOF' [Unit] Description=Emotion Command Server After=network.target [Service] Type=simple User=root WorkingDirectory=/opt/emotion Environment="PATH=/opt/emotion/venv/bin" ExecStart=/opt/emotion/venv/bin/python /opt/emotion/command_server.py Restart=always RestartSec=10 [Install] WantedBy=multi-user.target EOF echo "=== 8. Запуск сервисов ===" sudo systemctl daemon-reload sudo systemctl enable emotion-api emotion-processor emotion-command sudo systemctl start emotion-api emotion-processor emotion-command echo "=== 9. Проверка статуса ===" sleep 3 sudo systemctl status emotion-api --no-pager sudo systemctl status emotion-processor --no-pager sudo systemctl status emotion-command --no-pager echo "=== Emotion ВМ готова ===" echo "API эмоций: http://$EMOTION_HOST:$EMOTION_PORT" echo "Командный сервер: порт $PROCESSOR_PORT"