1(import argparse mpv mpd threading signal
2 [mpd.server [Server]]
3 [protocol [commands control status]])
4(require [hy.contrib.walk [let]])
5
6;; The socketserver needs to be closed from a different thread. This
7;; thread blocks until a signal is received and closes both the mpv
8;; connection and the socket server.
9(defclass CleanupThread [threading.Thread]
10 (defn --init-- [self socket-server mpv]
11 (setv self.server socket-server)
12 (setv self.mpv mpv)
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 (self.mpv.shutdown)))
22
23(defn start-server [addr port path]
24 (let [mpv-conn (mpv.Connection path)
25 handler (fn [cmd] (commands.call mpv-conn cmd))]
26 (with [server (Server (, addr port) handler)]
27 (.start (CleanupThread server mpv-conn))
28 (server.serve-forever))))
29
30(defmain [&rest args]
31 (let [parser (argparse.ArgumentParser)]
32 (parser.add-argument "PATH" :type string
33 :help "path to mpv IPC server")
34 (parser.add-argument "-p" :type int :metavar "PORT"
35 :default 6600 :help "TCP port used by the MPD server")
36 (parser.add-argument "-a" :type string :metavar "ADDR"
37 :default "localhost" :help "Address the MPD server binds to")
38 (let [args (parser.parse-args)]
39 (start-server args.a args.p args.PATH)))
40 0)