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])
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)
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()
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()
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()
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()
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()
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
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")
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)
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")
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)
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")
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])
def parse(self, data): try: return data.decode("utf-16-le").strip("\x00") except UnicodeDecodeError as e: reraise(ASFError, e, sys.exc_info()[2])