1(import [random [randrange]] os)2(require [hy.contrib.walk [let]])34(defclass Song []5 (setv path None)6 (setv metadata {})7 (setv position 0)89 (defn __init__ [self path metadata]10 (if (not (os.path.isfile path))11 (raise (FileNotFoundError12 (.format "file '{}' does not exist" path))))1314 (setv self.path path)15 (setv self.metadata metadata)))1617(defclass Playlist []18 (setv mode {19 :repeat False :random False20 :single False :consume False21 })2223 (defn __init__ [self]24 (setv self._current None)25 (setv self._next None)26 (setv self._list []))2728 (defn __iter__ [self]29 (iter self._list))3031 (defn _get-song [self index]32 (let [song (get self._list index)]33 (setv song.position index)34 song))3536 (defn psize [self]37 (len self._list))3839 (defn current [self]40 (if (is None self._current)41 None42 (get self._list self._current)))4344 (defn add [self song]45 (if (isinstance song Song)46 (.append self._list song)47 (raise (TypeError "not an instance of Song"))))4849 (defn get [self index]50 (._get-song self index))5152 (defn remove [self range]53 (let [start (. range start) stop (. range stop)]54 (if (= (len range) 1)55 (.pop self._list start)56 (setv self._list (cut self._list start stop)))))5758 (defn reset [self]59 (setv self._current None)60 (setv self._next None))6162 (defn nextup [self index]63 (if (>= index (len self._list))64 (raise (IndexError "song position out of range"))65 (setv self._next index)))6667 (defn next [self]68 (defn next-index [mode]69 (cond70 [(not self._list) None]71 [(is None self._current) 0]72 [(get mode :single)73 (if (get mode :repeat)74 (. self _current)75 None)]76 [True77 (let [n (if (get mode :random)78 (randrange (len self._list))79 (inc self._current))]80 (if (>= n (len self._list))81 (if (get mode :repeat) 0 None)82 n))]))8384 (if (get self.mode :consume)85 (.pop self._current))86 (let [idx (if (is None self._next)87 (next-index self.mode)88 (. self _next))]89 (setv self._next None)90 (setv self._current idx)91 (if (is None idx)92 None93 (._get-song self idx)))))