""" ORM models for database """ from datetime import datetime from sqlalchemy import Column, Integer, BigInteger, String, Boolean, DateTime, Text, ForeignKey from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import relationship Base = declarative_base() class User(Base): """User model""" __tablename__ = "users" user_id = Column(BigInteger, primary_key=True, unique=True, index=True) username = Column(String(255), nullable=True) first_name = Column(String(255), nullable=True) last_name = Column(String(255), nullable=True) is_admin = Column(Boolean, default=False) is_blocked = Column(Boolean, default=False) created_at = Column(DateTime, default=datetime.utcnow) updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) # Relationships tasks = relationship("Task", back_populates="user") def __repr__(self): return f"" class Task(Base): """Task model""" __tablename__ = "tasks" id = Column(BigInteger, primary_key=True, index=True) user_id = Column(BigInteger, ForeignKey("users.user_id"), nullable=False, index=True) # Index for frequent queries task_type = Column(String(50), nullable=False) # download, process, etc. status = Column(String(50), default="pending", index=True) # Index for status filtering url = Column(Text, nullable=True) file_path = Column(String(500), nullable=True) progress = Column(Integer, default=0) # 0-100 error_message = Column(String(1000), nullable=True) # Limit to 1000 characters created_at = Column(DateTime, default=datetime.utcnow, index=True) # Index for sorting updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) completed_at = Column(DateTime, nullable=True) # Relationships user = relationship("User", back_populates="tasks") def __repr__(self): return f"" class Download(Base): """Download model""" __tablename__ = "downloads" id = Column(Integer, primary_key=True, index=True) task_id = Column(BigInteger, ForeignKey("tasks.id"), nullable=False) url = Column(Text, nullable=False) download_type = Column(String(50), nullable=False) # direct, ytdlp file_path = Column(String(500), nullable=True) file_size = Column(Integer, nullable=True) duration = Column(Integer, nullable=True) # Download duration in seconds created_at = Column(DateTime, default=datetime.utcnow) # Relationships task = relationship("Task") def __repr__(self): return f"" class OTPCode(Base): """One-time password code model for web interface authentication""" __tablename__ = "otp_codes" id = Column(Integer, primary_key=True, index=True) user_id = Column(BigInteger, ForeignKey("users.user_id"), nullable=False, index=True) code = Column(String(6), nullable=False, index=True) # 6-digit code expires_at = Column(DateTime, nullable=False, index=True) used = Column(Boolean, default=False, index=True) created_at = Column(DateTime, default=datetime.utcnow) # Relationships user = relationship("User") def __repr__(self): return f""