def setUp(self):
        config.init()

        self.main = mkdtemp()

        self.dir1 = mkdtemp(dir=self.main)
        self.dir2 = mkdtemp(dir=self.main)

        h, self.cover1 = mkstemp(".png", dir=self.main)
        os.close(h)
        pb = GdkPixbuf.Pixbuf.new(GdkPixbuf.Colorspace.RGB, True, 8, 10, 10)
        pb.savev(self.cover1, "png", [], [])

        h, self.cover2 = mkstemp(".png", dir=self.main)
        os.close(h)
        pb = GdkPixbuf.Pixbuf.new(GdkPixbuf.Colorspace.RGB, True, 8, 20, 20)
        pb.savev(self.cover2, "png", [], [])

        fd, self.file1 = mkstemp(".mp3", dir=self.main)
        os.close(fd)
        shutil.copy(os.path.join(DATA_DIR, 'silence-44-s.mp3'), self.file1)

        fd, self.file2 = mkstemp(".mp3", dir=self.main)
        os.close(fd)
        shutil.copy(os.path.join(DATA_DIR, 'silence-44-s.mp3'), self.file2)

        self.manager = CoverManager()
Exemple #2
0
    def setUp(self):
        config.init()
        self.manager = CoverManager()

        self.dir = os.path.realpath(quux("~dirname"))
        self.files = [self.full_path("12345.jpg"),
                      self.full_path("nothing.jpg")
                      ]
        for f in self.files:
            file(f, "w").close()
Exemple #3
0
    def setUp(self):
        self.manager = CoverManager()

        self.dir = mkdtemp()
        self.song = self.an_album_song()

        # Safety check
        self.failIf(glob.glob(os.path.join(self.dir + "*.jpg")))
        files = [self.full_path("12345.jpg"), self.full_path("nothing.jpg")]
        for f in files:
            open(f, "w").close()
Exemple #4
0
    def setUp(self):
        config.init()
        self.manager = CoverManager()

        self.dir = os.path.realpath(quux("~dirname"))
        # Safety check
        self.failIf(glob.glob(self.dir + "/*.jpg"))
        self.files = [self.full_path("12345.jpg"),
                      self.full_path("nothing.jpg")
                      ]
        for f in self.files:
            open(f, "w").close()
    def test_acquire_cover(self):
        manager = CoverManager(use_built_in=False)
        handler = manager.plugin_handler
        for source in dummy_sources:
            handler.plugin_handle(source)
        handler.plugin_enable(dummy_sources[0])
        found = []
        result = []

        def done(_found, _result):
            found.append(_found)
            result.append(_result)
        manager.acquire_cover(done, None, None)
        self.runLoop()
        self.assertFalse(found[0])
        handler.plugin_enable(dummy_sources[1])
        manager.acquire_cover(done, None, None)
        self.runLoop()
        self.assertTrue(found[1])
        self.assertIs(result[1], DUMMY_COVER)
        handler.plugin_disable(dummy_sources[1])
        handler.plugin_enable(dummy_sources[2])
        manager.acquire_cover(done, None, None)
        self.runLoop()
        self.assertTrue(found[2])
        self.assertIs(result[2], DUMMY_COVER)
Exemple #6
0
    def setUp(self):
        self.manager = CoverManager()

        self.dir = mkdtemp()
        self.song = AudioFile({
            "~filename": os.path.join(self.dir, "asong.ogg"),
            "album": u"Quuxly",
        })

        # Safety check
        self.failIf(glob.glob(os.path.join(self.dir + "*.jpg")))
        files = [self.full_path("12345.jpg"), self.full_path("nothing.jpg")]
        for f in files:
            open(f, "w").close()
    def test_search(self):
        manager = CoverManager(use_built_in=False)
        handler = manager.plugin_handler
        for source in dummy_sources:
            handler.plugin_handle(source)
            handler.plugin_enable(source)
            source.cls.cover_call = False
            source.cls.fetch_call = False

        song = AudioFile({
            "~filename": os.path.join("/tmp/asong.ogg"),
            "album": "Abbey Road",
            "artist": "The Beatles"
        })
        songs = [song]
        results = []

        def done(manager, provider, result):
            self.failUnless(result, msg="Shouldn't succeed with no results")
            results.append(result)

        def finished(manager, songs):
            print("Finished!")

        manager.connect('covers-found', done)
        manager.search_cover(Cancellable(), songs)
        manager.connect('searches-complete', finished)
        run_loop()

        self.failUnlessEqual(len(results), 1)
Exemple #8
0
    def test_acquire_cover_sync(self):
        song = AudioFile({"~filename": "/dev/null"})

        manager = CoverManager(use_built_in=False)
        handler = manager.plugin_handler
        for source in dummy_sources:
            handler.plugin_handle(source)
        handler.plugin_enable(dummy_sources[0])
        self.assertIs(manager.acquire_cover_sync(song), None)
        handler.plugin_enable(dummy_sources[1])
        self.assertIs(manager.acquire_cover_sync(song), DUMMY_COVER)
        handler.plugin_enable(dummy_sources[2])
        self.assertIs(manager.acquire_cover_sync(song), DUMMY_COVER)
        handler.plugin_disable(dummy_sources[1])
        self.assertIs(manager.acquire_cover_sync(song), None)
Exemple #9
0
    def setUp(self):
        config.init()

        self.main = mkdtemp()

        self.dir1 = mkdtemp(dir=self.main)
        self.dir2 = mkdtemp(dir=self.main)

        h, self.cover1 = mkstemp(".png", dir=self.main)
        os.close(h)
        pb = GdkPixbuf.Pixbuf.new(GdkPixbuf.Colorspace.RGB, True, 8, 10, 10)
        pb.savev(self.cover1, "png", [], [])

        h, self.cover2 = mkstemp(".png", dir=self.main)
        os.close(h)
        pb = GdkPixbuf.Pixbuf.new(GdkPixbuf.Colorspace.RGB, True, 8, 20, 20)
        pb.savev(self.cover2, "png", [], [])

        fd, self.file1 = mkstemp(".mp3", dir=self.main)
        os.close(fd)
        shutil.copy(os.path.join(DATA_DIR, 'silence-44-s.mp3'), self.file1)

        fd, self.file2 = mkstemp(".mp3", dir=self.main)
        os.close(fd)
        shutil.copy(os.path.join(DATA_DIR, 'silence-44-s.mp3'), self.file2)

        self.manager = CoverManager()
Exemple #10
0
    def test_acquire_cover(self):
        manager = CoverManager(use_built_in=False)
        handler = manager.plugin_handler
        for source in dummy_sources:
            handler.plugin_handle(source)
        handler.plugin_enable(dummy_sources[0])
        found = []
        result = []

        def done(_found, _result):
            found.append(_found)
            result.append(_result)
        manager.acquire_cover(done, None, None)
        self.runLoop()
        self.assertFalse(found[0])
        handler.plugin_enable(dummy_sources[1])
        manager.acquire_cover(done, None, None)
        self.runLoop()
        self.assertTrue(found[1])
        self.assertIs(result[1], DUMMY_COVER)
        handler.plugin_disable(dummy_sources[1])
        handler.plugin_enable(dummy_sources[2])
        manager.acquire_cover(done, None, None)
        self.runLoop()
        self.assertTrue(found[2])
        self.assertIs(result[2], DUMMY_COVER)
    def test_search(self):
        manager = CoverManager(use_built_in=False)
        handler = manager.plugin_handler
        for source in dummy_sources:
            handler.plugin_handle(source)
            handler.plugin_enable(source)
            source.cls.cover_call = False
            source.cls.fetch_call = False

        song = AudioFile({
            "~filename": os.path.join("/tmp/asong.ogg"),
            "album": "Abbey Road",
            "artist": "The Beatles"
        })
        songs = [song]
        results = []

        def done(manager, provider, result):
            self.failUnless(result, msg="Shouldn't succeed with no results")
            results.append(result)

        def finished(manager, songs):
            print("Finished!")

        manager.connect('covers-found', done)
        manager.search_cover(Cancellable(), songs)
        manager.connect('searches-complete', finished)
        run_loop()

        self.failUnlessEqual(len(results), 1)
Exemple #12
0
    def test_acquire_cover_calls(self):
        # * fetch_cover shouldn't get called if source provides the cover
        #   synchronously
        # * First cover source should fail providing the cover both
        #   synchronously and asynchronously and only then the next source
        #   should be used
        manager = CoverManager(use_built_in=False)
        handler = manager.plugin_handler
        found = []
        result = []
        for source in dummy_sources:
            handler.plugin_handle(source)
            handler.plugin_enable(source)
            source.cls.cover_call = False
            source.cls.fetch_call = False

        def done(_found, _result):
            found.append(_found)
            result.append(_result)
        manager.acquire_cover(done, None, None)
        self.runLoop()
        self.assertTrue(found[0])
        self.assertIs(result[0], DUMMY_COVER)
        self.assertTrue(dummy_sources[0].cls.cover_call)
        self.assertTrue(dummy_sources[1].cls.cover_call)
        self.assertFalse(dummy_sources[2].cls.cover_call)
        self.assertFalse(dummy_sources[0].cls.fetch_call)
        self.assertFalse(dummy_sources[1].cls.fetch_call)
        self.assertFalse(dummy_sources[2].cls.fetch_call)
        for source in dummy_sources:
            source.cls.cover_call = False
            source.cls.fetch_call = False
        handler.plugin_disable(dummy_sources[1])
        manager.acquire_cover(done, None, None)
        self.runLoop()
        self.assertTrue(found[1])
        self.assertIs(result[1], DUMMY_COVER)
        self.assertTrue(dummy_sources[0].cls.cover_call)
        self.assertFalse(dummy_sources[1].cls.cover_call)
        self.assertTrue(dummy_sources[2].cls.cover_call)
        self.assertFalse(dummy_sources[0].cls.fetch_call)
        self.assertFalse(dummy_sources[1].cls.fetch_call)
        self.assertTrue(dummy_sources[2].cls.fetch_call)
Exemple #13
0
    def setUp(self):
        config.init()

        self.manager = CoverManager()
        self.dir = mkdtemp()
        self.song = self.an_album_song()

        # Safety check
        self.failIf(glob.glob(os.path.join(self.dir + "*.jpg")))
        files = [self.full_path("12345.jpg"), self.full_path("nothing.jpg")]
        for f in files:
            open(f, "w").close()
    def setUp(self):
        config.init()
        self.manager = CoverManager()

        self.dir = os.path.realpath(quux("~dirname"))
        # Safety check
        self.failIf(glob.glob(self.dir + "/*.jpg"))
        self.files = [self.full_path("12345.jpg"),
                      self.full_path("nothing.jpg")
                      ]
        for f in self.files:
            open(f, "w").close()
Exemple #15
0
    def setUp(self):
        config.init()

        self.main = mkdtemp()

        self.dir1 = mkdtemp(dir=self.main)
        self.dir2 = mkdtemp(dir=self.main)

        h, self.cover1 = mkstemp(".png", dir=self.main)
        os.close(h)
        pb = GdkPixbuf.Pixbuf.new(GdkPixbuf.Colorspace.RGB, True, 8, 10, 10)
        pb.savev(self.cover1, "png", [], [])

        h, self.cover2 = mkstemp(".png", dir=self.main)
        os.close(h)
        pb = GdkPixbuf.Pixbuf.new(GdkPixbuf.Colorspace.RGB, True, 8, 20, 20)
        pb.savev(self.cover2, "png", [], [])

        self.file1 = get_temp_copy(get_data_path('silence-44-s.mp3'))
        self.file2 = get_temp_copy(get_data_path('silence-44-s.mp3'))

        self.manager = CoverManager()
Exemple #16
0
    def setUp(self):
        self.manager = CoverManager()

        self.dir = mkdtemp()
        self.song = AudioFile({
            "~filename": os.path.join(self.dir, "asong.ogg"),
            "album": u"Quuxly",
        })

        # Safety check
        self.failIf(glob.glob(os.path.join(self.dir + "*.jpg")))
        files = [self.full_path("12345.jpg"), self.full_path("nothing.jpg")]
        for f in files:
            open(f, "w").close()
    def test_acquire_cover_sync(self):
        song = AudioFile({"~filename": "/dev/null"})

        manager = CoverManager(use_built_in=False)
        handler = manager.plugin_handler
        for source in dummy_sources:
            handler.plugin_handle(source)
        handler.plugin_enable(dummy_sources[0])
        self.assertIs(manager.acquire_cover_sync(song), None)
        handler.plugin_enable(dummy_sources[1])
        self.assertIs(manager.acquire_cover_sync(song), DUMMY_COVER)
        handler.plugin_enable(dummy_sources[2])
        self.assertIs(manager.acquire_cover_sync(song), DUMMY_COVER)
        handler.plugin_disable(dummy_sources[1])
        self.assertIs(manager.acquire_cover_sync(song), None)
    def setUp(self):
        config.init()

        self.main = mkdtemp()

        self.dir1 = mkdtemp(dir=self.main)
        self.dir2 = mkdtemp(dir=self.main)

        h, self.cover1 = mkstemp(".png", dir=self.main)
        os.close(h)
        pb = GdkPixbuf.Pixbuf.new(GdkPixbuf.Colorspace.RGB, True, 8, 10, 10)
        pb.savev(self.cover1, "png", [], [])

        h, self.cover2 = mkstemp(".png", dir=self.main)
        os.close(h)
        pb = GdkPixbuf.Pixbuf.new(GdkPixbuf.Colorspace.RGB, True, 8, 20, 20)
        pb.savev(self.cover2, "png", [], [])

        self.file1 = get_temp_copy(get_data_path('silence-44-s.mp3'))
        self.file2 = get_temp_copy(get_data_path('silence-44-s.mp3'))

        self.manager = CoverManager()
Exemple #19
0
    def test_acquire_cover_calls(self):
        # * fetch_cover shouldn't get called if source provides the cover
        #   synchronously
        # * First cover source should fail providing the cover both
        #   synchronously and asynchronously and only then the next source
        #   should be used
        manager = CoverManager(use_built_in=False)
        handler = manager.plugin_handler
        found = []
        result = []
        for source in dummy_sources:
            handler.plugin_handle(source)
            handler.plugin_enable(source)
            source.cls.cover_call = False
            source.cls.fetch_call = False

        def done(_found, _result):
            found.append(_found)
            result.append(_result)

        manager.acquire_cover(done, None, None)
        self.runLoop()
        self.assertTrue(found[0])
        self.assertIs(result[0], DUMMY_COVER)
        self.assertTrue(dummy_sources[0].cls.cover_call)
        self.assertTrue(dummy_sources[1].cls.cover_call)
        self.assertFalse(dummy_sources[2].cls.cover_call)
        self.assertFalse(dummy_sources[0].cls.fetch_call)
        self.assertFalse(dummy_sources[1].cls.fetch_call)
        self.assertFalse(dummy_sources[2].cls.fetch_call)
        for source in dummy_sources:
            source.cls.cover_call = False
            source.cls.fetch_call = False
        handler.plugin_disable(dummy_sources[1])
        manager.acquire_cover(done, None, None)
        self.runLoop()
        self.assertTrue(found[1])
        self.assertIs(result[1], DUMMY_COVER)
        self.assertTrue(dummy_sources[0].cls.cover_call)
        self.assertFalse(dummy_sources[1].cls.cover_call)
        self.assertTrue(dummy_sources[2].cls.cover_call)
        self.assertFalse(dummy_sources[0].cls.fetch_call)
        self.assertFalse(dummy_sources[1].cls.fetch_call)
        self.assertTrue(dummy_sources[2].cls.fetch_call)
class TCoverManagerBuiltin(TestCase):

    def setUp(self):
        config.init()

        self.main = mkdtemp()

        self.dir1 = mkdtemp(dir=self.main)
        self.dir2 = mkdtemp(dir=self.main)

        h, self.cover1 = mkstemp(".png", dir=self.main)
        os.close(h)
        pb = GdkPixbuf.Pixbuf.new(GdkPixbuf.Colorspace.RGB, True, 8, 10, 10)
        pb.savev(self.cover1, "png", [], [])

        h, self.cover2 = mkstemp(".png", dir=self.main)
        os.close(h)
        pb = GdkPixbuf.Pixbuf.new(GdkPixbuf.Colorspace.RGB, True, 8, 20, 20)
        pb.savev(self.cover2, "png", [], [])

        fd, self.file1 = mkstemp(".mp3", dir=self.main)
        os.close(fd)
        shutil.copy(os.path.join(DATA_DIR, 'silence-44-s.mp3'), self.file1)

        fd, self.file2 = mkstemp(".mp3", dir=self.main)
        os.close(fd)
        shutil.copy(os.path.join(DATA_DIR, 'silence-44-s.mp3'), self.file2)

        self.manager = CoverManager()

    def tearDown(self):
        shutil.rmtree(self.main)
        config.quit()

    def test_connect_cover_changed(self):

        called_with = []

        def sig_handler(*args):
            called_with.extend(args)

        obj = object()
        self.manager.connect("cover-changed", sig_handler)
        self.manager.cover_changed([obj])

        self.assertEqual(called_with, [self.manager, [obj]])

    def test_get_primary_image(self):
        self.assertFalse(MP3File(self.file1).has_images)
        self.assertFalse(MP3File(self.file1).has_images)

    def test_manager(self):
        self.assertEqual(len(list(self.manager.sources)), 2)

    def test_main(self):
        # embedd one cover, move one to the other dir
        MP3File(self.file1).set_image(EmbeddedImage.from_path(self.cover1))
        os.unlink(self.cover1)
        dest = os.path.join(self.dir2, "cover.png")
        shutil.move(self.cover2, dest)
        self.cover2 = dest

        # 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)

        def is_embedded(fileobj):
            return not path_equal(fileobj.name, self.cover2, True)

        # each should find a cover
        self.assertTrue(is_embedded(self.manager.get_cover(song1)))
        self.assertTrue(not is_embedded(self.manager.get_cover(song2)))

        # both settings should search both songs before giving up
        config.set("albumart", "prefer_embedded", True)
        self.assertTrue(
            is_embedded(self.manager.get_cover_many([song1, song2])))
        self.assertTrue(
            is_embedded(self.manager.get_cover_many([song2, song1])))

        config.set("albumart", "prefer_embedded", False)
        self.assertTrue(
            not is_embedded(self.manager.get_cover_many([song1, song2])))
        self.assertTrue(
            not is_embedded(self.manager.get_cover_many([song2, song1])))
Exemple #21
0
class TCoverManagerBuiltin(TestCase):

    def setUp(self):
        config.init()

        self.main = mkdtemp()

        self.dir1 = mkdtemp(dir=self.main)
        self.dir2 = mkdtemp(dir=self.main)

        h, self.cover1 = mkstemp(".png", dir=self.main)
        os.close(h)
        pb = GdkPixbuf.Pixbuf.new(GdkPixbuf.Colorspace.RGB, True, 8, 10, 10)
        pb.savev(self.cover1, "png", [], [])

        h, self.cover2 = mkstemp(".png", dir=self.main)
        os.close(h)
        pb = GdkPixbuf.Pixbuf.new(GdkPixbuf.Colorspace.RGB, True, 8, 20, 20)
        pb.savev(self.cover2, "png", [], [])

        fd, self.file1 = mkstemp(".mp3", dir=self.main)
        os.close(fd)
        shutil.copy(os.path.join(DATA_DIR, 'silence-44-s.mp3'), self.file1)

        fd, self.file2 = mkstemp(".mp3", dir=self.main)
        os.close(fd)
        shutil.copy(os.path.join(DATA_DIR, 'silence-44-s.mp3'), self.file2)

        self.manager = CoverManager()

    def tearDown(self):
        shutil.rmtree(self.main)
        config.quit()

    def test_connect_cover_changed(self):

        called_with = []

        def sig_handler(*args):
            called_with.extend(args)

        obj = object()
        self.manager.connect("cover-changed", sig_handler)
        self.manager.cover_changed([obj])

        self.assertEqual(called_with, [self.manager, [obj]])

    def test_get_primary_image(self):
        self.assertFalse(MP3File(self.file1).has_images)
        self.assertFalse(MP3File(self.file1).has_images)

    def test_manager(self):
        self.assertEqual(len(list(self.manager.sources)), 2)

    def test_main(self):
        # embedd one cover, move one to the other dir
        MP3File(self.file1).set_image(EmbeddedImage.from_path(self.cover1))
        os.unlink(self.cover1)
        dest = os.path.join(self.dir2, "cover.png")
        shutil.move(self.cover2, dest)
        self.cover2 = dest

        # 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)

        def is_embedded(fileobj):
            return not path_equal(fileobj.name, self.cover2, True)

        # each should find a cover
        self.assertTrue(is_embedded(self.manager.get_cover(song1)))
        self.assertTrue(not is_embedded(self.manager.get_cover(song2)))

        # both settings should search both songs before giving up
        config.set("albumart", "prefer_embedded", True)
        self.assertTrue(
            is_embedded(self.manager.get_cover_many([song1, song2])))
        self.assertTrue(
            is_embedded(self.manager.get_cover_many([song2, song1])))

        config.set("albumart", "prefer_embedded", False)
        self.assertTrue(
            not is_embedded(self.manager.get_cover_many([song1, song2])))
        self.assertTrue(
            not is_embedded(self.manager.get_cover_many([song2, song1])))
class TCoverManagerBuiltin(TestCase):
    def setUp(self):
        config.init()

        self.main = mkdtemp()

        self.dir1 = mkdtemp(dir=self.main)
        self.dir2 = mkdtemp(dir=self.main)

        h, self.cover1 = mkstemp(".png", dir=self.main)
        os.close(h)
        pb = GdkPixbuf.Pixbuf.new(GdkPixbuf.Colorspace.RGB, True, 8, 10, 10)
        pb.savev(self.cover1, "png", [], [])

        h, self.cover2 = mkstemp(".png", dir=self.main)
        os.close(h)
        pb = GdkPixbuf.Pixbuf.new(GdkPixbuf.Colorspace.RGB, True, 8, 20, 20)
        pb.savev(self.cover2, "png", [], [])

        self.file1 = get_temp_copy(get_data_path('silence-44-s.mp3'))
        self.file2 = get_temp_copy(get_data_path('silence-44-s.mp3'))

        self.manager = CoverManager()

    def tearDown(self):
        shutil.rmtree(self.main)
        config.quit()

    def test_connect_cover_changed(self):

        called_with = []

        def sig_handler(*args):
            called_with.extend(args)

        obj = object()
        self.manager.connect("cover-changed", sig_handler)
        self.manager.cover_changed([obj])

        self.assertEqual(called_with, [self.manager, [obj]])

    def test_get_primary_image(self):
        self.assertFalse(MP3File(self.file1).has_images)
        self.assertFalse(MP3File(self.file1).has_images)

    def test_manager(self):
        self.assertEqual(len(list(self.manager.sources)), 2)

    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 is_embedded(self, fileobj):
        return not path_equal(fileobj.name, self.external_cover, True)

    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")
Exemple #23
0
class TCoverManager(TestCase):

    def setUp(self):
        config.init()
        self.manager = CoverManager()

        self.dir = os.path.realpath(quux("~dirname"))
        self.files = [self.full_path("12345.jpg"),
                      self.full_path("nothing.jpg")
                      ]
        for f in self.files:
            file(f, "w").close()

    def _find_cover(self, song):
        return self.manager.get_cover(song)

    def tearDown(self):
        for f in self.files:
            os.unlink(f)
        config.quit()

    def full_path(self, path):
        return os.path.join(self.dir, path)

    def test_dir_not_exist(self):
        self.failIf(self._find_cover(bar_2_1))

    def test_nothing(self):
        self.failIf(self._find_cover(quux))

    def test_labelid(self):
        quux["labelid"] = "12345"
        self.failUnlessEqual(os.path.abspath(self._find_cover(quux).name),
                             self.full_path("12345.jpg"))
        del(quux["labelid"])

    def test_regular(self):
        files = [os.path.join(self.dir, f) for f in
                 ["cover.png", "folder.jpg", "frontcover.jpg",
                  "front_folder_cover.gif", "jacket_cover.front.folder.jpeg"]]
        for f in files:
            file(f, "w").close()
            self.files.append(f)
            self.failUnlessEqual(
                os.path.abspath(self._find_cover(quux).name), f)
        self.test_labelid() # labelid must work with other files present

    def test_file_encoding(self):
        if os.name == "nt":
            return

        f = self.full_path("\xff\xff\xff\xff - cover.jpg")
        file(f, "w").close()
        self.files.append(f)
        self.assertTrue(isinstance(quux("album"), unicode))
        h = self._find_cover(quux)
        self.assertEqual(h.name, normalize_path(f))

    def test_intelligent(self):
        song = quux
        song["artist"] = "Q-Man"
        song["title"] = "First Q falls hardest"
        files = [self.full_path(f) for f in
                 ["Quuxly - back.jpg", "Quuxly.jpg", "q-man - quxxly.jpg",
                  "folder.jpeg", "Q-man - Quuxly (FRONT).jpg"]]
        for f in files:
            file(f, "w").close()
            self.files.append(f)
            cover = self._find_cover(song)
            if cover:
                actual = os.path.abspath(cover.name)
                self.failUnlessEqual(actual, f)
            else:
                # Here, no cover is better than the back...
                self.failUnlessEqual(f, self.full_path("Quuxly - back.jpg"))

    def test_embedded_special_cover_words(self):
        """Tests that words incidentally containing embedded "special" words
        album keywords (e.g. cover, disc, back) don't trigger
        See Issue 818"""

        song = AudioFile({
            "~filename": fsnative(u"tests/data/asong.ogg"),
            "album": "foobar",
            "title": "Ode to Baz",
            "artist": "Q-Man",
        })
        files = [self.full_path(f) for f in
                 ['back.jpg',
                  'discovery.jpg', "Pharell - frontin'.jpg",
                  'nickelback - Curb.jpg',
                  'foobar.jpg', 'folder.jpg',     # Though this is debatable
                  'Q-Man - foobar.jpg', 'Q-man - foobar (cover).jpg']]
        for f in files:
            file(f, "w").close()
            self.files.append(f)
            cover = self._find_cover(song)
            if cover:
                actual = os.path.abspath(cover.name)
                self.failUnlessEqual(
                    actual, f, "\"%s\" should trump \"%s\"" % (f, actual))
            else:
                self.failUnless(f, self.full_path('back.jpg'))

    def test_get_thumbnail(self):
        self.assertTrue(self.manager.get_pixbuf(quux, 10, 10) is None)
        self.assertTrue(self.manager.get_pixbuf_many([quux], 10, 10) is None)
Exemple #24
0
class TCoverManager(TestCase):
    def setUp(self):
        self.manager = CoverManager()

        self.dir = mkdtemp()
        self.song = AudioFile({
            "~filename": os.path.join(self.dir, "asong.ogg"),
            "album": u"Quuxly",
        })

        # Safety check
        self.failIf(glob.glob(os.path.join(self.dir + "*.jpg")))
        files = [self.full_path("12345.jpg"), self.full_path("nothing.jpg")]
        for f in files:
            open(f, "w").close()

    def tearDown(self):
        shutil.rmtree(self.dir)

    def _find_cover(self, song):
        return self.manager.get_cover(song)

    def full_path(self, path):
        return os.path.join(self.dir, path)

    def test_dir_not_exist(self):
        self.failIf(self._find_cover(bar_2_1))

    def test_nothing(self):
        self.failIf(self._find_cover(self.song))

    def test_labelid(self):
        self.song["labelid"] = "12345"
        assert path_equal(os.path.abspath(self._find_cover(self.song).name),
                          self.full_path("12345.jpg"))
        del (self.song["labelid"])

    def test_regular(self):
        for fn in [
                "cover.png", "folder.jpg", "frontcover.jpg",
                "front_folder_cover.gif", "jacket_cover.front.folder.jpeg"
        ]:
            f = self.add_file(fn)
            assert path_equal(
                os.path.abspath(self._find_cover(self.song).name), f)
        self.test_labelid()  # labelid must work with other files present

    def test_file_encoding(self):
        if os.name == "nt":
            return

        f = self.add_file("\xff\xff\xff\xff - cover.jpg")
        self.assertTrue(isinstance(self.song("album"), unicode))
        h = self._find_cover(self.song)
        self.assertEqual(h.name, normalize_path(f))

    def test_intelligent(self):
        song = self.song
        song["artist"] = "Q-Man"
        song["title"] = "First Q falls hardest"
        fns = [
            "Quuxly - back.jpg", "Quuxly.jpg", "q-man - quxxly.jpg",
            "folder.jpeg", "Q-man - Quuxly (FRONT).jpg"
        ]
        for fn in fns:
            f = self.add_file(fn)
            cover = self._find_cover(song)
            if cover:
                actual = os.path.abspath(cover.name)
                assert path_equal(actual, f)
            else:
                # Here, no cover is better than the back...
                assert path_equal(f, self.full_path("Quuxly - back.jpg"))

    def test_embedded_special_cover_words(self):
        """Tests that words incidentally containing embedded "special" words
        album keywords (e.g. cover, disc, back) don't trigger
        See Issue 818"""

        song = AudioFile({
            "~filename":
            fsnative(os.path.join(self.dir, u"asong.ogg")),
            "album":
            "foobar",
            "title":
            "Ode to Baz",
            "artist":
            "Q-Man",
        })
        data = [
            ('back.jpg', False),
            ('discovery.jpg', False),
            ("Pharell - frontin'.jpg", False),
            ('nickelback - Curb.jpg', False),
            ('foobar.jpg', True),
            ('folder.jpg', True),  # Though this order is debatable
            ('Q-Man - foobar.jpg', True),
            ('Q-man - foobar (cover).jpg', True)
        ]
        for fn, should_find in data:
            f = self.add_file(fn)
            cover = self._find_cover(song)
            if cover:
                actual = os.path.abspath(cover.name)
                assert path_equal(actual, f,
                                  "\"%s\" should trump \"%s\"" % (f, actual))
            else:
                self.failIf(should_find,
                            msg="Couldn't find %s for %s" %
                            (f, song("~filename")))

    def add_file(self, fn):
        f = self.full_path(fn)
        open(f, "w").close()
        return f

    def test_multiple_people(self):
        song = AudioFile({
            "~filename": os.path.join(self.dir, "asong.ogg"),
            "album": "foobar",
            "title": "Ode to Baz",
            "performer": "The Performer",
            "artist": "The Composer\nThe Conductor",
            "composer": "The Composer",
        })
        for fn in [
                "foobar.jpg", "The Performer - foobar.jpg",
                "The Composer - The Performer - foobar.jpg",
                "The Composer - The Conductor, The Performer - foobar.jpg"
        ]:
            f = self.add_file(fn)
            cover = self._find_cover(song)
            self.failUnless(cover)
            actual = os.path.abspath(cover.name)
            cover.close()
            assert path_equal(actual, f,
                              "\"%s\" should trump \"%s\"" % (f, actual))

    def test_get_thumbnail(self):
        self.assertTrue(self.manager.get_pixbuf(self.song, 10, 10) is None)
        self.assertTrue(
            self.manager.get_pixbuf_many([self.song], 10, 10) is None)
 def setUp(self):
     self.manager = CoverManager()
Exemple #26
0
class TCoverManager(TestCase):

    def setUp(self):
        config.init()

        self.manager = CoverManager()
        self.dir = mkdtemp()
        self.song = self.an_album_song()

        # Safety check
        self.failIf(glob.glob(os.path.join(self.dir + "*.jpg")))
        files = [self.full_path("12345.jpg"), self.full_path("nothing.jpg")]
        for f in files:
            open(f, "w").close()

    def an_album_song(self, fn="asong.ogg"):
        return AudioFile({
            "~filename": os.path.join(self.dir, fn),
            "album": u"Quuxly",
            "artist": u"Some One",
        })

    def tearDown(self):
        shutil.rmtree(self.dir)
        config.quit()

    def _find_cover(self, song):
        return self.manager.get_cover(song)

    def full_path(self, path):
        return os.path.join(self.dir, path)

    def test_dir_not_exist(self):
        self.failIf(self._find_cover(bar_2_1))

    def test_nothing(self):
        self.failIf(self._find_cover(self.song))

    def test_labelid(self):
        self.song["labelid"] = "12345"
        assert path_equal(os.path.abspath(self._find_cover(self.song).name),
                          self.full_path("12345.jpg"))
        del(self.song["labelid"])

    def test_regular(self):
        for fn in ["cover.png", "folder.jpg", "Quuxly - front.png",
                   "Quuxly_front_folder_cover.gif"]:
            f = self.add_file(fn)
            cover = self._find_cover(self.song)
            assert cover, f"No cover found after adding {fn}"
            assert path_equal(os.path.abspath(cover.name), f)
        self.test_labelid() # labelid must work with other files present

    def test_file_encoding(self):
        f = self.add_file(fsnative(u"öäü - Quuxly - cover.jpg"))
        self.assertTrue(isinstance(self.song("album"), str))
        h = self._find_cover(self.song)
        assert h, "Nothing found"
        self.assertEqual(normalize_path(h.name), normalize_path(f))

    def test_glob(self):
        config.set("albumart", "force_filename", str(True))
        config.set("albumart", "filename", "foo.*")
        for fn in ["foo.jpg", "foo.png"]:
            f = self.add_file(fn)
            assert path_equal(
                os.path.abspath(self._find_cover(self.song).name), f)

    def test_invalid_glob(self):
        config.set("albumart", "force_filename", str(True))
        config.set("albumart", "filename", "[a-2].jpg")

        # Should match
        f = self.add_file("[a-2].jpg")
        assert path_equal(
            os.path.abspath(self._find_cover(self.song).name), f)

        # Should not crash
        f = self.add_file("test.jpg")
        assert not path_equal(
            os.path.abspath(self._find_cover(self.song).name), f)

    def test_invalid_glob_path(self):
        config.set("albumart", "force_filename", str(True))
        config.set("albumart", "filename", "*.jpg")

        # Make a dir which contains an invalid glob
        path = os.path.join(self.full_path("[a-2]"), "cover.jpg")
        mkdir(os.path.dirname(path))
        f = self.add_file(path)

        # Change the song's path to contain the invalid glob
        old_song_path = self.song['~filename']
        new_song_path = os.path.join(os.path.dirname(path),
                                     os.path.basename(old_song_path))
        self.song['~filename'] = new_song_path

        # The glob in the dirname should be ignored, while the
        # glob in the filename/basename is honored
        assert path_equal(
            os.path.abspath(self._find_cover(self.song).name), f)

        self.song['~filename'] = old_song_path

    def test_multiple_entries(self):
        config.set("albumart", "force_filename", str(True))
        # the order of these is important, since bar should be
        # preferred to both 'foo' files
        # the spaces after the comma and last name are intentional
        config.set("albumart", "filename", "bar*,foo.png, foo.jpg ")

        for fn in ["foo.jpg", "foo.png", "bar.jpg"]:
            f = self.add_file(fn)
            assert path_equal(
                os.path.abspath(self._find_cover(self.song).name), f)

    def test_intelligent(self):
        song = self.song
        song["artist"] = "Q-Man"
        song["title"] = "First Q falls hardest"
        fns = ["Quuxly - back.jpg", "Quuxly.jpg", "q-man - quxxly.jpg",
                  "folder.jpeg", "Q-man - Quuxly (FRONT).jpg"]
        for fn in fns:
            f = self.add_file(fn)
            cover = self._find_cover(song)
            if cover:
                actual = os.path.abspath(cover.name)
                assert path_equal(actual, f)
            else:
                # Here, no cover is better than the back...
                assert path_equal(f, self.full_path("Quuxly - back.jpg"))

    def test_embedded_special_cover_words(self):
        """Tests that words incidentally containing embedded "special" words
        album keywords (e.g. cover, disc, back) don't trigger
        See Issue 818"""

        song = AudioFile({
            "~filename": fsnative(os.path.join(self.dir, u"asong.ogg")),
            "album": "foobar",
            "title": "Ode to Baz",
            "artist": "Q-Man",
        })
        data = [('back.jpg', False),
                ('discovery.jpg', False),
                ("Pharell - frontin'.jpg", False),
                ('nickelback - Curb.jpg', False),
                ('foobar.jpg', True),
                ('folder.jpg', True),  # Though this order is debatable
                ('Q-Man - foobar.jpg', True),
                ('Q-man - foobar (cover).jpg', True)]
        for fn, should_find in data:
            f = self.add_file(fn)
            cover = self._find_cover(song)
            if cover:
                actual = os.path.abspath(cover.name)
                assert path_equal(actual, f), \
                    f"{basename(f)!r} should trump {basename(actual)!r}"
            else:
                self.failIf(should_find, msg="Couldn't find %s for %s" %
                                             (f, song("~filename")))

    def add_file(self, fn):
        f = self.full_path(fn)
        open(f, "wb").close()
        return f

    def test_multiple_people(self):
        song = AudioFile({
            "~filename": os.path.join(self.dir, "asong.ogg"),
            "album": "foobar",
            "title": "Ode to Baz",
            "performer": "The Performer",
            "artist": "The Composer\nThe Conductor",
            "composer": "The Composer",
        })
        for fn in ["foobar.jpg",
                   "The Performer - foobar.jpg",
                   "The Composer - The Performer - foobar.jpg",
                   "The Composer - The Conductor, The Performer - foobar.jpg"]:
            f = self.add_file(fn)
            cover = self._find_cover(song)
            self.failUnless(cover)
            actual = os.path.abspath(cover.name)
            cover.close()
            assert path_equal(
                actual, f, "\"%s\" should trump \"%s\"" % (f, actual))

    def test_get_thumbnail(self):
        self.assertTrue(self.manager.get_pixbuf(self.song, 10, 10) is None)
        self.assertTrue(
            self.manager.get_pixbuf_many([self.song], 10, 10) is None)

    def test_get_many(self):
        songs = [AudioFile({"~filename": os.path.join(self.dir, "song.ogg"),
                            "title": "Ode to Baz"}),
                 self.an_album_song()]
        plugin = Plugin(ArtworkUrlCover)
        self.manager.plugin_handler.plugin_enable(plugin)
        self.add_file('cover.jpg')
        cover = self.manager.get_cover_many(songs)
        assert cover

    def test_search_missing_artist(self):
        titled_album_song = self.an_album_song('z.ogg')
        titled_album_song["artist"] = "foo"
        album_songs = [self.an_album_song('x.ogg'), titled_album_song,
                       self.an_album_song()]
        self.manager.search_cover(Gio.Cancellable(), album_songs)
Exemple #27
0
class TCoverManager(TestCase):

    def setUp(self):
        config.init()

        self.manager = CoverManager()
        self.dir = mkdtemp()
        self.song = self.an_album_song()

        # Safety check
        self.failIf(glob.glob(os.path.join(self.dir + "*.jpg")))
        files = [self.full_path("12345.jpg"), self.full_path("nothing.jpg")]
        for f in files:
            open(f, "w").close()

    def an_album_song(self, fn="asong.ogg"):
        return AudioFile({
            "~filename": os.path.join(self.dir, fn),
            "album": u"Quuxly",
        })

    def tearDown(self):
        shutil.rmtree(self.dir)
        config.quit()

    def _find_cover(self, song):
        return self.manager.get_cover(song)

    def full_path(self, path):
        return os.path.join(self.dir, path)

    def test_dir_not_exist(self):
        self.failIf(self._find_cover(bar_2_1))

    def test_nothing(self):
        self.failIf(self._find_cover(self.song))

    def test_labelid(self):
        self.song["labelid"] = "12345"
        assert path_equal(os.path.abspath(self._find_cover(self.song).name),
                          self.full_path("12345.jpg"))
        del(self.song["labelid"])

    def test_regular(self):
        for fn in ["cover.png", "folder.jpg", "frontcover.jpg",
                   "front_folder_cover.gif", "jacket_cover.front.folder.jpeg"]:
            f = self.add_file(fn)
            assert path_equal(
                os.path.abspath(self._find_cover(self.song).name), f)
        self.test_labelid() # labelid must work with other files present

    def test_file_encoding(self):
        f = self.add_file(fsnative(u"öäü - cover.jpg"))
        self.assertTrue(isinstance(self.song("album"), text_type))
        h = self._find_cover(self.song)
        self.assertEqual(normalize_path(h.name), normalize_path(f))

    def test_glob(self):
        config.set("albumart", "force_filename", str(True))
        config.set("albumart", "filename", "foo.*")
        for fn in ["foo.jpg", "foo.png"]:
            f = self.add_file(fn)
            assert path_equal(
                os.path.abspath(self._find_cover(self.song).name), f)

    def test_invalid_glob(self):
        config.set("albumart", "force_filename", str(True))
        config.set("albumart", "filename", "[a-2].jpg")

        # Should match
        f = self.add_file("[a-2].jpg")
        assert path_equal(
            os.path.abspath(self._find_cover(self.song).name), f)

        # Should not crash
        f = self.add_file("test.jpg")
        assert not path_equal(
            os.path.abspath(self._find_cover(self.song).name), f)

    def test_invalid_glob_path(self):
        config.set("albumart", "force_filename", str(True))
        config.set("albumart", "filename", "*.jpg")

        # Make a dir which contains an invalid glob
        path = os.path.join(self.full_path("[a-2]"), "cover.jpg")
        mkdir(os.path.dirname(path))
        f = self.add_file(path)

        # Change the song's path to contain the invalid glob
        old_song_path = self.song['~filename']
        new_song_path = os.path.join(os.path.dirname(path),
                                     os.path.basename(old_song_path))
        self.song['~filename'] = new_song_path

        # The glob in the dirname should be ignored, while the
        # glob in the filename/basename is honored
        assert path_equal(
            os.path.abspath(self._find_cover(self.song).name), f)

        self.song['~filename'] = old_song_path

    def test_intelligent(self):
        song = self.song
        song["artist"] = "Q-Man"
        song["title"] = "First Q falls hardest"
        fns = ["Quuxly - back.jpg", "Quuxly.jpg", "q-man - quxxly.jpg",
                  "folder.jpeg", "Q-man - Quuxly (FRONT).jpg"]
        for fn in fns:
            f = self.add_file(fn)
            cover = self._find_cover(song)
            if cover:
                actual = os.path.abspath(cover.name)
                assert path_equal(actual, f)
            else:
                # Here, no cover is better than the back...
                assert path_equal(f, self.full_path("Quuxly - back.jpg"))

    def test_embedded_special_cover_words(self):
        """Tests that words incidentally containing embedded "special" words
        album keywords (e.g. cover, disc, back) don't trigger
        See Issue 818"""

        song = AudioFile({
            "~filename": fsnative(os.path.join(self.dir, u"asong.ogg")),
            "album": "foobar",
            "title": "Ode to Baz",
            "artist": "Q-Man",
        })
        data = [('back.jpg', False),
                ('discovery.jpg', False),
                ("Pharell - frontin'.jpg", False),
                ('nickelback - Curb.jpg', False),
                ('foobar.jpg', True),
                ('folder.jpg', True),  # Though this order is debatable
                ('Q-Man - foobar.jpg', True),
                ('Q-man - foobar (cover).jpg', True)]
        for fn, should_find in data:
            f = self.add_file(fn)
            cover = self._find_cover(song)
            if cover:
                actual = os.path.abspath(cover.name)
                assert path_equal(
                    actual, f, "\"%s\" should trump \"%s\"" % (f, actual))
            else:
                self.failIf(should_find, msg="Couldn't find %s for %s" %
                                             (f, song("~filename")))

    def add_file(self, fn):
        f = self.full_path(fn)
        open(f, "wb").close()
        return f

    def test_multiple_people(self):
        song = AudioFile({
            "~filename": os.path.join(self.dir, "asong.ogg"),
            "album": "foobar",
            "title": "Ode to Baz",
            "performer": "The Performer",
            "artist": "The Composer\nThe Conductor",
            "composer": "The Composer",
        })
        for fn in ["foobar.jpg",
                   "The Performer - foobar.jpg",
                   "The Composer - The Performer - foobar.jpg",
                   "The Composer - The Conductor, The Performer - foobar.jpg"]:
            f = self.add_file(fn)
            cover = self._find_cover(song)
            self.failUnless(cover)
            actual = os.path.abspath(cover.name)
            cover.close()
            assert path_equal(
                actual, f, "\"%s\" should trump \"%s\"" % (f, actual))

    def test_get_thumbnail(self):
        self.assertTrue(self.manager.get_pixbuf(self.song, 10, 10) is None)
        self.assertTrue(
            self.manager.get_pixbuf_many([self.song], 10, 10) is None)

    def test_get_many(self):
        songs = [AudioFile({"~filename": os.path.join(self.dir, "song.ogg"),
                            "title": "Ode to Baz"}),
                 self.an_album_song()]
        plugin = Plugin(ArtworkUrlCover)
        self.manager.plugin_handler.plugin_enable(plugin)
        self.add_file('cover.jpg')
        cover = self.manager.get_cover_many(songs)
        assert cover

    def test_search_missing_artist(self):
        titled_album_song = self.an_album_song('z.ogg')
        titled_album_song["artist"] = "foo"
        album_songs = [self.an_album_song('x.ogg'), titled_album_song,
                       self.an_album_song()]
        self.manager.search_cover(Gio.Cancellable(), album_songs)
class TCoverManager(TestCase):

    def setUp(self):
        config.init()
        self.manager = CoverManager()

        self.dir = os.path.realpath(quux("~dirname"))
        # Safety check
        self.failIf(glob.glob(self.dir + "/*.jpg"))
        self.files = [self.full_path("12345.jpg"),
                      self.full_path("nothing.jpg")
                      ]
        for f in self.files:
            open(f, "w").close()

    def _find_cover(self, song):
        return self.manager.get_cover(song)

    def tearDown(self):
        for f in self.files:
            os.unlink(f)
        config.quit()

    def full_path(self, path):
        return os.path.join(self.dir, path)

    def test_dir_not_exist(self):
        self.failIf(self._find_cover(bar_2_1))

    def test_nothing(self):
        self.failIf(self._find_cover(quux))

    def test_labelid(self):
        quux["labelid"] = "12345"
        self.failUnlessEqual(os.path.abspath(self._find_cover(quux).name),
                             self.full_path("12345.jpg"))
        del(quux["labelid"])

    def test_regular(self):
        for fn in ["cover.png", "folder.jpg", "frontcover.jpg",
                   "front_folder_cover.gif", "jacket_cover.front.folder.jpeg"]:
            f = self.add_file(fn)
            self.failUnlessEqual(
                os.path.abspath(self._find_cover(quux).name), f)
        self.test_labelid() # labelid must work with other files present

    def test_file_encoding(self):
        if os.name == "nt":
            return

        f = self.add_file("\xff\xff\xff\xff - cover.jpg")
        self.assertTrue(isinstance(quux("album"), unicode))
        h = self._find_cover(quux)
        self.assertEqual(h.name, normalize_path(f))

    def test_intelligent(self):
        song = quux
        song["artist"] = "Q-Man"
        song["title"] = "First Q falls hardest"
        fns = ["Quuxly - back.jpg", "Quuxly.jpg", "q-man - quxxly.jpg",
                  "folder.jpeg", "Q-man - Quuxly (FRONT).jpg"]
        for fn in fns:
            f = self.add_file(fn)
            cover = self._find_cover(song)
            if cover:
                actual = os.path.abspath(cover.name)
                self.failUnlessEqual(actual, f)
            else:
                # Here, no cover is better than the back...
                self.failUnlessEqual(f, self.full_path("Quuxly - back.jpg"))

    def test_embedded_special_cover_words(self):
        """Tests that words incidentally containing embedded "special" words
        album keywords (e.g. cover, disc, back) don't trigger
        See Issue 818"""

        song = AudioFile({
            "~filename": fsnative(os.path.join(self.dir, u"asong.ogg")),
            "album": "foobar",
            "title": "Ode to Baz",
            "artist": "Q-Man",
        })
        data = [('back.jpg', False),
                ('discovery.jpg', False),
                ("Pharell - frontin'.jpg", False),
                ('nickelback - Curb.jpg', False),
                ('foobar.jpg', True),
                ('folder.jpg', True),  # Though this order is debatable
                ('Q-Man - foobar.jpg', True),
                ('Q-man - foobar (cover).jpg', True)]
        for fn, should_find in data:
            f = self.add_file(fn)
            cover = self._find_cover(song)
            if cover:
                actual = os.path.abspath(cover.name)
                self.failUnlessEqual(
                    actual, f, "\"%s\" should trump \"%s\"" % (f, actual))
            else:
                self.failIf(should_find, msg="Couldn't find %s for %s" %
                                             (f, song("~filename")))

    def add_file(self, fn):
        f = self.full_path(fn)
        open(f, "w").close()
        self.files.append(f)
        return f

    def test_multiple_people(self):
        song = AudioFile({
            "~filename": fsnative(os.path.join(self.dir, u"asong.ogg")),
            "album": "foobar",
            "title": "Ode to Baz",
            "performer": "The Performer",
            "artist": "The Composer\nThe Conductor",
            "composer": "The Composer",
        })
        for fn in ["foobar.jpg",
                   "The Performer - foobar.jpg",
                   "The Composer: The Performer - foobar.jpg",
                   "The Composer: The Conductor, The Performer - foobar.jpg"]:
            f = self.add_file(fn)
            cover = self._find_cover(song)
            self.failUnless(cover)
            actual = os.path.abspath(cover.name)
            self.failUnlessEqual(
                    actual, f, "\"%s\" should trump \"%s\"" % (f, actual))

    def test_get_thumbnail(self):
        self.assertTrue(self.manager.get_pixbuf(quux, 10, 10) is None)
        self.assertTrue(self.manager.get_pixbuf_many([quux], 10, 10) is None)
class TCoverManagerBuiltin(TestCase):

    def setUp(self):
        config.init()

        self.main = mkdtemp()

        self.dir1 = mkdtemp(dir=self.main)
        self.dir2 = mkdtemp(dir=self.main)

        h, self.cover1 = mkstemp(".png", dir=self.main)
        os.close(h)
        pb = GdkPixbuf.Pixbuf.new(GdkPixbuf.Colorspace.RGB, True, 8, 10, 10)
        pb.savev(self.cover1, "png", [], [])

        h, self.cover2 = mkstemp(".png", dir=self.main)
        os.close(h)
        pb = GdkPixbuf.Pixbuf.new(GdkPixbuf.Colorspace.RGB, True, 8, 20, 20)
        pb.savev(self.cover2, "png", [], [])

        self.file1 = get_temp_copy(get_data_path('silence-44-s.mp3'))
        self.file2 = get_temp_copy(get_data_path('silence-44-s.mp3'))

        self.manager = CoverManager()

    def tearDown(self):
        shutil.rmtree(self.main)
        config.quit()

    def test_connect_cover_changed(self):

        called_with = []

        def sig_handler(*args):
            called_with.extend(args)

        obj = object()
        self.manager.connect("cover-changed", sig_handler)
        self.manager.cover_changed([obj])

        self.assertEqual(called_with, [self.manager, [obj]])

    def test_get_primary_image(self):
        self.assertFalse(MP3File(self.file1).has_images)
        self.assertFalse(MP3File(self.file1).has_images)

    def test_manager(self):
        self.assertEqual(len(list(self.manager.sources)), 2)

    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 is_embedded(self, fileobj):
        return not path_equal(fileobj.name, self.external_cover, True)

    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")