Files
you-music/backend/app/models/models.py
T
2025-10-30 23:50:11 +11:00

76 lines
3.3 KiB
Python

from sqlalchemy import Column, Integer, String, Float, DateTime, ForeignKey, Table, Text, Boolean
from sqlalchemy.orm import relationship
from datetime import datetime, timedelta
from app.db.session import Base
import secrets
# Association table for playlist-music many-to-many relationship
playlist_music = Table(
'playlist_music',
Base.metadata,
Column('playlist_id', Integer, ForeignKey('playlists.id'), primary_key=True),
Column('music_id', Integer, ForeignKey('music.id'), primary_key=True),
Column('position', Integer, default=0),
Column('added_at', DateTime, default=datetime.utcnow),
)
class Music(Base):
__tablename__ = "music"
id = Column(Integer, primary_key=True, index=True)
title = Column(String, index=True)
artist = Column(String, index=True, nullable=True)
album = Column(String, nullable=True)
duration = Column(Float, nullable=True)
file_path = Column(String, unique=True)
file_size = Column(Integer, nullable=True)
file_format = Column(String, nullable=True) # mp3, flac, m4a, wav, ogg, etc.
file_location = Column(String, nullable=True) # Full absolute path for user reference
file_exists = Column(Boolean, default=True) # Track if file still exists on disk
source_url = Column(String, nullable=True)
source_type = Column(String, nullable=True) # local, youtube, bilibili, etc.
thumbnail = Column(String, nullable=True)
lyrics = Column(Text, nullable=True)
share_token = Column(String, unique=True, index=True, nullable=True) # Secure share token
share_token_expires_at = Column(DateTime, nullable=True) # Expiration timestamp
created_at = Column(DateTime, default=datetime.utcnow)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
last_scanned_at = Column(DateTime, nullable=True) # Last time file was verified
playlists = relationship("Playlist", secondary=playlist_music, back_populates="music_items")
def generate_share_token(self, expiration_days: int = 14):
"""Generate a secure random share token with expiration"""
if not self.share_token:
self.share_token = secrets.token_urlsafe(16)
self.share_token_expires_at = datetime.utcnow() + timedelta(days=expiration_days)
def is_share_token_valid(self) -> bool:
"""Check if share token is still valid"""
if not self.share_token or not self.share_token_expires_at:
return False
return datetime.utcnow() < self.share_token_expires_at
class Playlist(Base):
__tablename__ = "playlists"
id = Column(Integer, primary_key=True, index=True)
name = Column(String, unique=True, index=True)
description = Column(Text, nullable=True)
thumbnail = Column(String, nullable=True)
created_at = Column(DateTime, default=datetime.utcnow)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
music_items = relationship("Music", secondary=playlist_music, back_populates="playlists")
class AppSettings(Base):
__tablename__ = "app_settings"
id = Column(Integer, primary_key=True, index=True)
key = Column(String, unique=True, index=True)
value = Column(Text)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)