import logging import os import socket from datetime import datetime from sqlalchemy import create_engine, Column, Integer, String, DateTime, Enum, Text from sqlalchemy.orm import declarative_base, sessionmaker import enum # Get Hostname for namespacing HOSTNAME = socket.gethostname() # Setup Logging log_dir = "logs" os.makedirs(log_dir, exist_ok=True) log_file = os.path.join(log_dir, f"transcriber_{HOSTNAME}_{datetime.now().strftime('%Y%m%d')}.log") logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', handlers=[ logging.FileHandler(log_file), logging.StreamHandler() ] ) logger = logging.getLogger(__name__) # Database Setup Base = declarative_base() DB_FILE = f"job_history_{HOSTNAME}.db" class JobStatus(enum.Enum): PENDING = "pending" PROCESSING = "processing" COMPLETED = "completed" FAILED = "failed" class Job(Base): __tablename__ = 'jobs' id = Column(Integer, primary_key=True) file_path = Column(String, unique=True, nullable=False) status = Column(Enum(JobStatus), default=JobStatus.PENDING) error_message = Column(Text, nullable=True) last_updated = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) # Track progress of individual steps step_extract = Column(String, default="pending") # pending, done, failed step_transcribe = Column(String, default="pending") step_translate = Column(String, default="pending") step_embed = Column(String, default="pending") engine = create_engine(f'sqlite:///{DB_FILE}') Base.metadata.create_all(engine) Session = sessionmaker(bind=engine) def get_job(file_path): session = Session() job = session.query(Job).filter_by(file_path=file_path).first() if not job: job = Job(file_path=file_path) session.add(job) session.commit() session.refresh(job) # Ensure we have the ID and defaults # Detach from session so we can use it after session.close() session.expunge(job) session.close() return job def update_job_status(file_path, status, error=None): session = Session() job = session.query(Job).filter_by(file_path=file_path).first() if job: job.status = status if error: job.error_message = str(error) session.commit() session.close() def update_step(file_path, step_name, status): session = Session() job = session.query(Job).filter_by(file_path=file_path).first() if job: setattr(job, step_name, status) session.commit() session.close() def get_failed_jobs(): session = Session() jobs = session.query(Job).filter_by(status=JobStatus.FAILED).all() session.close() return [j.file_path for j in jobs]