X-Git-Url: https://git.kaliko.me/?a=blobdiff_plain;f=sima%2Fmpdclient.py;h=6b461bacc28e86476bf5c0471ba419c3d2c2562f;hb=31cb581a72f067990a5dc3917542d15505f86990;hp=e8f69729974567f4b44cecca3a61d62181485103;hpb=6ce8e09e316f315d437377ab0850da045cb0f041;p=mpd-sima.git diff --git a/sima/mpdclient.py b/sima/mpdclient.py index e8f6972..6b461ba 100644 --- a/sima/mpdclient.py +++ b/sima/mpdclient.py @@ -26,7 +26,7 @@ from musicpd import MPDClient, MPDError # local import -from .lib.meta import Artist, Album +from .lib.meta import Meta, Artist, Album from .lib.track import Track from .lib.simastr import SimaStr from .utils.leven import levenshtein_ratio @@ -44,7 +44,7 @@ def bl_artist(func): return func(*args, **kwargs) result = func(*args, **kwargs) if not result: - return + return None names = list() for art in result.names: if cls.database.get_bl_artist(art, add_not=True): @@ -52,27 +52,32 @@ def bl_artist(func): continue names.append(art) if not names: - return + return None resp = Artist(name=names.pop(), mbid=result.mbid) for name in names: resp.add_alias(name) return resp return wrapper + def tracks_wrapper(func): + """Convert plain track mapping as returned by MPDClient into :py:obj:Track + objects. This decorator accepts single track or list of tracks as input. + """ @wraps(func) def wrapper(*args, **kwargs): ret = func(*args, **kwargs) if isinstance(ret, dict): return Track(**ret) - elif isinstance(ret, list): - return [Track(**t) for t in ret] + return [Track(**t) for t in ret] return wrapper # / decorators + def blacklist(artist=False, album=False, track=False): - #pylint: disable=C0111,W0212 + # pylint: disable=C0111,W0212 field = (album, track) + def decorated(func): def wrapper(*args, **kwargs): if not args[0].database: @@ -110,11 +115,16 @@ class MPD(MPDClient): .. note:: - * find methods are looking for exact match of the object provided attributes in MPD music library + * find methods are looking for exact match of the object provided + attributes in MPD music library * search methods are looking for exact match + fuzzy match. """ needed_cmds = ['status', 'stats', 'add', 'find', 'search', 'currentsong', 'ping'] + needed_mbid_tags = {'Artist', 'Album', 'AlbumArtist', + 'Title', 'Track', 'Genre', + 'MUSICBRAINZ_ARTISTID', 'MUSICBRAINZ_ALBUMID', + 'MUSICBRAINZ_ALBUMARTISTID', 'MUSICBRAINZ_TRACKID'} database = None def __init__(self, daemon): @@ -128,11 +138,7 @@ class MPD(MPDClient): # ######### Overriding MPDClient ########### def __getattr__(self, cmd): """Wrapper around MPDClient calls for abstract overriding""" - track_wrapped = { - 'currentsong', - 'find', - 'playlistinfo', - } + track_wrapped = {'currentsong', 'find', 'playlistinfo', } if cmd in track_wrapped: return tracks_wrapper(super().__getattr__(cmd)) return super().__getattr__(cmd) @@ -166,7 +172,7 @@ class MPD(MPDClient): try: self.password(password) except (MPDError, IOError) as err: - raise PlayerError("Could not connect to '%s': %s", (host, err)) + raise PlayerError("Could not connect to '%s': %s" % (host, err)) # Controls we have sufficient rights available_cmd = self.commands() for cmd in MPD.needed_cmds: @@ -176,20 +182,24 @@ class MPD(MPDClient): 'but command "%s" not available' % (host, cmd)) # Controls use of MusicBrainzIdentifier - # TODO: Use config instead of Artist object attibute? - if self.use_mbid: - tt = self.tagtypes() - if 'MUSICBRAINZ_ARTISTID' not in tt: - self.log.warning('Use of MusicBrainzIdentifier is set but MPD is ' - 'not providing related metadata') + self.tagtypes('clear') + for tag in MPD.needed_mbid_tags: + self.tagtypes('enable', tag) + if self.daemon.config.get('sima', 'musicbrainzid'): + tt = set(self.tagtypes()) + if len(MPD.needed_mbid_tags & tt) != len(MPD.needed_mbid_tags): + self.log.warning('Use of MusicBrainzIdentifier is set but MPD ' + 'is not providing related metadata') self.log.info(tt) self.log.warning('Disabling MusicBrainzIdentifier') - self.use_mbid = False + self.use_mbid = Meta.use_mbid = False else: - self.log.debug('Available metadata: %s', tt) # pylint: disable=no-member + self.log.debug('Available metadata: %s', tt) + self.use_mbid = Meta.use_mbid = True else: self.log.warning('Use of MusicBrainzIdentifier disabled!') self.log.info('Consider using MusicBrainzIdentifier for your music library') + self.use_mbid = Meta.use_mbid = False self._reset_cache() # ######### / Overriding MPDClient ######### @@ -251,8 +261,7 @@ class MPD(MPDClient): super().__getattr__('add')(payload.file) elif isinstance(payload, list): self.command_list_ok_begin() - for tr in payload: - self.add(tr) + map(self.add, payload) self.command_list_end() else: self.log.error('Cannot add %s', payload) @@ -303,10 +312,11 @@ class MPD(MPDClient): """ if isinstance(what, Artist): return self._find_art(what) - elif isinstance(what, Album): + if isinstance(what, Album): return self._find_alb(what) - elif isinstance(what, str): + if isinstance(what, str): return self.find_tracks(Artist(name=what)) + raise PlayerError('Bad input argument') def _find_art(self, artist): tracks = set() @@ -339,7 +349,7 @@ class MPD(MPDClient): """ Search artists based on a fuzzy search in the media library >>> art = Artist(name='the beatles', mbid=) # mbid optional - >>> bea = player.search_artist(art)c + >>> bea = player.search_artist(art) >>> print(bea.names) >>> ['The Beatles', 'Beatles', 'the beatles']