stuff
This commit is contained in:
109
src/database.py
109
src/database.py
@@ -61,6 +61,7 @@ class Recording:
|
||||
user_id: int # dataset_speaker_id
|
||||
scenario_id: str
|
||||
replica_index: int
|
||||
duration: float # длительность в секундах
|
||||
created_at: datetime
|
||||
|
||||
|
||||
@@ -120,6 +121,7 @@ def init_db() -> None:
|
||||
user_id INTEGER NOT NULL,
|
||||
scenario_id TEXT NOT NULL,
|
||||
replica_index INTEGER NOT NULL,
|
||||
duration REAL DEFAULT 0.0,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (user_id) REFERENCES users(id),
|
||||
FOREIGN KEY (scenario_id) REFERENCES scenarios(id),
|
||||
@@ -147,6 +149,14 @@ def init_db() -> None:
|
||||
CREATE INDEX IF NOT EXISTS idx_recordings_scenario
|
||||
ON recordings(scenario_id);
|
||||
""")
|
||||
|
||||
# Миграция: добавляем колонку duration если её нет
|
||||
cursor = conn.execute("PRAGMA table_info(recordings)")
|
||||
columns = [row[1] for row in cursor.fetchall()]
|
||||
if "duration" not in columns:
|
||||
conn.execute("ALTER TABLE recordings ADD COLUMN duration REAL DEFAULT 0.0")
|
||||
logger.info("Добавлена колонка duration в таблицу recordings")
|
||||
|
||||
conn.commit()
|
||||
|
||||
logger.info("База данных инициализирована")
|
||||
@@ -317,9 +327,9 @@ def create_recording(user_id: int, scenario_id: str, replica_index: int) -> Reco
|
||||
"""Создаёт запись об озвучке реплики."""
|
||||
with get_connection() as conn:
|
||||
cursor = conn.execute(
|
||||
"INSERT INTO recordings (user_id, scenario_id, replica_index) "
|
||||
"VALUES (?, ?, ?) "
|
||||
"RETURNING id, user_id, scenario_id, replica_index, created_at",
|
||||
"INSERT INTO recordings (user_id, scenario_id, replica_index, duration) "
|
||||
"VALUES (?, ?, ?, 0.0) "
|
||||
"RETURNING id, user_id, scenario_id, replica_index, duration, created_at",
|
||||
(user_id, scenario_id, replica_index),
|
||||
)
|
||||
row = cursor.fetchone()
|
||||
@@ -329,22 +339,25 @@ def create_recording(user_id: int, scenario_id: str, replica_index: int) -> Reco
|
||||
user_id=row["user_id"],
|
||||
scenario_id=row["scenario_id"],
|
||||
replica_index=row["replica_index"],
|
||||
duration=row["duration"],
|
||||
created_at=row["created_at"],
|
||||
)
|
||||
|
||||
|
||||
def upsert_recording(user_id: int, scenario_id: str, replica_index: int) -> Recording:
|
||||
def upsert_recording(
|
||||
user_id: int, scenario_id: str, replica_index: int, duration: float
|
||||
) -> Recording:
|
||||
"""Создаёт или обновляет запись об озвучке реплики."""
|
||||
with get_connection() as conn:
|
||||
cursor = conn.execute(
|
||||
"""
|
||||
INSERT INTO recordings (user_id, scenario_id, replica_index)
|
||||
VALUES (?, ?, ?)
|
||||
INSERT INTO recordings (user_id, scenario_id, replica_index, duration)
|
||||
VALUES (?, ?, ?, ?)
|
||||
ON CONFLICT(user_id, scenario_id, replica_index)
|
||||
DO UPDATE SET created_at = CURRENT_TIMESTAMP
|
||||
RETURNING id, user_id, scenario_id, replica_index, created_at
|
||||
DO UPDATE SET created_at = CURRENT_TIMESTAMP, duration = excluded.duration
|
||||
RETURNING id, user_id, scenario_id, replica_index, duration, created_at
|
||||
""",
|
||||
(user_id, scenario_id, replica_index),
|
||||
(user_id, scenario_id, replica_index, duration),
|
||||
)
|
||||
row = cursor.fetchone()
|
||||
conn.commit()
|
||||
@@ -353,6 +366,7 @@ def upsert_recording(user_id: int, scenario_id: str, replica_index: int) -> Reco
|
||||
user_id=row["user_id"],
|
||||
scenario_id=row["scenario_id"],
|
||||
replica_index=row["replica_index"],
|
||||
duration=row["duration"],
|
||||
created_at=row["created_at"],
|
||||
)
|
||||
|
||||
@@ -361,7 +375,7 @@ def get_user_recordings_for_scenario(user_id: int, scenario_id: str) -> list[Rec
|
||||
"""Получает все записи пользователя для сценария."""
|
||||
with get_connection() as conn:
|
||||
cursor = conn.execute(
|
||||
"SELECT id, user_id, scenario_id, replica_index, created_at "
|
||||
"SELECT id, user_id, scenario_id, replica_index, duration, created_at "
|
||||
"FROM recordings WHERE user_id = ? AND scenario_id = ? "
|
||||
"ORDER BY replica_index",
|
||||
(user_id, scenario_id),
|
||||
@@ -372,6 +386,7 @@ def get_user_recordings_for_scenario(user_id: int, scenario_id: str) -> list[Rec
|
||||
user_id=row["user_id"],
|
||||
scenario_id=row["scenario_id"],
|
||||
replica_index=row["replica_index"],
|
||||
duration=row["duration"],
|
||||
created_at=row["created_at"],
|
||||
)
|
||||
for row in cursor.fetchall()
|
||||
@@ -501,6 +516,32 @@ def get_stats() -> dict:
|
||||
)
|
||||
""").fetchone()[0]
|
||||
|
||||
# Количество полностью озвученных сценариев (все дорожки сценария озвучены)
|
||||
stats["completed_scenarios"] = conn.execute("""
|
||||
SELECT COUNT(*) FROM scenarios s
|
||||
WHERE (
|
||||
SELECT COUNT(DISTINCT speaker_id) FROM replicas WHERE scenario_id = s.id
|
||||
) = (
|
||||
SELECT COUNT(DISTINCT speaker_id) FROM (
|
||||
SELECT r.scenario_id, rep.speaker_id, COUNT(*) as cnt
|
||||
FROM recordings r
|
||||
JOIN replicas rep ON r.scenario_id = rep.scenario_id
|
||||
AND r.replica_index = rep.replica_index
|
||||
WHERE r.scenario_id = s.id
|
||||
GROUP BY r.scenario_id, rep.speaker_id
|
||||
HAVING cnt = (
|
||||
SELECT COUNT(*) FROM replicas rp
|
||||
WHERE rp.scenario_id = r.scenario_id
|
||||
AND rp.speaker_id = rep.speaker_id
|
||||
)
|
||||
) AS completed
|
||||
)
|
||||
""").fetchone()[0]
|
||||
|
||||
# Общая длительность всех записей в секундах
|
||||
result = conn.execute("SELECT SUM(duration) FROM recordings").fetchone()[0]
|
||||
stats["total_duration"] = result if result else 0.0
|
||||
|
||||
return stats
|
||||
|
||||
|
||||
@@ -551,3 +592,51 @@ def delete_scenario_data(scenario_id: str) -> None:
|
||||
conn.execute("DELETE FROM scenarios WHERE id = ?", (scenario_id,))
|
||||
conn.commit()
|
||||
logger.info(f"Deleted scenario {scenario_id} from database")
|
||||
|
||||
|
||||
def get_user_stats(user_id: int) -> dict:
|
||||
"""Получает статистику пользователя."""
|
||||
with get_connection() as conn:
|
||||
stats = {}
|
||||
|
||||
# Количество озвученных реплик
|
||||
stats["total_replicas"] = conn.execute(
|
||||
"SELECT COUNT(*) FROM recordings WHERE user_id = ?", (user_id,)
|
||||
).fetchone()[0]
|
||||
|
||||
# Количество уникальных сценариев
|
||||
stats["total_scenarios"] = conn.execute(
|
||||
"SELECT COUNT(DISTINCT scenario_id) FROM recordings WHERE user_id = ?",
|
||||
(user_id,),
|
||||
).fetchone()[0]
|
||||
|
||||
# Количество полностью озвученных дорожек
|
||||
stats["completed_tracks"] = conn.execute(
|
||||
"""
|
||||
SELECT COUNT(*) FROM (
|
||||
SELECT r.scenario_id, rep.speaker_id, COUNT(*) as cnt
|
||||
FROM recordings r
|
||||
JOIN replicas rep ON r.scenario_id = rep.scenario_id
|
||||
AND r.replica_index = rep.replica_index
|
||||
WHERE r.user_id = ?
|
||||
GROUP BY r.scenario_id, rep.speaker_id
|
||||
HAVING cnt = (
|
||||
SELECT COUNT(*) FROM replicas rp
|
||||
WHERE rp.scenario_id = r.scenario_id
|
||||
AND rp.speaker_id = rep.speaker_id
|
||||
)
|
||||
)
|
||||
""",
|
||||
(user_id,),
|
||||
).fetchone()[0]
|
||||
|
||||
return stats
|
||||
|
||||
|
||||
def get_user_audio_duration(user_id: int) -> float:
|
||||
"""Получает общую длительность аудиозаписей пользователя в секундах."""
|
||||
with get_connection() as conn:
|
||||
result = conn.execute(
|
||||
"SELECT SUM(duration) FROM recordings WHERE user_id = ?", (user_id,)
|
||||
).fetchone()[0]
|
||||
return result if result else 0.0
|
||||
|
||||
Reference in New Issue
Block a user