X-Git-Url: http://git.kaliko.me/?a=blobdiff_plain;f=sima%2Flib%2Ftrack.py;h=329392c93746c8098cfe6b6fb99b8e63ac59c5a3;hb=f2d54b31a8da9852fc532cc90b29623eabe27b9d;hp=3926c4d97c628541128aa7470054edcc9c9c1926;hpb=5b2c4dfff740e7c915951d57b6516b3146cad066;p=mpd-sima.git diff --git a/sima/lib/track.py b/sima/lib/track.py index 3926c4d..329392c 100644 --- a/sima/lib/track.py +++ b/sima/lib/track.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2009, 2010, 2011, 2013, 2014 Jack Kaliko +# Copyright (c) 2009-2021 kaliko # Copyright (c) 2009 J. Alexander Treuman (Tag collapse method) # Copyright (c) 2008 Rick van Hattem # @@ -23,35 +23,40 @@ import time -from .meta import Artist +from .meta import Artist, SEPARATOR class Track: """ Track object. - Instanciate with Player replies. + Instantiate with Player replies. + + :param str file: media file, defaults to ``None`` + :param int time: duration in second, defaults to 0 + :param int pos: position in queue, defaults to -1 + :param str title|artist|album: defaults to "" + :param str musicbrainz_artistid|musicbrainz_albumartistid: MusicBrainz IDs, defaults to ``None`` """ def __init__(self, file=None, time=0, pos=-1, **kwargs): self.title = self.artist = self.album = self.albumartist = '' self.musicbrainz_artistid = self.musicbrainz_albumartistid = None self.pos = int(pos) - self._empty = False self._file = file + self._empty = False + self._time = time if not kwargs: self._empty = True - self._time = time self.__dict__.update(**kwargs) self.tags_to_collapse = ['artist', 'album', 'title', 'date', 'genre', 'albumartist', 'musicbrainz_artistid', 'musicbrainz_albumartistid'] # have tags been collapsed? - self.collapse_tags_bool = False self.collapsed_tags = list() # Needed for multiple tags which returns a list instead of a string - self.collapse_tags() + self._collapse_tags() - def collapse_tags(self): + def _collapse_tags(self): """ Necessary to deal with tags defined multiple times. These entries are set as lists instead of strings. @@ -60,12 +65,11 @@ class Track: if tag not in self.tags_to_collapse: continue if isinstance(value, list): - self.collapse_tags_bool = True self.collapsed_tags.append(tag) - self.__dict__.update({tag: ', '.join(set(value))}) + self.__dict__.update({tag: SEPARATOR.join(value)}) def __repr__(self): - return '%s(artist="%s", album="%s", title="%s", filename="%s")' % ( + return '%s(artist="%s", album="%s", title="%s", file="%s")' % ( self.__class__.__name__, self.artist, self.album, @@ -74,8 +78,8 @@ class Track: ) def __str__(self): - return '{artist} - {album} - {title} ({duration})'.format( - duration=self.duration, + return '{artist} - {album} - {title} ({length})'.format( + length=self.length, **self.__dict__ ) @@ -91,8 +95,7 @@ class Track: def __hash__(self): if self.file: return hash(self.file) - else: - return id(self) + return id(self) def __eq__(self, other): return hash(self) == hash(other) @@ -101,6 +104,8 @@ class Track: return hash(self) != hash(other) def __bool__(self): + if not self._file: + return False return not self._empty @property @@ -116,28 +121,42 @@ class Track: """set time property""" self._time = int(value) - time = property(get_time, set_time, doc='song duration in seconds') + time = property(get_time, set_time, doc='song duration in seconds (use :attr:`length` for human readable time)') @property - def duration(self): - """Compute fancy duration""" - temps = time.gmtime(int(self.time)) + def length(self): + """Get a fancy duration as ``%H:%M:%S`` (use :attr:`time` to get duration in second only)""" + temps = time.gmtime(int(self.time)) #TODO: returns a date not a duration if temps.tm_hour: fmt = '%H:%M:%S' else: fmt = '%M:%S' return time.strftime(fmt, temps) - def get_artist(self): - """Get artist object from track""" - name = self.artist - mbid = self.musicbrainz_artistid - if self.albumartist and self.albumartist != 'Various Artists': - name = self.albumartist - if (self.musicbrainz_albumartistid and - self.musicbrainz_albumartistid != '89ad4ac3-39f7-470e-963a-56509c546377'): - mbid = self.musicbrainz_albumartistid - return Artist(name=name, mbid=mbid) + @property + def genres(self): + """Fetches Genres for the track + Multivalue genre are dealt with: + * when genre tag is multivalued + * when single tag uses coma or semi-colon separator + """ + if 'genre' not in self.__dict__: + return [] + genres = self.genre.split(SEPARATOR) + for sep in [',', ';']: + if sep in self.genre: + genres = [g for multi in genres for g in multi.split(sep) if g] + return list(map(str.strip, genres)) + + @property + def Artist(self): + """Get the :class:`sima.lib.meta.Artist` associated to this track""" + if not self.artist: + if not self.musicbrainz_artistid: + return Artist(name='[unknown]', + mbid='125ec42a-7229-4250-afc5-e057484327fe') + return Artist(name='[unknown]', **self.__dict__) + return Artist(**self.__dict__) # VIM MODLINE # vim: ai ts=4 sw=4 sts=4 expandtab