mirror of
https://github.com/Alexander-D-Karpov/akarpov
synced 2024-11-28 19:33:44 +03:00
Compare commits
No commits in common. "3adeb7c5a777fcbbc49c17b1fcc2ac75fb8e6771" and "4a407dfc06c9a83303d612a8cc3e0f86d85ef5df" have entirely different histories.
3adeb7c5a7
...
4a407dfc06
|
@ -1,4 +1,4 @@
|
||||||
from django_elasticsearch_dsl import Document, fields
|
from django_elasticsearch_dsl import Document
|
||||||
from django_elasticsearch_dsl.registries import registry
|
from django_elasticsearch_dsl.registries import registry
|
||||||
|
|
||||||
from akarpov.files.models import File
|
from akarpov.files.models import File
|
||||||
|
@ -6,41 +6,26 @@
|
||||||
|
|
||||||
@registry.register_document
|
@registry.register_document
|
||||||
class FileDocument(Document):
|
class FileDocument(Document):
|
||||||
name = fields.TextField(
|
|
||||||
attr="name",
|
|
||||||
fields={
|
|
||||||
"raw": fields.KeywordField(normalizer="lowercase"),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
description = fields.TextField(
|
|
||||||
attr="description",
|
|
||||||
fields={
|
|
||||||
"raw": fields.KeywordField(normalizer="lowercase"),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
content = fields.TextField(
|
|
||||||
attr="content",
|
|
||||||
fields={
|
|
||||||
"raw": fields.KeywordField(normalizer="lowercase"),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
class Django:
|
|
||||||
model = File
|
|
||||||
|
|
||||||
def prepare_description(self, instance):
|
|
||||||
return instance.description or ""
|
|
||||||
|
|
||||||
def prepare_content(self, instance):
|
|
||||||
# check instance.content is not None
|
|
||||||
return (
|
|
||||||
instance.content.decode("utf-8")
|
|
||||||
if instance.content and isinstance(instance.content, bytes)
|
|
||||||
else ""
|
|
||||||
)
|
|
||||||
|
|
||||||
class Index:
|
class Index:
|
||||||
name = "files"
|
name = "files"
|
||||||
settings = {"number_of_shards": 1, "number_of_replicas": 0}
|
settings = {"number_of_shards": 1, "number_of_replicas": 0}
|
||||||
|
|
||||||
|
class Django:
|
||||||
|
model = File
|
||||||
|
fields = [
|
||||||
|
"name",
|
||||||
|
"description",
|
||||||
|
"content",
|
||||||
|
]
|
||||||
|
|
||||||
|
def prepare_description(self, instance):
|
||||||
|
# This method is called for every instance before indexing
|
||||||
|
return instance.description or ""
|
||||||
|
|
||||||
|
def prepare_content(self, instance):
|
||||||
|
# This method is called for every instance before indexing
|
||||||
|
return (
|
||||||
|
instance.content.decode("utf-8")
|
||||||
|
if isinstance(instance.content, bytes)
|
||||||
|
else instance.content
|
||||||
|
)
|
||||||
|
|
|
@ -40,16 +40,13 @@ def search(self, query: str):
|
||||||
ES_Q(
|
ES_Q(
|
||||||
"multi_match",
|
"multi_match",
|
||||||
query=query,
|
query=query,
|
||||||
fields=["name^3", "description^2", "content"],
|
fields=["name", "description", "content"],
|
||||||
type="best_fields",
|
type="best_fields",
|
||||||
fuzziness="AUTO",
|
|
||||||
),
|
),
|
||||||
ES_Q("wildcard", name__raw=f"*{query.lower()}*"),
|
ES_Q("match_phrase_prefix", name=query),
|
||||||
ES_Q("wildcard", description__raw=f"*{query.lower()}*"),
|
ES_Q("wildcard", name=f"*{query}*"),
|
||||||
ES_Q("wildcard", content__raw=f"*{query.lower()}*"),
|
ES_Q("wildcard", description=f"*{query}*"),
|
||||||
ES_Q("wildcard", file_type__raw=f"*{query.lower()}*"),
|
ES_Q("wildcard", content=f"*{query}*"),
|
||||||
ES_Q("wildcard", file_obj__raw=f"*{query.lower()}*"),
|
|
||||||
ES_Q("wildcard", preview__raw=f"*{query.lower()}*"),
|
|
||||||
],
|
],
|
||||||
minimum_should_match=1,
|
minimum_should_match=1,
|
||||||
)
|
)
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
SongUserRating,
|
SongUserRating,
|
||||||
UserListenHistory,
|
UserListenHistory,
|
||||||
)
|
)
|
||||||
from akarpov.music.services.search import search_song
|
|
||||||
from akarpov.music.tasks import listen_to_song
|
from akarpov.music.tasks import listen_to_song
|
||||||
|
|
||||||
|
|
||||||
|
@ -84,11 +83,7 @@ class ListCreateSongAPIView(LikedSongsContextMixin, generics.ListCreateAPIView):
|
||||||
pagination_class = StandardResultsSetPagination
|
pagination_class = StandardResultsSetPagination
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
search = self.request.query_params.get("search", None)
|
qs = Song.objects.cache()
|
||||||
if search:
|
|
||||||
qs = search_song(search)
|
|
||||||
else:
|
|
||||||
qs = Song.objects.cache()
|
|
||||||
|
|
||||||
if "sort" in self.request.query_params:
|
if "sort" in self.request.query_params:
|
||||||
sorts = self.request.query_params["sort"].split(",")
|
sorts = self.request.query_params["sort"].split(",")
|
||||||
|
@ -116,12 +111,6 @@ def get_queryset(self):
|
||||||
|
|
||||||
@extend_schema(
|
@extend_schema(
|
||||||
parameters=[
|
parameters=[
|
||||||
OpenApiParameter(
|
|
||||||
name="search",
|
|
||||||
description="Search query",
|
|
||||||
required=False,
|
|
||||||
type=str,
|
|
||||||
),
|
|
||||||
OpenApiParameter(
|
OpenApiParameter(
|
||||||
name="sort",
|
name="sort",
|
||||||
description="Sorting algorithm",
|
description="Sorting algorithm",
|
||||||
|
|
|
@ -1,67 +0,0 @@
|
||||||
from django_elasticsearch_dsl import Document, fields
|
|
||||||
from django_elasticsearch_dsl.registries import registry
|
|
||||||
|
|
||||||
from akarpov.music.models import Song
|
|
||||||
|
|
||||||
|
|
||||||
@registry.register_document
|
|
||||||
class SongDocument(Document):
|
|
||||||
authors = fields.NestedField(
|
|
||||||
attr="authors",
|
|
||||||
properties={
|
|
||||||
"name": fields.TextField(
|
|
||||||
fields={
|
|
||||||
"raw": fields.KeywordField(normalizer="lowercase"),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
"link": fields.TextField(),
|
|
||||||
"meta": fields.ObjectField(dynamic=True),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
album = fields.NestedField(
|
|
||||||
attr="album",
|
|
||||||
properties={
|
|
||||||
"name": fields.TextField(
|
|
||||||
fields={
|
|
||||||
"raw": fields.KeywordField(normalizer="lowercase"),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
"link": fields.TextField(),
|
|
||||||
"meta": fields.ObjectField(dynamic=True),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
name = fields.TextField(
|
|
||||||
attr="name",
|
|
||||||
fields={
|
|
||||||
"raw": fields.KeywordField(normalizer="lowercase"),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
meta = fields.ObjectField(dynamic=True) # Added meta field here as dynamic object
|
|
||||||
|
|
||||||
class Index:
|
|
||||||
name = "songs"
|
|
||||||
settings = {"number_of_shards": 1, "number_of_replicas": 0}
|
|
||||||
# settings = {
|
|
||||||
# "number_of_shards": 1,
|
|
||||||
# "number_of_replicas": 0,
|
|
||||||
# "analysis": {
|
|
||||||
# "analyzer": {
|
|
||||||
# "russian_icu": {
|
|
||||||
# "type": "custom",
|
|
||||||
# "tokenizer": "icu_tokenizer",
|
|
||||||
# "filter": ["icu_folding","icu_normalizer"]
|
|
||||||
# }
|
|
||||||
# }
|
|
||||||
# }
|
|
||||||
# } TODO
|
|
||||||
|
|
||||||
class Django:
|
|
||||||
model = Song
|
|
||||||
|
|
||||||
def get_instances_from_related(self, related_instance):
|
|
||||||
if isinstance(related_instance, Song):
|
|
||||||
return related_instance.album
|
|
||||||
return related_instance.songs.all()
|
|
|
@ -1,47 +0,0 @@
|
||||||
from django.db.models import Case, When
|
|
||||||
from elasticsearch_dsl import Q as ES_Q
|
|
||||||
|
|
||||||
from akarpov.music.documents import SongDocument
|
|
||||||
from akarpov.music.models import Song
|
|
||||||
|
|
||||||
|
|
||||||
def search_song(query):
|
|
||||||
search = SongDocument.search()
|
|
||||||
search_query = ES_Q(
|
|
||||||
"bool",
|
|
||||||
should=[
|
|
||||||
ES_Q(
|
|
||||||
"multi_match",
|
|
||||||
query=query,
|
|
||||||
fields=["name^3", "authors.name^2", "album.name"],
|
|
||||||
fuzziness="AUTO",
|
|
||||||
), # Change here
|
|
||||||
ES_Q("wildcard", name__raw=f"*{query.lower()}*"),
|
|
||||||
ES_Q(
|
|
||||||
"nested",
|
|
||||||
path="authors",
|
|
||||||
query=ES_Q("wildcard", authors__name__raw=f"*{query.lower()}*"),
|
|
||||||
),
|
|
||||||
ES_Q(
|
|
||||||
"nested",
|
|
||||||
path="album",
|
|
||||||
query=ES_Q("wildcard", album__name__raw=f"*{query.lower()}*"),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
minimum_should_match=1,
|
|
||||||
)
|
|
||||||
|
|
||||||
search = search.query(search_query)
|
|
||||||
|
|
||||||
response = search.execute()
|
|
||||||
|
|
||||||
# Check for hits and get song instances
|
|
||||||
if response.hits:
|
|
||||||
hit_ids = [hit.meta.id for hit in response.hits]
|
|
||||||
songs = Song.objects.filter(id__in=hit_ids).order_by(
|
|
||||||
Case(*[When(pk=pk, then=pos) for pos, pk in enumerate(hit_ids)])
|
|
||||||
)
|
|
||||||
|
|
||||||
return songs
|
|
||||||
|
|
||||||
return Song.objects.none()
|
|
|
@ -48,14 +48,6 @@ COPY ./compose/production/django/entrypoint /entrypoint
|
||||||
RUN sed -i 's/\r$//g' /entrypoint
|
RUN sed -i 's/\r$//g' /entrypoint
|
||||||
RUN chmod +x /entrypoint
|
RUN chmod +x /entrypoint
|
||||||
|
|
||||||
COPY ./compose/production/django/manage /manage
|
|
||||||
RUN sed -i 's/\r$//g' /manage
|
|
||||||
RUN chmod +x /manage
|
|
||||||
|
|
||||||
COPY ./compose/production/django/manage /manage.py
|
|
||||||
RUN sed -i 's/\r$//g' /manage
|
|
||||||
RUN chmod +x /manage
|
|
||||||
|
|
||||||
COPY ./compose/local/django/start /start
|
COPY ./compose/local/django/start /start
|
||||||
RUN sed -i 's/\r$//g' /start
|
RUN sed -i 's/\r$//g' /start
|
||||||
RUN chmod +x /start
|
RUN chmod +x /start
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -o errexit
|
|
||||||
set -o pipefail
|
|
||||||
set -o nounset
|
|
||||||
|
|
||||||
if [ -z "${POSTGRES_USER}" ]; then
|
|
||||||
base_postgres_image_default_user='postgres'
|
|
||||||
export POSTGRES_USER="${base_postgres_image_default_user}"
|
|
||||||
fi
|
|
||||||
export DATABASE_URL="postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}"
|
|
||||||
|
|
||||||
|
|
||||||
exec /venv/bin/python /app/manage.py "$@"
|
|
Loading…
Reference in New Issue
Block a user