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 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__
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 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__
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))
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__
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__
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 LNK(LINK): """Linked information""" _framespec = [ FixedWidthStringSpec('frameid', 3), Latin1TextSpec('url') ] _optionalspec = [BinaryDataSpec('data')]
class CRM(Frame): """Encrypted meta frame""" _framespec = [Latin1TextSpec('owner'), Latin1TextSpec('desc'), BinaryDataSpec('data')] def __eq__(self, other): return self.data == other __hash__ = Frame.__hash__
class BinaryFrame(Frame): """Binary data The 'data' attribute contains the raw byte string. """ _framespec = [BinaryDataSpec('data')] def __eq__(self, other): return self.data == 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') ]
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__
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__
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 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__