]> kaliko git repositories - python-musicpd.git/blob - doc/source/use.rst
Add readpicture command
[python-musicpd.git] / doc / source / use.rst
1 Using the client library
2 =========================
3
4 Introduction
5 ------------
6
7 The client library can be used as follows:
8
9 .. code-block:: python
10
11     client = musicpd.MPDClient()       # create client object
12     client.connect()                   # use MPD_HOST/MPD_PORT if set else
13                                        #   test ${XDG_RUNTIME_DIR}/mpd/socket for existence
14                                        #   fallback to localhost:6600
15                                        # connect support host/port argument as well
16     print(client.mpd_version)          # print the mpd protocol version
17     print(client.cmd('foo', 42))       # print result of the request "cmd foo 42"
18                                        # (nb. for actual command, see link to the protocol below)
19     client.disconnect()                # disconnect from the server
20
21 In the example above `cmd` in not an actual MPD command, for a list of
22 supported commands, their arguments (as MPD currently understands
23 them), and the functions used to parse their responses see :ref:`commands`.
24
25 See the `MPD protocol documentation`_ for more details.
26
27 Command lists
28 -------------
29
30 Command lists are also supported using `command_list_ok_begin()` and
31 `command_list_end()` :
32
33 .. code-block:: python
34
35     client.command_list_ok_begin()       # start a command list
36     client.update()                      # insert the update command into the list
37     client.status()                      # insert the status command into the list
38     results = client.command_list_end()  # results will be a list with the results
39
40 Ranges
41 ------
42
43 Provide a 2-tuple as argument for command supporting ranges (cf. `MPD protocol documentation`_ for more details).
44 Possible ranges are: "START:END", "START:" and ":" :
45
46 .. code-block:: python
47
48     # An intelligent clear
49     # clears played track in the queue, currentsong included
50     pos = client.currentsong().get('pos', 0)
51     # the 2-tuple range object accepts str, no need to convert to int
52     client.delete((0, pos))
53     # missing end interpreted as highest value possible, pay attention still need a tuple.
54     client.delete((pos,))  # purge queue from current to the end
55
56 A notable case is the `rangeid` command allowing an empty range specified
57 as a single colon as argument (i.e. sending just ":"):
58
59 .. code-block:: python
60
61     # sending "rangeid :" to clear the range, play everything
62     client.rangeid(())  # send an empty tuple
63
64 Empty start in range (i.e. ":END") are not possible and will raise a CommandError.
65
66 Iterators
67 ----------
68
69 Commands may also return iterators instead of lists if `iterate` is set to
70 `True`:
71
72 .. code-block:: python
73
74     client.iterate = True
75     for song in client.playlistinfo():
76         print song['file']
77
78 Idle prefixed commands
79 ----------------------
80
81 Each command have a *send\_<CMD>* and a *fetch\_<CMD>* variant, which allows to
82 send a MPD command and then fetch the result later.
83 This is useful for the idle command:
84
85 .. code-block:: python
86
87     >>> client.send_idle()
88     # do something else or use function like select()
89     # http://docs.python.org/howto/sockets.html#non-blocking-sockets
90     # ex. select([client], [], [])
91     >>> events = client.fetch_idle()
92
93     # more complex use for example, with glib/gobject:
94     >>> def callback(source, condition):
95     >>>    changes = client.fetch_idle()
96     >>>    print changes
97     >>>    return False  # removes the IO watcher
98
99     >>> client.send_idle()
100     >>> gobject.io_add_watch(client, gobject.IO_IN, callback)
101     >>> gobject.MainLoop().run()
102
103 Fetching binary content (cover art)
104 -----------------------------------
105
106 Fetching album covers is possible with albumart, here is an example:
107
108 .. code-block:: python
109
110     >>> cli = musicpd.MPDClient()
111     >>> cli.connect()
112     >>> track = "Steve Reich/1978-Music for 18 Musicians"
113     >>> aart = cli.albumart(track, 0)
114     >>> received = int(aart.get('binary'))
115     >>> size = int(aart.get('size'))
116     >>> with open('/tmp/cover', 'wb') as cover:
117     >>>     # aart = {'size': 42, 'binary': 2051, data: bytes(...)}
118     >>>     cover.write(aart.get('data'))
119     >>>     while received < size:
120     >>>         aart = cli.albumart(track, received)
121     >>>         cover.write(aart.get('data'))
122     >>>         received += int(aart.get('binary'))
123     >>>     if received != size:
124     >>>         print('something went wrong', file=sys.stderr)
125     >>> cli.disconnect()
126
127 A `CommandError` is raised if the album does not expose a cover.
128
129 You can also use `readpicture` command to fetch embedded picture:
130
131 .. code-block:: python
132
133     >>> cli = musicpd.MPDClient()
134     >>> cli.connect()
135     >>> track = 'muse/Amon Tobin/2011-ISAM/01-Amon Tobin - Journeyman.mp3'
136     >>> rpict = cli.readpicture(track, 0)
137     >>> if not rpict:
138     >>>     print('No embedded picture found', file=sys.stderr)
139     >>>     sys.exit(1)
140     >>> size = int(rpict['size'])
141     >>> done = int(rpict['binary'])
142     >>> with open('/tmp/cover', 'wb') as cover:
143     >>>     cover.write(rpict['data'])
144     >>>     while size > done:
145     >>>         rpict = cli.readpicture(track, done)
146     >>>         done += int(rpict['binary'])
147     >>>         print(f'writing {rpict["binary"]}, done {100*done/size:03.0f}%')
148     >>>         cover.write(rpict['data'])
149     >>> cli.disconnect()
150
151 Refer to `MPD protocol documentation`_ for the meaning of `binary`, `size` and `data`.
152
153 .. _MPD protocol documentation: http://www.musicpd.org/doc/protocol/