예제 #1
0
    def _test_cover_art(self, filename):
        self._set_up(filename)
        try:
            # Use reasonable large data > 64kb.
            # This checks a mutagen error with ASF files.
            dummyload = "a" * 1024 * 128
            tests = {
                'jpg': {
                    'mime': 'image/jpeg',
                    'head': 'JFIF'
                },
                'png': {
                    'mime': 'image/png',
                    'head': 'PNG'
                },
            }
            for t in tests:
                f = picard.formats.open(self.filename)
                metadata = Metadata()
                imgdata = tests[t]['head'] + dummyload
                metadata.make_and_add_image(tests[t]['mime'], imgdata)
                f._save(self.filename, metadata)

                f = picard.formats.open(self.filename)
                loaded_metadata = f._load(self.filename)
                image = loaded_metadata.images[0]
                self.assertEqual(image.mimetype, tests[t]['mime'])
                self.assertEqual(image.data, imgdata)
        finally:
            self._tear_down()
예제 #2
0
파일: apev2.py 프로젝트: Braingate/picard
 def _load(self, filename):
     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.make_and_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
예제 #3
0
파일: mp4.py 프로젝트: Braingate/picard
    def _load(self, filename):
        log.debug("Loading file %r", filename)
        file = MP4(encode_filename(filename))
        if file.tags is None:
            file.add_tags()

        metadata = Metadata()
        for name, values in file.tags.items():
            if name in self.__text_tags:
                for value in values:
                    metadata.add(self.__text_tags[name], value)
            elif name in self.__bool_tags:
                metadata.add(self.__bool_tags[name], values and '1' or '0')
            elif name in self.__int_tags:
                for value in values:
                    metadata.add(self.__int_tags[name], unicode(value))
            elif name in self.__freeform_tags:
                for value in values:
                    value = value.strip("\x00").decode("utf-8", "replace")
                    metadata.add(self.__freeform_tags[name], value)
            elif name == "----:com.apple.iTunes:fingerprint":
                for value in values:
                    value = value.strip("\x00").decode("utf-8", "replace")
                    if value.startswith("MusicMagic Fingerprint"):
                        metadata.add("musicip_fingerprint", value[22:])
            elif name == "trkn":
                metadata["tracknumber"] = str(values[0][0])
                metadata["totaltracks"] = str(values[0][1])
            elif name == "disk":
                metadata["discnumber"] = str(values[0][0])
                metadata["totaldiscs"] = str(values[0][1])
            elif name == "covr":
                for value in values:
                    if value.imageformat == value.FORMAT_JPEG:
                        metadata.make_and_add_image("image/jpeg", value)
                    elif value.imageformat == value.FORMAT_PNG:
                        metadata.make_and_add_image("image/png", value)

        self._info(metadata, file)
        return metadata
예제 #4
0
파일: asf.py 프로젝트: queer1/picard
 def _load(self, filename):
     log.debug("Loading file %r", filename)
     file = ASF(encode_filename(filename))
     metadata = Metadata()
     for name, values in file.tags.items():
         if name == 'WM/Picture':
             for image in values:
                 (mime, data, type, description) = unpack_image(image.value)
                 metadata.make_and_add_image(mime, data, comment=description,
                                    imagetype=image_type_from_id3_num(type))
             continue
         elif name not in self.__RTRANS:
             continue
         elif name == 'WM/SharedUserRating':
             # Rating in WMA ranges from 0 to 99, normalize this to the range 0 to 5
             values[0] = int(round(int(unicode(values[0])) / 99.0 * (config.setting['rating_steps'] - 1)))
         name = self.__RTRANS[name]
         values = filter(bool, map(unicode, values))
         if values:
             metadata[name] = values
     self._info(metadata, file)
     return metadata
예제 #5
0
파일: vorbis.py 프로젝트: m42i/picard
 def _load(self, filename):
     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 = ''
                 if email != config.setting['rating_user_email']:
                     continue
                 name = '~rating'
                 value = unicode(int(round((float(value) * (config.setting['rating_steps'] - 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))
                 types, is_front = types_and_front(image.type)
                 metadata.make_and_add_image(image.mime, image.data,
                                             comment=image.desc,
                                             types=types,
                                             is_front=is_front)
                 continue
             elif name in self.__translate:
                 name = self.__translate[name]
             metadata.add(name, value)
     if self._File == mutagen.flac.FLAC:
         for image in file.pictures:
             types, is_front = types_and_front(image.type)
             metadata.make_and_add_image(image.mime, image.data, comment=image.desc,
                                         types=types, is_front=is_front)
     # 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.make_and_add_image(file["COVERARTMIME"][index],
                                             base64.standard_b64decode(data)
                                             )
         except KeyError:
             pass
     self._info(metadata, file)
     return metadata
예제 #6
0
파일: id3.py 프로젝트: queer1/picard
    def _load(self, filename):
        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":
                # If file is ID3v2.3, TIPL tag could contain TMCL
                # so we will test for TMCL values and add to TIPL if not TMCL
                for role, name in frame.people:
                    if role in self._tipl_roles and name:
                        metadata.add(self._tipl_roles[role], name)
                    else:
                        metadata.add('performer:%s' % role, name)
            elif frameid == 'TXXX':
                name = frame.desc
                if name in self.__translate_freetext:
                    name = self.__translate_freetext[name]
                elif ((name in self.__rtranslate) !=
                        (name in self.__rtranslate_freetext)):
                    # If the desc of a TXXX frame conflicts with the name of a
                    # Picard tag, load it into ~id3:TXXX:desc rather than desc.
                    #
                    # This basically performs an XOR, making sure that 'name'
                    # is in __rtranslate or __rtranslate_freetext, but not
                    # both. (Being in both implies we support reading it both
                    # ways.) Currently, the only tag in both is license.
                    name = '~id3:TXXX:' + name
                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_recordingid'] = frame.data.decode('ascii', 'ignore')
            elif frameid in self.__tag_re_parse.keys():
                m = self.__tag_re_parse[frameid].search(frame.text[0])
                if m:
                    for name, value in m.groupdict().iteritems():
                        if value is not None:
                            metadata[name] = value
                else:
                    log.error("Invalid %s value '%s' dropped in %r", frameid, frame.text[0], filename)
            elif frameid == 'APIC':
                metadata.make_and_add_image(frame.mime, frame.data, comment=frame.desc,
                                   imagetype=image_type_from_id3_num(frame.type))
            elif frameid == 'POPM':
                # Rating in ID3 ranges from 0 to 255, normalize this to the range 0 to 5
                if frame.email == config.setting['rating_user_email']:
                    rating = unicode(int(round(frame.rating / 255.0 * (config.setting['rating_steps'] - 1))))
                    metadata.add('~rating', rating)

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

        self._info(metadata, file)
        return metadata