summaryrefslogtreecommitdiff
path: root/nephilim/mpclient.py
diff options
context:
space:
mode:
authorAnton Khirnov <wyskas@gmail.com>2009-03-15 15:46:47 +0100
committerAnton Khirnov <wyskas@gmail.com>2009-03-15 15:46:47 +0100
commitfbd91f4b66e1567083f1ec63b199fd2801ad65de (patch)
tree971ce676ed9f8cfe792c20f98bace91240c8b905 /nephilim/mpclient.py
parent77e198c4d0a30a92b83b0e08d472bc6487bdfa96 (diff)
mpclient: better handling of permissions.
Diffstat (limited to 'nephilim/mpclient.py')
-rw-r--r--nephilim/mpclient.py240
1 files changed, 167 insertions, 73 deletions
diff --git a/nephilim/mpclient.py b/nephilim/mpclient.py
index 7611183..b459c94 100644
--- a/nephilim/mpclient.py
+++ b/nephilim/mpclient.py
@@ -11,10 +11,11 @@ class MPClient(QtCore.QObject):
_cur_lib = None
_cur_playlist = None
_cur_song = None
- _status = {'volume' : None, 'repeat' : None, 'random' : None,
- 'songid' : None, 'playlist' : None, 'playlistlength' : None,
- 'state' : None, 'time' : None, 'length' : None,
- 'xfade' : None, 'updatings_db' : None}
+ _logger = logging.getLogger('mpclient')
+ _status = {'volume' : 0, 'repeat' : 0, 'random' : 0,
+ 'songid' : 0, 'playlist' : 0, 'playlistlength' : 0,
+ 'time' : 0, 'length' : 0, 'xfade' : 0,
+ 'updatings_db' : 0,'state' : 'stop'}
_timer_id = None
@@ -24,27 +25,32 @@ class MPClient(QtCore.QObject):
QtCore.QObject.__init__(self)
self._cur_lib = []
self._cur_playlist = []
+ self._status = dict(MPClient._status)
def connect_mpd(self, host, port, password = None):
"""Connect to MPD@host:port, optionally using password.
- Returns Tue at success, False otherwise."""
+ Returns True at success, False otherwise."""
+
+ self._logger.info('Connecting to MPD...')
if self._client:
+ self._logger.warning('Attempted to connect when already connected.')
return True
+
try:
self._client = mpd.MPDClient()
self._client.connect(host, port)
- except socket.error:
- self._client = None
+ except socket.error, e:
+ self._logger.error('Socket error: %s.'%e)
+ self.disconnect_mpd()
return False
if password:
self.password(password)
if not 'listallinfo' in self.commands():
- logging.error('Don\'t have read permission, diconnecting.')
+ self._logger.error('Don\'t have MPD read permission, diconnecting.')
return self.disconnect_mpd()
- self._status = MPClient._status
self._update_lib()
self._update_playlist()
self._update_current_song()
@@ -52,27 +58,42 @@ class MPClient(QtCore.QObject):
self.emit(QtCore.SIGNAL('connected'))
self.timerEvent(None)
self._timer_id = self.startTimer(500)
+ self._logger.info('Successfully connected to MPD.')
return True
def disconnect_mpd(self):
"""Disconnect from MPD."""
+ self._logger.info('Disconnecting from MPD...')
if self._client:
self._client.close()
self._client.disconnect()
self._client = None
+ else:
+ logging.warning('Attempted to disconnect when not connected.')
+
+ self.killTimer(self._timer_id)
+ self._status = dict(MPClient._status)
+ self._cur_song = None
+ self._cur_lib = []
+ self._cur_playlist = []
+ self.emit(QtCore.SIGNAL('disconnected'))
def password(self, password):
"""Use the password to authenticate with MPD."""
+ if not self._client:
+ return self._logger.error('Not connected.')
try:
self._client.password(password)
logging.info('Successfully authenticated')
except mpd.CommandError:
- logging.error('Incorrect password.')
+ logging.error('Incorrect MPD password.')
def commands(self):
"""List all currently available MPD commands."""
- if self._client:
- return self._client.commands()
+ if not self._client:
+ self._logger.error('Not connected.')
+ return []
+ return self._retrieve(self._client.commands)
def is_connected(self):
"""Returns True if connected to MPD, False otherwise."""
@@ -80,50 +101,54 @@ class MPClient(QtCore.QObject):
def playlist(self):
"""Returns the current playlist."""
- if not self._client:
- return []
return self._cur_playlist
def library(self):
"""Returns current library."""
- if not self._client:
- return []
return self._cur_lib
def current_song(self):
"""Returns the current playing song."""
- if not self._client:
- return None
return self._cur_song
def status(self):
"""Get current MPD status."""
- if not self._client:
- return None
return self._status
def update_db(self, paths = None):
"""Starts MPD database update."""
- if not paths:
- return self._client.update()
- self._client.command_list_ok_begin()
- for path in paths:
- self._client.update(path)
- self._client.command_list_end()
+ if not self._client:
+ return self._logger.error('Not connected.')
+ try:
+ if not paths:
+ return self._client.update()
+ self._client.command_list_ok_begin()
+ for path in paths:
+ self._client.update(path)
+ self._client.command_list_end()
+ except mpd.CommandError, e:
+ self._logger.error('Can\'t update database: %s.'%('don\'t have admin permissions' if 'permission' in str(e)
+ else 'unknown error'))
def outputs(self):
"""Returns an array of configured MPD audio outputs."""
- if self.is_connected():
+ if self._client:
return self._retrieve(self._client.outputs)
else:
return []
def set_output(self, output_id, state):
"""Set audio output output_id to state (0/1)."""
- if state:
- self._client.enableoutput(output_id)
- else:
- self._client.disableoutput(output_id)
+ if not self._client:
+ return self._logger.error('Not connected.')
+ try:
+ if state:
+ self._client.enableoutput(output_id)
+ else:
+ self._client.disableoutput(output_id)
+ except mpd.CommandError, e:
+ self._logger.error('Can\'t set output state: %s.'%('don\'t have control permissions' if 'permission' in str(e)
+ else 'unknown error'))
def urlhandlers(self):
"""Returns an array of available url handlers."""
@@ -134,63 +159,127 @@ class MPClient(QtCore.QObject):
def repeat(self, val):
"""Set repeat playlist to val (True/False)."""
- if isinstance(val, bool):
- val = 1 if val else 0
- self._client.repeat(val)
+ if not self._client:
+ return self._logger.error('Not connected.')
+ try:
+ if isinstance(val, bool):
+ val = 1 if val else 0
+ self._client.repeat(val)
+ except mpd.CommandError, e:
+ self._logger.error('Can\'t set repeat: %s.' %('don\'t have control permissions' if 'permission' in str(e)
+ else 'unknown error'))
+
def random(self, val):
"""Set random playback to val (True, False)."""
- if isinstance(val, bool):
- val = 1 if val else 0
- self._client.random(val)
+ if not self._client:
+ return self._logger.error('Not connected.')
+ try:
+ if isinstance(val, bool):
+ val = 1 if val else 0
+ self._client.random(val)
+ except mpd.CommandError, e:
+ self._logger.error('Can\'t set random: %s.' %('don\'t have control permissions' if 'permission' in str(e)
+ else 'unknown error'))
def is_playing(self):
"""Returns True if MPD is playing, False otherwise."""
- return self.status()['state'] == 'play'
+ return self._status['state'] == 'play'
def play(self, id = None):
"""Play song with ID id or next song if id is None."""
- self._playCalled = True
- if id:
- self._client.playid(id)
- else:
- self._client.playid()
-
+ if not self._client:
+ return self._logger.error('Not connected.')
+ try:
+ if id:
+ self._client.playid(id)
+ else:
+ self._client.playid()
+ except mpd.CommandError, e:
+ self._logger.error('Can\'t start playback: %s.' %('don\'t have control permissions' if 'permission' in str(e)
+ else 'unknown error'))
def pause(self):
"""Pause playing."""
- self._client.pause(1)
+ if not self._client:
+ return self._logger.error('Not connected.')
+ try:
+ self._client.pause(1)
+ except mpd.CommandError, e:
+ self._logger.error('Can\'t pause: %s.' %('don\'t have control permissions' if 'permission' in str(e)
+ else 'unknown error'))
def resume(self):
"""Resume playing."""
- self._client.pause(0)
+ if not self._client:
+ return self._logger.error('Not connected.')
+
+ try:
+ self._client.pause(0)
+ except mpd.CommandError, e:
+ self._logger.error('Can\'t resume playback: %s.' %('don\'t have control permissions' if 'permission' in str(e)
+ else 'unknown error'))
def next(self):
"""Move on to the next song in the playlist."""
- self._playCalled = False
- self._client.next()
+ if not self._client:
+ return self._logger.error('Not connected.')
+ try:
+ self._client.next()
+ except mpd.CommandError, e:
+ self._logger.error('Can\'t skip to next song: %s.' %('don\'t have control permissions' if 'permission' in str(e)
+ else 'unknown error'))
def previous(self):
"""Move back to the previous song in the playlist."""
- self._client.previous()
+ if not self._client:
+ return self._logger.error('Not connected.')
+ try:
+ self._client.previous()
+ except mpd.CommandError, e:
+ self._logger.error('Can\'t skip to previous song: %s.' %('don\'t have control permissions' if 'permission' in str(e)
+ else 'unknown error'))
def stop(self):
"""Stop playing."""
- self._client.stop()
-
+ if not self._client:
+ return self._logger.error('Not connected.')
+ try:
+ self._client.stop()
+ except mpd.CommandError, e:
+ self._logger.error('Can\'t stop playback: %s.' %('don\'t have control permissions' if 'permission' in str(e)
+ else 'unknown error'))
def seek(self, time):
- """Seek to time."""
- if self._status and self._status['songid'] > 0:
- self._client.seekid(self._status['songid'], time)
+ """Seek to time (in seconds)."""
+ if not self._client:
+ return self._logger.error('Not connected.')
+ try:
+ if self._status['songid'] > 0:
+ self._client.seekid(self._status['songid'], time)
+ except mpd.CommandError, e:
+ self._logger.error('Can\'t seek: %s.' %('don\'t have control permissions' if 'permission' in str(e)
+ else 'unknown error'))
def delete(self, list):
"""Remove all song IDs in list from the playlist."""
- self._client.command_list_ok_begin()
- for id in list:
- self._client.deleteid(id)
- self._client.command_list_end()
- self._update_playlist()
+ if not self._client:
+ return self._logger.error('Not connected.')
+ try:
+ self._client.command_list_ok_begin()
+ for id in list:
+ self._client.deleteid(id)
+ self._client.command_list_end()
+ except mpd.CommandError, e:
+ self._logger.error('Can\'t delete from playlist: %s.' %('don\'t have control permissions' if 'permission' in str(e)
+ else 'unknown error'))
def clear(self):
"""Clear current playlist."""
- self._client.clear()
- self._update_playlist()
-
+ if not self._client:
+ return self._logger.error('Not connected.')
+ try:
+ self._client.clear()
+ except mpd.CommandError, e:
+ self._logger.error('Can\'t clear playlist: %s.' %('don\'t have control permissions' if 'permission' in str(e)
+ else 'unknown error'))
def add(self, paths):
"""Add all files in paths to the current playlist."""
+ if not self._client:
+ return self._logger.error('Not connected.')
+
try:
self._client.command_list_ok_begin()
for path in paths:
@@ -199,15 +288,23 @@ class MPClient(QtCore.QObject):
self._update_playlist()
if self._status['state'] == 'stop':
self.play(ret[0])
- except mpd.CommandError:
- logging.error('Cannot add some files, check permissions.')
+ except mpd.CommandError, e:
+ self._logger.error('Can\'t add to playlist: %s.'%('don\'t have add permissions' if 'permission' in str(e)
+ else 'probably wrong file permissions'))
def volume(self):
- return int(self.status()['volume'])
+ """Get current volume."""
+ return int(self._status['volume'])
def set_volume(self, volume):
"""Set volume to volume."""
- volume = min(100, max(0, volume))
- self._client.setvol(volume)
+ if not self._client:
+ return self._logger.error('Not connected.')
+ try:
+ volume = min(100, max(0, volume))
+ self._client.setvol(volume)
+ except mpd.CommandError, e:
+ self._logger.error('Can\'t set volume: %s.' %('don\'t have control permissions' if 'permission' in str(e)
+ else 'unknown error'))
def _retrieve(self, method):
"""Makes sure only one call is made at a time to MPD."""
@@ -216,7 +313,7 @@ class MPClient(QtCore.QObject):
ret = method()
except socket.error:
self._retr_mutex.unlock()
- self._client = None
+ self.disconnect_mpd()
return None
self._retr_mutex.unlock()
@@ -245,7 +342,7 @@ class MPClient(QtCore.QObject):
self._cur_song = Song(song)
def _update_status(self):
"""Get current status"""
- if self.is_connected() == False:
+ if not self._client:
return None
ret = self._retrieve(self._client.status)
if not ret:
@@ -274,10 +371,7 @@ class MPClient(QtCore.QObject):
self._status = self._update_status()
if not self._status:
- self._client = None
- self.emit(QtCore.SIGNAL('disconnected'))
- self.killTimer(self._timer_id)
- return
+ return self.disconnect_mpd()
self._update_current_song()