1(import mpd socketserver
2 [mpd.exceptions [*]]
3 [mpd.parser [parse-command]])
4(require [hy.contrib.walk [let]])
5
6(defclass Handler [socketserver.BaseRequestHandler]
7 (defn send-resp [self resp]
8 (self.request.sendall (.encode (+ (str resp) mpd.DELIMITER))))
9
10 (defn dispatch-single [self cmd]
11 (let [resp (self.server.handler cmd)]
12 (if resp (self.send-resp resp))))
13
14 (defn dispatch-list [self list]
15 (setv ok-list? (= list.name "command_list_ok_begin"))
16 ;; TODO: Response can be combined into a single packet
17 (for [cmd list.args]
18 (self.dispatch-single cmd)
19 (if ok-list? (self.send-resp "list_OK"))))
20
21 (defn dispatch [self input]
22 (try
23 (setv cmd (parse-command input))
24 (except [ValueError]
25 (self.send-resp (MPDException ACKError.UNKNOWN "syntax error"))
26 (return)))
27 (try
28 (if (cmd.list?)
29 (self.dispatch-list cmd)
30 (self.dispatch-single cmd))
31 (except [e MPDException]
32 (self.send-resp e))
33 (else (self.send-resp "OK"))))
34
35 (defn handle [self]
36 (self.send-resp (% "OK MPD %s" mpd.VERSION))
37 (with [file (self.request.makefile)]
38 (for [input (iter (mpd.util.Reader file) "")]
39 (self.dispatch input)))))
40
41(defclass Server [socketserver.ThreadingTCPServer]
42 (defn __init__ [self addr handler]
43 (.__init__ socketserver.ThreadingTCPServer self addr Handler)
44 (setv self.daemon_threads True)
45 (setv self.handler handler)))