polina_tg #1

Merged
Arxip222 merged 6 commits from polina_tg into main 2025-12-22 21:41:08 +03:00
10 changed files with 237 additions and 0 deletions
Showing only changes of commit 697644269e - Show all commits

9
.gitignore vendored Normal file
View File

@ -0,0 +1,9 @@
# Python
__pycache__/
*.pyc
*.pyo
*.pyd
.Python
.env
venv/
.venv/

93
create_database.py Normal file
View File

@ -0,0 +1,93 @@
import os
import sys
from sqlalchemy import create_engine, inspect
from sqlalchemy.orm import declarative_base, Session
from sqlalchemy import Column, String, DateTime, Boolean, Integer, Text
import uuid
from datetime import datetime
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
DB_PATH = os.path.join(BASE_DIR, 'data', 'bot.db')
DATABASE_URL = f"sqlite:///{DB_PATH}"
os.makedirs(os.path.dirname(DB_PATH), exist_ok=True)
if os.path.exists(DB_PATH):
try:
temp_engine = create_engine(DATABASE_URL)
inspector = inspect(temp_engine)
tables = inspector.get_table_names()
if tables:
sys.exit(0)
except:
pass
choice = input("Перезаписать БД? (y/N): ")
if choice.lower() != 'y':
sys.exit(0)
engine = create_engine(DATABASE_URL, echo=False)
Base = declarative_base()
class UserModel(Base):
__tablename__ = "users"
user_id = Column("user_id", String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
telegram_id = Column("telegram_id", String(100), nullable=False, unique=True)
created_at = Column("created_at", DateTime, default=datetime.utcnow, nullable=False)
role = Column("role", String(20), default="user", nullable=False)
is_premium = Column(Boolean, default=False, nullable=False)
premium_until = Column(DateTime, nullable=True)
questions_used = Column(Integer, default=0, nullable=False)
username = Column(String(100), nullable=True)
first_name = Column(String(100), nullable=True)
last_name = Column(String(100), nullable=True)
class PaymentModel(Base):
__tablename__ = "payments"
id = Column(Integer, primary_key=True, autoincrement=True)
payment_id = Column(String(36), default=lambda: str(uuid.uuid4()), nullable=False, unique=True)
user_id = Column(Integer, nullable=False)
amount = Column(String(20), nullable=False)
currency = Column(String(3), default="RUB", nullable=False)
status = Column(String(20), default="pending", nullable=False)
created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
yookassa_payment_id = Column(String(100), unique=True, nullable=True)
description = Column(Text, nullable=True)
try:
Base.metadata.create_all(bind=engine)
session = Session(bind=engine)
existing = session.query(UserModel).filter_by(telegram_id="123456789").first()
if not existing:
test_user = UserModel(
telegram_id="123456789",
username="test_user",
first_name="Test",
last_name="User",
is_premium=True
)
session.add(test_user)
existing_payment = session.query(PaymentModel).filter_by(yookassa_payment_id="test_yoo_001").first()
if not existing_payment:
test_payment = PaymentModel(
user_id=123456789,
amount="500.00",
status="succeeded",
description="Test payment",
yookassa_payment_id="test_yoo_001"
)
session.add(test_payment)
session.commit()
session.close()
except Exception as e:
print(f"Ошибка: {e}")
import traceback
traceback.print_exc()

31
create_tables.py Executable file
View File

@ -0,0 +1,31 @@
import sys
import os
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
try:
from tg_bot.infrastructure.database.database import engine, Base
from tg_bot.infrastructure.database import models
print("СОЗДАНИЕ ТАБЛИЦ БАЗЫ ДАННЫХ")
Base.metadata.create_all(bind=engine)
print("Таблицы успешно созданы!")
print(" • users")
print(" • payments")
print()
print(f"База данных: {engine.url}")
db_path = "data/bot.db"
if os.path.exists(db_path):
size = os.path.getsize(db_path)
print(f"Размер файла: {size} байт")
else:
print("Файл БД не найден, но таблицы созданы")
except Exception as e:
print(f"Ошибка: {e}")
import traceback
traceback.print_exc()
print("=" * 50)

9
requirements.txt Normal file
View File

@ -0,0 +1,9 @@
pydantic>=2.5.0
pydantic-settings>=2.1.0
python-dotenv>=1.0.0
aiogram>=3.10.0
sqlalchemy>=2.0.0
yookassa>=2.4.0
fastapi>=0.104.0
uvicorn>=0.24.0
python-multipart>=0.0.6

View File

View File

41
tg_bot/config/settings.py Normal file
View File

@ -0,0 +1,41 @@
import os
from typing import List, Optional
from pydantic_settings import BaseSettings, SettingsConfigDict
class Settings(BaseSettings):
model_config = SettingsConfigDict(
env_file=".env",
env_file_encoding="utf-8",
case_sensitive=True,
extra="allow"
)
APP_NAME: str = "VibeLawyerBot"
VERSION: str = "0.1.0"
DEBUG: bool = True
TELEGRAM_BOT_TOKEN: str = ""
FREE_QUESTIONS_LIMIT: int = 5
PAYMENT_AMOUNT: float = 500.0
DATABASE_URL: str = "sqlite:///data/bot.db"
LOG_LEVEL: str = "INFO"
LOG_FILE: str = "logs/bot.log"
YOOKASSA_SHOP_ID: str = "1230200"
YOOKASSA_SECRET_KEY: str = "test_GVoixmlp0FqohXcyFzFHbRlAUoA3B1I2aMtAkAE_ubw"
YOOKASSA_RETURN_URL: str = "https://t.me/vibelawyer_bot"
YOOKASSA_WEBHOOK_SECRET: Optional[str] = None
ADMIN_IDS_STR: str = ""
@property
def ADMIN_IDS(self) -> List[int]:
if not self.ADMIN_IDS_STR:
return []
try:
return [int(x.strip()) for x in self.ADMIN_IDS_STR.split(",")]
except:
return []
settings = Settings()

View File

@ -0,0 +1,15 @@
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from tg_bot.config.settings import settings
engine = create_engine(
settings.DATABASE_URL,
echo=settings.DEBUG
)
SessionLocal = sessionmaker(bind=engine)
def create_tables():
from .models import Base
Base.metadata.create_all(bind=engine)
print(f"Таблицы созданы: {settings.DATABASE_URL}")

View File

@ -0,0 +1,39 @@
import uuid
from datetime import datetime
from sqlalchemy import Column, String, DateTime, Boolean, Integer, Text
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class UserModel(Base):
__tablename__ = "users"
user_id = Column("user_id", String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
telegram_id = Column("telegram_id", String(100), nullable=False, unique=True)
created_at = Column("created_at", DateTime, default=datetime.utcnow, nullable=False)
role = Column("role", String(20), default="user", nullable=False)
is_premium = Column(Boolean, default=False, nullable=False)
premium_until = Column(DateTime, nullable=True)
questions_used = Column(Integer, default=0, nullable=False)
username = Column(String(100), nullable=True)
first_name = Column(String(100), nullable=True)
last_name = Column(String(100), nullable=True)
class PaymentModel(Base):
__tablename__ = "payments"
id = Column(Integer, primary_key=True, autoincrement=True)
payment_id = Column(String(36), default=lambda: str(uuid.uuid4()), nullable=False, unique=True)
user_id = Column(Integer, nullable=False)
amount = Column(String(20), nullable=False)
currency = Column(String(3), default="RUB", nullable=False)
status = Column(String(20), default="pending", nullable=False)
created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
yookassa_payment_id = Column(String(100), unique=True, nullable=True)
description = Column(Text, nullable=True)
def __repr__(self):
return f"<Payment(user_id={self.user_id}, amount={self.amount}, status={self.status})>"