Exemplo n.º 1
0
    def x_comm(self):
        """
        extract comment field

        sets: encoding, lang, shortcomment, longcomment
        """
        data = self.rawdata
        self.encoding = encodings[ord(data[0])]
        self.language = data[1:4]
        self.shortcomment = ''
        self.longcomment = ''

        if is_double_byte(self.encoding):
            for i in range(4,len(data)-1):
                if data[i:i+2] == '\x00\x00':
                    self.shortcomment = data[4:i].strip('\x00')
                    self.longcomment = data[i+2:].strip('\x00')
                    break
        else:
            for i in range(4,len(data)):
                if data[i] == '\x00':
                    self.shortcomment = data[4:i].strip('\x00')
                    self.longcomment = data[i+1:].strip('\x00')
                    break
                
        debug('Read Field: %s Len: %d Enc: %s Lang: %s Comm: %s' %
              (self.fid, self.length, self.encoding, self.language,
               str([self.shortcomment, self.longcomment])))
Exemplo n.º 2
0
    def x_text(self):
        """
        Extract Text Fields

        @todo: handle multiple strings seperated by \x00

        sets: encoding, strings
        """
        data = self.rawdata
        self.encoding = encodings[ord(data[0])]
        rawtext = data[1:]

        if normalize_encoding(self.encoding) == 'latin_1':
            text = rawtext
            self.strings = text.split('\x00')
        else:
            text = rawtext.decode(self.encoding)
            if is_double_byte(self.encoding):
                self.strings = text.split('\x00\x00')
            else:
                self.strings = text.split('\x00')

        try:
            dummy = text.encode('utf_8')
            debug('Read Field: %s Len: %d Enc: %s Text: %s' %
                  (self.fid, self.length, self.encoding, str([text])))
        except UnicodeDecodeError:
            debug('Read Field: %s Len: %d Enc: %s Text: %s (Err)' %
                  (self.fid, self.length, self.encoding, str([text])))
Exemplo n.º 3
0
    def parse_frames(self):
        """ Recursively Parse Frames """
        read = 0
        readframes = 0
        
        while read < self.tag["size"]:
            framedata = self.get_next_frame(self.tag["size"] - read)
            if framedata:
                try:
                    read += len(framedata)
                    if self.version == 2.2:
                        frame = ID3v2_2_Frame(frame=framedata)
                    elif self.version == 2.3:
                        frame = ID3v2_3_Frame(frame=framedata)
                    elif self.version == 2.4:
                        frame = ID3v2_4_Frame(frame=framedata)
                    readframes += 1
                    self.frames.append(frame)
                except ID3Exception:
                    pass # ignore unrecognised frames
            else:
                self.tag["padding"] = self._read_null_bytes()
                debug("NULL Padding: %d" % self.tag["padding"])
                break

        # do a sanity check on the size/padding
        if not self.tag.has_key("padding"):
            self.tag["padding"] = 0
            
        if self.tag["size"] != read + self.tag["padding"]:
            self.tag["size"] = read + self.tag["padding"]
            
        return len(self.frames)
Exemplo n.º 4
0
    def x_text(self):
        """
        Extract Text Fields

        @todo: handle multiple strings seperated by \x00

        sets: encoding, strings
        """
        data = self.rawdata
        self.encoding = encodings[ord(data[0])]
        rawtext = data[1:]
        
        if normalize_encoding(self.encoding) == 'latin_1':
            text = rawtext
            self.strings = text.split('\x00')
        else:
            text = rawtext.decode(self.encoding)
            if is_double_byte(self.encoding):
                self.strings = text.split('\x00\x00')               
            else:
                self.strings = text.split('\x00')
                
        try:
            dummy = text.encode('utf_8')
            debug('Read Field: %s Len: %d Enc: %s Text: %s' %
                   (self.fid, self.length, self.encoding, str([text])))
        except UnicodeDecodeError:
            debug('Read Field: %s Len: %d Enc: %s Text: %s (Err)' %
                   (self.fid, self.length, self.encoding, str([text])))
Exemplo n.º 5
0
    def parse_frames(self):
        """ Recursively Parse Frames """
        read = 0
        readframes = 0
        
        while read < self.tag["size"]:
            framedata = self.get_next_frame(self.tag["size"] - read)
            if framedata:
                try:
                    read += len(framedata)
                    if self.version == '2.2':
                        frame = ID3v2_2_Frame(frame=framedata)
                    elif self.version == '2.3':
                        frame = ID3v2_3_Frame(frame=framedata)
                    elif self.version == '2.4':
                        frame = ID3v2_4_Frame(frame=framedata)
                    readframes += 1
                    self.frames.append(frame)
                except ID3Exception:
                    pass # ignore unrecognised frames
            else:
                self.tag["padding"] = self._read_null_bytes()
                debug("NULL Padding: %d" % self.tag["padding"])
                break

        # do a sanity check on the size/padding
        if not self.tag.has_key("padding"):
            self.tag["padding"] = 0
            
        if self.tag["size"] != read + self.tag["padding"]:
            self.tag["size"] = read + self.tag["padding"]
            
        return len(self.frames)
Exemplo n.º 6
0
    def x_comm(self):
        """
        extract comment field

        sets: encoding, lang, shortcomment, longcomment
        """
        data = self.rawdata
        self.encoding = encodings[ord(data[0])]
        self.language = data[1:4]
        self.shortcomment = ''
        self.longcomment = ''

        if is_double_byte(self.encoding):
            for i in range(4, len(data) - 1):
                if data[i:i + 2] == '\x00\x00':
                    self.shortcomment = data[4:i].strip('\x00')
                    self.longcomment = data[i + 2:].strip('\x00')
                    break
        else:
            for i in range(4, len(data)):
                if data[i] == '\x00':
                    self.shortcomment = data[4:i].strip('\x00')
                    self.longcomment = data[i + 1:].strip('\x00')
                    break

        debug('Read Field: %s Len: %d Enc: %s Lang: %s Comm: %s' %
              (self.fid, self.length, self.encoding, self.language,
               str([self.shortcomment, self.longcomment])))
Exemplo n.º 7
0
    def x_geob(self):
        """
        Extract GEOB

        set: encoding, mimetype, filename, desc, obj
        """
        data = self.rawdata
        self.encoding = encodings[ord(data[0])]
        self.mimetype = ''
        self.filename = ''
        self.desc = ''
        self.obj = ''

        for i in range(1, len(data)):
            if data[i] == '\x00':
                self.mimetype = data[1:i]
                break

        if not self.mimetype:
            raise ID3FrameException("Unable to extract GEOB. Missing mimetype")

        # FIXME: because filename and desc are optional, we should be
        #        smarter about splitting
        if is_double_byte(self.encoding):
            for i in range(len(self.mimetype) + 2, len(data) - 1):
                if data[i:i + 2] == '\x00\x00':
                    self.filename = data[len(self.mimetype) + 2:i]
                    ptr = len(self.mimetype) + len(self.filename) + 4
                    break
        else:
            for i in range(len(self.mimetype) + 2, len(data) - 1):
                if data[i] == '\x00':
                    self.filename = data[len(self.mimetype) + 2:i]
                    ptr = len(self.mimetype) + len(self.filename) + 3
                    break

        if is_double_byte(self.encoding):
            for i in range(ptr, len(data) - 1):
                if data[i:i + 2] == '\x00\x00':
                    self.desc = data[ptr:i]
                    self.obj = data[i + 2:]
                    break
        else:
            for i in range(ptr, len(data) - 1):
                if data[i] == '\x00':
                    self.desc = data[ptr:i]
                    self.obj = data[i + 1:]
                    break

        debug(
            "Read Field: %s Len: %d Enc: %s Mime: %s Filename: %s Desc: %s ObjLen: %d"
            % (self.fid, self.length, self.encoding, self.mimetype,
               self.filename, self.desc, len(self.obj)))
Exemplo n.º 8
0
    def x_geob(self):
        """
        Extract GEOB

        set: encoding, mimetype, filename, desc, obj
        """
        data = self.rawdata
        self.encoding = encodings[ord(data[0])]
        self.mimetype = ''
        self.filename = ''
        self.desc = ''
        self.obj = ''
        
        for i in range(1,len(data)):
            if data[i] == '\x00':
                self.mimetype = data[1:i]
                break

        if not self.mimetype:
            raise ID3FrameException("Unable to extract GEOB. Missing mimetype")

        # FIXME: because filename and desc are optional, we should be
        #        smarter about splitting
        if is_double_byte(self.encoding):
            for i in range(len(self.mimetype)+2,len(data)-1):
                if data[i:i+2] == '\x00\x00':
                    self.filename = data[len(self.mimetype)+2:i]
                    ptr = len(self.mimetype) + len(self.filename) + 4
                    break
        else:
            for i in range(len(self.mimetype)+2,len(data)-1):
                if data[i] == '\x00':
                    self.filename = data[len(self.mimetype)+2:i]
                    ptr = len(self.mimetype) + len(self.filename) + 3
                    break

        if is_double_byte(self.encoding):
            for i in range(ptr,len(data)-1):
                if data[i:i+2] == '\x00\x00':
                    self.desc = data[ptr:i]
                    self.obj = data[i+2:]
                    break
        else:
            for i in range(ptr,len(data)-1):
                if data[i] == '\x00':
                    self.desc = data[ptr:i]
                    self.obj = data[i+1:]
                    break

        debug("Read Field: %s Len: %d Enc: %s Mime: %s Filename: %s Desc: %s ObjLen: %d" %
               (self.fid, self.length, self.encoding, self.mimetype,
                self.filename, self.desc, len(self.obj)))
Exemplo n.º 9
0
    def x_pcnt(self):
        """
        Extract Play Count

        sets: counter
        """
        data = self.rawdata
        bytes = self.length
        counter = 0
        if bytes == 4:
            counter = struct.unpack('!I',data)[0]
        else:
            for i in range(0,bytes):
                counter += struct.unpack('B',data[i]) * pow(256,i)
                
        debug('Read Field: %s Len: %d Count: %d' % (self.fid, bytes, counter))
        self.counter = counter
Exemplo n.º 10
0
    def x_pcnt(self):
        """
        Extract Play Count

        sets: counter
        """
        data = self.rawdata
        bytes = self.length
        counter = 0
        if bytes == 4:
            counter = struct.unpack('!I', data)[0]
        else:
            for i in range(0, bytes):
                counter += struct.unpack('B', data[i]) * pow(256, i)

        debug('Read Field: %s Len: %d Count: %d' % (self.fid, bytes, counter))
        self.counter = counter
Exemplo n.º 11
0
	def x_apic(self):
		"""
		Extract APIC

		set: encoding, mimetype, desc, pict, picttype
		"""
		data = self.rawdata
		self.encoding = encodings[ord(data[0])]
		self.mimetype = ''
		self.desc = ''
		self.pict = ''
		self.picttype = 0

		# get mime type (must be latin-1)
		for i in range(1,len(data)):
			if data[i] == '\x00':
				self.mimetype = data[1:i]
				break

		if not self.mimetype:
			raise ID3FrameException("APIC extraction failed. Missing mimetype")

		picttype = ord(data[len(self.mimetype) + 2])

		# get picture description

		if is_double_byte(self.encoding):
			for i in range(len(self.mimetype) + 2, len(data)-1):
				if data[i:i+2] == '\x00\x00':
					self.desc = data[len(self.mimetype)+2:i]
					self.pict = data[i+2:]
					break
		else:
			for i in range(len(self.mimetype) + 2, len(data)):
				if data[i] == '\x00':
					self.desc = data[len(self.mimetype)+2:i]
					self.pict = data[i+1:]
					break			
		debug('Read Field: %s Len: %d PicType: %d Mime: %s Desc: %s PicLen: %d' % 
			   (self.fid, self.length, self.picttype, self.mimetype,
				self.desc, len(self.pict)))
Exemplo n.º 12
0
    def x_apic(self):
        """
        Extract APIC

        set: encoding, mimetype, desc, pict, picttype
        """
        data = self.rawdata
        self.encoding = encodings[ord(data[0])]
        self.mimetype = ''
        self.desc = ''
        self.pict = ''
        self.picttype = 0

        # get mime type (must be latin-1)
        imgtype = data[1:4]
        if not imgtype:
            raise ID3FrameException("APIC extraction failed. Missing mimetype")

        if imgtype not in ID3V2_2_FRAME_IMAGE_FORMAT_TO_MIME_TYPE.keys():
            raise ID3FrameException("Unrecognised mime-type")
        else:
            self.mimetype = ID3V2_2_FRAME_IMAGE_FORMAT_TO_MIME_TYPE[imgtype]

        picttype = ord(data[len(imgtype) + 1])

        # get picture description
        for i in range(len(imgtype) + 2, len(data) - 1):
            print[data[i:i + 3]]
            if data[i] == '\x00':
                self.desc = data[len(imgtype) + 2:i]
                if data[i + 1] == '\x00':
                    self.pict = data[i + 2:]
                else:
                    self.pict = data[i + 1:]
                break

        debug(
            'Read Field: %s Len: %d PicType: %d Mime: %s Desc: %s PicLen: %d' %
            (self.fid, self.length, self.picttype, self.mimetype, self.desc,
             len(self.pict)))
Exemplo n.º 13
0
    def x_apic(self):
        """
        Extract APIC

        set: encoding, mimetype, desc, pict, picttype
        """
        data = self.rawdata
        self.encoding = encodings[ord(data[0])]
        self.mimetype = ''
        self.desc = ''
        self.pict = ''
        self.picttype = 0

        # get mime type (must be latin-1)
        imgtype = data[1:4]
        if not imgtype:
            raise ID3FrameException("APIC extraction failed. Missing mimetype")

        if imgtype not in ID3V2_2_FRAME_IMAGE_FORMAT_TO_MIME_TYPE.keys():
            raise ID3FrameException("Unrecognised mime-type")            
        else:
            self.mimetype = ID3V2_2_FRAME_IMAGE_FORMAT_TO_MIME_TYPE[imgtype]

        picttype = ord(data[len(imgtype) + 1])

        # get picture description
        for i in range(len(imgtype) + 2, len(data) - 1):
            #print [data[i:i+3]]
            if data[i] == '\x00':
                self.desc = data[len(imgtype)+2:i]
                if data[i+1] == '\x00':
                    self.pict = data[i+2:]
                else:
                    self.pict = data[i+1:]
                break
                    
        debug('Read Field: %s Len: %d PicType: %d Mime: %s Desc: %s PicLen: %d' % 
               (self.fid, self.length, self.picttype, self.mimetype,
                self.desc, len(self.pict)))
Exemplo n.º 14
0
    def x_apic(self):
        """
        Extract APIC

        set: encoding, mimetype, desc, pict, picttype
        """
        data = self.rawdata
        self.encoding = encodings[ord(data[0])]
        self.mimetype = ''
        self.desc = ''
        self.pict = ''
        self.picttype = 0

        # get mime type (must be latin-1)
        for i in range(1, len(data)):
            if data[i] == '\x00':
                self.mimetype = data[1:i]
                break

        if not self.mimetype:
            raise ID3FrameException("APIC extraction failed. Missing mimetype")

        picttype = ord(data[len(self.mimetype) + 2])

        # get picture description
        for i in range(len(self.mimetype) + 2, len(data) - 1):
            if data[i] == '\x00':
                self.desc = data[len(self.mimetype) + 2:i]
                if data[i + 1] == '\x00':
                    self.pict = data[i + 2:]
                else:
                    self.pict = data[i + 1:]
                break

        debug(
            'Read Field: %s Len: %d PicType: %d Mime: %s Desc: %s PicLen: %d' %
            (self.fid, self.length, self.picttype, self.mimetype, self.desc,
             len(self.pict)))
Exemplo n.º 15
0
    def parse_header(self):
        """
        Parse Header of the file

        """
        self.f.seek(0)
        data = self.f.read(ID3V2_FILE_HEADER_LENGTH)
        if len(data) != ID3V2_FILE_HEADER_LENGTH:
            raise ID3HeaderInvalidException("ID3 tag header is incomplete")
        
        self.tag = {}
        self.frames = []
        id3, ver, flags, rawsize = struct.unpack("!3sHB4s", data)
        
        if id3 != "ID3":
            raise ID3HeaderInvalidException("ID3v2 header not found")

        self.tag["size"] = unsyncsafe(rawsize)
        # NOTE: size  = excluding header + footer
        version = 2 + (ver / 0x100) * 0.1
        if version not in self.supported:
            raise ID3NotImplementedException("version %s not supported" % \
                                             str(version))
        else:
            self.version = version
            
        if self.version in [2.4, 2.3]:
            for flagname, bit in ID3V2_3_TAG_HEADER_FLAGS:
                self.tag[flagname] = (flags >> bit) & 0x01
        elif self.version in [2.2]:
            for flagname, bit in ID3V2_2_TAG_HEADER_FLAGS:
                self.tag[flagname] = (flags >> bit) & 0x01

        if self.tag.has_key("ext") and self.tag["ext"]:
            self.parse_ext_header()
    
        debug(self.tag)
Exemplo n.º 16
0
    def parse_header(self):
        """
        Parse Header of the file

        """
        self.f.seek(0)
        data = self.f.read(ID3V2_FILE_HEADER_LENGTH)
        if len(data) != ID3V2_FILE_HEADER_LENGTH:
            raise ID3HeaderInvalidException("ID3 tag header is incomplete")
        
        self.tag = {}
        self.frames = []
        id3, ver, flags, rawsize = struct.unpack("!3sHB4s", data)
        
        if id3 != "ID3":
            raise ID3HeaderInvalidException("ID3v2 header not found")

        self.tag["size"] = unsyncsafe(rawsize)
        # NOTE: size  = excluding header + footer
        version = '2.%d' % (ver >> 8)
        if version not in self.supported:
            raise ID3NotImplementedException("version %s not supported" % \
                                             version)
        else:
            self.version = version
            
        if self.version in ('2.4', '2.3'):
            for flagname, bit in ID3V2_3_TAG_HEADER_FLAGS:
                self.tag[flagname] = (flags >> bit) & 0x01
        elif self.version == '2.2':
            for flagname, bit in ID3V2_2_TAG_HEADER_FLAGS:
                self.tag[flagname] = (flags >> bit) & 0x01

        if self.tag.has_key("ext") and self.tag["ext"]:
            self.parse_ext_header()
    
        debug(self.tag)
Exemplo n.º 17
0
    def x_wxxx(self):
        """
        Extract URL
        
        set: encoding, desc, url
        """
        data = self.rawdata
        self.encoding = encodings[ord(data[0])]
        if is_double_byte(self.encoding):
            for i in range(1, len(data) - 1):
                if data[i:i + 2] == '\x00\x00':
                    self.desc = data[1:i]
                    self.url = data[i + 2:]
                    break
        else:
            for i in range(1, len(data)):
                if data[i] == '\x00':
                    self.desc = data[1:i]
                    self.url = data[i + 1:]
                    break

        debug(
            "Read field: %s Len: %s Enc: %s Desc: %s URL: %s" %
            (self.fid, self.length, self.encoding, self.desc, str([self.url])))
Exemplo n.º 18
0
    def x_wxxx(self):
        """
        Extract URL
        
        set: encoding, desc, url
        """
        data = self.rawdata
        self.encoding = encodings[ord(data[0])]
        if is_double_byte(self.encoding):
            for i in range(1,len(data)-1):
                if data[i:i+2] == '\x00\x00':
                    self.desc = data[1:i]
                    self.url = data[i+2:]
                    break
        else:
            for i in range(1,len(data)):
                if data[i] == '\x00':
                    self.desc = data[1:i]
                    self.url = data[i+1:]
                    break

        debug("Read field: %s Len: %s Enc: %s Desc: %s URL: %s" %
               (self.fid, self.length, self.encoding,
                self.desc, str([self.url])))
Exemplo n.º 19
0
 def x_url(self):
     debug("Read Field: %s Len: %d Data: %s" %
            (self.fid, self.length, [self.rawdata]))
     return
Exemplo n.º 20
0
 def x_url(self):
     debug("Read Field: %s Len: %d Data: %s" %
           (self.fid, self.length, [self.rawdata]))
     return