Beispiel #1
0
 def test_read_tags(self):
     shutil.copy(TagsTest.SRC_FILE, TagsTest.DST_FILE)
     song = Song(Path=TagsTest.DST_FILE)
     song.read_tags()
     self.assertEqual(song.Title, 'TestTitle')
     self.assertEqual(song.Artist, 'TestArtist')
     self.assertEqual(song.Album, 'TestAlbum')
Beispiel #2
0
    def setUp(self):
        pathlib.Path(LibraryTest.FOLDER).mkdir(exist_ok=True)

        usrcfg = userconfig.UserConfig()
        usrcfg['library'] = {}
        usrcfg['library']['music_directory'] = self.FOLDER
        usrcfg['library']['playlist_directory'] = self.FOLDER

        self.library = Library(appconfig.Testing, usrcfg)

        (pathlib.Path(self.FOLDER) / 'fake.png').touch()
        (pathlib.Path(self.FOLDER) / 'fakefolder').mkdir()

        # Create 8 songs on 4 different album from 2 different artist
        for index, path in enumerate(LibraryTest.DST_FILE):
            shutil.copy(LibraryTest.SRC_FILE, path)
            song = Song(Path=path)
            song.read_tags()
            song.Title = 'Title' + str(index)
            song.AlbumArtist = 'Artist' + str(int(index / 4))
            song.Artist = 'Artist' + str(int(index / 4))
            song.Album = 'Album' + str(int(index / 2))
            song.write_tags()

        playlist = M3uParser(LibraryTest.PLAYLIST_FILE)
        for path in LibraryTest.DST_FILE:
            playlist.append(pathlib.Path(path).name)
        playlist.write()
Beispiel #3
0
    def __sync_songs(self):
        paths = []
        # Create a list of every potential file in the music folder
        for x in pathlib.Path(self.musics_folder).glob('**/*'):
            try:
                if x.is_dir():
                    continue
                if x.suffix.lower() in self.INGORE_EXTENSION:
                    continue
                paths.append(str(x.resolve(False)))
            except OSError:
                self.logger.exception('Error while scanning songs')

        all_paths = set(paths)
        known_paths = {x.Path for x in Song.select(Song.Path)}
        new_paths = all_paths - known_paths
        deleted_paths = known_paths - all_paths

        with database_context.atomic():
            for index, path in enumerate(new_paths):
                mime = mimetypes.guess_type(path)
                if mime[0] and 'audio' in str(
                        mime[0]) and 'mpegurl' not in str(mime[0]):
                    s = Song(Path=path)
                    s.read_tags()
                    s.save()
                if index % 300 == 0 and index > 0:
                    self.logger.info(
                        f'Scanning songs {index}/{len(new_paths)}')

            for song in deleted_paths:
                Song.delete().where(Song.Path == song).execute()

        self.logger.info(f'Scanning songs completed')
Beispiel #4
0
    def __init__(self, appconfig, userconfig):
        self.logger = logging.getLogger('Library')
        database_context.init(appconfig.DATABASE_FILE)

        Song.create_table(True)
        Album.create_table(True)
        Artist.create_table(True)
        Playlist.create_table(True)

        self.appconfig = appconfig
        self.userconfig = userconfig
Beispiel #5
0
    def test_sync(self):
        self.library.sync()

        time.sleep(1)
        self.assertEqual(Song.select().count(), 8)
        self.assertEqual(Artist.select().count(), 2)
        self.assertEqual(Album.select().count(), 4)
        self.assertEqual(Playlist.select().count(), 1)

        self.library.sync()

        self.assertEqual(Song.select().count(), 8)
        self.assertEqual(Artist.select().count(), 2)
        self.assertEqual(Album.select().count(), 4)
        self.assertEqual(Playlist.select().count(), 1)
Beispiel #6
0
 def __init__(self, album=None, song_path=None):
     if album:
         self.album = album
     elif song_path:
         song = Song.get(Song.Path == song_path)
         self.album = Album.get(
             Album.Name == song.Album,
             peewee.fn.lower(Album.Artist) == song.AlbumArtist.lower())
Beispiel #7
0
    def test_sync_with_add(self):
        self.library.sync()

        new_song_path = './test/library/songa.ogg'
        shutil.copy(LibraryTest.SRC_FILE, new_song_path)

        song = Song(Path=new_song_path)
        song.read_tags()
        song.Title = 'Title!'
        song.Artist = 'Artist!'
        song.Album = 'Album!'
        song.write_tags()

        self.library.sync()

        self.assertEqual(Song.select().count(), 9)
        self.assertEqual(Artist.select().count(), 3)
        self.assertEqual(Album.select().count(), 5)
Beispiel #8
0
    def collections(self, order=AbstractPlaylist.OrderBy.DEFAULT, desc=False):
        field = [
            -Song.Added,
            peewee.fn.strip_articles(Song.AlbumArtist), Song.Year,
            peewee.fn.strip_articles(Song.Album), Song.Discnumber,
            Song.Tracknumber
        ]
        if desc:
            field[0] = Song.Added

        return Song.select().order_by(*field).limit(150)
Beispiel #9
0
    def test_sync_with_delete(self):
        self.library.sync()

        for index, path in enumerate(LibraryTest.DST_FILE):
            if index != 0:
                pathlib.Path(path).unlink()

        pathlib.Path(self.PLAYLIST_FILE).unlink()

        self.library.sync()

        self.assertEqual(Song.select().count(), 1)
        self.assertEqual(Album.select().count(), 1)
        self.assertEqual(Artist.select().count(), 1)
        self.assertEqual(Playlist.select().count(), 0)
Beispiel #10
0
    def collections(self, order=AbstractPlaylist.OrderBy.DEFAULT, desc=False):
        paths = list(self.parser)
        if desc:
            paths = list(reversed(self.parser))

        playlist_folder = pathlib.Path(self.parser.location).parent
        query = Song.select().where(
            Song.Path << paths
            | Song.Path << [playlist_folder / (path) for path in paths])

        if order == self.OrderBy.DEFAULT:
            result = {x.Path: x for x in query}
            for path in paths:
                if path in result:
                    yield result[path]
                else:
                    path_abs = str(playlist_folder / (path))
                    if path_abs in result:
                        yield result[path_abs]
        else:
            for song in (query.order_by(
                    *self.get_orderby_fields(order, desc))):
                yield song
Beispiel #11
0
 def collections(self, order=AbstractPlaylist.OrderBy.DEFAULT, desc=False):
     return (Song.select().where(
         Song.AlbumArtist == self.artist.Name).order_by(
             peewee.fn.strip_articles(Song.AlbumArtist), -Song.Year,
             peewee.fn.strip_articles(Song.Album), Song.Discnumber,
             Song.Tracknumber))
Beispiel #12
0
    def collections(self, order=AbstractPlaylist.OrderBy.DEFAULT, desc=False):
        if order == self.OrderBy.DEFAULT:
            order = self.OrderBy.ARTIST

        return Song.select().order_by(*self.get_orderby_fields(order, desc))
Beispiel #13
0
 def collections(self, order=AbstractPlaylist.OrderBy.DEFAULT, desc=False):
     field = Song.Last_played.asc() if desc else Song.Last_played.desc()
     return Song.select().where(Song.Played != 0).order_by(field).limit(25)
Beispiel #14
0
 def collections(self, order=AbstractPlaylist.OrderBy.DEFAULT, desc=False):
     return Song.select().where(Song.Album == self.album.Name).where(
         peewee.fn.lower(Song.AlbumArtist) ==
         self.album.Artist.lower()).order_by(Song.Discnumber,
                                             Song.Tracknumber)
Beispiel #15
0
 def test_write_tags(self):
     shutil.copy(TagsTest.SRC_FILE, TagsTest.DST_FILE)
     song = Song(Path=TagsTest.DST_FILE)
     song.read_tags()
     song.Title = 'Title 2'
     song.Artist = 'Artist 2'
     song.Album = 'Album 2'
     song.AlbumArtist = 'AlbumArtist 2'
     song.write_tags()
     song.read_tags()
     self.assertEqual(song.Title, 'Title 2')
     self.assertEqual(song.Artist, 'Artist 2')
     self.assertEqual(song.Album, 'Album 2')
     self.assertEqual(song.AlbumArtist, 'AlbumArtist 2')
Beispiel #16
0
 def test_save_invalid_file(self):
     with self.assertLogs(level=logging.ERROR):
         tmp = Song(Path='invalid/99999999/file')
         tmp.write_tags()
Beispiel #17
0
 def get_songs(self, paths):
     return Song.select().where(Song.Path << paths)
Beispiel #18
0
 def get_song(self, path):
     try:
         path = str(pathlib.Path(path).resolve(False))
         return Song.get(Song.Path == path)
     except:
         return None
Beispiel #19
0
 def collections(self, order=AbstractPlaylist.OrderBy.DEFAULT, desc=False):
     result = {x.Path: x for x in Song.select()}
     for path in list(self.queue):
         if not path == self.queue.peek() and path in result:
             yield result[path]
Beispiel #20
0
 def __init__(self, artist=None, song_path=None):
     if artist:
         self.artist = artist
     elif song_path:
         song = Song.get(Song.Path == song_path)
         self.artist = Artist.get(Artist.Name == song.AlbumArtist)