add playlist data query building

This commit is contained in:
Simon
2024-08-02 23:51:01 +02:00
parent 032a28e330
commit 49cfbd5796
6 changed files with 106 additions and 17 deletions

View File

@@ -0,0 +1,10 @@
"""playlist constants"""
import enum
class PlaylistTypesEnum(enum.Enum):
"""all playlist_type options"""
REGULAR = "regular"
CUSTOM = "custom"

View File

@@ -0,0 +1,53 @@
"""build query for playlists"""
from playlist.src.constants import PlaylistTypesEnum
class QueryBuilder:
"""contain functionality"""
def __init__(self, **kwargs):
self.request_params = kwargs
def build_data(self) -> dict:
"""build data dict"""
data = {}
data["query"] = self.build_query()
if sort := self.parse_sort():
data.update(sort)
return data
def build_query(self) -> dict:
"""build query key"""
must_list = []
channel = self.request_params.get("channel")
if channel:
must_list.append({"match": {"playlist_channel_id": channel[0]}})
subscribed = self.request_params.get("subscribed")
if subscribed:
subed_bool = subscribed[0] == "true"
must_list.append({"match": {"playlist_subscribed": subed_bool}})
playlist_type = self.request_params.get("type")
if playlist_type:
type_list = self.parse_type(playlist_type[0])
must_list.append(type_list)
query = {"bool": {"must": must_list}}
return query
def parse_type(self, playlist_type: str) -> dict:
"""parse playlist type"""
if not hasattr(PlaylistTypesEnum, playlist_type.upper()):
raise ValueError(f"'{playlist_type}' not in PlaylistTypesEnum")
type_parsed = getattr(PlaylistTypesEnum, playlist_type.upper()).value
return {"match": {"playlist_type.keyword": type_parsed}}
def parse_sort(self) -> dict:
"""return sort"""
return {"sort": [{"playlist_name.keyword": {"order": "asc"}}]}

View File

View File

@@ -0,0 +1,30 @@
"""test playlist query building"""
import pytest
from playlist.src.query_building import QueryBuilder
def test_build_data():
"""test for correct key building"""
qb = QueryBuilder(
channel=["test_channel"],
subscribed=["true"],
type=["regular"],
)
result = qb.build_data()
must_list = result["query"]["bool"]["must"]
assert "query" in result
assert "sort" in result
assert result["sort"] == [{"playlist_name.keyword": {"order": "asc"}}]
assert {"match": {"playlist_channel_id": "test_channel"}} in must_list
assert {"match": {"playlist_subscribed": True}} in must_list
def test_parse_type():
"""validate type"""
qb = QueryBuilder(type=["regular"])
with pytest.raises(ValueError):
qb.parse_type("invalid")
result = qb.parse_type("custom")
assert result == {"match": {"playlist_type.keyword": "custom"}}

View File

@@ -3,6 +3,7 @@
from common.views_base import AdminWriteOnly, ApiBaseView
from download.src.subscriptions import PlaylistSubscription
from playlist.src.index import YoutubePlaylist
from playlist.src.query_building import QueryBuilder
from rest_framework import status
from rest_framework.response import Response
from task.tasks import subscribe_to
@@ -12,31 +13,26 @@ from user.src.user_config import UserConfig
class PlaylistApiListView(ApiBaseView):
"""resolves to /api/playlist/
GET: returns list of indexed playlists
params:
- channel:str=<channel-id>
- subscribed: bool
- type:enum=regular|custom
POST: change subscribe state
"""
search_base = "ta_playlist/_search/"
permission_classes = [AdminWriteOnly]
valid_playlist_type = ["regular", "custom"]
def get(self, request):
"""handle get request"""
playlist_type = request.GET.get("playlist_type", None)
query = {"sort": [{"playlist_name.keyword": {"order": "asc"}}]}
if playlist_type is not None:
if playlist_type not in self.valid_playlist_type:
message = f"invalid playlist_type {playlist_type}"
return Response({"message": message}, status=400)
"""get request"""
try:
data = QueryBuilder(**request.GET).build_data()
except ValueError as err:
return Response({"error": str(err)}, status=400)
query.update(
{
"query": {
"term": {"playlist_type": {"value": playlist_type}}
},
}
)
self.data.update(query)
self.data = data
self.get_document_list(request)
return Response(self.response)
def post(self, request):