1
0
mirror of https://github.com/spl0k/supysonic.git synced 2024-12-22 08:56:17 +00:00

Album listing filtered by year or genre

Closes #47
This commit is contained in:
Alban Féron 2020-11-10 14:21:51 +01:00
parent 883623c558
commit c2f5ec43b9
No known key found for this signature in database
GPG Key ID: 8CE0313646D16165
3 changed files with 116 additions and 12 deletions

View File

@ -274,9 +274,9 @@ No parameter
| `type` | | ✔️ | | `type` | | ✔️ |
| `size` | | ✔️ | | `size` | | ✔️ |
| `offset` | | ✔️ | | `offset` | | ✔️ |
| `fromYear` | 1.10.1 | 📅 | | `fromYear` | | ✔️ |
| `toYear` | 1.10.1 | 📅 | | `toYear` | | ✔️ |
| `genre` | 1.10.1 | 📅 | | `genre` | | ✔️ |
| `musicFolderId` | 1.12.0 | 📅 | | `musicFolderId` | 1.12.0 | 📅 |
On 1.10.1, `byYear` and `byGenre` were added to `type` On 1.10.1, `byYear` and `byGenre` were added to `type`
@ -289,9 +289,9 @@ On 1.10.1, `byYear` and `byGenre` were added to `type`
| `type` | | ✔️ | | `type` | | ✔️ |
| `size` | | ✔️ | | `size` | | ✔️ |
| `offset` | | ✔️ | | `offset` | | ✔️ |
| `fromYear` | 1.10.1 | 📅 | | `fromYear` | | ✔️ |
| `toYear` | 1.10.1 | 📅 | | `toYear` | | ✔️ |
| `genre` | 1.10.1 | 📅 | | `genre` | | ✔️ |
| `musicFolderId` | 1.12.0 | 📅 | | `musicFolderId` | 1.12.0 | 📅 |
On 1.10.1, `byYear` and `byGenre` were added to `type` On 1.10.1, `byYear` and `byGenre` were added to `type`

View File

@ -7,7 +7,7 @@
from datetime import timedelta from datetime import timedelta
from flask import request from flask import request
from pony.orm import select, desc, avg, max, min, count from pony.orm import select, desc, avg, max, min, count, between
from ..db import ( from ..db import (
Folder, Folder,
@ -107,6 +107,19 @@ def album_list():
query = query.sort_by(Folder.name).distinct() query = query.sort_by(Folder.name).distinct()
elif ltype == "alphabeticalByArtist": elif ltype == "alphabeticalByArtist":
query = query.sort_by(lambda f: f.parent.name + f.name) query = query.sort_by(lambda f: f.parent.name + f.name)
elif ltype == "byYear":
startyear = int(request.values["fromYear"])
endyear = int(request.values["toYear"])
query = query.where(
lambda t: between(t.year, min(startyear, endyear), max(startyear, endyear))
)
if endyear < startyear:
query = query.sort_by(lambda f: desc(min(f.tracks.year)))
else:
query = query.sort_by(lambda f: min(f.tracks.year))
elif ltype == "byGenre":
genre = request.values["genre"]
query = query.where(lambda t: t.genre == genre)
else: else:
raise GenericError("Unknown search type") raise GenericError("Unknown search type")
@ -146,6 +159,21 @@ def album_list_id3():
query = query.order_by(Album.name) query = query.order_by(Album.name)
elif ltype == "alphabeticalByArtist": elif ltype == "alphabeticalByArtist":
query = query.order_by(lambda a: a.artist.name + a.name) query = query.order_by(lambda a: a.artist.name + a.name)
elif ltype == "byYear":
startyear = int(request.values["fromYear"])
endyear = int(request.values["toYear"])
query = query.where(
lambda a: between(
min(a.tracks.year), min(startyear, endyear), max(startyear, endyear)
)
)
if endyear < startyear:
query = query.order_by(lambda a: desc(min(a.tracks.year)))
else:
query = query.order_by(lambda a: min(a.tracks.year))
elif ltype == "byGenre":
genre = request.values["genre"]
query = query.where(lambda a: genre in a.tracks.genre)
else: else:
raise GenericError("Unknown search type") raise GenericError("Unknown search type")

View File

@ -1,10 +1,9 @@
#!/usr/bin/env python #!/usr/bin/env python
# coding: utf-8
# #
# This file is part of Supysonic. # This file is part of Supysonic.
# Supysonic is a Python implementation of the Subsonic server API. # Supysonic is a Python implementation of the Subsonic server API.
# #
# Copyright (C) 2017 Alban 'spl0k' Féron # Copyright (C) 2017-2020 Alban 'spl0k' Féron
# #
# Distributed under terms of the GNU AGPLv3 license. # Distributed under terms of the GNU AGPLv3 license.
@ -35,6 +34,7 @@ class AlbumSongsTestCase(ApiTestBase):
artist=artist, artist=artist,
disc=1, disc=1,
number=1, number=1,
year=123,
path="tests/assets/folder/1", path="tests/assets/folder/1",
folder=folder, folder=folder,
root_folder=folder, root_folder=folder,
@ -48,6 +48,8 @@ class AlbumSongsTestCase(ApiTestBase):
artist=artist, artist=artist,
disc=1, disc=1,
number=1, number=1,
year=124,
genre="Lampshade",
path="tests/assets/folder/2", path="tests/assets/folder/2",
folder=folder, folder=folder,
root_folder=folder, root_folder=folder,
@ -63,6 +65,13 @@ class AlbumSongsTestCase(ApiTestBase):
self._make_request( self._make_request(
"getAlbumList", {"type": "newest", "offset": "minus one"}, error=0 "getAlbumList", {"type": "newest", "offset": "minus one"}, error=0
) )
self._make_request("getAlbumList", {"type": "byYear"}, error=10)
self._make_request(
"getAlbumList",
{"type": "byYear", "fromYear": "Epoch", "toYear": "EOL"},
error=0,
)
self._make_request("getAlbumList", {"type": "byGenre"}, error=10)
types_and_count = [ types_and_count = [
("random", 1), ("random", 1),
@ -79,10 +88,40 @@ class AlbumSongsTestCase(ApiTestBase):
] ]
for t, c in types_and_count: for t, c in types_and_count:
rv, child = self._make_request( rv, child = self._make_request(
"getAlbumList", {"type": t}, tag="albumList", skip_post=True "getAlbumList", {"type": t}, tag="albumList", skip_post=t == "random"
) )
self.assertEqual(len(child), c) self.assertEqual(len(child), c)
rv, child = self._make_request(
"getAlbumList",
{"type": "byYear", "fromYear": 100, "toYear": 200},
tag="albumList",
)
self.assertEqual(len(child), 1)
rv, child = self._make_request(
"getAlbumList",
{"type": "byYear", "fromYear": 200, "toYear": 300},
tag="albumList",
)
self.assertEqual(len(child), 0)
# Need more data to properly test ordering
rv, child = self._make_request(
"getAlbumList",
{"type": "byYear", "fromYear": 200, "toYear": 100},
tag="albumList",
)
self.assertEqual(len(child), 1)
rv, child = self._make_request(
"getAlbumList", {"type": "byGenre", "genre": "FARTS"}, tag="albumList"
)
self.assertEqual(len(child), 0)
rv, child = self._make_request(
"getAlbumList", {"type": "byGenre", "genre": "Lampshade"}, tag="albumList"
)
self.assertEqual(len(child), 1)
with db_session: with db_session:
Folder.get().delete() Folder.get().delete()
rv, child = self._make_request( rv, child = self._make_request(
@ -99,6 +138,13 @@ class AlbumSongsTestCase(ApiTestBase):
self._make_request( self._make_request(
"getAlbumList2", {"type": "newest", "offset": "&v + 2"}, error=0 "getAlbumList2", {"type": "newest", "offset": "&v + 2"}, error=0
) )
self._make_request("getAlbumList2", {"type": "byYear"}, error=10)
self._make_request(
"getAlbumList2",
{"type": "byYear", "fromYear": "Epoch", "toYear": "EOL"},
error=0,
)
self._make_request("getAlbumList2", {"type": "byGenre"}, error=10)
types = [ types = [
"random", "random",
@ -111,13 +157,43 @@ class AlbumSongsTestCase(ApiTestBase):
] ]
for t in types: for t in types:
self._make_request( self._make_request(
"getAlbumList2", {"type": t}, tag="albumList2", skip_post=True "getAlbumList2", {"type": t}, tag="albumList2", skip_post=t == "random"
) )
rv, child = self._make_request( self._make_request(
"getAlbumList2", {"type": "random"}, tag="albumList2", skip_post=True "getAlbumList2", {"type": "random"}, tag="albumList2", skip_post=True
) )
rv, child = self._make_request(
"getAlbumList2",
{"type": "byYear", "fromYear": 100, "toYear": 200},
tag="albumList2",
)
self.assertEqual(len(child), 1)
rv, child = self._make_request(
"getAlbumList2",
{"type": "byYear", "fromYear": 200, "toYear": 300},
tag="albumList2",
)
self.assertEqual(len(child), 0)
# Need more data to properly test ordering
rv, child = self._make_request(
"getAlbumList2",
{"type": "byYear", "fromYear": 200, "toYear": 100},
tag="albumList2",
)
self.assertEqual(len(child), 1)
rv, child = self._make_request(
"getAlbumList2", {"type": "byGenre", "genre": "FARTS"}, tag="albumList2"
)
self.assertEqual(len(child), 0)
rv, child = self._make_request(
"getAlbumList2", {"type": "byGenre", "genre": "Lampshade"}, tag="albumList2"
)
self.assertEqual(len(child), 1)
with db_session: with db_session:
Track.select().delete() Track.select().delete()
Album.get().delete() Album.get().delete()