]> kaliko git repositories - mpd-sima.git/blob - sima/lib/meta.py
Deal with multi-tag for musicbrainz_albumartistid and albumartist
[mpd-sima.git] / sima / lib / meta.py
1 # -*- coding: utf-8 -*-
2 # Copyright (c) 2013, 2014 Jack Kaliko <kaliko@azylum.org>
3 #
4 #  This file is part of sima
5 #
6 #  sima is free software: you can redistribute it and/or modify
7 #  it under the terms of the GNU General Public License as published by
8 #  the Free Software Foundation, either version 3 of the License, or
9 #  (at your option) any later version.
10 #
11 #  sima is distributed in the hope that it will be useful,
12 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 #  GNU General Public License for more details.
15 #
16 #  You should have received a copy of the GNU General Public License
17 #  along with sima.  If not, see <http://www.gnu.org/licenses/>.
18 #
19 #
20 """
21 Defines some object to handle audio file metadata
22 """
23
24 from .simastr import SimaStr
25
26 class MetaException(Exception):
27     """Generic Meta Exception"""
28     pass
29
30 class NotSameArtist(MetaException):
31     pass
32
33
34 class Meta:
35     """Generic Class for Meta object"""
36
37     def __init__(self, **kwargs):
38         self.name = None
39         self.mbid = None
40         if 'name' not in kwargs:
41             raise MetaException('need at least a "name" argument')
42         self.__dict__.update(kwargs)
43
44     def __repr__(self):
45         fmt = '{0}(name="{1.name}", mbid="{1.mbid}")'
46         return fmt.format(self.__class__.__name__, self)
47
48     def __str__(self):
49         return str(self.name)
50
51     def __eq__(self, other):
52         """
53         Perform mbid equality test if present,
54         else fallback on fuzzy equality
55         """
56         if hasattr(other, 'mbid'):
57             if other.mbid and self.mbid:
58                 return self.mbid == other.mbid
59         return SimaStr(str(self)) == SimaStr(str(other))
60
61     def __hash__(self):
62         if self.mbid is not None:
63             return hash(self.mbid)
64         else:
65             return id(self)
66
67     def __bool__(self):  # empty name not possible for a valid obj
68         return bool(self.name)
69
70 class Album(Meta):
71     """Info:
72     If a class that overrides __eq__() needs to retain the implementation of
73     __hash__() from a parent class, the interpreter must be told this explicitly
74     by setting __hash__ = <ParentClass>.__hash__.
75     """
76     __hash__ = Meta.__hash__
77
78     def __init__(self, **kwargs):
79         super().__init__(**kwargs)
80
81     def __eq__(self, other):
82         """
83         Perform mbid equality test if present,
84         else fallback on self.name equality
85         """
86         if hasattr(other, 'mbid'):
87             if other.mbid and self.mbid:
88                 return self.mbid == other.mbid
89         return str(self) == str(other)
90
91     @property
92     def album(self):
93         return self.name
94
95
96 class Artist(Meta):
97
98     def __init__(self, **kwargs):
99         self._aliases = set()
100         super().__init__(**kwargs)
101
102     def append(self, name):
103         self._aliases.update({name,})
104
105     @property
106     def names(self):
107         return self._aliases | {self.name,}
108
109     def __add__(self, other):
110         if isinstance(other, Artist):
111             if self.mbid == other.mbid:
112                 res = Artist(**self.__dict__)
113                 res._aliases.extend(other.names)
114                 return res
115             else:
116                 raise NotSameArtist('different mbids: {0} and {1}'.format(self, other))
117
118 # vim: ai ts=4 sw=4 sts=4 expandtab