-
Notifications
You must be signed in to change notification settings - Fork 0
/
mpd_wrapper.py
166 lines (146 loc) · 4.69 KB
/
mpd_wrapper.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
From quantenschaum / piripherals, licenced under the GPL v3.0
https://github.com/quantenschaum/piripherals/blob/master/piripherals/mpd.py
"""
try:
from mpd import MPDClient
from mpd import ConnectionError as MPDConnectionError
from mpd import CommandError as MPDCommandError
except:
pass
__all__ = ['MPD']
class MPD(object):
"""Wrapper for `MPDClient`_ that adds
- automatic reconnect on connection loss, see `issue64`_.
- custom methods
- volume limit
It supports all methods of ``MPDClient``.
Args:
maxvol (int): volume limit
*args: args for ``MPDClient``
**kwargs: kwargs for ``MPDClient``
.. _MPDClient: https://github.com/Mic92/python-mpd2
.. _issue64: https://github.com/Mic92/python-mpd2/issues/64
"""
_mpd = None
_connect_args = None
def __init__(self, maxvol=100, *args, **kwargs):
self._mpd = MPDClient(*args, **kwargs)
self.maxvol = maxvol
self.timeout = 5
def __getattr__(self, name):
a = getattr(self._mpd, name)
if not callable(a):
return a
def with_reconnect(*args, **kwargs):
try:
return a(*args, **kwargs)
except (MPDConnectionError, ConnectionError, OSError) as e:
cargs = self._connect_args
if not cargs:
raise
cargs, ckwargs = cargs
self.connect(*cargs, **ckwargs)
return a(*args, **kwargs)
return with_reconnect
def __setattr__(self, name, value):
if hasattr(self._mpd, name):
setattr(self._mpd, name, value)
else:
self.__dict__[name] = value
def connect(self, *args, **kwargs):
"""establish connection
disconnects if already connected, host and port are stored,
will reconnect automatically if connection is lost
All parameters are passed to ``MPDClient.connect()``.
Args:
host (str): hostname/ip/socket
port (int): port, usually 6600
"""
self.disconnect()
self._connect_args = args, kwargs
self._mpd.connect(*args, **kwargs)
def disconnect(self):
"""disconnect, disables auto reconnect"""
try:
self._connect_args = None
self._mpd.close()
self._mpd.disconnect()
except (MPDConnectionError, ConnectionError) as e:
pass
finally:
self._mpd._reset()
def volume(self, v=None):
"""adjust volume
Args:
v: int = absolute volume 0-100,
str = absolute volume or relative volume change if prefixed
with ``+`` or ``-``
Return:
int: volume if v was omitted
"""
if v is not None:
try:
if v.startswith('+') or v.startswith('-'):
v = self.volume() + int(v)
except:
pass
self.setvol(max(0, min(self.maxvol, v)))
else:
return int(self.status()['volume'])
def state(self):
"""current playback state
Return:
str: ``stop``, ``play``, ``pause``
"""
return self.status()['state']
def toggle_play(self):
"""play or pause
- start playing if stopped or paused
- pause if playing
"""
if self.state() == 'stop':
self.play()
else:
self.pause()
def save_playlist(self, name):
"""save current playlist
if playlist exists, it will be overwritten
Args:
name (str): name of the playlist
"""
self.del_playlist(name)
self.save(name)
def del_playlist(self, name):
"""delete playlist
if playlist exists, this does nothing
Args:
name (str): name of the playlist to delete
"""
try:
self.rm(name)
except MPDCommandError:
pass
def has_playlist(self, name):
"""check for playlist
Args:
name (str): name of the playlist to look for
Return:
bool: true if playlist exists
"""
for i in self.listplaylists():
if name == i['playlist']:
return True
return False
def load_playlist(self, name):
"""load a playlist
- replaces current playlist with the named playlist
- if the given playlist does not exists, this does nothing
Args:
name (str): name of the playlist to load
"""
if self.has_playlist(name):
self.clear()
self.load(name)