Пример #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"))
Пример #2
0
 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"öäü")
Пример #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)
Пример #4
0
 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)"])
Пример #5
0
 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)
Пример #6
0
 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()
Пример #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()
Пример #8
0
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)
Пример #10
0
 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)
Пример #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()
Пример #12
0
    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"},
        )
Пример #13
0
 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)"])
Пример #14
0
 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()
Пример #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"
Пример #16
0
 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)
Пример #17
0
    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)"])
Пример #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"))
Пример #19
0
 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)"])
Пример #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
Пример #21
0
    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")))
Пример #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)
Пример #23
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")
Пример #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")))
Пример #25
0
 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)
Пример #26
0
    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"), [])
Пример #27
0
 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)
Пример #28
0
 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)
Пример #29
0
    def setUp(self):
        types = formats.types
        instances = []
        for t in types:
            instances.append(AudioFile.__new__(t))

        self.PICKLE = pickle.dumps(instances, 1)
Пример #30
0
    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)
Пример #31
0
 def test_set_bookmarks_invalid_time(self):
     self.failUnlessRaises(TypeError, setattr, AudioFile(), 'bookmarks',
                           [("notint", "!")])
Пример #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"})
Пример #33
0
 def test_bookmarks_simple(self):
     af = AudioFile({"~bookmark": "1:20 Mark 1"})
     self.failUnlessEqual([(80, "Mark 1")], af.bookmarks)
Пример #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)
Пример #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")
Пример #36
0
 def test_eq_ne(self):
     self.failIf(AudioFile({"a": "b"}) == AudioFile({"a": "b"}))
     self.failUnless(AudioFile({"a": "b"}) != AudioFile({"a": "b"}))
Пример #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()
Пример #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())
Пример #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):
Пример #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)
Пример #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",
Пример #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))
Пример #43
0
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))
Пример #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")
Пример #45
0
 def test_set_bookmarks_invalid_value(self):
     self.failUnlessRaises(ValueError, setattr, AudioFile(), 'bookmarks',
                           "huh?")
Пример #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
})
Пример #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")
Пример #48
0
 def test_set_bookmarks_unrealistic_time(self):
     self.failUnlessRaises(ValueError, setattr, AudioFile(), 'bookmarks',
                           [(-1, "!")])
Пример #49
0
 def test_bookmarks_none(self):
     self.failUnlessEqual([], AudioFile().bookmarks)
Пример #50
0
 def test_remove_empty(self):
     song = AudioFile()
     song.add("foo", u"")
     song.remove("foo", u"")
     self.assertFalse("foo" in song)
Пример #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)
Пример #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)
Пример #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)
Пример #54
0
 def test_set_bookmarks_none(self):
     af = AudioFile({"bookmark": "foo"})
     af.bookmarks = []
     self.failUnlessEqual([], AudioFile().bookmarks)
     self.failIf("~bookmark" in af)
Пример #55
0
def AF(*args, **kwargs):
    a = AudioFile(*args, **kwargs)
    a.sanitize()
    return a
Пример #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)
Пример #57
0
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)
Пример #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"])
Пример #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)
Пример #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