def search3(self, request, *args, **kwargs): data = request.GET or request.POST query = str(data.get("query", "")).replace("*", "") actor = utils.get_actor_from_request(request) conf = [ { "subsonic": "artist", "search_fields": ["name"], "queryset": (music_models.Artist.objects.with_albums_count().values( "id", "_albums_count", "name")), "serializer": lambda qs: [serializers.get_artist_data(a) for a in qs], }, { "subsonic": "album", "search_fields": ["title"], "queryset": (music_models.Album.objects.with_tracks_count().select_related( "artist")), "serializer": serializers.get_album_list2_data, }, { "subsonic": "song", "search_fields": ["title"], "queryset": (music_models.Track.objects.prefetch_related( "uploads").select_related("album__artist")), "serializer": serializers.get_song_list_data, }, ] payload = {"searchResult3": {}} for c in conf: offsetKey = "{}Offset".format(c["subsonic"]) countKey = "{}Count".format(c["subsonic"]) try: offset = int(data[offsetKey]) except (TypeError, KeyError, ValueError): offset = 0 try: size = int(data[countKey]) except (TypeError, KeyError, ValueError): size = 20 size = min(size, 100) queryset = c["queryset"] if query: queryset = c["queryset"].filter( utils.get_query(query, c["search_fields"])) queryset = queryset.playable_by(actor) queryset = common_utils.order_for_search(queryset, c["search_fields"][0]) queryset = queryset[offset:offset + size] payload["searchResult3"][c["subsonic"]] = c["serializer"](queryset) return response.Response(payload)
def get_tracks(self, query): search_fields = [ "mbid", "title__unaccent", "album__title__unaccent", "artist__name__unaccent", ] if settings.USE_FULL_TEXT_SEARCH: query_obj = utils.get_fts_query( query, fts_fields=["body_text", "album__body_text", "artist__body_text"], model=models.Track, ) else: query_obj = utils.get_query(query, search_fields) qs = ( models.Track.objects.all() .filter(query_obj) .prefetch_related( "artist", "attributed_to", Prefetch( "album", queryset=models.Album.objects.select_related( "artist", "attachment_cover", "attributed_to" ), ), ) ) return common_utils.order_for_search(qs, "title")[: self.max_results]
def get_albums(self, query): query_obj = utils.get_fts_query( query, fts_fields=["body_text", "artist__body_text"], model=models.Album) qs = (models.Album.objects.all().filter(query_obj).select_related( "artist", "attachment_cover", "attributed_to").prefetch_related("tracks__artist")) return common_utils.order_for_search(qs, "title")[:self.max_results]
def get_artists(self, query): search_fields = ["mbid", "name__unaccent"] if settings.USE_FULL_TEXT_SEARCH: query_obj = utils.get_fts_query(query, model=models.Artist) else: query_obj = utils.get_query(query, search_fields) qs = ( models.Artist.objects.all() .filter(query_obj) .with_albums() .prefetch_related("channel__actor") .select_related("attributed_to") ) return common_utils.order_for_search(qs, "name")[: self.max_results]
def get_tags(self, query): search_fields = ["name__unaccent"] query_obj = utils.get_query(query, search_fields) qs = Tag.objects.all().filter(query_obj) return common_utils.order_for_search(qs, "name")[: self.max_results]
def get_artists(self, query): query_obj = utils.get_fts_query(query, model=models.Artist) qs = (models.Artist.objects.all().filter(query_obj).with_albums( ).prefetch_related("channel__actor").select_related("attributed_to")) return common_utils.order_for_search(qs, "name")[:self.max_results]