chore: add ruff and ty, fix linting
- Add ruff (line-length 88) and ty to dev dependencies - Fix all ruff linting errors - Configure ty to ignore nullable type warnings - Update AGENTS.md with linting instructions
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
import sqlite3
|
||||
from collections.abc import Generator
|
||||
from contextlib import contextmanager
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime
|
||||
from enum import Enum
|
||||
from typing import Generator
|
||||
|
||||
from src.config import DB_PATH
|
||||
from src.logger import logger
|
||||
@@ -171,7 +171,8 @@ def get_or_create_user(telegram_id: int) -> User:
|
||||
)
|
||||
|
||||
cursor = conn.execute(
|
||||
"INSERT INTO users (telegram_id) VALUES (?) RETURNING id, telegram_id, created_at",
|
||||
"INSERT INTO users (telegram_id) VALUES (?) "
|
||||
"RETURNING id, telegram_id, created_at",
|
||||
(telegram_id,),
|
||||
)
|
||||
row = cursor.fetchone()
|
||||
@@ -244,10 +245,11 @@ def get_all_scenarios() -> list[Scenario]:
|
||||
|
||||
|
||||
def create_replicas(scenario_id: str, replicas: list[tuple[int, int, str]]) -> None:
|
||||
"""Создаёт реплики для сценария. replicas: [(speaker_id, replica_index, text), ...]"""
|
||||
"""Создаёт реплики. replicas: [(speaker_id, replica_index, text), ...]"""
|
||||
with get_connection() as conn:
|
||||
conn.executemany(
|
||||
"INSERT INTO replicas (scenario_id, speaker_id, replica_index, text) VALUES (?, ?, ?, ?)",
|
||||
"INSERT INTO replicas (scenario_id, speaker_id, replica_index, text) "
|
||||
"VALUES (?, ?, ?, ?)",
|
||||
[
|
||||
(scenario_id, speaker_id, idx, text)
|
||||
for speaker_id, idx, text in replicas
|
||||
@@ -300,7 +302,8 @@ def get_track_speaker_ids(scenario_id: str) -> list[int]:
|
||||
"""Получает список speaker_id (дорожек) в сценарии."""
|
||||
with get_connection() as conn:
|
||||
cursor = conn.execute(
|
||||
"SELECT DISTINCT speaker_id FROM replicas WHERE scenario_id = ? ORDER BY speaker_id",
|
||||
"SELECT DISTINCT speaker_id FROM replicas "
|
||||
"WHERE scenario_id = ? ORDER BY speaker_id",
|
||||
(scenario_id,),
|
||||
)
|
||||
return [row["speaker_id"] for row in cursor.fetchall()]
|
||||
@@ -314,7 +317,8 @@ 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",
|
||||
"VALUES (?, ?, ?) "
|
||||
"RETURNING id, user_id, scenario_id, replica_index, created_at",
|
||||
(user_id, scenario_id, replica_index),
|
||||
)
|
||||
row = cursor.fetchone()
|
||||
@@ -356,8 +360,9 @@ 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 FROM recordings "
|
||||
"WHERE user_id = ? AND scenario_id = ? ORDER BY replica_index",
|
||||
"SELECT id, user_id, scenario_id, replica_index, created_at "
|
||||
"FROM recordings WHERE user_id = ? AND scenario_id = ? "
|
||||
"ORDER BY replica_index",
|
||||
(user_id, scenario_id),
|
||||
)
|
||||
return [
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from collections.abc import Callable
|
||||
from functools import wraps
|
||||
from typing import Callable
|
||||
|
||||
from telegram import Update
|
||||
from telegram.ext import ContextTypes
|
||||
@@ -69,5 +69,3 @@ def require_state(*states: UserState):
|
||||
return wrapper
|
||||
|
||||
return decorator
|
||||
|
||||
|
||||
|
||||
@@ -26,9 +26,11 @@ INTRO_TEXT = """👋 Добро пожаловать!
|
||||
|
||||
Это бот для сбора датасета озвученных реплик совещаний.
|
||||
|
||||
Вы будете озвучивать реплики участников совещаний. Каждая дорожка — это реплики одного участника в рамках одного совещания.
|
||||
Вы будете озвучивать реплики участников совещаний.
|
||||
Каждая дорожка — это реплики одного участника в рамках одного совещания.
|
||||
|
||||
📋 Отправляя голосовые сообщения, вы соглашаетесь с тем, что они будут использованы в исследовательских целях для обучения моделей машинного обучения.
|
||||
📋 Отправляя голосовые сообщения, вы соглашаетесь с тем, что они будут
|
||||
использованы в исследовательских целях для обучения моделей машинного обучения.
|
||||
|
||||
Нажмите кнопку ниже, чтобы начать."""
|
||||
|
||||
@@ -201,6 +203,13 @@ def get_track_length(scenario_id: str, speaker_id: int) -> int:
|
||||
return len(get_replicas_for_track(scenario_id, speaker_id))
|
||||
|
||||
|
||||
def format_replica_message(session: UserSession) -> str:
|
||||
"""Форматирует сообщение с репликой."""
|
||||
replica_text = get_current_replica_text(session)
|
||||
header = SHOW_REPLICA_TEXT.format(num=session.replica_index + 1)
|
||||
return f"{header}\n\n{replica_text}"
|
||||
|
||||
|
||||
def format_admin_stats() -> str:
|
||||
"""Форматирует статистику для админки."""
|
||||
stats = get_stats()
|
||||
@@ -314,8 +323,7 @@ async def handle_rerecord_previous(
|
||||
replica_text = get_current_replica_text(session)
|
||||
await query.edit_message_text(f"{FIRST_REPLICA_INSTRUCTIONS}\n\n{replica_text}")
|
||||
else:
|
||||
replica_text = get_current_replica_text(session)
|
||||
text = f"{SHOW_REPLICA_TEXT.format(num=session.replica_index + 1)}\n\n{replica_text}"
|
||||
text = format_replica_message(session)
|
||||
await query.edit_message_text(text, reply_markup=get_show_replica_keyboard())
|
||||
|
||||
session.last_bot_message_id = query.message.message_id
|
||||
@@ -371,10 +379,7 @@ async def handle_cancel_restart(
|
||||
"""Обработчик отмены рестарта."""
|
||||
query = update.callback_query
|
||||
session.state = UserState.SHOW_REPLICA
|
||||
replica_text = get_current_replica_text(session)
|
||||
text = (
|
||||
f"{SHOW_REPLICA_TEXT.format(num=session.replica_index + 1)}\n\n{replica_text}"
|
||||
)
|
||||
text = format_replica_message(session)
|
||||
await query.edit_message_text(text, reply_markup=get_show_replica_keyboard())
|
||||
session.last_bot_message_id = query.message.message_id
|
||||
upsert_user_session(session)
|
||||
@@ -430,10 +435,7 @@ async def handle_rerecord_last(
|
||||
track_length = get_track_length(session.scenario_id, session.speaker_id)
|
||||
session.state = UserState.SHOW_REPLICA
|
||||
session.replica_index = track_length - 1
|
||||
replica_text = get_current_replica_text(session)
|
||||
text = (
|
||||
f"{SHOW_REPLICA_TEXT.format(num=session.replica_index + 1)}\n\n{replica_text}"
|
||||
)
|
||||
text = format_replica_message(session)
|
||||
await query.edit_message_text(text, reply_markup=get_show_replica_keyboard())
|
||||
session.last_bot_message_id = query.message.message_id
|
||||
upsert_user_session(session)
|
||||
@@ -497,8 +499,7 @@ async def handle_exit_admin(
|
||||
replica_text = get_current_replica_text(session)
|
||||
await query.edit_message_text(f"{FIRST_REPLICA_INSTRUCTIONS}\n\n{replica_text}")
|
||||
elif session.state == UserState.SHOW_REPLICA:
|
||||
replica_text = get_current_replica_text(session)
|
||||
text = f"{SHOW_REPLICA_TEXT.format(num=session.replica_index + 1)}\n\n{replica_text}"
|
||||
text = format_replica_message(session)
|
||||
await query.edit_message_text(text, reply_markup=get_show_replica_keyboard())
|
||||
elif session.state == UserState.CONFIRM_SAVE:
|
||||
await query.edit_message_text(
|
||||
@@ -547,10 +548,8 @@ async def handle_confirm_upload(
|
||||
"SELECT telegram_id FROM users WHERE id = ?", (waiting_user_id,)
|
||||
).fetchone()
|
||||
if row:
|
||||
await context.bot.send_message(
|
||||
row[0],
|
||||
"🎉 Появился новый сценарий для озвучивания! Используйте /start для продолжения.",
|
||||
)
|
||||
msg = "🎉 Появился новый сценарий! Используйте /start"
|
||||
await context.bot.send_message(row[0], msg)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
@@ -619,8 +618,7 @@ async def handle_voice_message(
|
||||
)
|
||||
else:
|
||||
session.state = UserState.SHOW_REPLICA
|
||||
replica_text = get_current_replica_text(session)
|
||||
text = f"{SHOW_REPLICA_TEXT.format(num=session.replica_index + 1)}\n\n{replica_text}"
|
||||
text = format_replica_message(session)
|
||||
msg_id = await send_message_and_save(
|
||||
update, context, session, text, get_show_replica_keyboard()
|
||||
)
|
||||
@@ -631,7 +629,10 @@ async def handle_voice_message(
|
||||
|
||||
@with_user_and_session
|
||||
async def handle_replica_number_input(
|
||||
update: Update, context: ContextTypes.DEFAULT_TYPE, user: User, session: UserSession | None
|
||||
update: Update,
|
||||
context: ContextTypes.DEFAULT_TYPE,
|
||||
user: User,
|
||||
session: UserSession | None,
|
||||
) -> None:
|
||||
"""Обработчик ввода номера реплики."""
|
||||
if not session or session.state != UserState.ASK_REPLICA_NUMBER:
|
||||
@@ -715,14 +716,21 @@ VOICE_EXPECTED_TEXT = "❌ Пожалуйста, отправьте голосо
|
||||
|
||||
@with_user_and_session
|
||||
async def handle_unexpected_text(
|
||||
update: Update, context: ContextTypes.DEFAULT_TYPE, user: User, session: UserSession | None
|
||||
update: Update,
|
||||
context: ContextTypes.DEFAULT_TYPE,
|
||||
user: User,
|
||||
session: UserSession | None,
|
||||
) -> None:
|
||||
"""Обработчик неожиданных текстовых сообщений."""
|
||||
if not session:
|
||||
await update.message.reply_text("Используйте /start для начала работы с ботом.")
|
||||
return
|
||||
|
||||
voice_states = {UserState.FIRST_REPLICA, UserState.SHOW_REPLICA, UserState.REPEAT_REPLICA}
|
||||
voice_states = {
|
||||
UserState.FIRST_REPLICA,
|
||||
UserState.SHOW_REPLICA,
|
||||
UserState.REPEAT_REPLICA,
|
||||
}
|
||||
if session.state in voice_states:
|
||||
await update.message.reply_text(VOICE_EXPECTED_TEXT)
|
||||
# В других состояниях игнорируем текст (например, INTRO, NO_MORE_SCENARIOS)
|
||||
|
||||
@@ -9,7 +9,6 @@ from src.database import (
|
||||
get_connection,
|
||||
get_replicas_for_track,
|
||||
get_scenario,
|
||||
get_track_speaker_ids,
|
||||
)
|
||||
from src.logger import logger
|
||||
|
||||
@@ -132,7 +131,7 @@ def find_available_track(user_id: int) -> tuple[str, int] | None:
|
||||
if key in track_recordings and user_id in track_recordings[key]:
|
||||
# Пользователь уже записывает эту дорожку — пропускаем
|
||||
continue
|
||||
# Пользователь записывает другую дорожку в этом сценарии — пропускаем весь сценарий
|
||||
# Пользователь записывает другую дорожку в этом сценарии
|
||||
continue
|
||||
|
||||
if key not in track_recordings:
|
||||
|
||||
Reference in New Issue
Block a user