diff --git a/supysonic/api/search.py b/supysonic/api/search.py index a56072d..90acc86 100644 --- a/supysonic/api/search.py +++ b/supysonic/api/search.py @@ -28,22 +28,32 @@ def old_search(): min_date = datetime.fromtimestamp(newer_than) if artist: - query = select( - t.folder.parent - for t in Track - if artist in t.folder.parent.name and t.folder.parent.created > min_date + Child = Folder.alias() + query = ( + Folder.select() + .join(Child, on=Child.parent == Folder.id) + .join(Track, on=Track.folder == Child.id) + .where(Folder.name.contains(artist), Folder.created > min_date) + .distinct() ) elif album: - query = select( - t.folder - for t in Track - if album in t.folder.name and t.folder.created > min_date + query = ( + Folder.select() + .join(Track, on=Track.folder) + .where(Folder.name.contains(album), Folder.created > min_date) + .distinct() ) elif title: - query = Track.select(lambda t: title in t.title and t.created > min_date) + query = Track.select().where( + Track.title.contains(title), Track.created > min_date + ) elif anyf: - folders = Folder.select(lambda f: anyf in f.name and f.created > min_date) - tracks = Track.select(lambda t: anyf in t.title and t.created > min_date) + folders = Folder.select().where( + Folder.name.contains(anyf), Folder.created > min_date + ) + tracks = Track.select().where( + Track.title.contains(anyf), Track.created > min_date + ) res = folders[offset : offset + count] fcount = folders.count() if offset + count > fcount: @@ -114,18 +124,30 @@ def new_search(): song_offset = int(song_offset) if song_offset else 0 root = get_root_folder(mfid) - artists = select(t.folder.parent for t in Track if query in t.folder.parent.name) - albums = select(t.folder for t in Track if query in t.folder.name) - songs = Track.select(lambda t: query in t.title) + Child = Folder.alias() + artists = ( + Folder.select() + .join(Child, on=Child.parent == Folder.id) + .join(Track, on=Track.folder == Child.id) + .where(Folder.name.contains(query)) + .distinct() + ) + albums = ( + Folder.select() + .join(Track, on=Track.folder) + .where(Folder.name.contains(query)) + .distinct() + ) + songs = Track.select().where(Track.title.contains(query)) if root is not None: - artists = artists.where(lambda t: t.root_folder == root) - albums = albums.where(lambda t: t.root_folder == root) - songs = songs.where(lambda t: t.root_folder == root) + artists = artists.where(Track.root_folder == root) + albums = albums.where(Track.root_folder == root) + songs = songs.where(Track.root_folder == root) - artists = artists.limit(artist_count, artist_offset) - albums = albums.limit(album_count, album_offset) - songs = songs.limit(song_count, song_offset) + artists = artists.limit(artist_count).offset(artist_offset) + albums = albums.limit(album_count).offset(album_offset) + songs = songs.limit(song_count).offset(song_offset) return request.formatter( "searchResult2", @@ -174,18 +196,18 @@ def search_id3(): song_offset = int(song_offset) if song_offset else 0 root = get_root_folder(mfid) - artists = Artist.select(lambda a: query in a.name) - albums = Album.select(lambda a: query in a.name) - songs = Track.select(lambda t: query in t.title) + artists = Artist.select().where(Artist.name.contains(query)) + albums = Album.select().where(Album.name.contains(query)) + songs = Track.select().where(Track.title.contains(query)) if root is not None: - artists = artists.where(lambda a: root in a.tracks.root_folder) - albums = albums.where(lambda a: root in a.tracks.root_folder) - songs = songs.where(lambda t: t.root_folder == root) + artists = artists.join(Track).where(Track.root_folder == root) + albums = albums.join(Track).where(Track.root_folder == root) + songs = songs.where(Track.root_folder == root) - artists = artists.limit(artist_count, artist_offset) - albums = albums.limit(album_count, album_offset) - songs = songs.limit(song_count, song_offset) + artists = artists.limit(artist_count).offset(artist_offset) + albums = albums.limit(album_count).offset(album_offset) + songs = songs.limit(song_count).offset(song_offset) return request.formatter( "searchResult3", diff --git a/tests/api/test_search.py b/tests/api/test_search.py index af63391..3aa71e8 100644 --- a/tests/api/test_search.py +++ b/tests/api/test_search.py @@ -8,8 +8,6 @@ import time import unittest -from pony.orm import db_session, commit - from supysonic.db import Folder, Artist, Album, Track from .apitestbase import ApiTestBase @@ -19,50 +17,49 @@ class SearchTestCase(ApiTestBase): def setUp(self): super().setUp() - with db_session: - root = Folder(root=True, name="Root folder", path="tests/assets") - Folder(root=True, name="Empty", path="/tmp") + root = Folder.create(root=True, name="Root folder", path="tests/assets") + Folder.create(root=True, name="Empty", path="/tmp") - for letter in "ABC": - folder = Folder( - name=letter + "rtist", - path="tests/assets/{}rtist".format(letter), - parent=root, + for letter in "ABC": + folder = Folder.create( + name=letter + "rtist", + path="tests/assets/{}rtist".format(letter), + root=False, + parent=root, + ) + artist = Artist.create(name=letter + "rtist") + + for lether in "AB": + afolder = Folder.create( + name=letter + lether + "lbum", + path="tests/assets/{0}rtist/{0}{1}lbum".format(letter, lether), + root=False, + parent=folder, ) - artist = Artist(name=letter + "rtist") - for lether in "AB": - afolder = Folder( - name=letter + lether + "lbum", - path="tests/assets/{0}rtist/{0}{1}lbum".format(letter, lether), - parent=folder, + album = Album.create(name=letter + lether + "lbum", artist=artist) + + for num, song in enumerate(["One", "Two", "Three"]): + Track.create( + disc=1, + number=num, + title=song, + duration=2, + album=album, + artist=artist, + bitrate=320, + path="tests/assets/{0}rtist/{0}{1}lbum/{2}".format( + letter, lether, song + ), + last_modification=0, + root_folder=root, + folder=afolder, ) - album = Album(name=letter + lether + "lbum", artist=artist) - - for num, song in enumerate(["One", "Two", "Three"]): - Track( - disc=1, - number=num, - title=song, - duration=2, - album=album, - artist=artist, - bitrate=320, - path="tests/assets/{0}rtist/{0}{1}lbum/{2}".format( - letter, lether, song - ), - last_modification=0, - root_folder=root, - folder=afolder, - ) - - commit() - - self.assertEqual(Folder.select().count(), 11) - self.assertEqual(Artist.select().count(), 3) - self.assertEqual(Album.select().count(), 6) - self.assertEqual(Track.select().count(), 18) + self.assertEqual(Folder.select().count(), 11) + self.assertEqual(Artist.select().count(), 3) + self.assertEqual(Album.select().count(), 6) + self.assertEqual(Track.select().count(), 18) def __track_as_pseudo_unique_str(self, elem): return elem.get("artist") + elem.get("album") + elem.get("title")