64 lines
2.0 KiB
Python
64 lines
2.0 KiB
Python
# playlists/playlist_model.py
|
|
from pydantic import BaseModel, Field, validator
|
|
from typing import List, Optional, Literal
|
|
import json
|
|
import db
|
|
|
|
|
|
class RuleSet(BaseModel):
|
|
include_labels: List[str] = []
|
|
exclude_labels: List[str] = []
|
|
include_playlists: List[str] = []
|
|
exclude_playlists: List[str] = []
|
|
date_after: Optional[str] = None
|
|
date_before: Optional[str] = None
|
|
logic: Literal["AND", "OR"] = "AND"
|
|
|
|
def to_json(self) -> str:
|
|
return json.dumps(self.dict(), ensure_ascii=False, indent=2)
|
|
|
|
@classmethod
|
|
def from_json(cls, raw):
|
|
"""Accepte None, str vide ou dict JSON."""
|
|
if not raw:
|
|
return cls()
|
|
if isinstance(raw, dict):
|
|
return cls(**raw)
|
|
try:
|
|
return cls(**json.loads(raw))
|
|
except Exception:
|
|
return cls()
|
|
|
|
|
|
class Playlist(BaseModel):
|
|
id: Optional[int] = None
|
|
name: str
|
|
description: Optional[str] = ""
|
|
type: Literal["manual", "dynamic"] = "manual"
|
|
rules: RuleSet = Field(default_factory=RuleSet)
|
|
|
|
@validator("rules", pre=True, always=True)
|
|
def ensure_rules(cls, v):
|
|
"""Transforme la valeur de rules_json (None, str ou dict) en RuleSet."""
|
|
if isinstance(v, RuleSet):
|
|
return v
|
|
return RuleSet.from_json(v)
|
|
|
|
def save(self):
|
|
"""Insert or update playlist"""
|
|
with db.get_conn() as conn:
|
|
cur = conn.cursor()
|
|
if self.id:
|
|
cur.execute("""
|
|
UPDATE playlists
|
|
SET name=?, description=?, type=?, rules_json=?, updated_at=CURRENT_TIMESTAMP
|
|
WHERE id=?
|
|
""", (self.name, self.description, self.type, self.rules.to_json(), self.id))
|
|
else:
|
|
cur.execute("""
|
|
INSERT INTO playlists (name, description, type, rules_json)
|
|
VALUES (?, ?, ?, ?)
|
|
""", (self.name, self.description, self.type, self.rules.to_json()))
|
|
self.id = cur.lastrowid
|
|
conn.commit()
|