first commit
This commit is contained in:
108
app/models.py
Normal file
108
app/models.py
Normal file
@@ -0,0 +1,108 @@
|
||||
import uuid
|
||||
from datetime import datetime
|
||||
|
||||
from flask_login import UserMixin
|
||||
from werkzeug.security import check_password_hash, generate_password_hash
|
||||
|
||||
from .extensions import db
|
||||
|
||||
|
||||
class Company(db.Model):
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
name = db.Column(db.String(120), unique=True, nullable=False)
|
||||
created_at = db.Column(db.DateTime, default=datetime.utcnow, nullable=False)
|
||||
|
||||
users = db.relationship("User", back_populates="company", cascade="all, delete-orphan")
|
||||
displays = db.relationship("Display", back_populates="company", cascade="all, delete-orphan")
|
||||
playlists = db.relationship("Playlist", back_populates="company", cascade="all, delete-orphan")
|
||||
|
||||
|
||||
class User(UserMixin, db.Model):
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
username = db.Column(db.String(80), unique=True, nullable=False)
|
||||
email = db.Column(db.String(255), unique=True, nullable=True)
|
||||
password_hash = db.Column(db.String(255), nullable=True)
|
||||
is_admin = db.Column(db.Boolean, default=False, nullable=False)
|
||||
|
||||
company_id = db.Column(db.Integer, db.ForeignKey("company.id"), nullable=True)
|
||||
company = db.relationship("Company", back_populates="users")
|
||||
|
||||
created_at = db.Column(db.DateTime, default=datetime.utcnow, nullable=False)
|
||||
|
||||
def set_password(self, password: str):
|
||||
self.password_hash = generate_password_hash(password)
|
||||
|
||||
def check_password(self, password: str) -> bool:
|
||||
if not self.password_hash:
|
||||
return False
|
||||
return check_password_hash(self.password_hash, password)
|
||||
|
||||
|
||||
class Playlist(db.Model):
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
company_id = db.Column(db.Integer, db.ForeignKey("company.id"), nullable=False)
|
||||
name = db.Column(db.String(120), nullable=False)
|
||||
created_at = db.Column(db.DateTime, default=datetime.utcnow, nullable=False)
|
||||
|
||||
company = db.relationship("Company", back_populates="playlists")
|
||||
items = db.relationship(
|
||||
"PlaylistItem",
|
||||
back_populates="playlist",
|
||||
cascade="all, delete-orphan",
|
||||
order_by="PlaylistItem.position.asc()",
|
||||
)
|
||||
|
||||
|
||||
class PlaylistItem(db.Model):
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
playlist_id = db.Column(db.Integer, db.ForeignKey("playlist.id"), nullable=False)
|
||||
|
||||
# image|video|webpage
|
||||
item_type = db.Column(db.String(20), nullable=False)
|
||||
title = db.Column(db.String(200), nullable=True)
|
||||
|
||||
# For image/video: stored under /static/uploads
|
||||
file_path = db.Column(db.String(400), nullable=True)
|
||||
# For webpage
|
||||
url = db.Column(db.String(1000), nullable=True)
|
||||
|
||||
# For image/webpage duration (seconds). For video we play until ended.
|
||||
duration_seconds = db.Column(db.Integer, default=10, nullable=False)
|
||||
position = db.Column(db.Integer, default=0, nullable=False)
|
||||
|
||||
created_at = db.Column(db.DateTime, default=datetime.utcnow, nullable=False)
|
||||
|
||||
playlist = db.relationship("Playlist", back_populates="items")
|
||||
|
||||
|
||||
class Display(db.Model):
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
company_id = db.Column(db.Integer, db.ForeignKey("company.id"), nullable=False)
|
||||
name = db.Column(db.String(120), nullable=False)
|
||||
token = db.Column(db.String(64), unique=True, nullable=False, default=lambda: uuid.uuid4().hex)
|
||||
|
||||
assigned_playlist_id = db.Column(db.Integer, db.ForeignKey("playlist.id"), nullable=True)
|
||||
assigned_playlist = db.relationship("Playlist")
|
||||
|
||||
created_at = db.Column(db.DateTime, default=datetime.utcnow, nullable=False)
|
||||
|
||||
company = db.relationship("Company", back_populates="displays")
|
||||
|
||||
|
||||
class DisplaySession(db.Model):
|
||||
"""Tracks active viewers of a display token so we can limit concurrent usage."""
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
display_id = db.Column(db.Integer, db.ForeignKey("display.id"), nullable=False, index=True)
|
||||
sid = db.Column(db.String(64), nullable=False)
|
||||
|
||||
created_at = db.Column(db.DateTime, default=datetime.utcnow, nullable=False)
|
||||
last_seen_at = db.Column(db.DateTime, default=datetime.utcnow, nullable=False, index=True)
|
||||
|
||||
# Optional diagnostics
|
||||
ip = db.Column(db.String(64), nullable=True)
|
||||
user_agent = db.Column(db.String(300), nullable=True)
|
||||
|
||||
display = db.relationship("Display")
|
||||
|
||||
__table_args__ = (db.UniqueConstraint("display_id", "sid", name="uq_display_session_display_sid"),)
|
||||
Reference in New Issue
Block a user