import datetime from sqlalchemy import create_engine, Column, Integer, String, Boolean, DateTime, Text, text from sqlalchemy.orm import declarative_base, sessionmaker Base = declarative_base() class Job(Base): __tablename__ = "jobs" id = Column(Integer, primary_key=True, autoincrement=True) name = Column(String(200), nullable=False) stream_url = Column(String(1000), nullable=False) stream_type = Column(String(20), default="auto") output_format = Column(String(10), default="") max_duration = Column(Integer, nullable=True) extra_ffmpeg_args = Column(String(500), default="") segment_duration = Column(Integer, nullable=True) schedule_enabled = Column(Boolean, default=False) schedule_once = Column(Boolean, default=False) schedule_date = Column(String(10), default="") schedule_days = Column(String(50), default="*") schedule_start = Column(String(5), default="") schedule_stop = Column(String(5), default="") schedule_end_date = Column(String(10), default="") pre_buffer = Column(Integer, default=0) post_buffer = Column(Integer, default=0) description = Column(Text, default="") plik_enabled = Column(Boolean, default=False) delete_after_upload = Column(Boolean, default=False) ntfy_enabled = Column(Boolean, default=False) station_id = Column(Integer, nullable=True) created_at = Column(DateTime, default=datetime.datetime.utcnow) updated_at = Column(DateTime, default=datetime.datetime.utcnow, onupdate=datetime.datetime.utcnow) class Station(Base): __tablename__ = "stations" id = Column(Integer, primary_key=True, autoincrement=True) name = Column(String(200), nullable=False) stream_url = Column(String(1000), nullable=False) stream_type = Column(String(20), default="auto") description = Column(Text, default="") created_at = Column(DateTime, default=datetime.datetime.utcnow) updated_at = Column(DateTime, default=datetime.datetime.utcnow, onupdate=datetime.datetime.utcnow) class Recording(Base): __tablename__ = "recordings" id = Column(Integer, primary_key=True, autoincrement=True) job_id = Column(Integer, nullable=True) job_name = Column(String(200), nullable=False) stream_url = Column(String(1000), nullable=False) stream_type = Column(String(20), default="") output_dir = Column(String(500), default="") output_file = Column(String(500), default="") pid = Column(Integer, nullable=True) status = Column(String(20), default="running") # running, stopped, completed, error started_at = Column(DateTime, default=datetime.datetime.utcnow) stopped_at = Column(DateTime, nullable=True) scheduled_stop = Column(DateTime, nullable=True) segment_mode = Column(Boolean, default=False) is_scheduled = Column(Boolean, default=False) error_message = Column(Text, nullable=True) file_size = Column(Integer, nullable=True) plik_url = Column(String(1000), nullable=True) class LogEntry(Base): __tablename__ = "logs" id = Column(Integer, primary_key=True, autoincrement=True) timestamp = Column(DateTime, default=datetime.datetime.utcnow) level = Column(String(10), default="INFO") message = Column(Text, nullable=False) job_name = Column(String(200), nullable=True) _engine = None _SessionLocal = None def init_db(db_path: str): global _engine, _SessionLocal _engine = create_engine(f"sqlite:///{db_path}", connect_args={"check_same_thread": False}) Base.metadata.create_all(_engine) _SessionLocal = sessionmaker(bind=_engine) _migrate(_engine) def _migrate(engine): with engine.connect() as conn: for stmt in [ "ALTER TABLE recordings ADD COLUMN file_size INTEGER", "ALTER TABLE jobs ADD COLUMN station_id INTEGER", "ALTER TABLE jobs ADD COLUMN pre_buffer INTEGER DEFAULT 0", "ALTER TABLE jobs ADD COLUMN post_buffer INTEGER DEFAULT 0", "ALTER TABLE recordings ADD COLUMN plik_url VARCHAR(1000)", ]: try: conn.execute(text(stmt)) conn.commit() except Exception: pass def get_session(): return _SessionLocal()