class SYLT(Frame):
    """Synchronised lyrics/text."""

    _framespec = [
        EncodingSpec('encoding'),
        StringSpec('lang', 3),
        ByteSpec('format'),
        ByteSpec('type'),
        EncodedTextSpec('desc'),
        SynchronizedTextSpec('text'),
    ]

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

    def __eq__(self, other):
        return str(self) == other

    __hash__ = Frame.__hash__

    def __str__(self):
        return u"".join(text for (text, time) in self.text)

    def __bytes__(self):
        return text_type(self).encode("utf-8")
class RBUF(FrameOpt):
    """Recommended buffer size.

    Attributes:

    * size -- recommended buffer size in bytes
    * info -- if ID3 tags may be elsewhere in the file (optional)
    * offset -- the location of the next ID3 tag, if any

    MutagenX will not find the next tag itself.
    """

    _framespec = [SizedIntegerSpec('size', 3)]

    _optionalspec = [
        ByteSpec('info'),
        SizedIntegerSpec('offset', 4),
    ]

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

    __hash__ = FrameOpt.__hash__

    def __pos__(self):
        return self.size
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__
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__
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)
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))
class MLLT(Frame):
    """MPEG location lookup table.

    This frame's attributes may be changed in the future based on
    feedback from real-world use.
    """

    _framespec = [
        SizedIntegerSpec('frames', 2),
        SizedIntegerSpec('bytes', 3),
        SizedIntegerSpec('milliseconds', 3),
        ByteSpec('bits_for_bytes'),
        ByteSpec('bits_for_milliseconds'),
        BinaryDataSpec('data'),
    ]

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

    __hash__ = Frame.__hash__
class ETCO(Frame):
    """Event timing codes."""

    _framespec = [
        ByteSpec("format"),
        KeyEventSpec("events"),
    ]

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

    __hash__ = Frame.__hash__
class PIC(APIC):
    """Attached Picture.

    The 'mime' attribute of an ID3v2.2 attached picture must be either
    'PNG' or 'JPG'.
    """
    _framespec = [
        EncodingSpec('encoding'),
        StringSpec('mime', 3),
        ByteSpec('type'),
        EncodedTextSpec('desc'),
        BinaryDataSpec('data')
    ]
Beispiel #10
0
class SYTC(Frame):
    """Synchronised tempo codes.

    This frame's attributes may be changed in the future based on
    feedback from real-world use.
    """

    _framespec = [
        ByteSpec("format"),
        BinaryDataSpec("data"),
    ]

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

    __hash__ = Frame.__hash__
Beispiel #11
0
class ASPI(Frame):
    """Audio seek point index.

    Attributes: S, L, N, b, and Fi. For the meaning of these, see
    the ID3v2.4 specification. Fi is a list of integers.
    """
    _framespec = [
        SizedIntegerSpec("S", 4),
        SizedIntegerSpec("L", 4),
        SizedIntegerSpec("N", 2),
        ByteSpec("b"),
        ASPIIndexSpec("Fi"),
    ]

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

    __hash__ = Frame.__hash__
Beispiel #12
0
class RVRB(Frame):
    """Reverb."""

    _framespec = [
        SizedIntegerSpec('left', 2),
        SizedIntegerSpec('right', 2),
        ByteSpec('bounce_left'),
        ByteSpec('bounce_right'),
        ByteSpec('feedback_ltl'),
        ByteSpec('feedback_ltr'),
        ByteSpec('feedback_rtr'),
        ByteSpec('feedback_rtl'),
        ByteSpec('premix_ltr'),
        ByteSpec('premix_rtl'),
    ]

    def __eq__(self, other):
        return (self.left, self.right) == other

    __hash__ = Frame.__hash__
Beispiel #13
0
class SIGN(Frame):
    """Signature frame."""

    _framespec = [
        ByteSpec('group'),
        BinaryDataSpec('sig'),
    ]

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

    def __bytes__(self):
        return self.sig

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

    __hash__ = Frame.__hash__
Beispiel #14
0
class POSS(Frame):
    """Position synchronisation frame

    Attribute:

    * format -- format of the position attribute (frames or milliseconds)
    * position -- current position of the file
    """

    _framespec = [
        ByteSpec('format'),
        IntegerSpec('position'),
    ]

    def __pos__(self):
        return self.position

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

    __hash__ = Frame.__hash__
Beispiel #15
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)
Beispiel #16
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__