]> kaliko git repositories - mpd-sima.git/blobdiff - sima/lib/track.py
Exposes genres in Track objets
[mpd-sima.git] / sima / lib / track.py
index 3926c4d97c628541128aa7470054edcc9c9c1926..329392c93746c8098cfe6b6fb99b8e63ac59c5a3 100644 (file)
@@ -1,6 +1,6 @@
 # -*- coding: utf-8 -*-
 
 # -*- coding: utf-8 -*-
 
-# Copyright (c) 2009, 2010, 2011, 2013, 2014 Jack Kaliko <kaliko@azylum.org>
+# Copyright (c) 2009-2021 kaliko <kaliko@azylum.org>
 # Copyright (c) 2009 J. Alexander Treuman (Tag collapse method)
 # Copyright (c) 2008 Rick van Hattem
 #
 # Copyright (c) 2009 J. Alexander Treuman (Tag collapse method)
 # Copyright (c) 2008 Rick van Hattem
 #
 
 import time
 
 
 import time
 
-from .meta import Artist
+from .meta import Artist, SEPARATOR
 
 class Track:
     """
     Track object.
 
 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)
     """
 
     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._file = file
+        self._empty = False
+        self._time = time
         if not kwargs:
             self._empty = True
         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.__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.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.
         """
         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):
             if tag not in self.tags_to_collapse:
                 continue
             if isinstance(value, list):
-                self.collapse_tags_bool = True
                 self.collapsed_tags.append(tag)
                 self.collapsed_tags.append(tag)
-                self.__dict__.update({tag: ', '.join(set(value))})
+                self.__dict__.update({tag: SEPARATOR.join(value)})
 
     def __repr__(self):
 
     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,
             self.__class__.__name__,
             self.artist,
             self.album,
@@ -74,8 +78,8 @@ class Track:
         )
 
     def __str__(self):
         )
 
     def __str__(self):
-        return '{artist} - {album} - {title} ({duration})'.format(
-                duration=self.duration,
+        return '{artist} - {album} - {title} ({length})'.format(
+                length=self.length,
                 **self.__dict__
                 )
 
                 **self.__dict__
                 )
 
@@ -91,8 +95,7 @@ class Track:
     def __hash__(self):
         if self.file:
             return hash(self.file)
     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)
 
     def __eq__(self, other):
         return hash(self) == hash(other)
@@ -101,6 +104,8 @@ class Track:
         return hash(self) != hash(other)
 
     def __bool__(self):
         return hash(self) != hash(other)
 
     def __bool__(self):
+        if not self._file:
+            return False
         return not self._empty
 
     @property
         return not self._empty
 
     @property
@@ -116,28 +121,42 @@ class Track:
         """set time property"""
         self._time = int(value)
 
         """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
 
     @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)
 
         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
 
 # VIM MODLINE
 # vim: ai ts=4 sw=4 sts=4 expandtab