Esempio n. 1
0
 def _load(self, filename):
     self.log.debug("Loading file %r", filename)
     file = self._File(encode_filename(filename))
     metadata = Metadata()
     if file.tags:
         for origname, values in file.tags.items():
             if origname.lower().startswith("cover art") and values.kind == mutagen.apev2.BINARY:
                 if '\0' in values.value:
                     descr, data = values.value.split('\0', 1)
                     mime = mimetype.get_from_data(data, descr, 'image/jpeg')
                     metadata.add_image(mime, data)
             # skip EXTERNAL and BINARY values
             if values.kind != mutagen.apev2.TEXT:
                 continue
             for value in values:
                 name = origname
                 if name == "Year":
                     name = "date"
                     value = sanitize_date(value)
                 elif name == "Track":
                     name = "tracknumber"
                     track = value.split("/")
                     if len(track) > 1:
                         metadata["totaltracks"] = track[1]
                         value = track[0]
                 elif name == "Disc":
                     name = "discnumber"
                     disc = value.split("/")
                     if len(disc) > 1:
                         metadata["totaldiscs"] = disc[1]
                         value = disc[0]
                 elif name == 'Performer' or name == 'Comment':
                     name = name.lower() + ':'
                     if value.endswith(')'):
                         start = value.rfind(' (')
                         if start > 0:
                             name += value[start + 2:-1]
                             value = value[:start]
                 elif name in self.__translate:
                     name = self.__translate[name]
                 else:
                     name = name.lower()
                 metadata.add(name, value)
     self._info(metadata, file)
     return metadata
Esempio n. 2
0
    def _load(self, filename):
        self.log.debug("Loading file %r", filename)
        file = self._File(encode_filename(filename))
        file.tags = file.tags or {}
        metadata = Metadata()
        for origname, values in file.tags.items():
            for value in values:
                name = origname
                if name == "date" or name == "originaldate":
                    # YYYY-00-00 => YYYY
                    value = sanitize_date(value)
                elif name == 'performer' or name == 'comment':
                    # transform "performer=Joe Barr (Piano)" to "performer:Piano=Joe Barr"
                    name += ':'
                    if value.endswith(')'):
                        start = len(value) - 2
                        count = 1
                        while count > 0 and start > 0:
                            if value[start] == ')':
                                count += 1
                            elif value[start] == '(':
                                count -= 1
                            start -= 1
                        if start > 0:
                            name += value[start + 2:-1]
                            value = value[:start]
                elif name.startswith('rating'):
                    try: name, email = name.split(':', 1)
                    except ValueError: email = ''
		    continue
                    if email != self.config.setting['rating_user_email']:
                        continue
                    name = '~rating'
                    value = unicode(int(round((float(value) * (5 - 1)))))
                elif name == "fingerprint" and value.startswith("MusicMagic Fingerprint"):
                    name = "musicip_fingerprint"
                    value = value[22:]
                elif name == "tracktotal":
                    if "totaltracks" in file.tags:
                        continue
                    name = "totaltracks"
                elif name == "disctotal":
                    if "totaldiscs" in file.tags:
                        continue
                    name = "totaldiscs"
                elif name == "metadata_block_picture":
                    image = mutagen.flac.Picture(base64.standard_b64decode(value))
                    metadata.add_image(image.mime, image.data)
                    continue
                metadata.add(name, value)
        if self._File == mutagen.flac.FLAC:
            for image in file.pictures:
                metadata.add_image(image.mime, image.data)
        # Read the unofficial COVERART tags, for backward compatibillity only
        if not "metadata_block_picture" in file.tags:
            try:
                for index, data in enumerate(file["COVERART"]):
                    metadata.add_image(file["COVERARTMIME"][index], base64.standard_b64decode(data))
            except KeyError:
                pass
        self._info(metadata, file)
        return metadata
Esempio n. 3
0
    def _save(self, filename, metadata, settings):
        """Save metadata to the file."""
        self.log.debug("Saving file %r", filename)
        file = self._File(encode_filename(filename))
        if file.tags is None:
            file.add_tags()
        if settings["clear_existing_tags"]:
            file.tags.clear()
        if self._File == mutagen.flac.FLAC and (
            settings["clear_existing_tags"] or
            (settings['save_images_to_tags'] and metadata.images)):
            file.clear_pictures()
        tags = {}
        for name, value in metadata.items():
            if name == '~rating':
                # Save rating according to http://code.google.com/p/quodlibet/wiki/Specs_VorbisComments
                if settings['rating_user_email']:
                    name = 'rating:%s' % settings['rating_user_email']
                else:
                    name = 'rating'
                value = unicode(float(value) / (settings['rating_steps'] - 1))
            # don't save private tags
            elif name.startswith("~"):
                continue
            if name.startswith('lyrics:'):
                name = 'lyrics'
            elif name == "date" or name == "originaldate":
                # YYYY-00-00 => YYYY
                value = sanitize_date(value)
            elif name.startswith('performer:') or name.startswith('comment:'):
                # transform "performer:Piano=Joe Barr" to "performer=Joe Barr (Piano)"
                name, desc = name.split(':', 1)
                if desc:
                    value += ' (%s)' % desc
            elif name == "musicip_fingerprint":
                name = "fingerprint"
                value = "MusicMagic Fingerprint%s" % value
            tags.setdefault(name.upper().encode('utf-8'), []).append(value)

        if "totaltracks" in metadata:
            tags.setdefault(u"TRACKTOTAL", []).append(metadata["totaltracks"])
        if "totaldiscs" in metadata:
            tags.setdefault(u"DISCTOTAL", []).append(metadata["totaldiscs"])

        if settings['save_images_to_tags']:
            for mime, data, filename in metadata.images:
                image = mutagen.flac.Picture()
                image.type = 3 # Cover image
                image.data = data
                image.mime = mime
                if self._File == mutagen.flac.FLAC:
                    file.add_picture(image)
                else:
                    tags.setdefault(u"METADATA_BLOCK_PICTURE", []).append(
                        base64.standard_b64encode(image.write()))
        file.tags.update(tags)
        kwargs = {}
        if self._File == mutagen.flac.FLAC and settings["remove_id3_from_flac"]:
            kwargs["deleteid3"] = True
        try:
            file.save(**kwargs)
        except TypeError:
            file.save()
Esempio n. 4
0
    def _load(self, filename):
        self.log.debug("Loading file %r", filename)
        file = self._File(encode_filename(filename), ID3=compatid3.CompatID3)
        tags = file.tags or {}
        # upgrade custom 2.3 frames to 2.4
        for old, new in self.__upgrade.items():
            if old in tags and new not in tags:
                f = tags.pop(old)
                tags.add(getattr(id3, new)(encoding=f.encoding, text=f.text))
        metadata = Metadata()
        for frame in tags.values():
            frameid = frame.FrameID
            if frameid in self.__translate:
                name = self.__translate[frameid]
                if frameid.startswith('T'):
                    for text in frame.text:
                        if text:
                            metadata.add(name, unicode(text))
                elif frameid == 'COMM':
                    for text in frame.text:
                        if text:
                            metadata.add('%s:%s' % (name, frame.desc), unicode(text))
                else:
                    metadata.add(name, unicode(frame))
            elif frameid == "TMCL":
                for role, name in frame.people:
                    if role or name:
                        metadata.add('performer:%s' % role, name)
            elif frameid == "TIPL":
                for role, name in frame.people:
                    if role in self.__tipl_roles and name:
                        metadata.add(self.__tipl_roles[role], name)
            elif frameid == 'TXXX':
                if frame.desc in self.__translate_freetext:
                    name = self.__translate_freetext[frame.desc]
                else:
                    name = str(frame.desc.lower())
                for text in frame.text:
                    metadata.add(name, unicode(text))
            elif frameid == 'USLT':
                name = 'lyrics'
                if frame.desc:
                    name += ':%s' % frame.desc
                metadata.add(name, unicode(frame.text))
            elif frameid == 'UFID' and frame.owner == 'http://musicbrainz.org':
                metadata['musicbrainz_trackid'] = unicode(frame.data)
            elif frameid == 'TRCK':
                value = frame.text[0].split('/')
                if len(value) > 1:
                    metadata['tracknumber'], metadata['totaltracks'] = value[:2]
                else:
                    metadata['tracknumber'] = value[0]
            elif frameid == 'TPOS':
                value = frame.text[0].split('/')
                if len(value) > 1:
                    metadata['discnumber'], metadata['totaldiscs'] = value[:2]
                else:
                    metadata['discnumber'] = value[0]
            elif frameid == 'APIC':
                metadata.add_image(frame.mime, frame.data)
            elif frameid == 'POPM':
                # Rating in ID3 ranges from 0 to 255, normalize this to the range 0 to 5
                if False:
                    rating = unicode(int(round(frame.rating / 255.0 * (5 - 1))))
                    metadata.add('~rating', rating)

        if 'date' in metadata:
            metadata['date'] = sanitize_date(metadata.getall('date')[0])

        self._info(metadata, file)
        return metadata