Exemple #1
0
    def delete(self, filething=None):
        """delete(filething=None)

        Remove tags from a file.

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

        Args:
            filething (filething)
        Raises:
            mutagen.MutagenError
        """

        fileobj = filething.fileobj

        self.tags.clear()
        # TODO: we should delegate the deletion to the subclass and not through
        # _inject.
        try:
            try:
                self.tags._inject(fileobj, lambda x: 0)
            except error as e:
                reraise(self._Error, e, sys.exc_info()[2])
            except EOFError:
                raise self._Error("no appropriate stream found")
        except IOError as e:
            reraise(self._Error, e, sys.exc_info()[2])
Exemple #2
0
    def save(self, filething=None, padding=None):

        values = []
        items = sorted(self.items(), key=lambda kv: _item_sort_key(*kv))
        for key, value in items:
            try:
                values.append(self._render(key, value))
            except (TypeError, ValueError) as s:
                reraise(MP4MetadataValueError, s, sys.exc_info()[2])

        for key, failed in self._failed_atoms.items():
            # don't write atoms back if we have added a new one with
            # the same name, this excludes freeform which can have
            # multiple atoms with the same key (most parsers seem to be able
            # to handle that)
            if key in self:
                assert _key2name(key) != b"----"
                continue
            for data in failed:
                values.append(Atom.render(_key2name(key), data))

        data = Atom.render(b"ilst", b"".join(values))

        # Find the old atoms.
        try:
            atoms = Atoms(filething.fileobj)
        except AtomError as err:
            reraise(error, err, sys.exc_info()[2])

        self.__save(filething.fileobj, atoms, data, padding)
Exemple #3
0
    def save(self, filething=None, v2_version=4, v23_sep='/', padding=None):
        """Save ID3v2 data to the DSF file"""

        fileobj = filething.fileobj
        fileobj.seek(0)

        dsd_header = DSDChunk(fileobj)
        if dsd_header.offset_metdata_chunk == 0:
            # create a new ID3 chunk at the end of the file
            fileobj.seek(0, 2)

            # store reference to ID3 location
            dsd_header.offset_metdata_chunk = fileobj.tell()
            dsd_header.write()

        try:
            data = self._prepare_data(fileobj, dsd_header.offset_metdata_chunk,
                                      self.size, v2_version, v23_sep, padding)
        except ID3Error as e:
            reraise(error, e, sys.exc_info()[2])

        fileobj.seek(dsd_header.offset_metdata_chunk)
        fileobj.write(data)
        fileobj.truncate()

        # Update total file size
        dsd_header.total_size = fileobj.tell()
        dsd_header.write()
Exemple #4
0
    def save(self, filename):
        """Save the metadata to the given filename."""
        values = []
        items = list(self.items())
        items.sort(key=self.__key_sort)
        for key, value in items:
            info = self.__atoms.get(key[:4], (None, type(self).__render_text))
            try:
                values.append(info[1](self, key, value, *info[2:]))
            except (TypeError, ValueError) as s:
                reraise(MP4MetadataValueError, s, sys.exc_info()[2])
        data = Atom.render("ilst", bytearray().join(values))

        # Find the old atoms.
        fileobj = open(filename, "rb+")
        try:
            atoms = Atoms(fileobj)
            try:
                path = atoms.path("moov", "udta", "meta", "ilst")
            except KeyError:
                self.__save_new(fileobj, atoms, data)
            else:
                self.__save_existing(fileobj, atoms, path, data)
        finally:
            fileobj.close()
Exemple #5
0
    def load(self, filename):
        """Load file information from a filename."""

        self.filename = filename
        fileobj = open(filename, "rb")
        try:
            try:
                self.info = self._Info(fileobj)
                self.tags = self._Tags(fileobj, self.info)

                if self.info.length:
                    # The streaminfo gave us real length information,
                    # don't waste time scanning the Ogg.
                    return

                last_page = OggPage.find_last(fileobj, self.info.serial)
                samples = last_page.position
                try:
                    denom = self.info.sample_rate
                except AttributeError:
                    denom = self.info.fps
                self.info.length = samples / float(denom)

            except error as e:
                reraise(self._Error, e, sys.exc_info()[2])
            except EOFError:
                raise self._Error("no appropriate stream found")
        finally:
            fileobj.close()
Exemple #6
0
    def load(self, filename):
        """Load file information from a filename."""

        self.filename = filename
        fileobj = open(filename, "rb")
        try:
            try:
                self.info = self._Info(fileobj)
                self.tags = self._Tags(fileobj, self.info)

                if self.info.length:
                    # The streaminfo gave us real length information,
                    # don't waste time scanning the Ogg.
                    return

                last_page = OggPage.find_last(fileobj, self.info.serial)
                samples = last_page.position
                try:
                    denom = self.info.sample_rate
                except AttributeError:
                    denom = self.info.fps
                self.info.length = samples / float(denom)

            except error as e:
                reraise(self._Error, e, sys.exc_info()[2])
            except EOFError:
                raise self._Error("no appropriate stream found")
        finally:
            fileobj.close()
Exemple #7
0
 def load(self, filename):
     self.filename = filename
     fileobj = open(filename, "rb")
     try:
         atoms = Atoms(fileobj)
         try: self.info = MP4Info(atoms, fileobj)
         except Exception as err:
             reraise(MP4StreamInfoError, err, sys.exc_info()[2])
         try: self.tags = self.MP4Tags(atoms, fileobj)
         except MP4MetadataError:
             self.tags = None
         except Exception as err:
             reraise(MP4MetadataError, err, sys.exc_info()[2])
     finally:
         fileobj.close()
Exemple #8
0
    def save(self, filename=None):
        """Save a tag to a file.

        If no filename is given, the one most recently loaded is used.
        """
        if filename is None:
            filename = self.filename
        fileobj = open(filename, "rb+")
        try:
            try: self.tags._inject(fileobj)
            except error as e:
                reraise(self._Error, e, sys.exc_info()[2])
            except EOFError:
                raise self._Error("no appropriate stream found")
        finally:
            fileobj.close()
Exemple #9
0
    def save(self, filename=None):
        """Save a tag to a file.

        If no filename is given, the one most recently loaded is used.
        """
        if filename is None:
            filename = self.filename
        fileobj = open(filename, "rb+")
        try:
            try:
                self.tags._inject(fileobj)
            except error as e:
                reraise(self._Error, e, sys.exc_info()[2])
            except EOFError:
                raise self._Error("no appropriate stream found")
        finally:
            fileobj.close()
Exemple #10
0
    def load(self, fileobj, errors='replace', framing=True):
        """Parse a Vorbis comment from a file-like object.

        Arguments:
            errors (str): 'strict', 'replace', or 'ignore'.
                This affects Unicode decoding and how other malformed content
                is interpreted.
            framing (bool): if true, fail if a framing bit is not present

        Framing bits are required by the Vorbis comment specification,
        but are not used in FLAC Vorbis comment blocks.
        """

        try:
            vendor_length = cdata.uint_le(fileobj.read(4))
            self.vendor = fileobj.read(vendor_length).decode('utf-8', errors)
            count = cdata.uint_le(fileobj.read(4))
            for i in range(count):
                length = cdata.uint_le(fileobj.read(4))
                try:
                    string = fileobj.read(length).decode('utf-8', errors)
                except (OverflowError, MemoryError):
                    raise error("cannot read %d bytes, too large" % length)
                try:
                    tag, value = string.split('=', 1)
                except ValueError as err:
                    if errors == "ignore":
                        continue
                    elif errors == "replace":
                        tag, value = u"unknown%d" % i, string
                    else:
                        reraise(VorbisEncodingError, err, sys.exc_info()[2])
                try:
                    tag = tag.encode('ascii', errors)
                except UnicodeEncodeError:
                    raise VorbisEncodingError("invalid tag name %r" % tag)
                else:
                    tag = tag.decode("ascii")
                    if is_valid_key(tag):
                        self.append((tag, value))

            if framing and not bytearray(fileobj.read(1))[0] & 0x01:
                raise VorbisUnsetFrameError("framing bit was unset")
        except (cdata.error, TypeError):
            raise error("file is not a valid Vorbis comment")
    def __parse_tag(self, tag, count):
        """Raises IOError and APEBadItemError"""

        fileobj = BytesIO(tag)

        for i in range(count):
            tag_data = fileobj.read(8)
            # someone writes wrong item counts
            if not tag_data:
                break
            if len(tag_data) != 8:
                raise error
            size = cdata.uint32_le(tag_data[:4])
            flags = cdata.uint32_le(tag_data[4:8])

            # Bits 1 and 2 bits are flags, 0-3
            # Bit 0 is read/write flag, ignored
            kind = (flags & 6) >> 1
            if kind == 3:
                raise APEBadItemError("value type must be 0, 1, or 2")

            key = value = fileobj.read(1)
            if not key:
                raise APEBadItemError
            while key[-1:] != b'\x00' and value:
                value = fileobj.read(1)
                if not value:
                    raise APEBadItemError
                key += value
            if key[-1:] == b"\x00":
                key = key[:-1]

            try:
                key = key.decode("ascii")
            except UnicodeError as err:
                reraise(APEBadItemError, err, sys.exc_info()[2])
            value = fileobj.read(size)
            if len(value) != size:
                raise APEBadItemError

            value = _get_value_type(kind)._new(value)

            self[key] = value
Exemple #12
0
    def save(self, filething=None, padding=None):
        """save(filething=None, padding=None)

        Save a tag to a file.

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

        Args:
            filething (filething)
            padding (:obj:`mutagen.PaddingFunction`)
        Raises:
            mutagen.MutagenError
        """

        try:
            self.tags._inject(filething.fileobj, padding)
        except (IOError, error) as e:
            reraise(self._Error, e, sys.exc_info()[2])
        except EOFError:
            raise self._Error("no appropriate stream found")
Exemple #13
0
    def save(self, filething, v1=1, v2_version=4, v23_sep='/', padding=None):
        """Save ID3v2 data to the Wave/RIFF file"""

        fileobj = filething.fileobj
        wave_file = _WaveFile(fileobj)

        if u'id3' not in wave_file:
            wave_file.insert_chunk(u'id3')

        chunk = wave_file[u'id3']

        try:
            data = self._prepare_data(
                fileobj, chunk.data_offset, chunk.data_size, v2_version,
                v23_sep, padding)
        except ID3Error as e:
            reraise(error, e, sys.exc_info()[2])

        chunk.resize(len(data))
        chunk.write(data)
Exemple #14
0
    def load(self, filething):
        """load(filething)

        Load file information from a filename.

        Args:
            filething (filething)
        Raises:
            mutagen.MutagenError
        """

        fileobj = filething.fileobj

        try:
            self.info = self._Info(fileobj)
            self.tags = self._Tags(fileobj, self.info)
            self.info._post_tags(fileobj)
        except (error, IOError) as e:
            reraise(self._Error, e, sys.exc_info()[2])
        except EOFError:
            raise self._Error("no appropriate stream found")
Exemple #15
0
    def save(self, filething=None, v2_version=4, v23_sep='/', padding=None):
        """Save ID3v2 data to the IFF file"""

        fileobj = filething.fileobj

        iff_file = self._load_file(fileobj)

        if 'ID3' not in iff_file:
            iff_file.insert_chunk('ID3')

        chunk = iff_file['ID3']

        try:
            data = self._prepare_data(fileobj, chunk.data_offset,
                                      chunk.data_size, v2_version, v23_sep,
                                      padding)
        except ID3Error as e:
            reraise(error, e, sys.exc_info()[2])

        chunk.resize(len(data))
        chunk.write(data)
Exemple #16
0
    def load(self, fileobj, errors='replace', framing=True):
        """Parse a Vorbis comment from a file-like object.

        Keyword arguments:
        errors:
          'strict', 'replace', or 'ignore'. This affects Unicode decoding
          and how other malformed content is interpreted.
        framing -- if true, fail if a framing bit is not present

        Framing bits are required by the Vorbis comment specification,
        but are not used in FLAC Vorbis comment blocks.

        """
        try:
            vendor_length = cdata.uint_le(fileobj.read(4))
            self.vendor = fileobj.read(vendor_length).decode('utf-8', errors)
            count = cdata.uint_le(fileobj.read(4))
            for i in range(count):
                length = cdata.uint_le(fileobj.read(4))
                try: string = fileobj.read(length).decode('utf-8', errors)
                except (OverflowError, MemoryError):
                    raise error("cannot read %d bytes, too large" % length)
                try: tag, value = string.split('=', 1)
                except ValueError as err:
                    if errors == "ignore":
                        continue
                    elif errors == "replace":
                        tag, value = "unknown%d" % i, string
                    else:
                        reraise(VorbisEncodingError, str(err), sys.exc_info()[2])
                try: tag = tag.encode('ascii', errors)
                except UnicodeEncodeError:
                    raise VorbisEncodingError("invalid tag name %r" % tag)
                else:
                    if is_valid_key(tag): self.append((tag.decode(), value))
            if framing and not ord(fileobj.read(1)) & 0x01:
                raise VorbisUnsetFrameError("framing bit was unset")
        except (cdata.error, TypeError):
            raise error("file is not a valid Vorbis comment")
Exemple #17
0
    def load(self, filething):
        fileobj = filething.fileobj

        try:
            atoms = Atoms(fileobj)
        except AtomError as err:
            reraise(error, err, sys.exc_info()[2])

        self.info = MP4Info()
        try:
            self.info.load(atoms, fileobj)
        except MP4NoTrackError:
            pass
        except error:
            raise
        except Exception as err:
            reraise(MP4StreamInfoError, err, sys.exc_info()[2])

        if not MP4Tags._can_load(atoms):
            self.tags = None
        else:
            try:
                self.tags = self.MP4Tags(atoms, fileobj)
            except error:
                raise
            except Exception as err:
                reraise(MP4MetadataError, err, sys.exc_info()[2])

        if not MP4Chapters._can_load(atoms):
            self.chapters = None
        else:
            try:
                self.chapters = self.MP4Chapters(atoms, fileobj)
            except error:
                raise
            except Exception as err:
                reraise(MP4MetadataError, err, sys.exc_info()[2])
 def _parse(self, data):
     try:
         self.value = data.decode("utf-8")
     except UnicodeDecodeError as e:
         reraise(APEBadItemError, e, sys.exc_info()[2])
Exemple #19
0
 def parse(self, data):
     try:
         return data.decode("utf-16-le").strip("\x00")
     except UnicodeDecodeError as e:
         reraise(ASFError, e, sys.exc_info()[2])