Files
2026-02-12 10:50:49 +01:00

88 lines
2.9 KiB
Python

from __future__ import annotations
from datetime import datetime
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import UniqueConstraint
db = SQLAlchemy()
class Display(db.Model):
__tablename__ = "displays"
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(120), nullable=False)
public_id = db.Column(db.String(64), nullable=False, unique=True, index=True)
last_seen = db.Column(db.DateTime, nullable=True)
is_online = db.Column(db.Boolean, nullable=False, default=False)
def __repr__(self) -> str:
return f"<Display {self.public_id} online={self.is_online}>"
class Video(db.Model):
__tablename__ = "videos"
id = db.Column(db.Integer, primary_key=True)
filename = db.Column(db.String(255), nullable=False, unique=True)
duration = db.Column(db.Float, nullable=True) # seconds
uploaded_at = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
def __repr__(self) -> str:
return f"<Video {self.filename}>"
class Event(db.Model):
__tablename__ = "events"
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(120), nullable=False)
udp_port = db.Column(db.Integer, nullable=True)
udp_payload = db.Column(db.String(255), nullable=True)
cooldown_seconds = db.Column(db.Integer, nullable=False, default=2)
last_triggered = db.Column(db.DateTime, nullable=True)
# Optional scheduled time could be added later (left out of DB intentionally unless required).
maps = db.relationship("EventDisplayMap", backref="event", cascade="all, delete-orphan")
def __repr__(self) -> str:
return f"<Event {self.name}>"
class EventDisplayMap(db.Model):
__tablename__ = "event_display_maps"
__table_args__ = (
UniqueConstraint("event_id", "display_id", name="uq_event_display"),
)
id = db.Column(db.Integer, primary_key=True)
event_id = db.Column(db.Integer, db.ForeignKey("events.id"), nullable=False)
display_id = db.Column(db.Integer, db.ForeignKey("displays.id"), nullable=False)
video_id = db.Column(db.Integer, db.ForeignKey("videos.id"), nullable=False)
display = db.relationship("Display")
video = db.relationship("Video")
class EventLog(db.Model):
__tablename__ = "event_logs"
id = db.Column(db.Integer, primary_key=True)
event_id = db.Column(db.Integer, db.ForeignKey("events.id"), nullable=False)
triggered_at = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
trigger_source = db.Column(db.String(32), nullable=False) # manual|udp
source_ip = db.Column(db.String(64), nullable=True)
event = db.relationship("Event")
class AppSetting(db.Model):
__tablename__ = "app_settings"
# Small key/value store for global settings (SQLite-friendly)
key = db.Column(db.String(64), primary_key=True)
value = db.Column(db.String(255), nullable=False)