from datetime import datetime from flask_sqlalchemy import SQLAlchemy from werkzeug.security import generate_password_hash, check_password_hash db = SQLAlchemy() class User(db.Model): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(80), unique=True, nullable=False) password_hash = db.Column(db.String(255), nullable=False) role = db.Column(db.String(20), default='streamer', nullable=False) active = db.Column(db.Boolean, default=True, nullable=False) created_at = db.Column(db.DateTime, default=datetime.utcnow, nullable=False) def set_password(self, password: str) -> None: self.password_hash = generate_password_hash(password) def check_password(self, password: str) -> bool: return check_password_hash(self.password_hash, password) class Stream(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(120), nullable=False) slug = db.Column(db.String(120), unique=True, nullable=False) token = db.Column(db.String(120), nullable=False) active = db.Column(db.Boolean, default=True, nullable=False) chat_type = db.Column(db.String(20), default='none', nullable=False) chat_url = db.Column(db.String(500), default='', nullable=False) notes = db.Column(db.Text, default='', nullable=False) created_at = db.Column(db.DateTime, default=datetime.utcnow, nullable=False) updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False) is_live = db.Column(db.Boolean, default=False, nullable=False) last_ready_at = db.Column(db.DateTime) last_not_ready_at = db.Column(db.DateTime) sessions = db.relationship('StreamSession', backref='stream', lazy=True, cascade='all, delete-orphan') class StreamSession(db.Model): id = db.Column(db.Integer, primary_key=True) stream_id = db.Column(db.Integer, db.ForeignKey('stream.id'), nullable=False) status = db.Column(db.String(30), default='offline', nullable=False) publisher_ip = db.Column(db.String(80), default='', nullable=False) source_type = db.Column(db.String(50), default='', nullable=False) source_id = db.Column(db.String(120), default='', nullable=False) video_codec = db.Column(db.String(50), default='', nullable=False) audio_codec = db.Column(db.String(50), default='', nullable=False) width = db.Column(db.Integer) height = db.Column(db.Integer) fps = db.Column(db.Float) bitrate = db.Column(db.Integer) audio_channels = db.Column(db.Integer) audio_sample_rate = db.Column(db.Integer) started_at = db.Column(db.DateTime, default=datetime.utcnow, nullable=False) ended_at = db.Column(db.DateTime) updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False) class EventLog(db.Model): id = db.Column(db.Integer, primary_key=True) stream_id = db.Column(db.Integer, db.ForeignKey('stream.id')) level = db.Column(db.String(20), default='info', nullable=False) message = db.Column(db.Text, nullable=False) created_at = db.Column(db.DateTime, default=datetime.utcnow, nullable=False)