add routes to get all albums and artists with sort

+ rewrite load all albums + artist logic with itertools.groupby
+ add a function to convert seconds to string
This commit is contained in:
mungai-njoroge
2023-12-08 09:20:51 +03:00
parent 7f87cde96c
commit 336360d509
12 changed files with 265 additions and 29 deletions
+28 -1
View File
@@ -4,14 +4,41 @@ Contains methods relating to albums.
from dataclasses import asdict
from typing import Any
from itertools import groupby
from app.logger import log
from app.models.track import Track
from app.store.albums import AlbumStore
from app.store.tracks import TrackStore
def create_albums():
"""
Creates albums from the tracks in the store.
"""
# group all tracks by albumhash
tracks = TrackStore.tracks
tracks = sorted(tracks, key=lambda t: t.albumhash)
grouped = groupby(tracks, lambda t: t.albumhash)
# create albums from the groups
albums: list[Track] = []
for albumhash, tracks in grouped:
count = len(list(tracks))
duration = sum(t.duration for t in tracks)
created_date = min(t.created_date for t in tracks)
album = AlbumStore.create_album(list(tracks)[0])
album.set_count(count)
album.set_duration(duration)
album.set_created_date(created_date)
albums.append(album)
return albums
def validate_albums():
"""
Removes albums that have no tracks.
+58 -13
View File
@@ -1,3 +1,5 @@
from collections import namedtuple
from itertools import groupby
import os
import urllib
from concurrent.futures import ThreadPoolExecutor
@@ -12,6 +14,7 @@ from requests.exceptions import ReadTimeout
from app import settings
from app.models import Album, Artist, Track
from app.store import artists as artist_store
from app.store.tracks import TrackStore
from app.utils.hashing import create_hash
from app.utils.progressbar import tqdm
@@ -190,21 +193,63 @@ def get_albumartists(albums: list[Album]) -> set[str]:
def get_all_artists(tracks: list[Track], albums: list[Album]) -> list[Artist]:
artists_from_tracks = get_artists_from_tracks(tracks=tracks)
artist_from_albums = get_albumartists(albums=albums)
TrackInfo = namedtuple(
"TrackInfo",
[
"artisthash",
"albumhash",
"trackhash",
"duration",
"artistname",
"created_date",
],
)
src_tracks = TrackStore.tracks
all_tracks: set[TrackInfo] = set()
artists = list(artists_from_tracks.union(artist_from_albums))
artists.sort()
for track in src_tracks:
artist_hashes = {(a.name, a.artisthash) for a in track.artists}.union(
(a.name, a.artisthash) for a in track.albumartists
)
# Remove duplicates
artists_dup_free = set()
artist_hashes = set()
for artist in artist_hashes:
track_info = TrackInfo(
artistname=artist[0],
artisthash=artist[1],
albumhash=track.albumhash,
trackhash=track.trackhash,
duration=track.duration,
created_date=track.created_date,
# work on created date
)
for artist in artists:
artist_hash = create_hash(artist, decode=True)
all_tracks.add(track_info)
if artist_hash not in artist_hashes:
artists_dup_free.add(artist)
artist_hashes.add(artist_hash)
all_tracks = sorted(all_tracks, key=lambda x: x.artisthash)
all_tracks = groupby(all_tracks, key=lambda x: x.artisthash)
return [Artist(a) for a in artists_dup_free]
artists = []
for artisthash, tracks in all_tracks:
tracks: list[TrackInfo] = list(tracks)
artistname = (
sorted({t.artistname for t in tracks})[0]
if len(tracks) > 1
else tracks[0].artistname
)
albumcount = len({t.albumhash for t in tracks})
duration = sum(t.duration for t in tracks)
created_date = min(t.created_date for t in tracks)
artist = Artist(name=artistname)
artist.set_trackcount(len(tracks))
artist.set_albumcount(albumcount)
artist.set_duration(duration)
artist.set_created_date(created_date)
artists.append(artist)
return artists