def test_acquire_prefer_embedded(self): # embed one cover... MP3File(self.file1).set_image(EmbeddedImage.from_path(self.cover1)) os.unlink(self.cover1) self.external_cover = os.path.join(self.dir1, "cover.png") # ...and save a different cover externally shutil.copy(self.cover2, self.external_cover) shutil.move(self.file1, self.dir1) self.file1 = os.path.join(self.dir1, os.path.basename(self.file1)) both_song = MP3File(self.file1) results = [] def acquire(song): def cb(source, result): results.append(result) self.manager.acquire_cover(cb, None, song) def result_was_embedded(): return self.is_embedded(results.pop()) config.set("albumart", "prefer_embedded", True) acquire(both_song) self.failUnless(result_was_embedded(), "Embedded image expected due to prefs") config.set("albumart", "prefer_embedded", False) acquire(both_song) self.failIf(result_was_embedded(), "Got an embedded image despite prefs")
def test_get_cover_many_prefer_embedded(self): # embed one cover, move one to the other dir MP3File(self.file1).set_image(EmbeddedImage.from_path(self.cover1)) os.unlink(self.cover1) self.external_cover = os.path.join(self.dir2, "cover.png") shutil.move(self.cover2, self.external_cover) # move one audio file in each dir shutil.move(self.file1, self.dir1) self.file1 = os.path.join(self.dir1, os.path.basename(self.file1)) shutil.move(self.file2, self.dir2) self.file2 = os.path.join(self.dir2, os.path.basename(self.file2)) song1 = MP3File(self.file1) song2 = MP3File(self.file2) # each should find a cover self.failUnless(self.is_embedded(self.manager.get_cover(song1))) self.failIf(self.is_embedded(self.manager.get_cover(song2))) cover_for = self.manager.get_cover_many # both settings should search both songs before giving up config.set("albumart", "prefer_embedded", True) self.failUnless(self.is_embedded(cover_for([song1, song2]))) self.failUnless(self.is_embedded(cover_for([song2, song1]))) config.set("albumart", "prefer_embedded", False) self.failIf(self.is_embedded(cover_for([song1, song2]))) self.failIf(self.is_embedded(cover_for([song2, song1])))
def test_foobar2k_replaygain_read_new(self): # Others don't like RVA2, so we have to read/write foobar style # https://github.com/quodlibet/quodlibet/issues/1027 f = mutagen.File(self.filename) f.tags.add( mutagen.id3.TXXX(encoding=3, desc="replaygain_track_gain", text=["-6 db"])) f.tags.add( mutagen.id3.TXXX(encoding=3, desc="replaygain_track_peak", text=["0.9"])) f.tags.add( mutagen.id3.TXXX(encoding=3, desc="replaygain_album_gain", text=["3 db"])) f.tags.add( mutagen.id3.TXXX(encoding=3, desc="replaygain_album_peak", text=["0.8"])) f.save() song = MP3File(self.filename) self.failUnlessEqual(song("replaygain_track_gain"), "-6 db") self.failUnlessEqual(song("replaygain_track_peak"), "0.9") self.failUnlessEqual(song("replaygain_album_gain"), "3 db") self.failUnlessEqual(song("replaygain_album_peak"), "0.8") # still prefer RVA2 in case there are both f.tags.add(mutagen.id3.RVA2(desc="track", channel=1, gain=-9, peak=1.0)) f.save() song = MP3File(self.filename) self.failUnlessAlmostEqual(song.replay_gain(["track"]), 0.35, 1)
def test_set_image_no_tag(self): f = mutagen.File(self.filename) f.delete() song = MP3File(self.filename) fileobj = StringIO.StringIO("foo") image = EmbeddedImage(fileobj, "image/jpeg", 10, 10, 8) song.set_image(image) song = MP3File(self.filename) self.assertTrue(song.has_images)
def test_set_image(self): fileobj = StringIO.StringIO("foo") image = EmbeddedImage(fileobj, "image/jpeg", 10, 10, 8) song = MP3File(self.filename) self.failIf(song.has_images) song.set_image(image) self.assertTrue(song.has_images) song = MP3File(self.filename) self.assertTrue(song.has_images) self.assertEqual(song.get_primary_image().mime_type, "image/jpeg")
def test_TXXX_DATE(self): # https://github.com/quodlibet/quodlibet/issues/220 f = mutagen.File(self.filename) f.tags.add( mutagen.id3.TXXX(encoding=3, desc=u'DATE', text=u'2010-01-13')) f.tags.add(mutagen.id3.TDRC(encoding=3, text=u'2010-01-14')) f.save() self.assertEquals(MP3File(self.filename)['date'], '2010-01-14') f.tags.delall('TDRC') f.save() self.assertEquals(MP3File(self.filename)['date'], '2010-01-13') f.delete() MP3File(self.filename)
def test_USLT(self): """Tests reading and writing of lyrics in USLT""" f = mutagen.File(self.filename) f.tags.add( mutagen.id3.USLT(encoding=3, desc=u'', lang='\x00\x00\x00', text=u'lyrics')) f.tags.add( mutagen.id3.USLT(encoding=3, desc=u'desc', lang='\x00\x00\x00', text=u'lyrics with non-empty desc')) f.tags.add( mutagen.id3.USLT(encoding=3, desc=u'', lang='xyz', text=u'lyrics with non-empty lang')) f.save() f = MP3File(self.filename) self.failUnlessEqual(f['lyrics'], u'lyrics') f['lyrics'] = u'modified lyrics' f.write() f = mutagen.File(self.filename) self.failUnlessEqual(f.tags[u'USLT::\x00\x00\x00'], u'modified lyrics') self.failUnlessEqual(f.tags[u'USLT:desc:\x00\x00\x00'], u'lyrics with non-empty desc') self.failUnlessEqual(f.tags[u'USLT::xyz'], u'lyrics with non-empty lang') f = MP3File(self.filename) self.failUnlessEqual(f['lyrics'], u'modified lyrics') del f['lyrics'] f.write() f = mutagen.File(self.filename) self.failIf('USLT' in f.tags, 'There should be no USLT tag when lyrics were deleted') self.failUnlessEqual(f.tags[u'USLT:desc:\x00\x00\x00'], u'lyrics with non-empty desc') self.failUnlessEqual(f.tags[u'USLT::xyz'], u'lyrics with non-empty lang') f = MP3File(self.filename) self.failIf('lyrics' in f, 'There should be no lyrics key when there is no USLT')
def test_without_id3_tag(self): f = mutagen.File(self.filename) f.delete() f.save() song = MP3File(self.filename) song.get_primary_image() song.write()
def test_load_tcon(self): # check if the mutagen preprocessing is used f = mutagen.File(self.filename) f.tags.add(mutagen.id3.TCON(encoding=3, text=["4", "5"])) f.save() genres = set(MP3File(self.filename).list("genre")) self.failUnlessEqual(genres, set(["Funk", "Disco"]))
def test_tlen(self): f = mutagen.File(self.filename) f.tags.add(mutagen.id3.TLEN(encoding=0, text=['20000'])) f.save() self.failUnlessEqual(MP3File(self.filename)("~#length"), 20) # ignore <= 0 [issue 222] f = mutagen.File(self.filename) f.tags.add(mutagen.id3.TLEN(encoding=0, text=['0'])) f.save() self.failUnless(MP3File(self.filename)("~#length") > 0) # inval f.tags.add(mutagen.id3.TLEN(encoding=0, text=['x'])) f.save() self.failUnless(MP3File(self.filename)("~#length") > 0)
def test_clear_images(self): f = mutagen.File(self.filename) apic = mutagen.id3.APIC(encoding=3, mime="image/jpeg", type=4, desc="foo", data="bar") f.tags.add(apic) f.save() song = MP3File(self.filename) self.failUnless(song.has_images) song.clear_images() song = MP3File(self.filename) self.assertFalse(song.has_images)
def test_unhandled(self): f = mutagen.File(self.filename) t1 = mutagen.id3.AENC(owner="x", preview_start=1, preview_length=3) f.tags.add(t1) f.save() MP3File(self.filename)
def test_tcon(self): f = mutagen.File(self.filename) f.tags.add(mutagen.id3.TMCL(encoding=3, people=[["foo", "bar"]])) f.save() song = MP3File(self.filename) self.failUnless("performer:foo" in song) self.failUnlessEqual(song("performer:foo"), "bar")
def test_rva_large(self): song = MP3File(self.filename) song["replaygain_track_peak"] = "3" song["replaygain_track_gain"] = "100" song.write() song["replaygain_track_peak"] = "-1" song["replaygain_track_gain"] = "-100" song.write()
def test_lang_read_TLAN(self): """Tests reading language from TLAN""" f = mutagen.File(self.filename) lang = u'eng' try: f.tags.add(mutagen.id3.TLAN(encoding=3, text=lang)) f.save() self.assertEquals(MP3File(self.filename)['language'], lang) finally: f.delete()
def test_optional_POPM_count(self): # https://github.com/quodlibet/quodlibet/issues/364 f = mutagen.File(self.filename) f.tags.add(mutagen.id3.POPM(const.EMAIL, 42)) try: f.save() except TypeError: # https://github.com/quodlibet/quodlibet/issues/33 pass else: MP3File(self.filename)
def test_id3_bug(self): # http://code.google.com/p/mutagen/issues/detail?id=97 tag = mutagen.id3.ID3(self.filename2) self.failUnless(tag.unknown_frames) version = mutagen.version mutagen.version = (1, 20) song = MP3File(self.filename2) song.write() mutagen.version = version tag = mutagen.id3.ID3(self.filename2) self.failIf(tag.unknown_frames)
def test_load_comment(self): # comm with empty descriptions => comment f = mutagen.File(self.filename) f.tags.add( mutagen.id3.COMM(encoding=3, lang="aar", desc="", text=["foo", "bar"])) f.save() comments = set(MP3File(self.filename).list("comment")) self.failUnlessEqual(comments, set(["bar", "foo"]))
def test_optional_POPM_count(self): #http://code.google.com/p/quodlibet/issues/detail?id=364 f = mutagen.File(self.filename) f.tags.add(mutagen.id3.POPM(const.EMAIL, 42)) try: f.save() except TypeError: #http://code.google.com/p/mutagen/issues/detail?id=33 pass else: MP3File(self.filename)
def test_quodlibet_txxx_inval(self): # This shouldn't happen in our namespace, but check anyway since # we might open the whole TXXX namespace sometime f = mutagen.File(self.filename) f.tags.add( mutagen.id3.TXXX(encoding=3, desc="QuodLibet::valid", text=["quux"])) f.tags.add( mutagen.id3.TXXX(encoding=3, desc="QuodLibet::foo=", text=["quux", "bar"])) f.tags.add( mutagen.id3.COMM(encoding=3, desc=u"QuodLibet::öäü", text=["quux", "bar"], lang="aar")) f.tags.add( mutagen.id3.COMM(encoding=3, desc=u"", text=["a"], lang="aar")) f.tags.add( mutagen.id3.COMM(encoding=3, desc=u"", text=["b"], lang="foo")) f.save() # check if all keys are valid for k in MP3File(self.filename).keys(): self.failUnless(isinstance(k, str)) song = MP3File(self.filename) self.failIf("foo=" in song) self.failIf(u"öäü" in song) self.failUnlessEqual(set(song.list("comment")), set(["a", "b"])) self.failUnlessEqual(song("valid"), "quux") del song["valid"] song.write() f = mutagen.File(self.filename) self.failUnless(f.tags.getall("TXXX:QuodLibet::foo=")) self.failIf(f.tags.getall("TXXX:QuodLibet::valid")) self.failUnlessEqual(len(f.tags.getall("COMM")), 2) self.failUnlessEqual(len(f.tags.getall("COMM:")), 1)
def test_lang_read_multiple_TLAN(self): """Tests reading multiple language from TLAN""" f = mutagen.File(self.filename) # Include an invalid one; current behaviour is to load anyway lang = u'eng\0der\0fra\0fooooo' exp = u'eng\nder\nfra\nfooooo' try: f.tags.add(mutagen.id3.TLAN(encoding=3, text=lang)) f.save() self.assertEquals(MP3File(self.filename)['language'], exp) finally: f.delete()
def test_foobar2k_replaygain(self): # foobar2k saved gain there f = mutagen.File(self.filename) f.tags.add( mutagen.id3.TXXX(encoding=3, desc="replaygain_track_gain", text=["-6 db"])) f.save() song = MP3File(self.filename) self.failIfAlmostEqual(song.replay_gain(["track"]), 1.0, 1) # check if all keys are str for k in MP3File(self.filename).keys(): self.failUnless(isinstance(k, str)) # remove value, save, reload and check if still gone del song["replaygain_track_gain"] song.write() song.reload() self.failUnlessAlmostEqual(song.replay_gain(["track"]), 1.0, 1)
def test_write_lang_iso(self): """Tests that if you use an ISO 639-2 code, TLAN gets populated""" for iso_lang in ['eng', 'ger', 'zho']: af = MP3File(self.filename) af["language"] = iso_lang self.failUnlessEqual(af("language"), iso_lang) af.write() tags = mutagen.File(self.filename).tags self.failIf(u'TXXX:QuodLibet::language' in tags, "Should have used TLAN tag for '%s'" % iso_lang) self.failUnlessEqual(tags[u'TLAN'], iso_lang) af.clear()
def test_nonascii_unsup_tcon(self): people = [["a=", "a"], ["b~", "b"], [u"äöü", "u"], ["quux", "x"]] f = mutagen.File(self.filename) f.tags.add(mutagen.id3.TMCL(encoding=3, people=people)) f.save() # we only support one of them self.failUnlessEqual(len(MP3File(self.filename).list("~performer")), 1) # but after writing they should still be there song = MP3File(self.filename) song.write() f = mutagen.File(self.filename) self.failUnlessEqual(len(f.tags["TMCL"].people), 4) self.failUnlessEqual(f.tags["TMCL"].people, people) # also change something.. song["performer:quux"] = "foo" song.write() f = mutagen.File(self.filename) self.failUnlessEqual(dict(f.tags["TMCL"].people)["quux"], "foo")
def test_rva_unknown(self): f = mutagen.File(self.filename) f.tags.add(mutagen.id3.RVA2(desc="track", channel=2, gain=-6, peak=1.0)) f.tags.add(mutagen.id3.RVA2(desc="foo", channel=1, gain=-3, peak=1.0)) f.save() # we use foo as track if nothing else is there song = MP3File(self.filename) self.failUnlessAlmostEqual(song.replay_gain(["track"]), 0.7, 1) song.write() # and we write that over track.. f = mutagen.File(self.filename) self.failUnlessAlmostEqual(f.tags["RVA2:track"].gain, -3.0, 1) # now that one is there, ignore foo f = mutagen.File(self.filename) f.tags.add(mutagen.id3.RVA2(desc="foo", channel=1, gain=0, peak=1.0)) f.save() song = MP3File(self.filename) self.failUnlessAlmostEqual(song.replay_gain(["track"]), 0.7, 1)
def test_foobar2k_replaygain_write_new(self): # Others don't like RVA2, so we have to read/write foobar style # https://github.com/quodlibet/quodlibet/issues/1027 song = MP3File(self.filename) song["replaygain_track_gain"] = "-6 db" song["replaygain_track_peak"] = "0.9" song["replaygain_album_gain"] = "3 db" song["replaygain_album_peak"] = "0.8" song.write() f = mutagen.File(self.filename) for k in ["track_peak", "track_gain", "album_peak", "album_gain"]: self.failUnless(f["TXXX:replaygain_" + k])
def test_id3_hack(self): # will only show the content of the last frame f = mutagen.File(self.filename) self.failUnless(len(f.tags["TPE1"].text), 1) # will merge both frames and translate TP1 to TPE1, so 3 values f = mutagen.mp3.MP3(self.filename, ID3=ID3hack) f.tags.add(mutagen.id3.TP1(encoding=3, text="blah")) self.failUnless(len(f.tags["TPE1"].text), 3) # same here, but without the TP1, so 2 values song = MP3File(self.filename) self.failUnlessEqual(len(song.list("artist")), 2)
def test_woar(self): f = mutagen.File(self.filename) t1 = mutagen.id3.WOAR(url="http://this.is.a.test") f.tags.add(t1) f.save() song = MP3File(self.filename) self.failUnlessEqual(song("website"), t1.url) song["website"] = "http://another.test\nhttp://omg.another.one" song.write() f = mutagen.File(self.filename) self.failUnlessEqual(len(f.tags.getall("WOAR")), 2)
def test_distrust_latin1(self): x = u"Å" # abuse mutagen a bit, and get some utf-8 in with the wrong encoding f = mutagen.File(self.filename) f.tags.add(mutagen.id3.TPE1(encoding=0, text=x.encode("utf-8"))) f.save() # back to utf-8 song = MP3File(self.filename) self.failUnlessEqual(song("artist"), x) song.write() # because it's not ascii, saved as utf-16 f = mutagen.File(self.filename) self.failUnlessEqual(f.tags["TPE1"].encoding, 1) # and now latin-1 that is not decodable using utf-8/16 x = u"äöü".encode("ibm1026").decode("latin-1") f.tags.add(mutagen.id3.TPE1(encoding=0, text=x)) f.save() self.failUnlessEqual(MP3File(self.filename)("artist"), x)
def test_mb_track_id(self): f = mutagen.File(self.filename) f.tags.add(mutagen.id3.UFID(owner="http://musicbrainz.org", data="x")) f.save() song = MP3File(self.filename) self.failUnlessEqual(song("musicbrainz_trackid"), "x") song["musicbrainz_trackid"] = "y" song.write() f = mutagen.File(self.filename) self.failUnlessEqual(f.tags["UFID:http://musicbrainz.org"].data, "y") del song["musicbrainz_trackid"] song.write() f = mutagen.File(self.filename) self.failIf(f.tags.get("UFID:http://musicbrainz.org"))