12 changed files with 244 additions and 1 deletions
@ -0,0 +1,3 @@ |
|||||||
|
from autoLoader.database import * |
||||||
|
from autoLoader.loader import Loader |
||||||
|
loader = Loader() |
||||||
@ -0,0 +1,7 @@ |
|||||||
|
import os |
||||||
|
|
||||||
|
SFTP_HOSTNAME = os.getenv("SFPT_HOSTNAME", "192.168.1.150") |
||||||
|
SFTP_USERNAME = os.getenv("SFPT_USERNAME", "monitor") |
||||||
|
SFTP_PASSWORD = os.getenv("SFPT_PASSWORD", "Audio4analy6!6") |
||||||
|
FILESAPTH = os.getenv("FILESAPTH", "audiofiles") |
||||||
|
DATABASE_URL = os.getenv("DATABASE_URL", "sqlite:///./speech_analytics.db") |
||||||
@ -0,0 +1,22 @@ |
|||||||
|
from sqlalchemy import Column, UUID, ForeignKey, DateTime, JSON |
||||||
|
from sqlalchemy.orm import relationship |
||||||
|
from apiApp.database import Base |
||||||
|
import uuid |
||||||
|
from datetime import datetime |
||||||
|
|
||||||
|
|
||||||
|
class AiConclusion(Base): |
||||||
|
__tablename__ = "ai_conclusion" |
||||||
|
|
||||||
|
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) |
||||||
|
audio_id = Column(UUID(as_uuid=True), ForeignKey("audio.id"), nullable=False) |
||||||
|
conclusion = Column(JSON, default=lambda: { |
||||||
|
"transcription": [], |
||||||
|
"ai_transcription": [], |
||||||
|
"conclusion": {} |
||||||
|
}) |
||||||
|
index_date = Column(DateTime, default=datetime.utcnow) |
||||||
|
end_date = Column(DateTime) |
||||||
|
|
||||||
|
audio_id = Column(UUID(as_uuid=True), ForeignKey("audio.id")) |
||||||
|
version = relationship("ConclusionVersion", back_populates="ai_conclusion") |
||||||
@ -0,0 +1,28 @@ |
|||||||
|
from sqlalchemy import Column, String, DateTime, UUID, ForeignKey, Float, Integer |
||||||
|
from sqlalchemy.orm import relationship |
||||||
|
from apiApp.database import Base |
||||||
|
import uuid |
||||||
|
from datetime import datetime |
||||||
|
|
||||||
|
|
||||||
|
class Audio(Base): |
||||||
|
__tablename__ = "audio" |
||||||
|
|
||||||
|
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) |
||||||
|
filename = Column(String(255), nullable=False) |
||||||
|
index_date = Column(DateTime, default=datetime.utcnow) |
||||||
|
file_path = Column(String(500)) |
||||||
|
duration = Column(Float) |
||||||
|
file_size = Column(Integer) |
||||||
|
|
||||||
|
ai_conclusion = relationship("AiConclusion", back_populates="audio", cascade="all, delete-orphan") |
||||||
|
|
||||||
|
def to_dict(self): |
||||||
|
return { |
||||||
|
"id": str(self.id), |
||||||
|
"filename": self.filename, |
||||||
|
"index_date": self.index_date.isoformat() if self.index_date else None, |
||||||
|
"file_path": self.file_path, |
||||||
|
"duration": self.duration, |
||||||
|
"file_size": self.file_size |
||||||
|
} |
||||||
@ -0,0 +1,12 @@ |
|||||||
|
from sqlalchemy import Column, UUID, ForeignKey, Integer, Text |
||||||
|
from apiApp.database import Base |
||||||
|
import uuid |
||||||
|
|
||||||
|
|
||||||
|
class ConclusionVersion(Base): |
||||||
|
__tablename__ = "conclusion_version" |
||||||
|
|
||||||
|
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) |
||||||
|
conclusion_id = Column(UUID(as_uuid=True), ForeignKey("ai_conclusion.id")) |
||||||
|
version = Column(Integer) |
||||||
|
content = Column(Text) |
||||||
@ -0,0 +1,16 @@ |
|||||||
|
from sqlalchemy import Column, UUID, String, Integer |
||||||
|
from sqlalchemy.orm import relationship |
||||||
|
from apiApp.database import Base |
||||||
|
import uuid |
||||||
|
|
||||||
|
|
||||||
|
class Operator(Base): |
||||||
|
__tablename__ = "operator" |
||||||
|
|
||||||
|
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) |
||||||
|
fio = Column(String(100)) |
||||||
|
num = Column(Integer) |
||||||
|
|
||||||
|
calls = relationship("Call", back_populates="operator") |
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,31 @@ |
|||||||
|
from sqlalchemy import create_engine |
||||||
|
from sqlalchemy.ext.declarative import declarative_base |
||||||
|
from sqlalchemy.orm import sessionmaker |
||||||
|
from autoLoader.config import DATABASE_URL |
||||||
|
|
||||||
|
# Создание engine |
||||||
|
engine = create_engine( |
||||||
|
DATABASE_URL, |
||||||
|
connect_args={"check_same_thread": False} if "sqlite" in DATABASE_URL else {} |
||||||
|
) |
||||||
|
|
||||||
|
# SessionLocal |
||||||
|
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) |
||||||
|
|
||||||
|
# Base |
||||||
|
Base = declarative_base() |
||||||
|
|
||||||
|
|
||||||
|
# Зависимость для получения сессии БД |
||||||
|
def get_db(): |
||||||
|
db = SessionLocal() |
||||||
|
try: |
||||||
|
yield db |
||||||
|
finally: |
||||||
|
db.close() |
||||||
|
|
||||||
|
|
||||||
|
# from apiApp.database.Operator import Operator |
||||||
|
from apiApp.database.Audio import Audio |
||||||
|
from apiApp.database.AiConclusion import AiConclusion |
||||||
|
from apiApp.database.ConclusionVersion import ConclusionVersion |
||||||
@ -0,0 +1,2 @@ |
|||||||
|
from autoLoader.loader.connector import * |
||||||
|
from autoLoader.loader.loader import * |
||||||
@ -0,0 +1,53 @@ |
|||||||
|
from autoLoader.config import SFTP_HOSTNAME, SFTP_USERNAME, SFTP_PASSWORD |
||||||
|
|
||||||
|
|
||||||
|
import socket |
||||||
|
def check_connection(): |
||||||
|
"""Проверка доступности сервера""" |
||||||
|
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) |
||||||
|
sock.settimeout(10) |
||||||
|
|
||||||
|
try: |
||||||
|
result = sock.connect_ex((SFTP_HOSTNAME, 22)) |
||||||
|
if result == 0: |
||||||
|
print("Порт 22 доступен") |
||||||
|
else: |
||||||
|
print(f"Порт 22 недоступен. Код ошибки: {result}") |
||||||
|
except Exception as e: |
||||||
|
print(f"Ошибка проверки соединения: {e}") |
||||||
|
finally: |
||||||
|
sock.close() |
||||||
|
|
||||||
|
# Перед подключением вызовите проверку |
||||||
|
# check_connection() |
||||||
|
|
||||||
|
import paramiko |
||||||
|
class ConnectorSFTP(): |
||||||
|
def __init__(self): |
||||||
|
self.sftp = None |
||||||
|
self.ssh = paramiko.SSHClient() |
||||||
|
|
||||||
|
def connect(self, remote_path: str): |
||||||
|
try: |
||||||
|
self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) |
||||||
|
self.ssh.connect( |
||||||
|
hostname=SFTP_HOSTNAME, |
||||||
|
username=SFTP_USERNAME, |
||||||
|
password=SFTP_PASSWORD, |
||||||
|
) |
||||||
|
self.sftp = self.ssh.open_sftp() |
||||||
|
remote_path = remote_path.lstrip('/') # Удаляем начальный слэш, если есть |
||||||
|
self.sftp.chdir(remote_path) # Переходим в директори |
||||||
|
|
||||||
|
except paramiko.AuthenticationException: |
||||||
|
print("Ошибка аутентификации. Проверьте имя пользователя и пароль.") |
||||||
|
return None, None |
||||||
|
except paramiko.SSHException as e: |
||||||
|
print(f"Ошибка SSH: {e}") |
||||||
|
return None, None |
||||||
|
except FileNotFoundError: |
||||||
|
print(f"Директория {remote_path} не найдена на сервере.") |
||||||
|
return None, None |
||||||
|
except IOError as e: |
||||||
|
print(f"Ошибка ввода-вывода: {e}") |
||||||
|
return None, None |
||||||
@ -0,0 +1,58 @@ |
|||||||
|
from autoLoader.config import FILESAPTH |
||||||
|
from autoLoader.loader import ConnectorSFTP |
||||||
|
import datetime, os |
||||||
|
from autoLoader.database import * |
||||||
|
|
||||||
|
local_path = os.path.join(os.getcwd(), FILESAPTH) |
||||||
|
class Loader(): |
||||||
|
def __init__(self): |
||||||
|
self.call_types = ['in'] |
||||||
|
pass |
||||||
|
|
||||||
|
def filter_call(self, filename: str): |
||||||
|
if filename.split("-")[0] in self.call_types: |
||||||
|
return True |
||||||
|
return False |
||||||
|
|
||||||
|
def load(self): |
||||||
|
|
||||||
|
date_now = datetime.datetime.now()# - datetime.timedelta(days=1) |
||||||
|
remote_path = f"/{date_now.strftime('%Y/%m/%d')}" |
||||||
|
|
||||||
|
connector = ConnectorSFTP() |
||||||
|
connector.connect(remote_path=remote_path) |
||||||
|
|
||||||
|
sftp_client = connector.sftp |
||||||
|
ssh_client = connector.ssh |
||||||
|
|
||||||
|
if sftp_client is None or ssh_client is None: |
||||||
|
print("Не удалось подключиться к SFTP. Завершение работы.") |
||||||
|
exit(1) |
||||||
|
|
||||||
|
db = get_db() |
||||||
|
|
||||||
|
try: |
||||||
|
listdir = sftp_client.listdir() |
||||||
|
os.makedirs(local_path, exist_ok = True) |
||||||
|
diskdir = os.listdir(local_path) |
||||||
|
|
||||||
|
for file in listdir: |
||||||
|
if self.filter_call(filename=file): |
||||||
|
remote_file = f"{file}".lstrip('/') |
||||||
|
filepath = os.path.join(local_path, file) |
||||||
|
try: |
||||||
|
sftp_client.get(remote_file, filepath) # Скачиваем файл |
||||||
|
audio = Audio() |
||||||
|
audio.index_date = datetime.datetime.now() |
||||||
|
audio.filename = file |
||||||
|
db.session.add(audio) |
||||||
|
db.session.commit() |
||||||
|
|
||||||
|
print(f"Скачан файл: {remote_file}") |
||||||
|
except Exception as e: |
||||||
|
print(f"Ошибка при скачивании файла {remote_file}: {e}") |
||||||
|
|
||||||
|
finally: |
||||||
|
# Закрываем соединения |
||||||
|
sftp_client.close() |
||||||
|
ssh_client.close() |
||||||
Loading…
Reference in new issue