Example #1
0
 def test_can_change(self):
     af = AudioFile()
     self.failIf(af.can_change("~foobar"))
     self.failIf(af.can_change("=foobar"))
     self.failIf(af.can_change("foo=bar"))
     self.failIf(af.can_change(""))
     self.failUnless(af.can_change("foo bar"))
 def test_to_dump_unicode(self):
     b = AudioFile(bar_1_1)
     b[u"öäü"] = u"öäü"
     dump = b.to_dump()
     n = AudioFile()
     n.from_dump(dump)
     self.assertEqual(n[u"öäü"], u"öäü")
Example #3
0
    def test(self):
        lib = SongFileLibrary()

        with temp_filename() as song_fn:
            song = AudioFile({"~filename": song_fn})
            song.sanitize()
            lib.add([song])

            with temp_filename() as xml_fn:
                with open(xml_fn, "wb") as h:
                    x = get_example_xml(song("~filename"), 1, 1371802107)
                    h.write(x)

                handler = self.mod.RBDBContentHandler(lib)
                xml.sax.parse(xml_fn, handler)

                self.assertEqual(song("~#rating"), 0.2)
                self.assertEqual(song("~#lastplayed"), 1371802107)
                self.assertEqual(song("~#playcount"), 1)

                with open(xml_fn, "wb") as h:
                    x = get_example_xml(song("~filename"), 2, 1371802107 - 1)
                    h.write(x)

                handler = self.mod.RBDBContentHandler(lib)
                xml.sax.parse(xml_fn, handler)

                self.assertEqual(song("~#rating"), 0.4)
                self.assertEqual(song("~#lastplayed"), 1371802107)
 def test_people(self):
     q = AudioFile([("performer:vocals", "A"), ("performer:guitar", "B"),
                    ("performer", "C"), ("arranger", "A"),
                    ("albumartist", "B"), ("artist", "C")])
     self.failUnlessEqual(q.list("~people"), ["C", "B", "A"])
     self.failUnlessEqual(q.list("~people:roles"),
                      ["C", "B (Guitar)", "A (Arrangement, Vocals)"])
 def test_has_rating(self):
     song = AudioFile()
     self.assertFalse(song.has_rating)
     song["~#rating"] = 0.5
     self.assertTrue(song.has_rating)
     song.remove_rating()
     self.assertFalse(song.has_rating)
 def setUp(self):
     self.rg_data = {"replaygain_album_gain": "-1.00 dB",
                     "replaygain_album_peak": "1.1",
                     "replaygain_track_gain": "+1.0000001 dB",
                     "replaygain_track_peak": "0.9"}
     self.song = AudioFile(self.rg_data)
     self.no_rg_song = AudioFile()
Example #7
0
    def test_masked_handling(self):
        if os.name == "nt":
            # FIXME: masking isn't properly implemented on Windows
            return
        # playlists can contain songs and paths for masked handling..
        lib = FileLibrary("foobar")
        with self.wrap("playlist", lib) as pl:
            song = Fakesong({"date": "2038", "~filename": fsnative(u"/fake")})
            song.sanitize()
            lib.add([song])

            # mask and update
            lib.mask("/")
            pl.append(song)
            pl.remove_songs([song])
            self.failUnless("/fake" in pl)

            pl.extend(self.TWO_SONGS)

            # check if collections can handle the mix
            self.failUnlessEqual(pl("date"), "2038")

            # unmask and update
            lib.unmask("/")
            pl.add_songs(["/fake"], lib)
            self.failUnless(song in pl)

            lib.destroy()
class TRatingsMenuItem(TestCase):

    def setUp(self):
        config.RATINGS = config.HardCodedRatingsPrefs()
        self.failUnlessEqual(config.RATINGS.number, NUM_RATINGS)
        self.library = SongLibrary()
        self.library.librarian = SongLibrarian()
        self.af = AudioFile({"~filename": fsnative(u"/foo"), "~#rating": 1.0})
        self.af.sanitize()
        self.rmi = RatingsMenuItem([self.af], self.library)

    def tearDown(self):
        self.rmi.destroy()
        self.library.destroy()
        self.library.librarian.destroy()

    def test_menuitem_children(self):
        children = [mi for mi in self.rmi.get_submenu().get_children()
                    if isinstance(mi, Gtk.CheckMenuItem)]
        self.failUnlessEqual(len(children), NUM_RATINGS + 1)
        highest = children[-1]
        self.failUnlessEqual(highest.get_active(), True)
        self.failUnlessEqual(children[1].get_active(), False)

    def test_set_remove_rating(self):
        self.rmi.set_rating(0.5, [self.af], self.library)
        self.failUnless(self.af.has_rating)
        self.failUnlessEqual(self.af('~#rating'), 0.5)
        self.rmi.remove_rating([self.af], self.library)
        self.failIf(self.af.has_rating)
 def test_msic(self):
     with realized(self.b):
         self.b.activate()
         self.b.status_text(1000)
         self.b.status_text(1)
         song = AudioFile({"~filename": dummy_path(u"/fake")})
         song.sanitize()
         self.b.scroll(song)
 def test_msic(self):
     with realized(self.b):
         self.b.activate()
         self.b.statusbar(1000)
         self.b.statusbar(1)
         song = AudioFile({"~filename": fsnative(u"/fake")})
         song.sanitize()
         self.b.scroll(song)
Example #11
0
 def setUp(self):
     config.init()
     player = NullPlayer()
     song = AudioFile()
     song.bookmarks = [(10, "bla")]
     song.sanitize(fsnative(u"/"))
     player.song = song
     self.player = player
     self.library = SongLibrary()
    def test_performers_multi_value(self):
        q = AudioFile([("performer:vocals", "X\nA\nY"), ("performer:guitar", "Y\nB\nA"), ("performer", "C\nF\nB\nA")])

        self.failUnlessEqual(set(q.list("~performer")), {"A", "B", "C", "F", "X", "Y"})

        self.failUnlessEqual(
            set(q.list("~performer:roles")),
            {"A (Guitar, Vocals)", "C", "B (Guitar)", "X (Vocals)", "Y (Guitar, Vocals)", "F"},
        )
 def test_people_mix(self):
     q = AudioFile([
         ("performer:arrangement", "A"),
         ("arranger", "A"),
         ("performer", "A"),
         ("performer:foo", "A"),
     ])
     self.failUnlessEqual(q.list("~people"), ["A"])
     self.failUnlessEqual(q.list("~people:roles"),
                          ["A (Arrangement, Arrangement, Foo)"])
 def test_menuitem(self):
     library = SongLibrary()
     library.librarian = SongLibrarian()
     a = AudioFile({"~filename": fsnative(u"/foo")})
     a.sanitize()
     x = RatingsMenuItem([a], library)
     x.set_rating(0, [a], library)
     x.destroy()
     library.destroy()
     library.librarian.destroy()
Example #15
0
def _print_playing(app, fstring="<artist~album~tracknumber~title>"):
    from quodlibet.formats import AudioFile
    from quodlibet.pattern import Pattern

    song = app.player.info
    if song is None:
        song = AudioFile({"~filename": fsnative(u"/")})
        song.sanitize()

    return Pattern(fstring).format(song) + "\n"
 def test_remove_all(self):
     song = AudioFile()
     song.add("foo", "bar")
     song.add("foo", "another")
     song.add("foo", "one more")
     song.remove("foo")
     self.assertFalse("foo" in song)
    def test_people_multi_value(self):
        q = AudioFile([
            ("arranger", "A\nX"),
            ("performer", "A\nY"),
            ("performer:foo", "A\nX"),
        ])

        self.failUnlessEqual(q.list("~people"), ["A", "Y", "X"])
        self.failUnlessEqual(
            q.list("~people:roles"),
            ["A (Arrangement, Foo)", "Y", "X (Arrangement, Foo)"])
Example #18
0
    def test_list(self):
        for key in bar_1_1.realkeys():
            self.failUnlessEqual(bar_1_1.list(key), [bar_1_1(key)])

        af = AudioFile({"~filename": fsnative(u"foo")})
        self.failUnlessEqual(af.list("artist"), [])
        self.failUnlessEqual(af.list("title"), [af("title")])
        self.failUnlessEqual(af.list("not a key"), [])

        self.failUnlessEqual(len(bar_2_1.list("artist")), 2)
        self.failUnlessEqual(bar_2_1.list("artist"),
                             bar_2_1["artist"].split("\n"))
 def test_peoplesort(self):
     q = AudioFile([("performer:vocals", "The A"),
                    ("performersort:vocals", "A, The"),
                    ("performer:guitar", "The B"),
                    ("performersort:guitar", "B, The"),
                    ("performer", "The C"),
                    ("performersort", "C, The"),
                    ("albumartist", "The B"),
                    ("albumartistsort", "B, The")])
     self.failUnlessEqual(q.list("~peoplesort"),
                          ["B, The", "C, The", "A, The"])
     self.failUnlessEqual(q.list("~peoplesort:roles"),
                          ["B, The (Guitar)", "C, The", "A, The (Vocals)"])
Example #20
0
 def getline(key, value):
     song = AudioFile({"~filename": "/dev/null"})
     song.sanitize()
     song[key] = value
     lines = format_tags(song).splitlines()
     if not lines:
         return ""
     if len(lines) == 1:
         return lines[0]
     # hackery since title defaults to the filename..
     for l in lines:
         if not l.startswith("Title"):
             return l
    def test_to_dump(self):
        dump = bar_1_1.to_dump()
        num = len(set(bar_1_1.keys()) | INTERN_NUM_DEFAULT)
        self.failUnlessEqual(dump.count("\n"), num + 2)
        for key, value in bar_1_1.items():
            self.failUnless(key in dump)
            self.failUnless(value in dump)
        for key in INTERN_NUM_DEFAULT:
            self.failUnless(key in dump)

        n = AudioFile()
        n.from_dump(dump)
        self.failUnless(set(dump.split("\n")) == set(n.to_dump().split("\n")))
Example #22
0
 def test_lyrics_from_file(self):
     with temp_filename() as filename:
         af = AudioFile(artist='Motörhead', title='this: again')
         af.sanitize(filename)
         lyrics = "blah!\nblasé 😬\n"
         lyrics_dir = os.path.dirname(af.lyric_filename)
         mkdir(lyrics_dir)
         with io.open(af.lyric_filename, "w", encoding='utf-8') as lf:
             lf.write(text_type(lyrics))
         self.failUnlessEqual(af("~lyrics").splitlines(),
                              lyrics.splitlines())
         os.remove(af.lyric_filename)
         os.rmdir(lyrics_dir)
 def test_sanitize(self):
     q = AudioFile(quux)
     b = AudioFile(bar_1_1)
     q.sanitize()
     b.pop("~filename")
     self.failUnlessRaises(ValueError, b.sanitize)
     n = AudioFile({"artist": u"foo\0bar", "title": u"baz\0", "~filename": fsnative(u"whatever")})
     n.sanitize()
     self.failUnlessEqual(n["artist"], "foo\nbar")
     self.failUnlessEqual(n["title"], "baz")
Example #24
0
    def test_to_dump(self):
        dump = bar_1_1.to_dump()
        num = len(set(bar_1_1.keys()) | NUMERIC_ZERO_DEFAULT)
        self.failUnlessEqual(dump.count(b"\n"), num + 2)
        for key, value in bar_1_1.items():
            self.failUnless(key.encode("utf-8") in dump)
            self.failUnless(value.encode("utf-8") in dump)
        for key in NUMERIC_ZERO_DEFAULT:
            self.failUnless(key.encode("utf-8") in dump)

        n = AudioFile()
        n.from_dump(dump)
        self.failUnless(
            set(dump.split(b"\n")) == set(n.to_dump().split(b"\n")))
 def test_album_key(self):
     album_key_tests = [
         ({}, ("", "", "")),
         ({"album": "foo"}, (("foo",), "", "")),
         ({"labelid": "foo"}, ("", "", "foo")),
         ({"musicbrainz_albumid": "foo"}, ("", "", "foo")),
         ({"album": "foo", "labelid": "bar"}, (("foo",), "", "bar")),
         ({"album": "foo", "labelid": "bar", "musicbrainz_albumid": "quux"}, (("foo",), "", "bar")),
         ({"albumartist": "a"}, ("", ("a",), "")),
     ]
     for tags, expected in album_key_tests:
         afile = AudioFile(**tags)
         afile.sanitize(fsnative(u"/dir/fn"))
         self.failUnlessEqual(afile.album_key, expected)
    def test_list_sort_length_diff(self):
        s = AudioFile({"artist": "a\nb", "artistsort": "c"})
        self.assertEqual(s.list_sort("artist"), [("a", "c"), ("b", "b")])

        s = AudioFile({"artist": "a\nb", "artistsort": "c\nd\ne"})
        self.assertEqual(s.list_sort("artist"), [("a", "c"), ("b", "d")])

        s = AudioFile({"artistsort": "c\nd\ne"})
        self.assertEqual(s.list_sort("artist"), [])

        s = AudioFile({"artist": "a\nb"})
        self.assertEqual(s.list_sort("artist"), [("a", "a"), ("b", "b")])

        s = AudioFile({})
        self.assertEqual(s.list_sort("artist"), [])
 def test_album_key(self):
     album_key_tests = [
         ({}, ((), (), '')),
         ({'album': 'foo'}, (('foo',), (), '')),
         ({'labelid': 'foo'}, ((), (), 'foo')),
         ({'musicbrainz_albumid': 'foo'}, ((), (), 'foo')),
         ({'album': 'foo', 'labelid': 'bar'}, (('foo',), (), 'bar')),
         ({'album': 'foo', 'labelid': 'bar', 'musicbrainz_albumid': 'quux'},
             (('foo',), (), 'bar')),
         ({'albumartist': 'a'}, ((), ('a',), '')),
         ]
     for tags, expected in album_key_tests:
         afile = AudioFile(**tags)
         afile.sanitize(fsnative(u'/dir/fn'))
         self.failUnlessEqual(afile.album_key, expected)
 def test_save_ascii_keys_as_bytes_on_py3(self):
     i = AudioFile.__new__(list(formats.types)[0])
     dict.__setitem__(i, u"foo", u"bar")
     data = dump_audio_files([i], process=True)
     if PY3:
         items = load_audio_files(data, process=False)
         assert isinstance(list(items[0].keys())[0], bytes)
Example #29
0
    def setUp(self):
        types = formats.types
        instances = []
        for t in types:
            instances.append(AudioFile.__new__(t))

        self.PICKLE = pickle.dumps(instances, 1)
    def test_sort_func(self):
        tags = [lambda s: s("foo"), "artistsort", "albumsort", "~filename", "~format", "discnumber", "~#track"]

        for tag in tags:
            f = AudioFile.sort_by_func(tag)
            f(bar_1_1)
            f(bar_1_2)
            f(bar_2_1)
Example #31
0
 def test_set_bookmarks_invalid_time(self):
     self.failUnlessRaises(TypeError, setattr, AudioFile(), 'bookmarks',
                           [("notint", "!")])
Example #32
0
 def test_performers(self):
     q = AudioFile([("performer:vocals", "A"), ("performer:guitar", "B"),
                    ("performer", "C")])
     self.failUnlessEqual(set(q.list("~performers")), {"A", "B", "C"})
     self.failUnlessEqual(set(q.list("~performers:roles")),
                          {"A (Vocals)", "B (Guitar)", "C"})
Example #33
0
 def test_bookmarks_simple(self):
     af = AudioFile({"~bookmark": "1:20 Mark 1"})
     self.failUnlessEqual([(80, "Mark 1")], af.bookmarks)
Example #34
0
    def test(self):
        lib = SongFileLibrary()

        with temp_filename() as song_fn:
            song = AudioFile({"~filename": song_fn})
            song.sanitize()
            lib.add([song])

            # test recovery of basic song
            data = {"path": song("~filename"), "rating": 1,
            "playcount": 1, "skipcount": 2,
            "lastplayed": 1371802107, "added": 1260691996}

            db = get_example_db(data["path"], data["rating"],
                                data["playcount"], data["skipcount"],
                                data["lastplayed"], data["added"])

            importer = self.mod.BansheeDBImporter(lib)
            importer.read(db)
            count = importer.finish()
            db.close()

            self.assertEqual(song("~#rating"), data["rating"] / 5.0)
            self.assertEqual(song("~#playcount"), data["playcount"])
            self.assertEqual(song("~#skipcount"), data["skipcount"])
            self.assertEqual(song("~#lastplayed"), data["lastplayed"])
            self.assertEqual(song("~#added"), data["added"])
            self.assertEqual(count, 1)

            # test recovery of different version of same song
            data_mod = {"path": song("~filename"), "rating": 2,
            "playcount": 4, "skipcount": 1,
            "lastplayed": data["lastplayed"] - 1, "added": data["added"] + 1}

            db = get_example_db(data_mod["path"], data_mod["rating"],
                                data_mod["playcount"], data_mod["skipcount"],
                                data_mod["lastplayed"], data_mod["added"])

            importer = self.mod.BansheeDBImporter(lib)
            importer.read(db)
            count = importer.finish()
            db.close()

            self.assertEqual(song("~#rating"), data_mod["rating"] / 5.0)
            self.assertEqual(song("~#playcount"), data_mod["playcount"])
            self.assertEqual(song("~#skipcount"), data_mod["skipcount"])
            self.assertEqual(song("~#lastplayed"), data["lastplayed"])
            self.assertEqual(song("~#added"), data["added"])
            self.assertEqual(count, 1)

            # test that no recovery is performed when data is identical
            db = get_example_db(data_mod["path"], data_mod["rating"],
                                data_mod["playcount"], data_mod["skipcount"],
                                data_mod["lastplayed"], data_mod["added"])

            importer = self.mod.BansheeDBImporter(lib)
            importer.read(db)
            count = importer.finish()
            db.close()

            self.assertEqual(count, 0)
Example #35
0
 def test_set_bookmarks_simple(self):
     af = AudioFile()
     af.bookmarks = [(120, "A mark"), (140, "Mark twain")]
     self.failUnlessEqual(af["~bookmark"], "2:00 A mark\n2:20 Mark twain")
Example #36
0
 def test_eq_ne(self):
     self.failIf(AudioFile({"a": "b"}) == AudioFile({"a": "b"}))
     self.failUnless(AudioFile({"a": "b"}) != AudioFile({"a": "b"}))
Example #37
0
from gi.repository import Gtk

from tests import TestCase, init_fake_app, destroy_fake_app
from helper import realized, dummy_path

from quodlibet import browsers
from quodlibet.formats import AudioFile
from quodlibet import config
from quodlibet.browsers import Browser
from quodlibet.library import SongFileLibrary, SongLibrarian


SONGS = [
    AudioFile({
        "title": "one",
        "artist": "piman",
        "~filename": dummy_path(u"/dev/null"),
    }),
    AudioFile({
        "title": "two",
        "artist": "mu",
        "~filename": dummy_path(u"/dev/zero"),
    }),
    AudioFile({
        "title": "three",
        "artist": "boris",
        "~filename": dummy_path(u"/bin/ls"),
    })
]
SONGS.sort()
Example #38
0
    def test_website(self):
        song = AudioFile()
        song["comment"] = "www.foo"
        song["contact"] = "*****@*****.**"
        self.failUnlessEqual(song.website(), "www.foo")
        song["contact"] = "https://www.foo.org"
        self.failUnlessEqual(song.website(), "https://www.foo.org")
        song["website"] = "foo\nhttps://another.com"
        self.failUnlessEqual(song.website(), "foo")

        song = AudioFile({"artist": "Artist", "album": "Album"})
        for value in song.values():
            self.failUnless(value in song.website())
        song["labelid"] = "QL-12345"
        self.failIf(song["artist"] in song.website())
        self.failUnless(song["labelid"] in song.website())
Example #39
0
# -*- coding: utf-8 -*-
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation

from gi.repository import Gtk
from senf import fsnative

from tests import TestCase

from quodlibet import config
from quodlibet.formats import AudioFile
from quodlibet.qltk.delete import DeleteDialog, TrashDialog, TrashMenuItem

SONG = AudioFile({"~filename": fsnative(u"/dev/null")})
SONG.sanitize()


class TDeleteDialog(TestCase):

    def setUp(self):
        config.init()

    def tearDown(self):
        config.quit()

    def test_delete_songs(self):
        dialog = DeleteDialog.for_songs(None, [])
        dialog.destroy()

    def test_delete_files(self):
Example #40
0
 def test_bookmarks_two(self):
     af = AudioFile({"~bookmark": "1:40 Mark 2\n1:20 Mark 1"})
     self.failUnlessEqual([(80, "Mark 1"), (100, "Mark 2")], af.bookmarks)
Example #41
0
from quodlibet import config

from quodlibet.browsers.albums import AlbumList
from quodlibet.browsers.albums.prefs import Preferences, DEFAULT_PATTERN_TEXT
from quodlibet.browsers.albums.main import (compare_title, compare_artist,
    compare_genre, compare_rating, compare_date)
from quodlibet.formats import AudioFile
from quodlibet.library import SongLibrary, SongLibrarian
from quodlibet.util.path import fsnative
from quodlibet.util.collection import Album

SONGS = [
    AudioFile({
        "album": "one",
        "artist": "piman",
        "~filename": fsnative(u"/dev/null"),
    }),
    AudioFile({
        "album": "two",
        "artist": "mu",
        "~filename": fsnative(u"/dev/zero"),
    }),
    AudioFile({
        "album": "three",
        "artist": "boris",
        "~filename": fsnative(u"/bin/ls"),
    }),
    AudioFile({
        "album": "three",
        "artist": "boris",
Example #42
0
class Treplay_gain(TestCase):

    # -6dB is approximately equal to half magnitude
    minus_6db = 0.501187234

    def setUp(self):
        self.rg_data = {
            "replaygain_album_gain": "-1.00 dB",
            "replaygain_album_peak": "1.1",
            "replaygain_track_gain": "+1.0000001 dB",
            "replaygain_track_peak": "0.9"
        }
        self.song = AudioFile(self.rg_data)
        self.no_rg_song = AudioFile()

    def test_no_rg_song(self):
        scale = self.no_rg_song.replay_gain(["track"], 0, -6.0)
        self.failUnlessAlmostEqual(scale, self.minus_6db)

        scale = self.no_rg_song.replay_gain(["track"], +10, +10)
        self.failUnlessEqual(scale, 1.0)

        scale = self.no_rg_song.replay_gain(["track"], -16.0, +10)
        self.failUnlessAlmostEqual(scale, self.minus_6db)

    def test_nogain(self):
        self.failUnlessEqual(self.song.replay_gain(["none", "track"]), 1)

    def test_fallback_track(self):
        del (self.song["replaygain_track_gain"])
        self.failUnlessAlmostEqual(self.song.replay_gain(["track"], 0, -6.0),
                                   self.minus_6db)

    def test_fallback_album(self):
        del (self.song["replaygain_album_gain"])
        self.failUnlessAlmostEqual(self.song.replay_gain(["album"], 0, -6.0),
                                   self.minus_6db)

    def test_fallback_and_preamp(self):
        del (self.song["replaygain_track_gain"])
        self.failUnlessEqual(self.song.replay_gain(["track"], 9, -9), 1)

    def test_preamp_track(self):
        self.failUnlessAlmostEqual(self.song.replay_gain(["track"], -7.0, 0),
                                   self.minus_6db)

    def test_preamp_album(self):
        self.failUnlessAlmostEqual(self.song.replay_gain(["album"], -5.0, 0),
                                   self.minus_6db)

    def test_preamp_clip(self):
        # Make sure excess pre-amp won't clip a track (with peak data)
        self.failUnlessAlmostEqual(self.song.replay_gain(["track"], 12.0, 0),
                                   1.0 / 0.9)

    def test_trackgain(self):
        self.failUnless(self.song.replay_gain(["track"]) > 1)

    def test_albumgain(self):
        self.failUnless(self.song.replay_gain(["album"]) < 1)

    def test_invalid(self):
        self.song["replaygain_album_gain"] = "fdsodgbdf"
        self.failUnlessEqual(self.song.replay_gain(["album"]), 1)

    def test_track_fallback(self):
        radio_rg = self.song.replay_gain(["track"])
        del (self.song["replaygain_album_gain"])
        del (self.song["replaygain_album_peak"])
        # verify defaulting to track when album is present
        self.failUnlessAlmostEqual(self.song.replay_gain(["album", "track"]),
                                   radio_rg)

    def test_numeric_rg_tags(self):
        """"Tests fully-numeric (ie no "db") RG tags.  See Issue 865"""
        self.failUnless(self.song("replaygain_album_gain"), "-1.00 db")
        for key, exp in self.rg_data.items():
            # Hack the nasties off and produce the "real" expected value
            exp = float(exp.split(" ")[0])
            # Compare as floats. Seems fairer.
            album_rg = self.song("~#%s" % key)
            try:
                val = float(album_rg)
            except ValueError:
                self.fail("Invalid %s returned: %s" % (key, album_rg))
            self.failUnlessAlmostEqual(val,
                                       exp,
                                       places=5,
                                       msg="%s should be %s not %s" %
                                       (key, exp, val))
class TPlaylistIntegration(TestCase):
    DUPLICATES = 1
    SONG = AudioFile({
        "title": "two",
        "artist": "mu",
        "~filename": dummy_path(u"/dev/zero")
    })
    SONGS = [
        AudioFile({
            "title": "one",
            "artist": "piman",
            "~filename": dummy_path(u"/dev/null")
        }),
        SONG,
        AudioFile({
            "title": "three",
            "artist": "boris",
            "~filename": dummy_path(u"/bin/ls")
        }),
        AudioFile({
            "title": "four",
            "artist": "random",
            "album": "don't stop",
            "labelid": "65432-1",
            "~filename": dummy_path(u"/dev/random")
        }),
        SONG,
    ]

    def setUp(self):
        quodlibet.config.init()
        self.lib = quodlibet.browsers.tracks.library = FileLibrary()
        quodlibet.browsers.tracks.library.librarian = SongLibrarian()
        for af in self.SONGS:
            af.sanitize()
        self.lib.add(self.SONGS)
        self._dir = mkdtemp()
        self.pl = FileBackedPlaylist.new(self._dir, "Foobar", self.lib)
        self.pl.extend(self.SONGS)

    def tearDown(self):
        self.pl.delete()
        self.lib.destroy()
        self.lib.librarian.destroy()
        quodlibet.config.quit()
        shutil.rmtree(self._dir)

    def test_remove_song(self):
        # Check: library should have one song fewer (the duplicate)
        self.failUnlessEqual(len(self.lib), len(self.SONGS) - self.DUPLICATES)
        self.failUnlessEqual(len(self.pl), len(self.SONGS))

        # Remove an unduplicated song
        self.pl.remove_songs([self.SONGS[0]])
        self.failUnlessEqual(len(self.pl), len(self.SONGS) - 1)

    def test_remove_duplicated_song(self):
        self.failUnlessEqual(self.SONGS[1], self.SONGS[4])
        self.pl.remove_songs([self.SONGS[1]])
        self.failUnlessEqual(len(self.pl), len(self.SONGS) - 2)

    def test_remove_multi_duplicated_song(self):
        self.pl.extend([self.SONG, self.SONG])
        self.failUnlessEqual(len(self.pl), 7)
        self.pl.remove_songs([self.SONG], False)
        self.failUnlessEqual(len(self.pl), 7 - 2 - 2)

    def test_remove_duplicated_song_leave_dupes(self):
        self.pl.remove_songs([self.SONGS[1]], True)
        self.failUnlessEqual(len(self.pl), len(self.SONGS) - 1)

    def test_remove_no_lib(self):
        pl = FileBackedPlaylist.new(self._dir, "Foobar")
        pl.extend(self.SONGS)
        self.assertTrue(len(pl))
        pl.remove_songs(self.SONGS, False)
        self.assertFalse(len(pl))
Example #44
0
 def test_change(self):
     song = AudioFile()
     song.add("foo", "bar")
     song.add("foo", "another")
     song.change("foo", "bar", "one more")
     self.failUnlessEqual(song.list("foo"), ["one more", "another"])
     song.change("foo", "does not exist", "finally")
     self.failUnlessEqual(song["foo"], "finally")
     song.change("foo", "finally", "we're done")
     self.failUnlessEqual(song["foo"], "we're done")
Example #45
0
 def test_set_bookmarks_invalid_value(self):
     self.failUnlessRaises(ValueError, setattr, AudioFile(), 'bookmarks',
                           "huh?")
Example #46
0
# -*- coding: utf-8 -*-
from tests import TestCase, DATA_DIR

import os

from quodlibet import config
from quodlibet.util.path import is_fsnative, fsnative, fsdecode
from quodlibet.compat import PY2
from quodlibet.formats import AudioFile
from quodlibet.formats._audio import INTERN_NUM_DEFAULT
from quodlibet.formats import decode_value

bar_1_1 = AudioFile({
    "~filename": fsnative(u"/fakepath/1"),
    "title": "A song",
    "discnumber": "1/2",
    "tracknumber": "1/3",
    "artist": "Foo",
    "album": "Bar"
})
bar_1_2 = AudioFile({
    "~filename": fsnative(u"/fakepath/2"),
    "title": "Perhaps another",
    "discnumber": "1",
    "tracknumber": "2/3",
    "artist": "Lali-ho!",
    "album": "Bar",
    "date": "2004-12-12",
    "originaldate": "2005-01-01",
    "~#filesize": 1024**2,
    "~#bitrate": 128
})
Example #47
0
 def test_sanitize(self):
     q = AudioFile(quux)
     b = AudioFile(bar_1_1)
     q.sanitize()
     b.pop('~filename')
     self.failUnlessRaises(ValueError, b.sanitize)
     n = AudioFile({
         "artist": u"foo\0bar",
         "title": u"baz\0",
         "~filename": fsnative(u"whatever")
     })
     n.sanitize()
     self.failUnlessEqual(n["artist"], "foo\nbar")
     self.failUnlessEqual(n["title"], "baz")
Example #48
0
 def test_set_bookmarks_unrealistic_time(self):
     self.failUnlessRaises(ValueError, setattr, AudioFile(), 'bookmarks',
                           [(-1, "!")])
Example #49
0
 def test_bookmarks_none(self):
     self.failUnlessEqual([], AudioFile().bookmarks)
Example #50
0
 def test_remove_empty(self):
     song = AudioFile()
     song.add("foo", u"")
     song.remove("foo", u"")
     self.assertFalse("foo" in song)
Example #51
0
from tests import TestCase, skipUnless, AbstractTestCase

from quodlibet import player
from quodlibet import library
from quodlibet import config
from quodlibet.util.path import fsnative
from quodlibet.util import connect_obj
from quodlibet.player.nullbe import NullPlayer
from quodlibet.formats import AudioFile
from quodlibet.qltk.songmodel import PlaylistModel
from quodlibet.qltk.controls import Volume

FILES = [
    AudioFile({
        "~filename": fsnative(u"/foo/bar1"),
        "title": "1"
    }),
    AudioFile({
        "~filename": fsnative(u"/foo/bar2"),
        "title": "2"
    }),
    AudioFile({
        "~filename": fsnative(u"/foo/bar3"),
        "title": "3"
    }),
]
for file_ in FILES:
    file_.sanitize()

UNKNOWN_FILE = FILES.pop(-1)
Example #52
0
 def test_remove(self):
     song = AudioFile()
     song.add("foo", "bar")
     song.add("foo", "another")
     song.add("foo", "one more")
     song.remove("foo", "another")
     self.failUnlessEqual(song.list("foo"), ["bar", "one more"])
     song.remove("foo", "bar")
     self.failUnlessEqual(song.list("foo"), ["one more"])
     song.remove("foo", "one more")
     self.failIf("foo" in song)
Example #53
0
    def parse(self):
        try:
            doc = feedparser.parse(self.uri)
        except Exception as e:
            print_w("Couldn't parse feed: %s (%s)" % (self.uri, e))
            return False

        try:
            album = doc.channel.title
        except AttributeError:
            print_w("No channel title in %s" % doc)
            return False

        if album:
            self.name = album
        else:
            self.name = _("Unknown")

        defaults = AudioFile({"feed": self.uri})
        try:
            self.__fill_af(doc.channel, defaults)
        except Exception as e:
            print_w("Error creating feed data: %s (%s)" % (self.uri, e))
            return False

        entries = []
        uris = set()
        print_d("Found %d entries in channel" % len(doc.entries))
        for entry in doc.entries:
            try:
                for enclosure in entry.enclosures:
                    try:
                        if ("audio" in enclosure.type
                                or "ogg" in enclosure.type
                                or formats.filter(enclosure.url)):
                            uri = enclosure.url
                            if not isinstance(uri, str):
                                uri = uri.decode('utf-8')
                            try:
                                size = float(enclosure.length)
                            except (AttributeError, ValueError):
                                size = 0
                            entries.append((uri, entry, size))
                            uris.add(uri)
                            break
                    except AttributeError:
                        pass
            except AttributeError:
                print_d("No enclosures found in %s" % entry)

        for entry in list(self):
            if entry["~uri"] not in uris:
                self.remove(entry)
            else:
                uris.remove(entry["~uri"])
        print_d("Successfully got %d episodes in channel" % len(entries))
        entries.reverse()
        for uri, entry, size in entries:
            if uri in uris:
                song = RemoteFile(uri)
                song["~#size"] = size
                song.fill_metadata = False
                song.update(defaults)
                song["album"] = self.name
                try:
                    self.__fill_af(entry, song)
                except Exception as e:
                    print_d("Couldn't convert %s to AudioFile (%s)" % (uri, e))
                else:
                    self.insert(0, song)
        self.__lastgot = time.time()
        return bool(uris)
Example #54
0
 def test_set_bookmarks_none(self):
     af = AudioFile({"bookmark": "foo"})
     af.bookmarks = []
     self.failUnlessEqual([], AudioFile().bookmarks)
     self.failIf("~bookmark" in af)
Example #55
0
def AF(*args, **kwargs):
    a = AudioFile(*args, **kwargs)
    a.sanitize()
    return a
Example #56
0
from senf import fsnative

from tests import TestCase, skipUnless, get_data_path

from quodlibet import player
from quodlibet import library
from quodlibet import config
from quodlibet.util import connect_obj
from quodlibet.player.nullbe import NullPlayer
from quodlibet.formats import AudioFile
from quodlibet.qltk.songmodel import PlaylistModel
from quodlibet.qltk.controls import Volume

FILES = [
    AudioFile({
        "~filename": fsnative(u"/foo/bar1"),
        "title": "1"
    }),
    AudioFile({
        "~filename": fsnative(u"/foo/bar2"),
        "title": "2"
    }),
    AudioFile({
        "~filename": fsnative(u"/foo/bar3"),
        "title": "3"
    }),
]
for file_ in FILES:
    file_.sanitize()

UNKNOWN_FILE = FILES.pop(-1)
class TPlaylistsBrowser(TestCase):
    Bar = PlaylistsBrowser

    ANOTHER_SONG = AudioFile({
        "title": "lonely",
        "artist": "new artist",
        "~filename": dummy_path(u"/dev/urandom")
    })

    def setUp(self):
        self.success = False
        # Testing locally is VERY dangerous without this...
        self.assertTrue(_TEMP_DIR in PLAYLISTS or os.name == "nt",
                        msg="Failing, don't want to delete %s" % PLAYLISTS)
        try:
            shutil.rmtree(PLAYLISTS)
        except OSError:
            pass

        mkdir(PLAYLISTS)

        init_fake_app()

        self.lib = quodlibet.browsers.playlists.library = SongFileLibrary()
        self.lib.librarian = SongLibrarian()
        all_songs = SONGS + [self.ANOTHER_SONG]
        for af in all_songs:
            af.sanitize()
        self.lib.add(all_songs)

        self.big = pl = FileBackedPlaylist.new(PLAYLISTS, "Big", self.lib)
        pl.extend(SONGS)
        pl.write()

        self.small = pl = FileBackedPlaylist.new(PLAYLISTS, "Small", self.lib)
        pl.extend([self.ANOTHER_SONG])
        pl.write()

        PlaylistsBrowser.init(self.lib)

        self.bar = PlaylistsBrowser(self.lib)
        self.bar.connect('songs-selected', self._expected)
        self.bar._select_playlist(self.bar.playlists()[0])
        self.expected = None

    def tearDown(self):
        self.bar.destroy()
        self.lib.destroy()
        shutil.rmtree(PLAYLISTS)
        PlaylistsBrowser.deinit(self.lib)
        destroy_fake_app()

    def _expected(self, bar, songs, sort):
        songs.sort()
        if self.expected is not None:
            self.failUnlessEqual(self.expected, songs)
        self.success = True

    def _do(self):
        while Gtk.events_pending():
            Gtk.main_iteration()
        self.failUnless(self.success or self.expected is None)

    def test_saverestore(self):
        # Flush previous signals, etc. Hmm.
        self.expected = None
        self._do()
        self.expected = [SONGS[0]]
        self.bar.filter_text("title = %s" % SONGS[0]["title"])
        self.bar._select_playlist(self.bar.playlists()[0])
        self.expected = [SONGS[0]]
        self._do()
        self.bar.save()
        self.bar.filter_text("")
        self.expected = list(sorted(SONGS))
        self._do()
        self.bar.restore()
        self.bar.activate()
        self.expected = [SONGS[0]]
        self._do()

    def test_active_filter_playlists(self):
        self.bar._select_playlist(self.bar.playlists()[1])

        # Second playlist should not have any of `SONGS`
        self.assertFalse(self.bar.active_filter(SONGS[0]))

        # But it should have `ANOTHER_SONG`
        self.assertTrue(self.bar.active_filter(self.ANOTHER_SONG),
                        msg="Couldn't find song from second playlist")

        # ... and setting a reasonable filter on that song should match still
        self.bar.filter_text("lonely")
        self.assertTrue(self.bar.active_filter(self.ANOTHER_SONG),
                        msg="Couldn't find song from second playlist with "
                        "filter of 'lonely'")

        # ...unless it doesn't match that song
        self.bar.filter_text("piman")
        self.assertFalse(self.bar.active_filter(self.ANOTHER_SONG),
                         msg="Shouldn't have matched 'piman' on second list")

    def test_rename(self):
        self.assertEquals(self.bar.playlists()[1], self.small)
        self.bar._rename(0, "zBig")
        self.assertEquals(self.bar.playlists()[0], self.small)
        self.assertEquals(self.bar.playlists()[1].name, "zBig")

    def test_default_display_pattern(self):
        pattern_text = self.bar.display_pattern_text
        self.failUnlessEqual(pattern_text, DEFAULT_PATTERN_TEXT)
        self.failUnless("<~name>" in pattern_text)

    def test_drag_data_get(self):
        b = self.bar
        song = AudioFile()
        song["~filename"] = fsnative(u"foo")
        sel = MockSelData()
        qltk.selection_set_songs(sel, [song])
        b._drag_data_get(None, None, sel, DND_QL, None)

    def test_deletion(self):
        def a_delete_event():
            ev = Gdk.Event()
            ev.type = Gdk.EventType.KEY_PRESS
            ev.keyval, accel_mod = Gtk.accelerator_parse("Delete")
            ev.state = Gtk.accelerator_get_default_mod_mask() & accel_mod
            return ev

        b = self.bar
        self._fake_browser_pack(b)
        event = a_delete_event()
        # This is selected in setUp()
        first_pl = b.playlists()[0]
        app.window.songlist.set_songs(first_pl)
        app.window.songlist.select_by_func(lambda x: True,
                                           scroll=False,
                                           one=True)
        original_length = len(first_pl)
        ret = b.key_pressed(event)
        self.failUnless(ret, msg="Didn't simulate a delete keypress")
        self.failUnlessEqual(len(first_pl), original_length - 1)

    def test_import(self):
        pl_name = u"_€3 œufs à Noël"
        pl = FileBackedPlaylist(_TEMP_DIR, pl_name, None)
        pl.extend(SONGS)
        pl.write()
        new_fn = os.path.splitext(text2fsn(pl.name))[0] + '.m3u'
        new_path = os.path.join(pl.dir, new_fn)
        os.rename(pl.path, new_path)
        added = self.bar._import_playlists([new_path], self.lib)
        self.failUnlessEqual(added, 1, msg="Failed to add '%s'" % new_path)
        os.unlink(new_path)
        pls = self.bar.playlists()
        self.failUnlessEqual(len(pls), 3)
        # Leading underscore makes it always the last entry
        imported = pls[-1]
        self.failUnlessEqual(imported.name, pl_name)

        def fns(songs):
            return [song('~filename') for song in songs]

        self.failUnlessEqual(fns(imported.songs), fns(pl.songs))

    @staticmethod
    def _fake_browser_pack(b):
        app.window.get_child().pack_start(b, True, True, 0)
Example #58
0
 def test_remove_unknown(self):
     song = AudioFile()
     song.add("foo", "bar")
     song.remove("foo", "not in list")
     song.remove("nope")
     self.failUnlessEqual(song.list("foo"), ["bar"])
Example #59
0
 def test_cache_attributes(self):
     x = AudioFile()
     x.multisong = not x.multisong
     x["a"] = "b"  # clears cache
     # attribute should be unchanged
     self.failIfEqual(AudioFile().multisong, x.multisong)
Example #60
0
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.

from quodlibet.formats import AudioFile
from quodlibet.qltk.cover import ALBUM_ART_PLUGIN_ID
from tests.plugin import PluginTestCase

from quodlibet import library, config
from quodlibet import app

A_SONG = AudioFile({
    '~filename': '/dev/null',
    'artist': 'Mr Man',
    'album': 'Bars of Foo'
})

# Keep IDEs happy
DownloadAlbumArt = AlbumArtWindow = CoverArea = None


# TODO: Some real tests.
class TAlbumArt(PluginTestCase):
    @classmethod
    def setUpClass(cls):
        app.library = library.init()
        config.init()

    @classmethod