1(import argparse mpd threading signal
2 [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]])
7
8;; The socketserver needs to be closed from a different thread. This
9;; 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.SIGINT
15 (fn [signal frame] (self.lock.release)))
16 (.__init__ threading.Thread self))
17
18 (defn run [self]
19 (self.lock.acquire)
20 (self.server.shutdown)))
21
22(defclass ConnHandler []
23 (defn __init__ [self playback beets]
24 (setv self.disabled-tags [])
25 (setv self.playback playback)
26 (setv self.beets beets))
27
28 (defn __call__ [self cmd]
29 (.handle commands self cmd)))
30
31(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))))
36
37(defmain [&rest args]
38 (let [parser (argparse.ArgumentParser)]
39 (parser.add-argument "LIBRARY" :type str
40 :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)