]> kaliko git repositories - mpd-sima.git/blobdiff - sima/lib/track.py
Mainly use literal for list/dict and f-strings when possible
[mpd-sima.git] / sima / lib / track.py
index b5ffc15545d0092303d51bc266d67e3adeb117ee..2df220cc849811e48ac95e342302f4a7257cbdf5 100644 (file)
@@ -1,6 +1,6 @@
 # -*- coding: utf-8 -*-
 
-# Copyright (c) 2009, 2010, 2011, 2013, 2014, 2015 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
 #
 
 import time
 
-from .meta import Artist, SEPARATOR
+from .meta import Artist, Album, SEPARATOR
+
 
 class Track:
     """
     Track object.
     Instantiate with Player replies.
+
+    :param str file: media file, defaults to ``None``
+    :param int duration: duration in second, defaults to 0
+    :param int pos: position in queue, defaults to -1
+    :param str title|artist|album|albumartist: defaults to ""
+    :param str musicbrainz_{artistid|albumartistid|albumid|trackid}: MusicBrainz IDs, defaults to ``None``
     """
 
-    def __init__(self, file=None, time=0, pos=-1, **kwargs):
-        self.title = self.artist = self.album = self.albumartist = ''
+    def __init__(self, file=None, duration=0, pos=-1, **kwargs):
+        self.title = self.artist = self.album = self.albumartist = self.genre = ''
         self.musicbrainz_artistid = self.musicbrainz_albumartistid = None
+        self.musicbrainz_albumid = self.musicbrainz_trackid = None
         self.pos = int(pos)
         self._file = file
         self._empty = False
-        self._time = time
+        self.duration = float(duration)
         if not kwargs:
             self._empty = True
         self.__dict__.update(**kwargs)
@@ -45,8 +53,8 @@ class Track:
                                  'genre', 'albumartist',
                                  'musicbrainz_artistid',
                                  'musicbrainz_albumartistid']
-        #  have tags been collapsed?
-        self.collapsed_tags = list()
+        # Which tags have been collapsed?
+        self.collapsed_tags = []
         # Needed for multiple tags which returns a list instead of a string
         self._collapse_tags()
 
@@ -60,7 +68,7 @@ class Track:
                 continue
             if isinstance(value, list):
                 self.collapsed_tags.append(tag)
-                self.__dict__.update({tag: SEPARATOR.join(set(value))})
+                self.__dict__.update({tag: SEPARATOR.join(value)})
 
     def __repr__(self):
         return '%s(artist="%s", album="%s", title="%s", file="%s")' % (
@@ -72,25 +80,24 @@ class Track:
         )
 
     def __str__(self):
-        return '{artist} - {album} - {title} ({duration})'.format(
-                duration=self.duration,
-                **self.__dict__
-                )
+        return '{artist} - {album} - {title} ({length})'.format(
+            length=self.length,
+            **self.__dict__
+        )
 
     def __int__(self):
-        return self.time
+        return int(self.duration)
 
     def __add__(self, other):
-        return Track(time=self.time + other.time)
+        return Track(duration=self.duration + other.duration)
 
     def __sub__(self, other):
-        return Track(time=self.time - other.time)
+        return Track(duration=self.duration - other.duration)
 
     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)
@@ -108,26 +115,33 @@ class Track:
         """file is an immutable attribute that's used for the hash method"""
         return self._file
 
-    def get_time(self):
-        """get time property"""
-        return self._time
-
-    def set_time(self, value):
-        """set time property"""
-        self._time = int(value)
-
-    time = property(get_time, set_time, doc='song duration in seconds (use :attr:`duration` for human readable time)')
-
     @property
-    def duration(self):
-        """Get a fancy duration %H:%M:%S (use :attr:`time` to get duration in second only)"""
-        temps = time.gmtime(int(self.time))
+    def length(self):
+        """Get a fancy duration as ``%H:%M:%S`` (use :attr:`duration` to get
+        duration in second only)"""
+        temps = time.gmtime(self.duration)  # TODO: returns a date not a duration
         if temps.tm_hour:
             fmt = '%H:%M:%S'
         else:
             fmt = '%M:%S'
         return time.strftime(fmt, temps)
 
+    @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 not self.genre:
+            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"""
@@ -138,5 +152,12 @@ class Track:
             return Artist(name='[unknown]', **self.__dict__)
         return Artist(**self.__dict__)
 
+    @property
+    def Album(self):
+        """Get the :class:`sima.lib.meta.Album` associated to this track"""
+        if not self.album:
+            return Album(name='[unknown]', **self.__dict__)
+        return Album(name=self.album, **self.__dict__)
+
 # VIM MODLINE
 # vim: ai ts=4 sw=4 sts=4 expandtab