SEPARATOR = chr(0x1F) # ASCII Unit Separator
def is_uuid4(uuid):
+ """Controls MusicBrainz UUID4 format
+
+ :param str uuid: String representing the UUID
+ :returns: boolean
+ """
regexp = re.compile(UUID_RE, re.IGNORECASE)
if regexp.match(uuid):
return True
- raise WrongUUID4(uuid)
+ return False
class MetaException(Exception):
"""Generic Meta Exception"""
pass
-class WrongUUID4(MetaException):
- pass
-
def mbidfilter(func):
def wrapper(*args, **kwargs):
cls = args[0]
class Meta:
- """Generic Class for Meta object
+ """
+ A generic Class to handle tracks metadata such as artist, album, albumartist
+ names and their associated MusicBrainz's ID.
+
Using generic kwargs in constructor for convenience but the actual signature is:
>>> Meta(name, mbid=None, **kwargs)
- :param string name: set name attribute
- :param string mbid: set MusicBrainz ID (optional)
+ :param str name: set name attribute
+ :param str mbid: set MusicBrainz ID
"""
use_mbid = True
+ """Class attribute to disable use of MusicBrainz IDs"""
def __init__(self, **kwargs):
"""Meta(name=<str>[, mbid=UUID4])"""
else:
self.__name = kwargs.pop('name')
if 'mbid' in kwargs and kwargs.get('mbid'):
- try:
- is_uuid4(kwargs.get('mbid'))
+ if is_uuid4(kwargs.get('mbid')):
self.__mbid = kwargs.pop('mbid').lower()
- except WrongUUID4:
+ else:
self.log.warning('Wrong mbid %s:%s', self.__name,
kwargs.get('mbid'))
# mbid immutable as hash rests on
return hash(self.__name)
def add_alias(self, other):
+ """Add alternative name to `aliases` attibute.
+
+ `other` can be a :class:`sima.lib.meta.Meta` object in which case aliases are merged.
+
+ :param str other: Alias to add, could be any object with ``__str__`` method.
+ """
if getattr(other, '__str__', None):
if callable(other.__str__) and other.__str__() != self.name:
self.__aliases |= {other.__str__()}
@property
def names(self):
+ """aliases + name"""
return self.__aliases | {self.__name,}
class Artist(Meta):
"""Artist object deriving from :class:`Meta`.
- :param string name: Artist name, default ``None``
- :param string mbid: Musicbrainz artist ID, defautl ``None``
- :param string artist: Overrides "name" argument
- :param string albumartist: Overrides "name" and "artist" argument
- :param string musicbrainz_artistid: Overrides "mbid" argument
- :param string musicbrainz_albumartistid: Overrides "musicbrainz_artistid" argument
+ :param str name: Artist name
+ :param str mbid: Musicbrainz artist ID
+ :param str artist: Overrides "name" argument
+ :param str albumartist: Overrides "name" and "artist" argument
+ :param str musicbrainz_artistid: Overrides "mbid" argument
+ :param str musicbrainz_albumartistid: Overrides "musicbrainz_artistid" argument
:Example:
"""
Track object.
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):
@property
def duration(self):
- """Get a fancy duration %H:%M:%S (use :attr:`time` to get duration in second only)"""
+ """Get a fancy duration as ``%H:%M:%S`` (use :attr:`time` to get duration in second only)"""
temps = time.gmtime(int(self.time))
if temps.tm_hour:
fmt = '%H:%M:%S'
import unittest
from sima.lib.meta import Meta, Artist, MetaContainer, is_uuid4
-from sima.lib.meta import WrongUUID4, MetaException, SEPARATOR
+from sima.lib.meta import MetaException, SEPARATOR
VALID = '110e8100-e29b-41d1-a716-116655250000'
def test_uuid_integrity(self):
wrong = VALID +'a'
- self.assertRaises(WrongUUID4, is_uuid4, wrong)
+ self.assertFalse(is_uuid4(wrong))
# test UUID4 format validation
- self.assertRaises(WrongUUID4, is_uuid4, VALID.replace('4', '3'))
- self.assertRaises(WrongUUID4, is_uuid4, VALID.replace('a', 'z'))
+ self.assertFalse(is_uuid4(VALID.replace('4', '3')))
+ self.assertFalse(is_uuid4(VALID.replace('a', 'z')))
def test_init(self):
for args in [