def setUp(self): fd, self.filename = mkstemp(suffix='wma') os.close(fd) shutil.copy(self.original, self.filename) audio = ASF(self.filename) audio["large_value1"] = "#" * 50000 audio.save()
def _save(self, filename, metadata): log.debug("Saving file %r", filename) file = ASF(encode_filename(filename)) tags = file.tags if config.setting['clear_existing_tags']: tags.clear() cover = [] for image in metadata.images_to_be_saved_to_tags: tag_data = pack_image(image.mimetype, image.data, image_type_as_id3_num(image.maintype), image.comment) cover.append(ASFByteArrayAttribute(tag_data)) if cover: tags['WM/Picture'] = cover for name, values in metadata.rawitems(): if name.startswith('lyrics:'): name = 'lyrics' elif name == '~rating': values[0] = int( values[0]) * 99 // (config.setting['rating_steps'] - 1) elif name == 'discnumber' and 'totaldiscs' in metadata: values[0] = '%s/%s' % (metadata['discnumber'], metadata['totaldiscs']) if name not in self.__TRANS: continue name = self.__TRANS[name] tags[name] = values self._remove_deleted_tags(metadata, tags) file.save()
def setUp(self): # WMA 9.1 64kbps CBR 48khz self.wma1 = ASF(os.path.join("tests", "data", "silence-1.wma")) # WMA 9.1 Professional 192kbps VBR 44khz self.wma2 = ASF(os.path.join("tests", "data", "silence-2.wma")) # WMA 9.1 Lossless 44khz self.wma3 = ASF(os.path.join("tests", "data", "silence-3.wma"))
def _save(self, filename, metadata): log.debug("Saving file %r", filename) file = ASF(encode_filename(filename)) if config.setting['clear_existing_tags']: file.tags.clear() if config.setting['save_images_to_tags']: cover = [] for image in metadata.images: if not save_this_image_to_tags(image): continue tag_data = pack_image(image.mimetype, image.data, image_type_as_id3_num(image.maintype()), image.description) cover.append(ASFByteArrayAttribute(tag_data)) if cover: file.tags['WM/Picture'] = cover for name, values in metadata.rawitems(): if name.startswith('lyrics:'): name = 'lyrics' elif name == '~rating': values[0] = int(values[0]) * 99 / (config.setting['rating_steps'] - 1) if name not in self.__TRANS: continue name = self.__TRANS[name] file.tags[name] = map(unicode, values) file.save()
def _save(self, filename, metadata, settings): self.log.debug("Saving file %r", filename) file = ASF(encode_filename(filename)) if settings['clear_existing_tags']: file.tags.clear() if settings['save_images_to_tags']: cover = [] for image in metadata.images: if self.config.setting["save_only_front_images_to_tags"] and image["type"] != "front": continue imagetype = ID3_IMAGE_TYPE_MAP.get(image["type"], 0) tag_data = pack_image(image["mime"], image["data"], imagetype, image["description"]) cover.append(ASFByteArrayAttribute(tag_data)) if cover: file.tags['WM/Picture'] = cover for name, values in metadata.rawitems(): if name.startswith('lyrics:'): name = 'lyrics' elif name == '~rating': values[0] = int(values[0]) * 99 / (settings['rating_steps'] - 1) if name not in self.__TRANS: continue name = self.__TRANS[name] file.tags[name] = map(unicode, values) file.save()
class TASFIssue29(TestCase): original = os.path.join("tests", "data", "issue_29.wma") def setUp(self): fd, self.filename = mkstemp(suffix='wma') os.close(fd) shutil.copy(self.original, self.filename) self.audio = ASF(self.filename) def tearDown(self): os.unlink(self.filename) def test_pprint(self): self.audio.pprint() def test_issue_29_description(self): self.audio["Description"] = "Hello" self.audio.save() audio = ASF(self.filename) self.failUnless("Description" in audio) self.failUnlessEqual(audio["Description"], ["Hello"]) del(audio["Description"]) self.failIf("Description" in audio) audio.save() audio = ASF(self.filename) self.failIf("Description" in audio)
def test_non_text_type(self): audio = ASF(self.filename) audio["Author"] = [42] audio.save() self.assertFalse(audio.to_content_description) new = ASF(self.filename) self.assertEqual(new["Author"], [42])
def test_save_large_bytearray(self): audio = ASF(self.filename) audio["QL/LargeObject"] = [ASFValue(b"." * (0xFFFF + 1), BYTEARRAY)] audio.save() self.failIf("QL/LargeObject" in audio.to_extended_content_description) self.failIf("QL/LargeObject" in audio.to_metadata) self.failIf("QL/LargeObject" not in dict(audio.to_metadata_library))
def test_save_large_string(self): audio = ASF(self.filename) audio["QL/LargeObject"] = [ASFValue("." * 0x7FFF, UNICODE)] audio.save() self.failIf("QL/LargeObject" in audio.to_extended_content_description) self.failIf("QL/LargeObject" in audio.to_metadata) self.failIf("QL/LargeObject" not in dict(audio.to_metadata_library))
def _save(self, filename, metadata): log.debug("Saving file %r", filename) file = ASF(encode_filename(filename)) if config.setting["clear_existing_tags"]: file.tags.clear() if config.setting["save_images_to_tags"]: cover = [] for image in metadata.images: if not save_this_image_to_tags(image): continue tag_data = pack_image(image["mime"], image["data"], image_type_as_id3_num(image["type"]), image["desc"]) cover.append(ASFByteArrayAttribute(tag_data)) if cover: file.tags["WM/Picture"] = cover for name, values in metadata.rawitems(): if name.startswith("lyrics:"): name = "lyrics" elif name == "~rating": values[0] = int(values[0]) * 99 / (config.setting["rating_steps"] - 1) if name not in self.__TRANS: continue name = self.__TRANS[name] file.tags[name] = map(unicode, values) file.save()
def _save(self, filename, metadata): log.debug("Saving file %r", filename) file = ASF(encode_filename(filename)) if config.setting['clear_existing_tags']: file.tags.clear() cover = [] for image in metadata.images_to_be_saved_to_tags: tag_data = pack_image(image.mimetype, image.data, image_type_as_id3_num(image.maintype), image.comment) cover.append(ASFByteArrayAttribute(tag_data)) if cover: file.tags['WM/Picture'] = cover for name, values in metadata.rawitems(): if name.startswith('lyrics:'): name = 'lyrics' elif name == '~rating': values[0] = int(values[0]) * 99 / (config.setting['rating_steps'] - 1) elif name == 'discnumber' and 'totaldiscs' in metadata: values[0] = '%s/%s' % (metadata['discnumber'], metadata['totaldiscs']) if name not in self.__TRANS: continue name = self.__TRANS[name] file.tags[name] = map(unicode, values) file.save()
def test_multiple_delete(self): self.audio["large_value1"] = "#" * 50000 self.audio.save() audio = ASF(self.filename) for tag in audio.keys(): del(audio[tag]) audio.save()
def test_save_guid(self): # https://github.com/quodlibet/mutagen/issues/81 audio = ASF(self.filename) audio["QL/GuidObject"] = [ASFValue(b" " * 16, GUID)] audio.save() self.failIf("QL/GuidObject" in audio.to_extended_content_description) self.failIf("QL/GuidObject" in audio.to_metadata) self.failIf("QL/GuidObject" not in dict(audio.to_metadata_library))
def test_save_guid(self): # http://code.google.com/p/mutagen/issues/detail?id=81 audio = ASF(self.filename) audio["QL/GuidObject"] = [ASFValue(b" " * 16, GUID)] audio.save() self.failIf("QL/GuidObject" in audio.to_extended_content_description) self.failIf("QL/GuidObject" in audio.to_metadata) self.failIf("QL/GuidObject" not in dict(audio.to_metadata_library))
def test_multiple_delete(self): self.audio["large_value1"] = "#" * 50000 self.audio.save() audio = ASF(self.filename) for tag in audio.keys(): del (audio[tag]) audio.save()
def test_empty(self): audio = ASF(self.filename) audio["Author"] = [u"", u""] audio["Title"] = [u""] audio["Copyright"] = [] audio.save() new = ASF(self.filename) self.assertEqual(new["Author"], [u"", u""]) self.assertEqual(new["Title"], [u""]) self.assertFalse("Copyright" in new)
def set_key(self, key, value, result=None): self.audio[key] = value self.audio.save() self.audio = ASF(self.audio.filename) self.failUnless(key in self.audio) newvalue = self.audio[key] if isinstance(newvalue, list): for a, b in zip(sorted(newvalue), sorted(result or value)): self.failUnlessEqual(a, b) else: self.failUnlessEqual(audio[key], result or value)
def test_issue_29_description(self): self.audio["Description"] = "Hello" self.audio.save() audio = ASF(self.filename) self.failUnless("Description" in audio) self.failUnlessEqual(audio["Description"], ["Hello"]) del(audio["Description"]) self.failIf("Description" in audio) audio.save() audio = ASF(self.filename) self.failIf("Description" in audio)
def test_author(self): audio = ASF(self.filename) values = [u"Foo", u"Bar", u"Baz"] audio["Author"] = values audio.save() self.assertEqual(list(audio.to_content_description.items()), [(u"Author", u"Foo")]) self.assertEqual(audio.to_metadata_library, [(u"Author", u"Bar"), (u"Author", u"Baz")]) new = ASF(self.filename) self.assertEqual(new["Author"], values)
def test_author(self): audio = ASF(self.filename) values = [u"Foo", u"Bar", u"Baz"] audio["Author"] = values audio.save() self.assertEqual( list(audio.to_content_description.items()), [(u"Author", u"Foo")]) self.assertEqual( audio.to_metadata_library, [(u"Author", u"Bar"), (u"Author", u"Baz")]) new = ASF(self.filename) self.assertEqual(new["Author"], values)
def test_author_long(self): audio = ASF(self.filename) # 2 ** 16 - 2 bytes encoded text + 2 bytes termination just_small_enough = u"a" * (((2 ** 16) // 2) - 2) audio["Author"] = [just_small_enough] audio.save() self.assertTrue(audio.to_content_description) self.assertFalse(audio.to_metadata_library) audio["Author"] = [just_small_enough + u"a"] audio.save() self.assertFalse(audio.to_content_description) self.assertTrue(audio.to_metadata_library)
def set_key(self, key, value, result=None, expected=True): self.audio[key] = value self.audio.save() self.audio = ASF(self.audio.filename) self.failUnless(key in self.audio) self.failUnless(key in self.audio.tags) self.failUnless(key in self.audio.tags.keys()) self.failUnless(key in self.audio.tags.as_dict().keys()) newvalue = self.audio[key] if isinstance(newvalue, list): for a, b in zip(sorted(newvalue), sorted(result or value)): self.failUnlessEqual(a, b) else: self.failUnlessEqual(self.audio[key], result or value)
def songSort(song, ext): if (ext == "mp3"): metadata = EasyID3(song) album = str(metadata['album']) elif (ext == "m4a"): metadata = MP4(song) album = str(metadata["\xa9alb"]) elif (ext == "wma"): metadata = ASF(song) album = str(metadata["WM/AlbumTitle"]) album = album[22:-3] else: album = album[2:-2] albumList = os.listdir(musicSort / "Albums") #album folder check if (album not in albumList): if (DEBUG): print(song) print(album + " not found") os.mkdir(musicSort / "Albums" / album) return (musicSort / "Albums" / album)
def _load(self, filename): self.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) = unpack_image(image.value) if type == 3: # Only cover images metadata.add_image(mime, data) 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 * (self.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
def __collect_stats_wma(self): """ Process a WMA file to grab meta-data from it """ for file in self.music_files['wma']: try: asf = ASF(file) artist = unicode(asf.get('WM/AlbumArtist', ['Unknown Artist'])[0]).lower() song = unicode(asf.get('Title', ['Unknown Title'])[0]).lower() album = unicode(asf.get('WM/AlbumTitle', ['Unknown Album'])[0]).lower() self.__add_stats(artist, album, song) except Exception as e: print("Error: "+str(e)) print("File: "+file)
def test_lang_and_stream_mix(self): self.audio["QL/Mix"] = [ ASFValue("Whee", UNICODE, stream=1), ASFValue("Whee", UNICODE, language=2), ASFValue("Whee", UNICODE, stream=3, language=4), ASFValue("Whee", UNICODE), ] self.audio.save() self.audio = ASF(self.audio.filename) self.failUnlessEqual(self.audio["QL/Mix"][0].language, None) self.failUnlessEqual(self.audio["QL/Mix"][0].stream, 1) self.failUnlessEqual(self.audio["QL/Mix"][1].language, 2) self.failUnlessEqual(self.audio["QL/Mix"][1].stream, 0) self.failUnlessEqual(self.audio["QL/Mix"][2].language, 4) self.failUnlessEqual(self.audio["QL/Mix"][2].stream, 3) self.failUnlessEqual(self.audio["QL/Mix"][3].language, None) self.failUnlessEqual(self.audio["QL/Mix"][3].stream, None)
def test_stream(self): self.audio["QL/OneHasStream"] = [ ASFValue("Whee", UNICODE, stream=2), ASFValue("Whee", UNICODE), ] self.audio["QL/AllHaveStream"] = [ ASFValue("Whee", UNICODE, stream=1), ASFValue("Whee", UNICODE, stream=2), ] self.audio["QL/NoStream"] = ASFValue("Whee", UNICODE) self.audio.save() self.audio = ASF(self.audio.filename) self.failUnlessEqual(self.audio["QL/NoStream"][0].stream, None) self.failUnlessEqual(self.audio["QL/OneHasStream"][1].stream, 2) self.failUnlessEqual(self.audio["QL/OneHasStream"][0].stream, None) self.failUnlessEqual(self.audio["QL/AllHaveStream"][0].stream, 1) self.failUnlessEqual(self.audio["QL/AllHaveStream"][1].stream, 2)
def test_language(self): self.audio["QL/OneHasLang"] = [ ASFValue("Whee", UNICODE, language=2), ASFValue("Whee", UNICODE), ] self.audio["QL/AllHaveLang"] = [ ASFValue("Whee", UNICODE, language=1), ASFValue("Whee", UNICODE, language=2), ] self.audio["QL/NoLang"] = ASFValue("Whee", UNICODE) self.audio.save() self.audio = ASF(self.audio.filename) self.failUnlessEqual(self.audio["QL/NoLang"][0].language, None) self.failUnlessEqual(self.audio["QL/OneHasLang"][0].language, 2) self.failUnlessEqual(self.audio["QL/OneHasLang"][1].language, None) self.failUnlessEqual(self.audio["QL/AllHaveLang"][0].language, 1) self.failUnlessEqual(self.audio["QL/AllHaveLang"][1].language, 2)
def getTrack(filename): """ Return a Track created from an asf file """ from mutagen.asf import ASF asfFile = ASF(filename) length = int(round(asfFile.info.length)) bitrate = int(asfFile.info.bitrate) samplerate = int(asfFile.info.sample_rate) try: trackNumber = str(asfFile['WM/TrackNumber'][0]) except: trackNumber = None try: discNumber = str(asfFile['WM/PartOfSet'][0]) except: discNumber = None try: date = str(asfFile['WM/Year'][0]) except: date = None try: title = str(asfFile['Title'][0]) except: title = None try: album = str(asfFile['WM/AlbumTitle'][0]) except: album = None try: artist = str(asfFile['Author'][0]) except: artist = None try: albumArtist = str(asfFile['WM/AlbumArtist'][0]) except: albumArtist = None try: genre = str(asfFile['WM/Genre'][0]) except: genre = None try: musicbrainzId = str(asfFile['MusicBrainz/Track Id'][0]) except: musicbrainzId = None return createFileTrack(filename, bitrate, length, samplerate, False, title, album, artist, albumArtist, musicbrainzId, genre, trackNumber, date, discNumber)
def _load(self, filename): log.debug("Loading file %r", filename) config = get_config() self.__casemap = {} file = ASF(encode_filename(filename)) metadata = Metadata() for name, values in file.tags.items(): if name == 'WM/Picture': for image in values: try: (mime, data, image_type, description) = unpack_image(image.value) except ValueError as e: log.warning('Cannot unpack image from %r: %s', filename, e) continue try: coverartimage = TagCoverArtImage( file=filename, tag=name, types=types_from_id3(image_type), comment=description, support_types=True, data=data, id3_type=image_type, ) except CoverArtImageError as e: log.error('Cannot load image from %r: %s' % (filename, e)) else: metadata.images.append(coverartimage) 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(str(values[0])) / 99.0 * (config.setting['rating_steps'] - 1))) elif name == 'WM/PartOfSet': disc = str(values[0]).split("/") if len(disc) > 1: metadata["totaldiscs"] = disc[1] values[0] = disc[0] name_lower = name.lower() if name in self.__RTRANS: name = self.__RTRANS[name] elif name_lower in self.__RTRANS_CI: orig_name = name name = self.__RTRANS_CI[name_lower] self.__casemap[name] = orig_name else: continue values = [str(value) for value in values if value] if values: metadata[name] = values self._info(metadata, file) return metadata
def _save(self, filename, metadata): log.debug("Saving file %r", filename) config = get_config() file = ASF(encode_filename(filename)) tags = file.tags if config.setting['clear_existing_tags']: cover = tags.get( 'WM/Picture') if config.setting['preserve_images'] else None tags.clear() if cover: tags['WM/Picture'] = cover cover = [] for image in metadata.images.to_be_saved_to_tags(): tag_data = pack_image(image.mimetype, image.data, image.id3_type, image.comment) cover.append(ASFByteArrayAttribute(tag_data)) if cover: tags['WM/Picture'] = cover for name, values in metadata.rawitems(): if name.startswith('lyrics:'): name = 'lyrics' elif name == '~rating': values = [ int(values[0]) * 99 // (config.setting['rating_steps'] - 1) ] elif name == 'discnumber' and 'totaldiscs' in metadata: values = [ '%s/%s' % (metadata['discnumber'], metadata['totaldiscs']) ] if name in self.__TRANS: name = self.__TRANS[name] elif name in self.__TRANS_CI: if name in self.__casemap: name = self.__casemap[name] else: name = self.__TRANS_CI[name] delall_ci(tags, name) else: continue tags[name] = values self._remove_deleted_tags(metadata, tags) file.save()
def test_padding(self): old_tags = sorted(self.audio.items()) def get_padding(fn): header = ASF(fn)._header return len(header.get_child(PaddingObject.GUID).data) for i in [0, 1, 2, 3, 42, 100, 5000, 30432, 1]: def padding_cb(info): self.assertEqual(info.size, 30432) return i self.audio.save(padding=padding_cb) self.assertEqual(get_padding(self.filename), i) last = ASF(self.filename) self.assertEqual(sorted(last.items()), old_tags)
def __init__(self, file, threshold=60, duration_distance_threshold=10000): self.file = file self.threshold = threshold self.ddt = duration_distance_threshold self.cleaner = re.compile(r"[^A-Za-z0-9 ]").sub try: self.audio = MP3(file, ID3=EasyID3) except: try: self.audio = FLAC(file) except: try: self.audio = OggVorbis(file) except: try: self.audio = OggFLAC(file) except: try: self.audio = OggTheora(file) except: try: self.audio = APEv2(file) except: try: self.audio = ASF(file) except: try: self.audio = MP4(file) except: try: self.audio = Musepack(file) except: try: self.audio = TrueAudio(file) except: try: self.audio = WavPack(file) except: raise FileTypeException( 'Unknown file type, no metadata, or file not found.' ) try: [title] = self.audio['title'] self.title = self.__clean_literal(str(title)) except: self.title = None try: [artist] = self.audio['artist'] self.artist = self.__clean_literal(str(artist)) except: self.artist = None try: [album] = self.audio['album'] self.album = self.__clean_literal(str(album)) except: self.album = None self.mbzQuery()
def test_invalid_header(self): with warnings.catch_warnings(): warnings.simplefilter("ignore") asf = ASF() fileobj = cBytesIO( b"0&\xb2u\x8ef\xcf\x11\xa6\xd9\x00\xaa\x00b\xcel\x19\xbf\x01\x00" b"\x00\x00\x00\x00\x07\x00\x00\x00\x01\x02") self.assertRaises(ASFHeaderError, HeaderObject.parse_full, asf, fileobj)
def test_lang_and_stream_mix(self): self.audio["QL/Mix"] = [ ASFValue("Whee", UNICODE, stream=1), ASFValue("Whee", UNICODE, language=2), ASFValue("Whee", UNICODE, stream=3, language=4), ASFValue("Whee", UNICODE), ] self.audio.save() self.audio = ASF(self.audio.filename) # order not preserved here because they end up in different objects. self.failUnlessEqual(self.audio["QL/Mix"][1].language, None) self.failUnlessEqual(self.audio["QL/Mix"][1].stream, 1) self.failUnlessEqual(self.audio["QL/Mix"][2].language, 2) self.failUnlessEqual(self.audio["QL/Mix"][2].stream, 0) self.failUnlessEqual(self.audio["QL/Mix"][3].language, 4) self.failUnlessEqual(self.audio["QL/Mix"][3].stream, 3) self.failUnlessEqual(self.audio["QL/Mix"][0].language, None) self.failUnlessEqual(self.audio["QL/Mix"][0].stream, None)
def test_stream(self): self.audio["QL/OneHasStream"] = [ASFValue("Whee", UNICODE, stream=2), ASFValue("Whee", UNICODE)] self.audio["QL/AllHaveStream"] = [ASFValue("Whee", UNICODE, stream=1), ASFValue("Whee", UNICODE, stream=2)] self.audio["QL/NoStream"] = ASFValue("Whee", UNICODE) self.audio.save() self.audio = ASF(self.audio.filename) self.failUnlessEqual(self.audio["QL/NoStream"][0].stream, None) self.failUnlessEqual(self.audio["QL/OneHasStream"][0].stream, 2) self.failUnlessEqual(self.audio["QL/OneHasStream"][1].stream, None) self.failUnlessEqual(self.audio["QL/AllHaveStream"][0].stream, 1) self.failUnlessEqual(self.audio["QL/AllHaveStream"][1].stream, 2)
def read_asf_tags(song, path): audio = ASF(path) song[Song.artist] = get_str(audio, "WM/AlbumArtist", "unknown artist") song[Song.album] = get_str(audio, "WM/AlbumTitle", "unknown album") song[Song.title] = get_str(audio, "Title", "unknown title") song[Song.genre] = get_str(audio, "WM/Genre", "unknown genre") song[Song.album_index] = get_int(audio, 'WM/TrackNumber') song[Song.year] = get_int(audio, "WM/Year", '-') song[Song.length] = int(audio.info.length)
def _save(self, filename, metadata, settings): self.log.debug("Saving file %r", filename) file = ASF(encode_filename(filename)) if settings['clear_existing_tags']: file.tags.clear() if settings['save_images_to_tags']: cover = [] for mime, data in metadata.images: tag_data = pack_image(mime, data, 3) cover.append(ASFByteArrayAttribute(tag_data)) if cover: file.tags['WM/Picture'] = cover for name, values in metadata.rawitems(): if name.startswith('lyrics:'): name = 'lyrics' elif name == '~rating': values[0] = int( values[0]) * 99 / (settings['rating_steps'] - 1) if name not in self.__TRANS: continue name = self.__TRANS[name] file.tags[name] = map(unicode, values) file.save()
def _save(self, filename, metadata): log.debug("Saving file %r", filename) file = ASF(encode_filename(filename)) if config.setting['clear_existing_tags']: file.tags.clear() if config.setting['save_images_to_tags']: cover = [] for image in metadata.images: if not save_this_image_to_tags(image): continue tag_data = pack_image(image["mime"], image["data"], image_type_as_id3_num(image['type']), image['desc']) cover.append(ASFByteArrayAttribute(tag_data)) if cover: file.tags['WM/Picture'] = cover for name, values in metadata.rawitems(): if name.startswith('lyrics:'): name = 'lyrics' elif name == '~rating': values[0] = int( values[0]) * 99 / (config.setting['rating_steps'] - 1) if name not in self.__TRANS: continue name = self.__TRANS[name] file.tags[name] = map(unicode, values) file.save()
def setUp(self): fd, self.filename = mkstemp(suffix='wma') os.close(fd) shutil.copy(self.original, self.filename) audio = ASF(self.filename) audio.clear() audio.save()
def test_language(self): self.failIf("QL/OneHasLang" in self.audio) self.failIf("QL/AllHaveLang" in self.audio) self.audio["QL/OneHasLang"] = [ASFValue("Whee", UNICODE, language=2), ASFValue("Whee", UNICODE)] self.audio["QL/AllHaveLang"] = [ASFValue("Whee", UNICODE, language=1), ASFValue("Whee", UNICODE, language=2)] self.audio["QL/NoLang"] = ASFValue("Whee", UNICODE) self.audio.save() self.audio = ASF(self.audio.filename) self.failUnlessEqual(self.audio["QL/NoLang"][0].language, None) self.failUnlessEqual(self.audio["QL/OneHasLang"][0].language, 2) self.failUnlessEqual(self.audio["QL/OneHasLang"][1].language, None) self.failUnlessEqual(self.audio["QL/AllHaveLang"][0].language, 1) self.failUnlessEqual(self.audio["QL/AllHaveLang"][1].language, 2)
class TASFIssue29(TestCase): original = os.path.join(DATA_DIR, "issue_29.wma") def setUp(self): self.filename = get_temp_copy(self.original) self.audio = ASF(self.filename) def tearDown(self): os.unlink(self.filename) def test_pprint(self): self.audio.pprint() def test_issue_29_description(self): self.audio["Description"] = "Hello" self.audio.save() audio = ASF(self.filename) self.failUnless("Description" in audio) self.failUnlessEqual(audio["Description"], ["Hello"]) del(audio["Description"]) self.failIf("Description" in audio) audio.save() audio = ASF(self.filename) self.failIf("Description" in audio)
def _save(self, filename, metadata, settings): self.log.debug("Saving file %r", filename) file = ASF(encode_filename(filename)) if settings["clear_existing_tags"]: file.tags.clear() if settings["save_images_to_tags"]: cover = [] for mime, data in metadata.images: tag_data = pack_image(mime, data, 3) cover.append(ASFByteArrayAttribute(tag_data)) if cover: file.tags["WM/Picture"] = cover for name, values in metadata.rawitems(): if name.startswith("lyrics:"): name = "lyrics" elif name == "~rating": values[0] = int(values[0]) * 99 / (settings["rating_steps"] - 1) if name not in self.__TRANS: continue name = self.__TRANS[name] file.tags[name] = map(unicode, values) file.save()
def load(self, filename): ASF.load(self,filename) self.tags.__class__ = EasyASFTags
class TASFMixin(object): def test_pprint(self): self.failUnless(self.audio.pprint()) def set_key(self, key, value, result=None, expected=True): self.audio[key] = value self.audio.save() self.audio = ASF(self.audio.filename) self.failUnless(key in self.audio) self.failUnless(key in self.audio.tags) self.failUnless(key in self.audio.tags.keys()) self.failUnless(key in self.audio.tags.as_dict().keys()) newvalue = self.audio[key] if isinstance(newvalue, list): for a, b in zip(sorted(newvalue), sorted(result or value)): self.failUnlessEqual(a, b) else: self.failUnlessEqual(self.audio[key], result or value) def test_slice(self): tags = self.audio.tags tags.clear() tags["Author"] = [u"Foo", u"Bar"] self.assertEqual(tags[:], [("Author", "Foo"), ("Author", "Bar")]) del tags[:] self.assertEqual(tags[:], []) tags[:] = [("Author", "Baz")] self.assertEqual(tags.items(), [("Author", ["Baz"])]) def test_iter(self): self.assertEqual(next(iter(self.audio.tags)), ("Title", "test")) self.assertEqual(list(self.audio.tags)[0], ("Title", "test")) def test_contains(self): self.failUnlessEqual("notatag" in self.audio.tags, False) def test_inval_type(self): self.failUnlessRaises(ValueError, ASFValue, "", 4242) def test_repr(self): repr(ASFValue(u"foo", UNICODE, stream=1, language=2)) def test_auto_guuid(self): value = ASFValue(b'\x9eZl}\x89\xa2\xb5D\xb8\xa30\xfe', GUID) self.set_key(u"WM/WMCollectionGroupID", value, [value]) def test_py3_bytes(self): if PY3: value = ASFValue(b'\xff\x00', BYTEARRAY) self.set_key(u"QL/Something", [b'\xff\x00'], [value]) def test_set_invalid(self): setitem = self.audio.__setitem__ if PY2: self.assertRaises(ValueError, setitem, u"QL/Something", [b"\xff"]) self.assertRaises(TypeError, setitem, u"QL/Something", [object()]) # don't delete on error setitem(u"QL/Foobar", [u"ok"]) self.assertRaises(TypeError, setitem, u"QL/Foobar", [object()]) self.assertEqual(self.audio[u"QL/Foobar"], [u"ok"]) def test_auto_unicode(self): self.set_key(u"WM/AlbumTitle", u"foo", [ASFValue(u"foo", UNICODE)]) def test_auto_unicode_list(self): self.set_key(u"WM/AlbumTitle", [u"foo", u"bar"], [ASFValue(u"foo", UNICODE), ASFValue(u"bar", UNICODE)]) def test_word(self): self.set_key(u"WM/Track", ASFValue(24, WORD), [ASFValue(24, WORD)]) def test_auto_word(self): self.set_key(u"WM/Track", 12, [ASFValue(12, DWORD)]) def test_auto_word_list(self): self.set_key(u"WM/Track", [12, 13], [ASFValue(12, WORD), ASFValue(13, WORD)]) def test_auto_dword(self): self.set_key(u"WM/Track", 12, [ASFValue(12, DWORD)]) def test_auto_dword_list(self): self.set_key(u"WM/Track", [12, 13], [ASFValue(12, DWORD), ASFValue(13, DWORD)]) def test_auto_qword(self): self.set_key(u"WM/Track", 12, [ASFValue(12, QWORD)]) def test_auto_qword_list(self): self.set_key(u"WM/Track", [12, 13], [ASFValue(12, QWORD), ASFValue(13, QWORD)]) def test_auto_bool(self): self.set_key(u"IsVBR", True, [ASFValue(True, BOOL)]) def test_auto_bool_list(self): self.set_key(u"IsVBR", [True, False], [ASFValue(True, BOOL), ASFValue(False, BOOL)]) def test_basic_tags(self): self.set_key("Title", "Wheeee", ["Wheeee"]) self.set_key("Author", "Whoooo", ["Whoooo"]) self.set_key("Copyright", "Whaaaa", ["Whaaaa"]) self.set_key("Description", "Wii", ["Wii"]) self.set_key("Rating", "5", ["5"]) def test_stream(self): self.audio["QL/OneHasStream"] = [ ASFValue("Whee", UNICODE, stream=2), ASFValue("Whee", UNICODE), ] self.audio["QL/AllHaveStream"] = [ ASFValue("Whee", UNICODE, stream=1), ASFValue("Whee", UNICODE, stream=2), ] self.audio["QL/NoStream"] = ASFValue("Whee", UNICODE) self.audio.save() self.audio = ASF(self.audio.filename) self.failUnlessEqual(self.audio["QL/NoStream"][0].stream, None) self.failUnlessEqual(self.audio["QL/OneHasStream"][1].stream, 2) self.failUnlessEqual(self.audio["QL/OneHasStream"][0].stream, None) self.failUnlessEqual(self.audio["QL/AllHaveStream"][0].stream, 1) self.failUnlessEqual(self.audio["QL/AllHaveStream"][1].stream, 2) def test_language(self): self.failIf("QL/OneHasLang" in self.audio) self.failIf("QL/AllHaveLang" in self.audio) self.audio["QL/OneHasLang"] = [ ASFValue("Whee", UNICODE, language=2), ASFValue("Whee", UNICODE), ] self.audio["QL/AllHaveLang"] = [ ASFValue("Whee", UNICODE, language=1), ASFValue("Whee", UNICODE, language=2), ] self.audio["QL/NoLang"] = ASFValue("Whee", UNICODE) self.audio.save() self.audio = ASF(self.audio.filename) self.failUnlessEqual(self.audio["QL/NoLang"][0].language, None) self.failUnlessEqual(self.audio["QL/OneHasLang"][1].language, 2) self.failUnlessEqual(self.audio["QL/OneHasLang"][0].language, None) self.failUnlessEqual(self.audio["QL/AllHaveLang"][0].language, 1) self.failUnlessEqual(self.audio["QL/AllHaveLang"][1].language, 2) def test_lang_and_stream_mix(self): self.audio["QL/Mix"] = [ ASFValue("Whee", UNICODE, stream=1), ASFValue("Whee", UNICODE, language=2), ASFValue("Whee", UNICODE, stream=3, language=4), ASFValue("Whee", UNICODE), ] self.audio.save() self.audio = ASF(self.audio.filename) # order not preserved here because they end up in different objects. self.failUnlessEqual(self.audio["QL/Mix"][1].language, None) self.failUnlessEqual(self.audio["QL/Mix"][1].stream, 1) self.failUnlessEqual(self.audio["QL/Mix"][2].language, 2) self.failUnlessEqual(self.audio["QL/Mix"][2].stream, 0) self.failUnlessEqual(self.audio["QL/Mix"][3].language, 4) self.failUnlessEqual(self.audio["QL/Mix"][3].stream, 3) self.failUnlessEqual(self.audio["QL/Mix"][0].language, None) self.failUnlessEqual(self.audio["QL/Mix"][0].stream, None) def test_data_size(self): v = ASFValue("", UNICODE, data=b'4\xd8\x1e\xdd\x00\x00') self.failUnlessEqual(v.data_size(), len(v._render()))
def test_multiple_delete(self): audio = ASF(self.filename) for tag in audio.keys(): del(audio[tag]) audio.save()