Exemple #1
0
 def save_frame(frame):
     #Copied from mutagen.id3.ID3
     flags = 0
     framedata = frame._writeData()
     datasize = BitPaddedInt.to_str(len(framedata), width=4)
     header = pack('>4s4sH', type(frame).__name__, datasize, flags)
     return header + framedata
Exemple #2
0
 def save_frame(frame):
     #Copied from mutagen.id3.ID3
     flags = 0
     framedata = frame._writeData()
     datasize = BitPaddedInt.to_str(len(framedata), width=4)
     header = pack('>4s4sH', type(frame).__name__, datasize, flags)
     return header + framedata
Exemple #3
0
 def test_long(self):
     if PY2:
         data = BitPaddedInt.to_str(sys.maxint + 1, width=16)
         val = BitPaddedInt(data)
         self.assertEqual(val, sys.maxint + 1)
         self.assertTrue(isinstance(val, BitPaddedLong))
     else:
         self.assertTrue(BitPaddedInt is BitPaddedLong)
Exemple #4
0
 def test_long(self):
     if PY2:
         data = BitPaddedInt.to_str(sys.maxint + 1, width=16)
         val = BitPaddedInt(data)
         self.assertEqual(val, sys.maxint + 1)
         self.assertTrue(isinstance(val, BitPaddedLong))
     else:
         self.assertTrue(BitPaddedInt is BitPaddedLong)
Exemple #5
0
 def __save_frame(self, frame, v2):
     flags = 0
     if self.PEDANTIC and isinstance(frame, TextFrame):
         if len(str(frame)) == 0: return ''
     framedata = frame._writeData()
     if v2 == 3: bits=8
     else: bits=7
     datasize = BitPaddedInt.to_str(len(framedata), width=4, bits=bits)
     header = pack('>4s4sH', type(frame).__name__, datasize, flags)
     return header + framedata
Exemple #6
0
 def test_s65(self):
     self.assertEquals(BitPaddedInt.to_str(0x41, 6), b'\x00\x00\x01\x01')
Exemple #7
0
 def test_s129(self):
     self.assertEquals(BitPaddedInt.to_str(129), b'\x00\x00\x01\x01')
Exemple #8
0
 def test_s1l(self):
     self.assertEquals(
         BitPaddedInt.to_str(1, bigendian=False), b'\x01\x00\x00\x00')
Exemple #9
0
 def test_s0(self):
     self.assertEquals(BitPaddedInt.to_str(0), b'\x00\x00\x00\x00')
Exemple #10
0
    def save(self, filename=None, v1=1, v2=4):
        """Save changes to a file.

        If no filename is given, the one most recently loaded is used.

        Keyword arguments:
        v1 -- if 0, ID3v1 tags will be removed
              if 1, ID3v1 tags will be updated but not added
              if 2, ID3v1 tags will be created and/or updated
        v2 -- version of ID3v2 tags (3 or 4). By default Mutagen saves ID3v2.4
              tags. If you want to save ID3v2.3 tags, you must call method
              update_to_v23 before saving the file.

        The lack of a way to update only an ID3v1 tag is intentional.
        """

        # Sort frames by 'importance'
        order = ["TIT2", "TPE1", "TRCK", "TALB", "TPOS", "TDRC", "TCON"]
        order = dict(zip(order, range(len(order))))
        last = len(order)
        frames = self.items()
        frames.sort(lambda a, b: cmp(order.get(a[0][:4], last),
                                     order.get(b[0][:4], last)))

        framedata = [self.__save_frame(frame, v2) for (key, frame) in frames]
        framedata.extend([data for data in self.unknown_frames
                          if len(data) > 10])
        if not framedata:
            try:
                self.delete(filename)
            except EnvironmentError as err:
                from errno import ENOENT
                if err.errno != ENOENT:
                    raise
            return

        framedata = ''.join(framedata)
        framesize = len(framedata)

        if filename is None:
            filename = self.filename
        try:
            f = open(filename, 'rb+')
        except IOError as err:
            from errno import ENOENT
            if err.errno != ENOENT:
                raise
            f = open(filename, 'ab')  # create, then reopen
            f = open(filename, 'rb+')
        try:
            idata = f.read(10)
            try:
                id3, vmaj, vrev, flags, insize = unpack('>3sBBB4s', idata)
            except struct.error:
                id3, insize = '', 0
            insize = BitPaddedInt(insize)
            if id3 != 'ID3':
                insize = -10

            if insize >= framesize:
                outsize = insize
            else:
                outsize = (framesize + 1023) & ~0x3FF
            framedata += '\x00' * (outsize - framesize)

            framesize = BitPaddedInt.to_str(outsize, width=4)
            flags = 0
            header = pack('>3sBBB4s', 'ID3', v2, 0, flags, framesize)
            data = header + framedata

            if (insize < outsize):
                insert_bytes(f, outsize - insize, insize + 10)
            f.seek(0)
            f.write(data)

            try:
                f.seek(-128, 2)
            except IOError as err:
                from errno import EINVAL
                if err.errno != EINVAL:
                    raise
                f.seek(0, 2)  # ensure read won't get "TAG"

            if f.read(3) == "TAG":
                f.seek(-128, 2)
                if v1 > 0:
                    f.write(MakeID3v1(self))
                else:
                    f.truncate()
            elif v1 == 2:
                f.seek(0, 2)
                f.write(MakeID3v1(self))

        finally:
            f.close()
Exemple #11
0
 def test_varwidth(self):
     self.assertEquals(len(BitPaddedInt.to_str(100)), 4)
     self.assertEquals(len(BitPaddedInt.to_str(100, width=-1)), 4)
     self.assertEquals(len(BitPaddedInt.to_str(2 ** 32, width=-1)), 5)
Exemple #12
0
    def save(self, filename=None, v1=0):
        """Save changes to a file.
        If no filename is given, the one most recently loaded is used.
        Keyword arguments:
        v1 -- if 0, ID3v1 tags will be removed
                    if 1, ID3v1 tags will be updated but not added
                    if 2, ID3v1 tags will be created and/or updated
        The lack of a way to update only an ID3v1 tag is intentional.
        """
        # Sort frames by 'importance'
        order = ["TIT2", "TPE1", "TRCK", "TALB", "TPOS", "TDRC", "TCON"]
        order = dict(zip(order, range(len(order))))
        last = len(order)
        frames = self.items()
        frames.sort(lambda a, b: cmp(order.get(a[0][:4], last), order.get(b[0][:4], last)))

        framedata = [self.__save_frame(frame) for (key, frame) in frames]
        framedata.extend([data for data in self.unknown_frames if len(data) > 10])

        framedata = "".join(framedata)
        framesize = len(framedata)

        if filename is None:
            filename = self.filename
        f = open(filename, "rb+")
        try:
            idata = f.read(10)
            try:
                id3, vmaj, vrev, flags, insize = struct.unpack(">3sBBB4s", idata)
            except struct.error:
                id3, insize = "", 0
            insize = BitPaddedInt(insize)
            if id3 != "ID3":
                insize = -10
            if insize >= framesize:
                outsize = insize
            else:
                outsize = (framesize + 1023) & ~0x3FF
            framedata += "\x00" * (outsize - framesize)

            framesize = BitPaddedInt.to_str(outsize, width=4)
            flags = 0
            header = struct.pack(">3sBBB4s", "ID3", 4, 0, flags, framesize)
            data = header + framedata

            if insize < outsize:
                insert_bytes(f, outsize - insize, insize + 10)
            f.seek(0)

            try:
                f.seek(-128, 2)
            except IOError, err:
                if err.errno != EINVAL:
                    raise
                f.seek(0, 2)  # ensure read won't get "TAG"

            if f.read(3) == "TAG":
                f.seek(-128, 2)
                if v1 > 0:
                    f.write(MakeID3v1(self))
                else:
                    f.truncate()
            elif v1 == 2:
                f.seek(0, 2)
                f.write(MakeID3v1(self))
Exemple #13
0
 def test_s1(self):
     self.assertEquals(BitPaddedInt.to_str(1), "\x00\x00\x00\x01")
Exemple #14
0
            idata = f.read(10)
            try:
                id3, vmaj, vrev, flags, insize = unpack('>3sBBB4s', idata)
            except struct.error:
                id3, insize = '', 0
            insize = BitPaddedInt(insize)
            if id3 != 'ID3':
                insize = -10

            if insize >= framesize:
                outsize = insize
            else:
                outsize = (framesize + 1023) & ~0x3FF
            framedata += '\x00' * (outsize - framesize)

            framesize = BitPaddedInt.to_str(outsize, width=4)
            flags = 0
            header = pack('>3sBBB4s', 'ID3', v2, 0, flags, framesize)
            data = header + framedata

            if (insize < outsize):
                insert_bytes(f, outsize-insize, insize+10)
            f.seek(0)
            f.write(data)

            try:
                f.seek(-128, 2)
            except IOError, err:
                from errno import EINVAL
                if err.errno != EINVAL:
                    raise
Exemple #15
0
    def save(self, filename=None, v1=1, v2_version=4):
        """Save changes to a file.

        If no filename is given, the one most recently loaded is used.

        Keyword arguments:
        v1 -- if 0, ID3v1 tags will be removed
              if 1, ID3v1 tags will be updated but not added
              if 2, ID3v1 tags will be created and/or updated
        v2_version -- version of ID3v2 tags (3 or 4). By default Mutagen saves ID3v2.4
              tags. If you want to save ID3v2.3 tags, you must call method
              update_to_v23 before saving the file.

        The lack of a way to update only an ID3v1 tag is intentional.
        """

        # Sort frames by 'importance'
        order = ["TIT2", "TPE1", "TRCK", "TALB", "TPOS", "TDRC", "TCON"]
        order = dict(zip(order, range(len(order))))
        last = len(order)
        frames = self.items()
        frames.sort(lambda a, b: cmp(order.get(a[0][:4], last),
                                     order.get(b[0][:4], last)))

        framedata = [
            self.__save_frame(frame, v2_version) for (key, frame) in frames
        ]
        framedata.extend(
            [data for data in self.unknown_frames if len(data) > 10])
        if not framedata:
            try:
                self.delete(filename)
            except EnvironmentError as err:
                from errno import ENOENT
                if err.errno != ENOENT:
                    raise
            return

        framedata = ''.join(framedata)
        framesize = len(framedata)

        if filename is None:
            filename = self.filename
        try:
            f = open(filename, 'rb+')
        except IOError as err:
            from errno import ENOENT
            if err.errno != ENOENT:
                raise
            f = open(filename, 'ab')  # create, then reopen
            f = open(filename, 'rb+')
        try:
            idata = f.read(10)
            try:
                id3, vmaj, vrev, flags, insize = unpack('>3sBBB4s', idata)
            except struct.error:
                id3, insize = '', 0
            insize = BitPaddedInt(insize)
            if id3 != 'ID3':
                insize = -10

            if insize >= framesize:
                outsize = insize
            else:
                outsize = (framesize + 1023) & ~0x3FF
            framedata += '\x00' * (outsize - framesize)

            framesize = BitPaddedInt.to_str(outsize, width=4)
            flags = 0
            header = pack('>3sBBB4s', 'ID3', v2_version, 0, flags, framesize)
            data = header + framedata

            if (insize < outsize):
                insert_bytes(f, outsize - insize, insize + 10)
            f.seek(0)
            f.write(data)

            try:
                f.seek(-128, 2)
            except IOError as err:
                from errno import EINVAL
                if err.errno != EINVAL:
                    raise
                f.seek(0, 2)  # ensure read won't get "TAG"

            if f.read(3) == "TAG":
                f.seek(-128, 2)
                if v1 > 0:
                    f.write(MakeID3v1(self))
                else:
                    f.truncate()
            elif v1 == 2:
                f.seek(0, 2)
                f.write(MakeID3v1(self))

        finally:
            f.close()
Exemple #16
0
 def test_w129(self):
     self.assertEquals(BitPaddedInt.to_str(129, width=2), b'\x01\x01')
Exemple #17
0
 def test_w129l(self):
     self.assertEquals(
         BitPaddedInt.to_str(129, width=2, bigendian=False), b'\x01\x01')
Exemple #18
0
            idata = f.read(10)
            try:
                id3, vmaj, vrev, flags, insize = unpack('>3sBBB4s', idata)
            except struct.error:
                id3, insize = '', 0
            insize = BitPaddedInt(insize)
            if id3 != 'ID3':
                insize = -10

            if insize >= framesize:
                outsize = insize
            else:
                outsize = (framesize + 1023) & ~0x3FF
            framedata += '\x00' * (outsize - framesize)

            framesize = BitPaddedInt.to_str(outsize, width=4)
            flags = 0
            header = pack('>3sBBB4s', 'ID3', v2, 0, flags, framesize)
            data = header + framedata

            if (insize < outsize):
                insert_bytes(f, outsize - insize, insize + 10)
            f.seek(0)
            f.write(data)

            try:
                f.seek(-128, 2)
            except IOError, err:
                from errno import EINVAL
                if err.errno != EINVAL:
                    raise
Exemple #19
0
 def test_minwidth(self):
     self.assertEquals(
         len(BitPaddedInt.to_str(100, width=-1, minwidth=6)), 6)
Exemple #20
0
    def save(self, filename=None, v1=0):
        """Save changes to a file.
        If no filename is given, the one most recently loaded is used.
        Keyword arguments:
        v1 -- if 0, ID3v1 tags will be removed
                    if 1, ID3v1 tags will be updated but not added
                    if 2, ID3v1 tags will be created and/or updated
        The lack of a way to update only an ID3v1 tag is intentional.
        """
        # Sort frames by 'importance'
        order = ["TIT2", "TPE1", "TRCK", "TALB", "TPOS", "TDRC", "TCON"]
        order = dict(zip(order, range(len(order))))
        last = len(order)
        frames = self.items()
        frames.sort(lambda a, b: cmp(order.get(a[0][:4], last),
                    order.get(b[0][:4], last)))

        framedata = [self.__save_frame(frame) for (key, frame) in frames]
        framedata.extend([data for data in self.unknown_frames
                          if len(data) > 10])

        framedata = ''.join(framedata)
        framesize = len(framedata)

        if filename is None:
            filename = self.filename
        f = open(filename, 'rb+')
        try:
            idata = f.read(10)
            try:
                id3, vmaj, vrev, flags, insize = struct.unpack('>3sBBB4s',
                                                               idata)
            except struct.error:
                id3, insize = '', 0
            insize = BitPaddedInt(insize)
            if id3 != 'ID3':
                insize = -10
            if insize >= framesize:
                outsize = insize
            else:
                outsize = (framesize + 1023) & ~0x3FF
            framedata += '\x00' * (outsize - framesize)

            framesize = BitPaddedInt.to_str(outsize, width=4)
            flags = 0
            header = struct.pack('>3sBBB4s', 'ID3', 4, 0, flags, framesize)
            data = header + framedata

            if (insize < outsize):
                insert_bytes(f, outsize-insize, insize+10)
            f.seek(0)

            try:
                f.seek(-128, 2)
            except IOError, err:
                if err.errno != EINVAL:
                    raise
                f.seek(0, 2)  # ensure read won't get "TAG"

            if f.read(3) == "TAG":
                f.seek(-128, 2)
                if v1 > 0:
                    f.write(MakeID3v1(self))
                else:
                    f.truncate()
            elif v1 == 2:
                f.seek(0, 2)
                f.write(MakeID3v1(self))