1 # -*- coding: utf-8 -*-
3 # python-musicpd: Python MPD client library
4 # Copyright (C) 2014-2015 Kaliko Jack <kaliko@azylum.org>
6 # python-musicpdasio is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU Lesser General Public License as published by
8 # the Free Software Foundation, either version 3 of the License, or
9 # (at your option) any later version.
11 # python-musicpd is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU Lesser General Public License for more details.
16 # You should have received a copy of the GNU Lesser General Public License
17 # along with python-musicpd. If not, see <http://www.gnu.org/licenses/>.
22 print('Failed to import asyncio, need python >= 3.4')
26 HELLO_PREFIX = "OK MPD "
32 class MPDError(Exception):
35 class ConnectionError(MPDError):
38 class ProtocolError(MPDError):
41 class CommandError(MPDError):
44 class CommandListError(MPDError):
47 class PendingCommandError(MPDError):
50 class IteratingError(MPDError):
53 loop = asyncio.get_event_loop()
62 return '{0}, {1}… ({2})'.format(self.err, self.resp[:15], self.version)
64 class MPDProto(asyncio.Protocol):
65 def __init__(self, future, payload):
67 self.payload = payload
68 self.sess = Response()
70 def connection_made(self, transport):
71 self.transport = transport
72 self.transport.write(bytes('{}\n'.format(self.payload), 'utf-8'))
74 def data_received(self, data):
75 rcv = data.decode('utf-8')
77 self.sess.err = 'Connection lost while reading line'
78 self.future.set_result(self.sess)
79 raise ConnectionError("Connection lost while reading line")
83 if rcv.startswith(HELLO_PREFIX):
84 self.sess.version = rcv[len(HELLO_PREFIX):]
86 self.transport.close()
88 # set the result on the Future so that the main() coroutine can
90 if rcv.startswith(ERROR_PREFIX):
91 self.sess.err = rcv[len(ERROR_PREFIX):].strip()
92 self.future.set_result(self.sess)
96 self.future.set_result(self.sess)
99 future = asyncio.Future()
101 cli = MPDProto(future, payload)
102 # kick off a task to create the connection to MPD.
103 asyncio.async(loop.create_connection(lambda: cli, host='192.168.0.20', port=6600))
105 future.set_result((None, None, None))
107 # return the future for the main() coroutine to wait on.
114 logging.basicConfig(level=logging.DEBUG)
115 res = yield from command('currentsongt')
117 raise CommandError(res.err)
121 if __name__ == '__main__':
122 loop.run_until_complete(main())