Compare commits

..

1 Commits

Author SHA1 Message Date
dependabot[bot]
9f18605069
Bump werkzeug from 2.3.8 to 3.0.1
Bumps [werkzeug](https://github.com/pallets/werkzeug) from 2.3.8 to 3.0.1.
- [Release notes](https://github.com/pallets/werkzeug/releases)
- [Changelog](https://github.com/pallets/werkzeug/blob/main/CHANGES.rst)
- [Commits](https://github.com/pallets/werkzeug/compare/2.3.8...3.0.1)

---
updated-dependencies:
- dependency-name: werkzeug
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-17 21:44:23 +00:00
14 changed files with 979 additions and 1165 deletions

View File

@ -13,11 +13,6 @@
from ..documents import FileDocument from ..documents import FileDocument
from .lema import lemmatize_and_remove_stopwords from .lema import lemmatize_and_remove_stopwords
"""
Calculus on types of searches:
https://new.akarpov.ru/files/FZUTFBIyfbdlDHVzxUNU
"""
class BaseSearch: class BaseSearch:
def __init__(self, queryset: QuerySet | None = None): def __init__(self, queryset: QuerySet | None = None):

View File

@ -92,7 +92,9 @@ def get_queryset(self):
): ):
return self.filter(BaseFileItem.objects.none()) return self.filter(BaseFileItem.objects.none())
return self.filter( return self.filter(
BaseFileItem.objects.filter(user=self.request.user, parent__isnull=True) BaseFileItem.objects.cache().filter(
user=self.request.user, parent__isnull=True
)
) )

View File

@ -7,8 +7,10 @@ class MusicConfig(AppConfig):
name = "akarpov.music" name = "akarpov.music"
def ready(self): def ready(self):
try:
import akarpov.music.signals # noqa F401 import akarpov.music.signals # noqa F401
except ImportError:
pass
try: try:
from akarpov.music.tasks import start_next_song from akarpov.music.tasks import start_next_song

View File

@ -1,27 +0,0 @@
# Generated by Django 4.2.8 on 2023-12-17 22:22
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("music", "0011_alter_playlist_private_userlistenhistory"),
]
operations = [
migrations.AddField(
model_name="album",
name="meta",
field=models.JSONField(blank=True, null=True),
),
migrations.AddField(
model_name="author",
name="albums",
field=models.ManyToManyField(related_name="authors", to="music.album"),
),
migrations.AddField(
model_name="author",
name="meta",
field=models.JSONField(blank=True, null=True),
),
]

View File

@ -1,31 +0,0 @@
# Generated by Django 4.2.8 on 2023-12-18 11:44
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("music", "0012_album_meta_author_albums_author_meta"),
]
operations = [
migrations.RemoveField(
model_name="author",
name="albums",
),
migrations.AddField(
model_name="album",
name="authors",
field=models.ManyToManyField(related_name="albums", to="music.album"),
),
migrations.AlterField(
model_name="album",
name="name",
field=models.CharField(max_length=200, unique=True),
),
migrations.AlterField(
model_name="author",
name="name",
field=models.CharField(max_length=200, unique=True),
),
]

View File

@ -1,17 +0,0 @@
# Generated by Django 4.2.8 on 2023-12-18 14:30
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("music", "0013_remove_author_albums_album_authors_alter_album_name_and_more"),
]
operations = [
migrations.AlterField(
model_name="album",
name="authors",
field=models.ManyToManyField(related_name="albums", to="music.author"),
),
]

View File

@ -8,9 +8,8 @@
class Author(BaseImageModel, ShortLinkModel): class Author(BaseImageModel, ShortLinkModel):
name = models.CharField(max_length=200, unique=True) name = models.CharField(max_length=200)
link = models.URLField(blank=True) link = models.URLField(blank=True)
meta = models.JSONField(blank=True, null=True)
def get_absolute_url(self): def get_absolute_url(self):
return reverse("music:author", kwargs={"slug": self.slug}) return reverse("music:author", kwargs={"slug": self.slug})
@ -20,10 +19,8 @@ def __str__(self):
class Album(BaseImageModel, ShortLinkModel): class Album(BaseImageModel, ShortLinkModel):
name = models.CharField(max_length=200, unique=True) name = models.CharField(max_length=200)
link = models.URLField(blank=True) link = models.URLField(blank=True)
meta = models.JSONField(blank=True, null=True)
authors = models.ManyToManyField("Author", related_name="albums")
def get_absolute_url(self): def get_absolute_url(self):
return reverse("music:album", kwargs={"slug": self.slug}) return reverse("music:album", kwargs={"slug": self.slug})

View File

@ -27,28 +27,16 @@ def load_track(
if album and type(album) is str and album.startswith("['"): if album and type(album) is str and album.startswith("['"):
album = album.replace("['", "").replace("']", "") album = album.replace("['", "").replace("']", "")
re_authors = []
if authors: if authors:
for x in authors: authors = [Author.objects.get_or_create(name=x)[0] for x in authors if authors]
try: else:
re_authors.append(Author.objects.get(name=x)) authors = []
except Author.DoesNotExist:
re_authors.append(Author.objects.create(name=x))
authors = re_authors
album_name = None
if album: if album:
if type(album) is str: if type(album) is str:
album_name = album album = Album.objects.get_or_create(name=album)[0]
elif type(album) is list: elif type(album) is list:
album_name = album[0] album = Album.objects.get_or_create(name=album[0])[0]
else: else:
album_name = None
if album_name:
try:
album = Album.objects.get(name=album_name)
except Album.DoesNotExist:
album = Album.objects.create(name=album_name)
if not album_name:
album = None album = None
if sng := Song.objects.filter( if sng := Song.objects.filter(
@ -90,7 +78,7 @@ def load_track(
str( str(
slugify( slugify(
GoogleTranslator(source="auto", target="en").translate( GoogleTranslator(source="auto", target="en").translate(
f"{song.name} {' '.join([x.name for x in authors])}", f"{song.name} {' '.join([x.name for x in song.authors])}",
target_language="en", target_language="en",
) )
) )
@ -113,7 +101,7 @@ def load_track(
album.save() album.save()
if authors: if authors:
song.authors.set([x.id for x in authors]) song.authors.set(authors)
# set music meta # set music meta
tag = MutagenFile(song.file.path) tag = MutagenFile(song.file.path)
@ -136,9 +124,9 @@ def load_track(
data=f.read(), data=f.read(),
) )
) )
if "release" in kwargs and kwargs["release"]: if "release" in kwargs:
tag.tags.add(TORY(text=kwargs["release"])) tag.tags.add(TORY(text=kwargs["release"]))
if "genre" in kwargs and kwargs["genre"]: if "genre" in kwargs:
tag.tags.add(TCON(text=kwargs["genre"])) tag.tags.add(TCON(text=kwargs["genre"]))
tag.save() tag.save()

View File

@ -2,6 +2,8 @@
from django.conf import settings from django.conf import settings
from spotipy.oauth2 import SpotifyClientCredentials from spotipy.oauth2 import SpotifyClientCredentials
from akarpov.music.services.yandex import search_ym
def login() -> spotipy.Spotify: def login() -> spotipy.Spotify:
if not settings.MUSIC_SPOTIFY_ID or not settings.MUSIC_SPOTIFY_SECRET: if not settings.MUSIC_SPOTIFY_ID or not settings.MUSIC_SPOTIFY_SECRET:
@ -45,7 +47,15 @@ def get_track_info(name: str) -> dict:
# try to get genre # try to get genre
sp = login() sp = login()
genres = sp.album(res["album"]["external_urls"]["spotify"])["genres"] genres = sp.album(res["album"]["external_urls"]["spotify"])["genres"]
if not genres:
ym_info = search_ym(info["artist"] + " " + info["title"])
if ym_info and "genre" in ym_info:
info["genre"] = ym_info["genre"]
else:
genres = sp.artist(res["artists"][0]["external_urls"]["spotify"])["genres"]
if genres: if genres:
info["genre"] = genres[0] info["genre"] = genres[0]
else:
info["genre"] = genres[0]
return info return info

View File

@ -2,13 +2,11 @@
from random import randint from random import randint
from django.conf import settings from django.conf import settings
from django.core.files import File from django.utils.text import slugify
from yandex_music import Client, Playlist, Search, Track from yandex_music import Client, Playlist, Search, Track
from yandex_music.exceptions import NotFoundError
from akarpov.music import tasks from akarpov.music import tasks
from akarpov.music.models import Album as AlbumModel from akarpov.music.models import Song, SongInQue
from akarpov.music.models import Author, Song, SongInQue
from akarpov.music.services.db import load_track from akarpov.music.services.db import load_track
@ -45,7 +43,7 @@ def search_ym(name: str):
return info return info
def load_file_meta(track: int, user_id: int) -> str: def load_file_meta(track: int, user_id: int):
que = SongInQue.objects.create() que = SongInQue.objects.create()
client = login() client = login()
track = client.tracks(track)[0] # type: Track track = client.tracks(track)[0] # type: Track
@ -57,27 +55,19 @@ def load_file_meta(track: int, user_id: int) -> str:
name=track.title, album__name=track.albums[0].title name=track.title, album__name=track.albums[0].title
): ):
que.delete() que.delete()
return str(sng.first()) return sng.first()
except IndexError: except IndexError:
que.delete() que.delete()
return "" return
filename = f"_{str(randint(10000, 9999999))}" filename = slugify(f"{track.artists[0].name} - {track.title}")
orig_path = f"{settings.MEDIA_ROOT}/{filename}.mp3" orig_path = f"{settings.MEDIA_ROOT}/{filename}.mp3"
album = track.albums[0] album = track.albums[0]
track.download(filename=orig_path, codec="mp3") track.download(filename=orig_path, codec="mp3")
img_pth = str(settings.MEDIA_ROOT + f"/_{str(randint(10000, 99999))}.png") img_pth = str(settings.MEDIA_ROOT + f"/_{str(randint(10000, 99999))}.png")
try:
track.download_cover(filename=img_pth) track.download_cover(filename=img_pth)
except NotFoundError:
img_pth = None
try:
lyrics = track.get_lyrics("LRC").fetch_lyrics()
except NotFoundError:
lyrics = ""
song = load_track( song = load_track(
orig_path, orig_path,
img_pth, img_pth,
@ -87,9 +77,6 @@ def load_file_meta(track: int, user_id: int) -> str:
track.title, track.title,
release=album.release_date, release=album.release_date,
genre=album.genre, genre=album.genre,
lyrics=lyrics,
explicit=track.explicit,
track_source=track.track_source,
) )
if os.path.exists(orig_path): if os.path.exists(orig_path):
os.remove(orig_path) os.remove(orig_path)
@ -109,64 +96,3 @@ def load_playlist(link: str, user_id: int):
tasks.load_ym_file_meta.apply_async( tasks.load_ym_file_meta.apply_async(
kwargs={"track": track.track.id, "user_id": user_id} kwargs={"track": track.track.id, "user_id": user_id}
) )
def update_album_info(album: AlbumModel) -> None:
client = login()
search = client.search(album.name, type_="album") # type: Search
if search.albums:
search_album = search.albums.results[0]
data = {
"name": search_album.title,
"tracks": search_album.track_count,
"explicit": search_album.explicit,
"year": search_album.year,
"genre": search_album.genre,
"description": search_album.description,
"type": search_album.type,
}
album.meta = data
image_path = str(settings.MEDIA_ROOT + f"/_{str(randint(10000, 99999))}.png")
if search_album.cover_uri:
search_album.download_cover(filename=image_path)
with open(image_path, "rb") as f:
album.image = File(f, name=image_path.split("/")[-1])
album.save()
os.remove(image_path)
authors = []
if search_album.artists:
for x in search_album.artists:
try:
authors.append(Author.objects.get(name=x.name))
except Author.DoesNotExist:
authors.append(Author.objects.create(name=x.name))
album.authors.set([x.id for x in authors])
album.save()
def update_author_info(author: Author) -> None:
client = login()
search = client.search(author.name, type_="artist") # type: Search
if search.artists:
search_artist = search.artists.results[0]
data = {
"name": search_artist.name,
"description": search_artist.description,
"genres": search_artist.genres,
}
author.meta = data
image_path = str(settings.MEDIA_ROOT + f"/_{str(randint(10000, 99999))}.png")
if not search_artist.cover:
author.save()
return
search_artist.cover.download(filename=image_path)
with open(image_path, "rb") as f:
author.image = File(f, name=image_path.split("/")[-1])
author.save()
os.remove(image_path)

View File

@ -4,7 +4,6 @@
from django.dispatch import receiver from django.dispatch import receiver
from akarpov.music.models import Album, Author, PlaylistSong, Song, SongUserRating from akarpov.music.models import Album, Author, PlaylistSong, Song, SongUserRating
from akarpov.music.services.yandex import update_album_info, update_author_info
@receiver(post_delete, sender=Song) @receiver(post_delete, sender=Song)
@ -17,13 +16,15 @@ def auto_delete_file_on_delete(sender, instance, **kwargs):
@receiver(post_save, sender=Author) @receiver(post_save, sender=Author)
def author_create(sender, instance, created, **kwargs): def author_create(sender, instance, created, **kwargs):
if created: if created:
update_author_info(instance) # TODO: add logic to retrieve author info here
return
@receiver(post_save, sender=Album) @receiver(post_save, sender=Album)
def album_create(sender, instance, created, **kwargs): def album_create(sender, instance, created, **kwargs):
if created: if created:
update_album_info(instance) # TODO: add logic to retrieve author info here
return
@receiver(post_save) @receiver(post_save)

View File

@ -3,6 +3,7 @@
set -o errexit set -o errexit
set -o nounset set -o nounset
python manage.py makemigrations
python manage.py migrate python manage.py migrate
rm -f './celerybeat.pid' rm -f './celerybeat.pid'
celery -A config.celery_app beat -l INFO celery -A config.celery_app beat -l INFO

1903
poetry.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -28,7 +28,7 @@ django-crispy-forms = "^2.1"
crispy-bootstrap5 = "^0.7" crispy-bootstrap5 = "^0.7"
django-redis = "^5.2.0" django-redis = "^5.2.0"
django-ckeditor = "^6.5.1" django-ckeditor = "^6.5.1"
django-colorfield = "^0.11.0" django-colorfield = "^0.8.0"
djangorestframework = "^3.14.0" djangorestframework = "^3.14.0"
django-rest-auth = "^0.9.5" django-rest-auth = "^0.9.5"
django-cors-headers = "^4.0.0" django-cors-headers = "^4.0.0"
@ -77,7 +77,7 @@ pydub = "^0.25.1"
python-mpd2 = "^3.0.5" python-mpd2 = "^3.0.5"
yandex-music = "^2.1.1" yandex-music = "^2.1.1"
pyjwt = "^2.8.0" pyjwt = "^2.8.0"
rawpy = "^0.19.0" rawpy = "^0.18.1"
xvfbwrapper = "^0.2.9" xvfbwrapper = "^0.2.9"
vtk = "^9.2.6" vtk = "^9.2.6"
ffmpeg-python = "^0.2.0" ffmpeg-python = "^0.2.0"