1(import argparse mpd threading signal2 [beets.library [Library]]3 [mpd.server [Server]]4 [protocol [control connection commands playback queue status]]5 [playback.playback [Playback]])6(require [hy.contrib.walk [let]])78;; The socketserver needs to be closed from a different thread. This9;; thread blocks until a signal is received then closes the server.10(defclass CleanupThread [threading.Thread]11 (defn __init__ [self socket-server]12 (setv self.server socket-server)13 (setv self.lock (threading.Semaphore 0))14 (signal.signal signal.SIGINT15 (fn [signal frame] (self.lock.release)))16 (.__init__ threading.Thread self))1718 (defn run [self]19 (self.lock.acquire)20 (self.server.shutdown)))2122(defclass ConnHandler []23 (defn __init__ [self playback beets]24 (setv self.disabled-tags [])25 (setv self.playback playback)26 (setv self.beets beets))2728 (defn __call__ [self cmd]29 (.handle commands self cmd)))3031(defn start-server [addr port playback beets]32 (let [handler (ConnHandler playback beets)]33 (with [server (Server (, addr port) handler)]34 (.start (CleanupThread server))35 (server.serve-forever))))3637(defmain [&rest args]38 (let [parser (argparse.ArgumentParser)]39 (parser.add-argument "LIBRARY" :type str40 :help "Path to the beets database")41 (parser.add-argument "-p" :type int :metavar "PORT"42 :default 6600 :help "TCP port used by the MPD server")43 (parser.add-argument "-a" :type str :metavar "ADDR"44 :default "localhost" :help "Address the MPD server binds to")45 (let [args (parser.parse-args)]46 (start-server args.a args.p (Playback) (Library args.LIBRARY))))47 0)