summaryrefslogtreecommitdiff
path: root/model.lisp
diff options
context:
space:
mode:
authorColin Okay <colin@cicadas.surf>2022-10-27 06:57:19 -0500
committerColin Okay <colin@cicadas.surf>2022-10-27 06:57:19 -0500
commitf0eff7d9c69de2e6c7257b8d94e7deb7b89becdf (patch)
tree283dabb89380e6c976038ff701afec0a79b297ba /model.lisp
parent05d38ae1fba94569e1fd4f53ca3ad33c5af6e016 (diff)
Add+Move: user and model files, moved code into files
Diffstat (limited to 'model.lisp')
-rw-r--r--model.lisp96
1 files changed, 96 insertions, 0 deletions
diff --git a/model.lisp b/model.lisp
new file mode 100644
index 0000000..246e27f
--- /dev/null
+++ b/model.lisp
@@ -0,0 +1,96 @@
+;;;; model.lisp
+
+(in-package :vampire)
+
+(defclass/bknr keyed ()
+ ((key
+ :r :std (nuid)
+ :index-type string-unique-index
+ :index-reader object-with-key)))
+
+(defclass/bknr user (keyed)
+ ((name :with :std "")
+ (playlists :with :std (list))
+ (pw pwhash :with)))
+
+(defclass/bknr playlist (keyed)
+ ((title :with :std (default-name "playlist"))
+ (tracks editors :with :std (list))
+ (cover-image :with :std nil :doc "A url to the cover of this album.")
+ (user :with
+ :std (error "A USER is required to have created the content."))))
+
+(defmethod initialize-instance :after ((pl playlist) &key)
+ (pushnew pl (user-playlists (playlist-user pl)) :test #'eq))
+
+
+(defclass/bknr track (keyed)
+ ((source file title artist album thumb-url duration codec :with)
+ (playlists :with :std (list) :doc "A list of playlists in which this track appears")))
+
+
+;;; MODEL OPERATIONS
+
+(defun user-with-key (key)
+ (when-let (obj (object-with-key key))
+ (when (typep obj 'user)
+ obj)))
+
+(defun playlist-duration (pl)
+ (reduce #'+
+ (playlist-tracks pl)
+ :key 'track-duration
+ :initial-value 0))
+
+(defun add-track (tr pl &optional (n -1))
+ (setf (playlist-tracks pl)
+ (insert-nth tr n (playlist-tracks pl))))
+
+(defun remove-nth-from-playlist (pl n)
+ (multiple-value-bind (newlist track)
+ (remove-nth n (playlist-tracks pl) t)
+ (setf (playlist-tracks pl) newlist
+ (track-playlists track) (delete pl (track-playlists track)
+ :test #'eq :count 1))))
+
+(defun track-with-source (source)
+ (find source (store-objects-with-class 'track) :test #'string-equal :key 'track-source))
+
+;;; TRANSACTIONS
+
+(defun new-user (&key name)
+ (with-transaction ()
+ (make-instance 'user :name name)))
+
+(defun append-track (pl tr)
+ (with-transaction ()
+ (add-track tr pl)))
+
+(defun delete-track-at (pl pos)
+ (when-let (tr (nth pos (playlist-tracks pl)))
+ (with-transaction ()
+ (setf (playlist-tracks pl)
+ (delete tr (playlist-tracks pl)))
+ t)))
+
+(defun swap-tracks (pl n m)
+ (unless (or (minusp (min m n))
+ (>= (max m n) (length (playlist-tracks pl)) ))
+ (with-transaction ()
+ (setf (playlist-tracks pl)
+ (nswap (playlist-tracks pl) n m)))))
+
+(defun new-track (file trackinfo)
+ "Trackinfo is a plist containing information about the track to create."
+ (with-transaction ()
+ (let ((track (apply #'make-instance 'track trackinfo)))
+ (setf (track-file track) (namestring file))
+ track)))
+
+(defun new-playlist (user &key title)
+ (with-transaction ()
+ (make-instance 'playlist :title title :user user)))
+
+(defun update-playlist-title (playlist title)
+ (with-transaction ()
+ (setf (playlist-title playlist) title)))