]> kaliko git repositories - mpd-sima.git/blob - sima/lib/track.py
Collapse musicbrainz tags
[mpd-sima.git] / sima / lib / track.py
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2009, 2010, 2011, 2013, 2014 Jack Kaliko <kaliko@azylum.org>
4 # Copyright (c) 2009 J. Alexander Treuman (Tag collapse method)
5 # Copyright (c) 2008 Rick van Hattem
6 #
7 #  This file is part of sima
8 #
9 #  sima is free software: you can redistribute it and/or modify
10 #  it under the terms of the GNU General Public License as published by
11 #  the Free Software Foundation, either version 3 of the License, or
12 #  (at your option) any later version.
13 #
14 #  sima is distributed in the hope that it will be useful,
15 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 #  GNU General Public License for more details.
18 #
19 #  You should have received a copy of the GNU General Public License
20 #  along with sima.  If not, see <http://www.gnu.org/licenses/>.
21 #
22 #
23
24 import time
25
26 from .meta import Artist
27
28 class Track:
29     """
30     Track object.
31     Instanciate with Player replies.
32     """
33
34     def __init__(self, file=None, time=0, pos=-1, **kwargs):
35         self.title = self.artist = self.album = self.albumartist = ''
36         self.musicbrainz_artistid = self.musicbrainz_albumartistid = None
37         self.pos = int(pos)
38         self._empty = False
39         self._file = file
40         if not kwargs:
41             self._empty = True
42         self._time = time
43         self.__dict__.update(**kwargs)
44         self.tags_to_collapse = ['artist', 'album', 'title', 'date',
45                                  'genre', 'albumartist',
46                                  'musicbrainz_artistid',
47                                  'musicbrainz_albumartistid']
48         #  have tags been collapsed?
49         self.collapse_tags_bool = False
50         self.collapsed_tags = list()
51         # Needed for multiple tags which returns a list instead of a string
52         self.collapse_tags()
53
54     def collapse_tags(self):
55         """
56         Necessary to deal with tags defined multiple times.
57         These entries are set as lists instead of strings.
58         """
59         for tag, value in self.__dict__.items():
60             if tag not in self.tags_to_collapse:
61                 continue
62             if isinstance(value, list):
63                 self.collapse_tags_bool = True
64                 self.collapsed_tags.append(tag)
65                 self.__dict__.update({tag: ', '.join(set(value))})
66
67     def __repr__(self):
68         return '%s(artist="%s", album="%s", title="%s", filename="%s")' % (
69             self.__class__.__name__,
70             self.artist,
71             self.album,
72             self.title,
73             self.file,
74         )
75
76     def __str__(self):
77         return '{artist} - {album} - {title} ({duration})'.format(
78                 duration=self.duration,
79                 **self.__dict__
80                 )
81
82     def __int__(self):
83         return self.time
84
85     def __add__(self, other):
86         return Track(time=self.time + other.time)
87
88     def __sub__(self, other):
89         return Track(time=self.time - other.time)
90
91     def __hash__(self):
92         if self.file:
93             return hash(self.file)
94         else:
95             return id(self)
96
97     def __eq__(self, other):
98         return hash(self) == hash(other)
99
100     def __ne__(self, other):
101         return hash(self) != hash(other)
102
103     def __bool__(self):
104         return not self._empty
105
106     @property
107     def file(self):
108         """file is an immutable attribute that's used for the hash method"""
109         return self._file
110
111     def get_time(self):
112         """get time property"""
113         return self._time
114
115     def set_time(self, value):
116         """set time property"""
117         self._time = int(value)
118
119     time = property(get_time, set_time, doc='song duration in seconds')
120
121     @property
122     def duration(self):
123         """Compute fancy duration"""
124         temps = time.gmtime(int(self.time))
125         if temps.tm_hour:
126             fmt = '%H:%M:%S'
127         else:
128             fmt = '%M:%S'
129         return time.strftime(fmt, temps)
130
131     def get_artist(self):
132        """Get artist object from track"""
133        name = self.artist
134        mbid = self.musicbrainz_artistid
135        if self.albumartist != 'Various Artists':
136            name = self.albumartist
137        if self.musicbrainz_albumartistid != '89ad4ac3-39f7-470e-963a-56509c546377':
138            mbid = self.musicbrainz_albumartistid
139        return Artist(name=name, mbid=mbid)
140
141 # VIM MODLINE
142 # vim: ai ts=4 sw=4 sts=4 expandtab