Files
BDFR_Web/web_interface/app/models.py
T

130 lines
5.0 KiB
Python

"""
Database models for scheduled downloads.
"""
from sqlalchemy import Column, String, Integer, Boolean, DateTime, Time, ForeignKey, Text
from sqlalchemy.orm import relationship
from datetime import datetime, time as time_type
import uuid
import pytz
from .database import Base
def generate_uuid():
"""Generate a UUID string"""
return str(uuid.uuid4())
class ScheduledTask(Base):
"""
Represents a scheduled download task.
Tasks run at a specified time each day.
"""
__tablename__ = "scheduled_tasks"
# Primary key
id = Column(String(36), primary_key=True, default=generate_uuid)
# Task identification
name = Column(String(255), nullable=False, index=True)
enabled = Column(Boolean, default=True, nullable=False, index=True)
# Download configuration
source_type = Column(String(20), nullable=False) # "subreddit" or "user"
source_name = Column(String(255), nullable=False, index=True)
download_mode = Column(String(20), nullable=False) # "download", "archive", "clone"
# Filter options
limit = Column(Integer, default=25, nullable=False)
sort = Column(String(20), default="hot", nullable=False)
time_filter = Column(String(20), default="day", nullable=False) # Always "day" for daily tasks
min_score = Column(Integer, nullable=True)
no_dupes = Column(Boolean, default=True, nullable=False) # Always true for scheduled
simple_check = Column(Boolean, default=False, nullable=False)
# Scheduling
schedule_frequency = Column(String(20), default="daily", nullable=False)
run_time = Column(Time, nullable=False) # Time of day to run
timezone = Column(String(50), default="UTC", nullable=False)
# Metadata
created_at = Column(DateTime, default=lambda: datetime.now(pytz.UTC), nullable=False)
updated_at = Column(DateTime, default=lambda: datetime.now(pytz.UTC), onupdate=lambda: datetime.now(pytz.UTC), nullable=False)
last_run_at = Column(DateTime, nullable=True, index=True)
next_run_at = Column(DateTime, nullable=True, index=True)
# Authentication
auth_state = Column(String(255), nullable=True)
# Relationships
executions = relationship("TaskExecutionHistory", back_populates="task", cascade="all, delete-orphan")
def to_dict(self):
"""Convert to dictionary for JSON serialization"""
return {
"id": self.id,
"name": self.name,
"enabled": self.enabled,
"source_type": self.source_type,
"source_name": self.source_name,
"download_mode": self.download_mode,
"limit": self.limit,
"sort": self.sort,
"time_filter": self.time_filter,
"min_score": self.min_score,
"no_dupes": self.no_dupes,
"simple_check": self.simple_check,
"schedule_frequency": self.schedule_frequency,
"run_time": self.run_time.isoformat() if self.run_time else None,
"timezone": self.timezone,
"created_at": self.created_at.isoformat() if self.created_at else None,
"updated_at": self.updated_at.isoformat() if self.updated_at else None,
"last_run_at": self.last_run_at.isoformat() if self.last_run_at else None,
"next_run_at": self.next_run_at.isoformat() if self.next_run_at else None,
"auth_state": self.auth_state
}
class TaskExecutionHistory(Base):
"""
Records each execution of a scheduled task.
Tracks success/failure and metrics.
"""
__tablename__ = "task_execution_history"
# Primary key
id = Column(String(36), primary_key=True, default=generate_uuid)
# Foreign key to task
task_id = Column(String(36), ForeignKey("scheduled_tasks.id", ondelete="CASCADE"), nullable=False, index=True)
# Execution details
started_at = Column(DateTime, default=lambda: datetime.now(pytz.UTC), nullable=False, index=True)
completed_at = Column(DateTime, nullable=True)
status = Column(String(20), default="queued", nullable=False, index=True) # queued, running, success, failed, skipped
# Results
items_found = Column(Integer, default=0, nullable=False)
items_downloaded = Column(Integer, default=0, nullable=False)
error_message = Column(Text, nullable=True)
# Link to download
download_id = Column(String(255), nullable=True, index=True)
# Relationships
task = relationship("ScheduledTask", back_populates="executions")
def to_dict(self):
"""Convert to dictionary for JSON serialization"""
return {
"id": self.id,
"task_id": self.task_id,
"started_at": self.started_at.isoformat() if self.started_at else None,
"completed_at": self.completed_at.isoformat() if self.completed_at else None,
"status": self.status,
"items_found": self.items_found,
"items_downloaded": self.items_downloaded,
"error_message": self.error_message,
"download_id": self.download_id
}