示例#1
0
class COMR(FrameOpt):
    """Commercial frame."""

    _framespec = [
        EncodingSpec('encoding'),
        Latin1TextSpec('price'),
        StringSpec('valid_until', 8),
        Latin1TextSpec('contact'),
        ByteSpec('format'),
        EncodedTextSpec('seller'),
        EncodedTextSpec('desc'),
    ]

    _optionalspec = [
        Latin1TextSpec('mime'),
        BinaryDataSpec('logo'),
    ]

    @property
    def HashKey(self):
        return '%s:%s' % (self.FrameID, self._writeData())

    def __eq__(self, other):
        return self._writeData() == other._writeData()

    __hash__ = FrameOpt.__hash__
示例#2
0
class CRM(Frame):
    """Encrypted meta frame"""
    _framespec = [Latin1TextSpec('owner'), Latin1TextSpec('desc'),
                  BinaryDataSpec('data')]

    def __eq__(self, other):
        return self.data == other
    __hash__ = Frame.__hash__
示例#3
0
class UFID(Frame):
    """Unique file identifier.

    Attributes:

    * owner -- format/type of identifier
    * data -- identifier
    """

    _framespec = [
        Latin1TextSpec('owner'),
        BinaryDataSpec('data'),
    ]

    @property
    def HashKey(self):
        return '%s:%s' % (self.FrameID, self.owner)

    def __eq__(s, o):
        if isinstance(o, UFI):
            return s.owner == o.owner and s.data == o.data
        else:
            return s.data == o

    __hash__ = Frame.__hash__

    def _pprint(self):
        isascii = ord_(max(self.data)) < 128
        if isascii:
            return "%s=%s" % (self.owner, self.data)
        else:
            return "%s (%d bytes)" % (self.owner, len(self.data))
示例#4
0
class LINK(FrameOpt):
    """Linked information.

    Attributes:

    * frameid -- the ID of the linked frame
    * url -- the location of the linked frame
    * data -- further ID information for the frame
    """

    _framespec = [
        StringSpec('frameid', 4),
        Latin1TextSpec('url'),
    ]

    _optionalspec = [BinaryDataSpec('data')]

    @property
    def HashKey(self):
        try:
            return "%s:%s:%s:%r" % (self.FrameID, self.frameid, self.url,
                                    self.data)
        except AttributeError:
            return "%s:%s:%s" % (self.FrameID, self.frameid, self.url)

    def __eq__(self, other):
        try:
            return (self.frameid, self.url, self.data) == other
        except AttributeError:
            return (self.frameid, self.url) == other

    __hash__ = FrameOpt.__hash__
示例#5
0
class GEOB(Frame):
    """General Encapsulated Object.

    A blob of binary data, that is not a picture (those go in APIC).

    Attributes:

    * encoding -- encoding of the description
    * mime -- MIME type of the data or '-->' if the data is a URI
    * filename -- suggested filename if extracted
    * desc -- text description of the data
    * data -- raw data, as a byte string
    """

    _framespec = [
        EncodingSpec('encoding'),
        Latin1TextSpec('mime'),
        EncodedTextSpec('filename'),
        EncodedTextSpec('desc'),
        BinaryDataSpec('data'),
    ]

    @property
    def HashKey(self):
        return '%s:%s' % (self.FrameID, self.desc)

    def __eq__(self, other):
        return self.data == other

    __hash__ = Frame.__hash__
示例#6
0
class APIC(Frame):
    """Attached (or linked) Picture.

    Attributes:

    * encoding -- text encoding for the description
    * mime -- a MIME type (e.g. image/jpeg) or '-->' if the data is a URI
    * type -- the source of the image (3 is the album front cover)
    * desc -- a text description of the image
    * data -- raw image data, as a byte string

    MutagenX will automatically compress large images when saving tags.
    """

    _framespec = [
        EncodingSpec('encoding'),
        Latin1TextSpec('mime'),
        ByteSpec('type'),
        EncodedTextSpec('desc'),
        BinaryDataSpec('data'),
    ]

    def __eq__(self, other):
        return self.data == other

    __hash__ = Frame.__hash__

    @property
    def HashKey(self):
        return '%s:%s' % (self.FrameID, self.desc)

    def _pprint(self):
        return "%s (%s, %d bytes)" % (self.desc, self.mime, len(self.data))
示例#7
0
class POPM(FrameOpt):
    """Popularimeter.

    This frame keys a rating (out of 255) and a play count to an email
    address.

    Attributes:

    * email -- email this POPM frame is for
    * rating -- rating from 0 to 255
    * count -- number of times the files has been played (optional)
    """

    _framespec = [
        Latin1TextSpec('email'),
        ByteSpec('rating'),
    ]

    _optionalspec = [IntegerSpec('count')]

    @property
    def HashKey(self):
        return '%s:%s' % (self.FrameID, self.email)

    def __eq__(self, other):
        return self.rating == other

    __hash__ = FrameOpt.__hash__

    def __pos__(self):
        return self.rating

    def _pprint(self):
        return "%s=%r %r/255" % (self.email, getattr(self, 'count',
                                                     None), self.rating)
示例#8
0
class PRIV(Frame):
    """Private frame."""

    _framespec = [
        Latin1TextSpec('owner'),
        BinaryDataSpec('data'),
    ]

    @property
    def HashKey(self):
        return '%s:%s:%s' % (self.FrameID, self.owner,
                             self.data.decode('latin1'))

    def __bytes__(self):
        return self.data

    def __eq__(self, other):
        return self.data == other

    def _pprint(self):
        isascii = ord_(max(self.data)) < 128
        if isascii:
            return "%s=%s" % (self.owner, self.data)
        else:
            return "%s (%d bytes)" % (self.owner, len(self.data))

    __hash__ = Frame.__hash__
示例#9
0
class UrlFrame(Frame):
    """A frame containing a URL string.

    The ID3 specification is silent about IRIs and normalized URL
    forms. MutagenX assumes all URLs in files are encoded as Latin 1,
    but string conversion of this frame returns a UTF-8 representation
    for compatibility with other string conversions.

    The only sane way to handle URLs in MP3s is to restrict them to
    ASCII.
    """

    _framespec = [Latin1TextSpec('url')]

    def __bytes__(self):
        return self.url.encode('utf-8')

    def __str__(self):
        return self.url

    def __eq__(self, other):
        return self.url == other

    __hash__ = Frame.__hash__

    def _pprint(self):
        return self.url
示例#10
0
class GRID(FrameOpt):
    """Group identification registration."""

    _framespec = [
        Latin1TextSpec('owner'),
        ByteSpec('group'),
    ]

    _optionalspec = [BinaryDataSpec('data')]

    @property
    def HashKey(self):
        return '%s:%s' % (self.FrameID, self.group)

    def __pos__(self):
        return self.group

    def __bytes__(self):
        return self.owner.encode('utf-8')

    def __str__(self):
        return self.owner

    def __eq__(self, other):
        return self.owner == other or self.group == other

    __hash__ = FrameOpt.__hash__
示例#11
0
class AENC(FrameOpt):
    """Audio encryption.

    Attributes:

    * owner -- key identifying this encryption type
    * preview_start -- unencrypted data block offset
    * preview_length -- number of unencrypted blocks
    * data -- data required for decryption (optional)

    MutagenX cannot decrypt files.
    """

    _framespec = [
        Latin1TextSpec('owner'),
        SizedIntegerSpec('preview_start', 2),
        SizedIntegerSpec('preview_length', 2),
    ]

    _optionalspec = [BinaryDataSpec('data')]

    @property
    def HashKey(self):
        return '%s:%s' % (self.FrameID, self.owner)

    def __bytes__(self):
        return self.owner.encode('utf-8')

    def __str__(self):
        return self.owner

    def __eq__(self, other):
        return self.owner == other

    __hash__ = FrameOpt.__hash__
示例#12
0
class LNK(LINK):
    """Linked information"""
    _framespec = [
        FixedWidthStringSpec('frameid', 3),
        Latin1TextSpec('url')
    ]

    _optionalspec = [BinaryDataSpec('data')]
示例#13
0
class WXXX(UrlFrame):
    """User-defined URL data.

    Like TXXX, this has a freeform description associated with it.
    """

    _framespec = [
        EncodingSpec('encoding'),
        EncodedTextSpec('desc'),
        Latin1TextSpec('url'),
    ]

    @property
    def HashKey(self):
        return '%s:%s' % (self.FrameID, self.desc)
示例#14
0
class RVA2(Frame):
    """Relative volume adjustment (2).

    This frame is used to implemented volume scaling, and in
    particular, normalization using ReplayGain.

    Attributes:

    * desc -- description or context of this adjustment
    * channel -- audio channel to adjust (master is 1)
    * gain -- a + or - dB gain relative to some reference level
    * peak -- peak of the audio as a floating point number, [0, 1]

    When storing ReplayGain tags, use descriptions of 'album' and
    'track' on channel 1.
    """

    _framespec = [
        Latin1TextSpec('desc'),
        ChannelSpec('channel'),
        VolumeAdjustmentSpec('gain'),
        VolumePeakSpec('peak'),
    ]

    _channels = ["Other", "Master volume", "Front right", "Front left",
                 "Back right", "Back left", "Front centre", "Back centre",
                 "Subwoofer"]

    @property
    def HashKey(self):
        return '%s:%s' % (self.FrameID, self.desc)

    def __eq__(self, other):
        try:
            return ((str(self) == other) or
                    (self.desc == other.desc and
                     self.channel == other.channel and
                     self.gain == other.gain and
                     self.peak == other.peak))
        except AttributeError:
            return False

    __hash__ = Frame.__hash__

    def __str__(self):
        return "%s: %+0.4f dB/%0.4f" % (
            self._channels[self.channel], self.gain, self.peak)
示例#15
0
class OWNE(Frame):
    """Ownership frame."""

    _framespec = [
        EncodingSpec('encoding'),
        Latin1TextSpec('price'),
        FixedWidthStringSpec('date', 8),
        EncodedTextSpec('seller'),
    ]

    def __str__(self):
        return self.seller

    def __eq__(self, other):
        return self.seller == other

    __hash__ = Frame.__hash__
示例#16
0
class EQU2(Frame):
    """Equalisation (2).

    Attributes:
    method -- interpolation method (0 = band, 1 = linear)
    desc -- identifying description
    adjustments -- list of (frequency, vol_adjustment) pairs
    """

    _framespec = [
        ByteSpec("method"),
        Latin1TextSpec("desc"),
        VolumeAdjustmentsSpec("adjustments"),
    ]

    def __eq__(self, other):
        return self.adjustments == other

    __hash__ = Frame.__hash__

    @property
    def HashKey(self):
        return '%s:%s' % (self.FrameID, self.desc)
示例#17
0
class ENCR(Frame):
    """Encryption method registration.

    The standard does not allow multiple ENCR frames with the same owner
    or the same method. MutagenX only verifies that the owner is unique.
    """

    _framespec = [
        Latin1TextSpec('owner'),
        ByteSpec('method'),
        BinaryDataSpec('data'),
    ]

    @property
    def HashKey(self):
        return "%s:%s" % (self.FrameID, self.owner)

    def __bytes__(self):
        return self.data

    def __eq__(self, other):
        return self.data == other

    __hash__ = Frame.__hash__