fix: album favorite state, artist and album colors

+ fix: unserialized artist result
+ misc
This commit is contained in:
cwilvx
2024-08-02 12:25:55 +03:00
parent 16db3e1ad2
commit 0463c80070
16 changed files with 195 additions and 165 deletions
+4
View File
@@ -51,3 +51,7 @@
- New table to hold similar artist entries - New table to hold similar artist entries
- Create 2 way relationships, such that if an artist A is similar to another B with a certain weight, - Create 2 way relationships, such that if an artist A is similar to another B with a certain weight,
then artist B is similar to A with the same weight, unless overwritten. then artist B is similar to A with the same weight, unless overwritten.
# Bug fixes
- Duplicates on search
+2 -8
View File
@@ -3,7 +3,6 @@ Contains all the album routes.
""" """
from dataclasses import asdict from dataclasses import asdict
from pprint import pprint
import random import random
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
@@ -39,7 +38,6 @@ def get_album_tracks_and_info(body: AlbumHashSchema):
Returns album info and tracks for the given albumhash. Returns album info and tracks for the given albumhash.
""" """
albumhash = body.albumhash albumhash = body.albumhash
# album = AlbumDb.get_album_by_albumhash(albumhash)
albumentry = AlbumStore.albummap.get(albumhash) albumentry = AlbumStore.albummap.get(albumhash)
if albumentry is None: if albumentry is None:
@@ -53,14 +51,9 @@ def get_album_tracks_and_info(body: AlbumHashSchema):
tracks=tracks, singleTrackAsSingle=UserConfig().showAlbumsAsSingles tracks=tracks, singleTrackAsSingle=UserConfig().showAlbumsAsSingles
) )
print("is_favorite", album.is_favorite)
track_total = sum({int(t.extra.get("track_total", 1) or 1) for t in tracks}) track_total = sum({int(t.extra.get("track_total", 1) or 1) for t in tracks})
avg_bitrate = sum(t.bitrate for t in tracks) // (len(tracks) or 1) avg_bitrate = sum(t.bitrate for t in tracks) // (len(tracks) or 1)
album.fav_userids = [1]
pprint(album)
return { return {
"info": { "info": {
**asdict(album), **asdict(album),
@@ -128,10 +121,11 @@ def get_more_from_artist(body: GetMoreFromArtistsBody):
a a
for a in albums for a in albums
# INFO: filter out albums added to other artists # INFO: filter out albums added to other artists
if a.albumhash not in seen_hashes if a.albumhash not in seen_hashes and artisthash in a.artisthashes
# INFO: filter out albums with the same base title # INFO: filter out albums with the same base title
and create_hash(a.base_title) != create_hash(base_title) and create_hash(a.base_title) != create_hash(base_title)
] ]
all_albums[artisthash] = serialize_for_card_many( all_albums[artisthash] = serialize_for_card_many(
[a for a in albums if create_hash(a.base_title) != create_hash(base_title)][ [a for a in albums if create_hash(a.base_title) != create_hash(base_title)][
:limit :limit
+13 -3
View File
@@ -21,7 +21,7 @@ from app.config import UserConfig
from app.db.userdata import SimilarArtistTable from app.db.userdata import SimilarArtistTable
from app.serializers.album import serialize_for_card_many from app.serializers.album import serialize_for_card_many
from app.serializers.artist import serialize_for_cards from app.serializers.artist import serialize_for_cards, serialize_for_card
from app.serializers.track import serialize_tracks from app.serializers.track import serialize_tracks
from app.store.albums import AlbumStore from app.store.albums import AlbumStore
@@ -69,7 +69,14 @@ def get_artist(path: ArtistHashSchema, query: TrackLimitSchema):
artist.genres.insert(0, {"name": decade, "genrehash": decade}) artist.genres.insert(0, {"name": decade, "genrehash": decade})
return { return {
"artist": {**asdict(artist), "is_favorite": artist.is_favorite}, "artist": {
**serialize_for_card(artist),
"duration": sum(t.duration for t in tracks) if tracks else 0,
"trackcount": tcount,
"albumcount": artist.albumcount,
"genres": artist.genres,
"is_favorite": artist.is_favorite,
},
"tracks": serialize_tracks(tracks[:limit]), "tracks": serialize_tracks(tracks[:limit]),
} }
@@ -128,7 +135,10 @@ def get_artist_albums(path: ArtistHashSchema, query: GetArtistAlbumsQuery):
res["singles_and_eps"].append(album) res["singles_and_eps"].append(album)
elif album.type == "compilation": elif album.type == "compilation":
res["compilations"].append(album) res["compilations"].append(album)
elif album.albumhash in missing_albumhashes or artisthash not in album.artisthashes: elif (
album.albumhash in missing_albumhashes
or artisthash not in album.artisthashes
):
res["appearances"].append(album) res["appearances"].append(album)
else: else:
res["albums"].append(album) res["albums"].append(album)
+30 -25
View File
@@ -1,13 +1,11 @@
from typing import List, TypeVar from typing import List, TypeVar
from flask_jwt_extended import current_user
from flask_openapi3 import Tag from flask_openapi3 import Tag
from flask_openapi3 import APIBlueprint from flask_openapi3 import APIBlueprint
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from app.api.apischemas import GenericLimitSchema from app.api.apischemas import GenericLimitSchema
from app.db.libdata import ArtistTable from app.db.libdata import TrackTable
from app.db.libdata import AlbumTable, TrackTable
from app.db.userdata import FavoritesTable from app.db.userdata import FavoritesTable
from app.models import FavType from app.models import FavType
from app.settings import Defaults from app.settings import Defaults
@@ -45,6 +43,29 @@ class FavoritesAddBody(BaseModel):
type: str = Field(description="The type of the item", example=FavType.album) type: str = Field(description="The type of the item", example=FavType.album)
def toggle_fav(type: str, hash: str):
"""
Toggles a favorite item.
"""
if type == FavType.track:
entry = TrackStore.trackhashmap.get(hash)
if entry is not None:
entry.toggle_favorite_user()
elif type == FavType.album:
entry = AlbumStore.albummap.get(hash)
if entry is not None:
entry.toggle_favorite_user()
elif type == FavType.artist:
entry = ArtistStore.artistmap.get(hash)
if entry is not None:
entry.toggle_favorite_user()
return {"msg": "Added to favorites"}
@api.post("/add") @api.post("/add")
def toggle_favorite(body: FavoritesAddBody): def toggle_favorite(body: FavoritesAddBody):
""" """
@@ -56,21 +77,7 @@ def toggle_favorite(body: FavoritesAddBody):
except: except:
return {"msg": "Failed! An error occured"}, 500 return {"msg": "Failed! An error occured"}, 500
if body.type == FavType.track: toggle_fav(body.type, body.hash)
entry = TrackStore.trackhashmap.get(body.hash)
if entry is not None:
entry.toggle_favorite_user()
elif body.type == FavType.album:
entry = AlbumStore.albummap.get(body.hash)
if entry is not None:
entry.toggle_favorite_user()
elif body.type == FavType.artist:
entry = ArtistStore.artistmap.get(body.hash)
if entry is not None:
entry.toggle_favorite_user()
return {"msg": "Added to favorites"} return {"msg": "Added to favorites"}
@@ -80,14 +87,12 @@ def remove_favorite(body: FavoritesAddBody):
""" """
Removes a favorite from the database. Removes a favorite from the database.
""" """
FavoritesTable.remove_item({"hash": body.hash, "type": body.type}) try:
FavoritesTable.remove_item({"hash": body.hash, "type": body.type})
except:
return {"msg": "Failed! An error occured"}, 500
if body.type == FavType.track: toggle_fav(body.type, body.hash)
TrackTable.set_is_favorite(body.hash, False)
elif body.type == FavType.album:
AlbumTable.set_is_favorite(body.hash, False)
elif body.type == FavType.artist:
ArtistTable.set_is_favorite(body.hash, False)
return {"msg": "Removed from favorites"} return {"msg": "Removed from favorites"}
+18 -13
View File
@@ -1,6 +1,4 @@
import datetime import datetime
import enum
from shlex import join
from typing import Any from typing import Any
from sqlalchemy import ( from sqlalchemy import (
JSON, JSON,
@@ -13,15 +11,12 @@ from sqlalchemy import (
insert, insert,
select, select,
update, update,
join,
) )
from sqlalchemy.orm import Mapped, mapped_column from sqlalchemy.orm import Mapped, mapped_column
from app.db.engine import DbEngine from app.db.engine import DbEngine
from app.db.utils import ( from app.db.utils import (
albums_to_dataclasses,
artists_to_dataclasses,
favorites_to_dataclass, favorites_to_dataclass,
playlist_to_dataclass, playlist_to_dataclass,
playlists_to_dataclasses, playlists_to_dataclasses,
@@ -29,7 +24,6 @@ from app.db.utils import (
similar_artist_to_dataclass, similar_artist_to_dataclass,
similar_artists_to_dataclass, similar_artists_to_dataclass,
tracklog_to_dataclasses, tracklog_to_dataclasses,
tracks_to_dataclasses,
user_to_dataclass, user_to_dataclass,
user_to_dataclasses, user_to_dataclasses,
) )
@@ -377,11 +371,12 @@ class PlaylistTable(Base):
) )
class ArtistData(Base): class LibDataTable(Base):
__tablename__ = "artistdata" __tablename__ = "artistdata"
id: Mapped[int] = mapped_column(primary_key=True) id: Mapped[int] = mapped_column(primary_key=True)
artisthash: Mapped[str] = mapped_column(String(), index=True) itemhash: Mapped[str] = mapped_column(String(), unique=True, index=True)
itemtype: Mapped[str] = mapped_column(String())
color: Mapped[str] = mapped_column(String(), nullable=True) color: Mapped[str] = mapped_column(String(), nullable=True)
bio: Mapped[str] = mapped_column(String(), nullable=True) bio: Mapped[str] = mapped_column(String(), nullable=True)
info: Mapped[dict[str, Any]] = mapped_column(JSON(), nullable=True) info: Mapped[dict[str, Any]] = mapped_column(JSON(), nullable=True)
@@ -390,11 +385,21 @@ class ArtistData(Base):
) )
@classmethod @classmethod
def find_one(cls, artisthash: str): def update_one(cls, hash: str, data: dict[str, Any]):
result = cls.execute(select(cls).where(cls.artisthash == artisthash)) return cls.execute(
update(cls).where(cls.itemhash == hash).values(data), commit=True
)
@classmethod
def find_one(cls, hash: str, type: str):
result = cls.execute(
select(cls).where((cls.itemhash == hash) & (cls.itemtype == type))
)
return result.fetchone() return result.fetchone()
@classmethod @classmethod
def get_all_colors(cls) -> dict[str, str]: def get_all_colors(cls, type: str) -> list[dict[str, str]]:
result = cls.execute(select(cls.artisthash, cls.color)) result = cls.execute(
return dict(result.fetchall()) select(cls.itemhash, cls.color).where(cls.itemtype == type)
)
return [{"itemhash": r[0], "color": r[1]} for r in result.fetchall()]
+59 -56
View File
@@ -2,19 +2,16 @@
Contains everything that deals with image color extraction. Contains everything that deals with image color extraction.
""" """
import json
from pathlib import Path from pathlib import Path
import colorgram import colorgram
from app import settings from app import settings
from app.db.sqlite.albumcolors import SQLiteAlbumMethods as aldb
from app.db.sqlite.artistcolors import SQLiteArtistMethods as adb
from app.db.sqlite.utils import SQLiteManager
from app.db.userdata import ArtistData from app.db.userdata import LibDataTable
from app.logger import log from app.logger import log
from app.lib.errors import PopulateCancelledError from app.lib.errors import PopulateCancelledError
from app.store.albums import AlbumStore
from app.store.artists import ArtistStore from app.store.artists import ArtistStore
from app.utils.progressbar import tqdm from app.utils.progressbar import tqdm
@@ -52,47 +49,45 @@ def process_color(item_hash: str, is_album=True):
return get_image_colors(str(path)) return get_image_colors(str(path))
# class ProcessAlbumColors: class ProcessAlbumColors:
# """ """
# Extracts the most dominant color from the album art and saves it to the database. Extracts the most dominant color from the album art and saves it to the database.
# """ """
# def __init__(self, instance_key: str) -> None: def __init__(self, instance_key: str) -> None:
# global PROCESS_ALBUM_COLORS_KEY global PROCESS_ALBUM_COLORS_KEY
# PROCESS_ALBUM_COLORS_KEY = instance_key PROCESS_ALBUM_COLORS_KEY = instance_key
# albums = [ albums = [a for a in AlbumStore.get_flat_list() if not a.color]
# a
# for a in AlbumStore.albums
# if a is not None and a.colors is not None and len(a.colors) == 0
# ]
# with SQLiteManager() as cur: for album in tqdm(albums, desc="Processing missing album colors"):
# try: albumhash = album.albumhash
# for album in tqdm(albums, desc="Processing missing album colors"): if PROCESS_ALBUM_COLORS_KEY != instance_key:
# if PROCESS_ALBUM_COLORS_KEY != instance_key: raise PopulateCancelledError(
# raise PopulateCancelledError( "A newer 'ProcessAlbumColors' instance is running. Stopping this one."
# "A newer 'ProcessAlbumColors' instance is running. Stopping this one." )
# )
# # TODO: Stop hitting the database for every album. albumrecord = LibDataTable.find_one(albumhash, type="album")
# # Instead, fetch all the data from the database and if albumrecord is not None and albumrecord.color is not None:
# # check from memory. continue
# exists = aldb.exists(album.albumhash, cur=cur) colors = process_color(albumhash)
# if exists:
# continue
# colors = process_color(album.albumhash) if colors is None:
continue
# if colors is None: album = AlbumStore.albummap.get(albumhash)
# continue
# album.set_colors(colors) if album:
# color_str = json.dumps(colors) album.set_color(colors[0])
# aldb.insert_one_album(cur, album.albumhash, color_str)
# finally: # INFO: Write to the database.
# cur.close() if albumrecord is None:
LibDataTable.insert_one(
{"itemhash": albumhash, "color": colors[0], "itemtype": "album"}
)
else:
LibDataTable.update_one(albumhash, {"color": colors[0]})
class ProcessArtistColors: class ProcessArtistColors:
@@ -101,29 +96,37 @@ class ProcessArtistColors:
""" """
def __init__(self, instance_key: str) -> None: def __init__(self, instance_key: str) -> None:
all_artists = ArtistStore.get_flat_list() all_artists = [a for a in ArtistStore.get_flat_list() if not a.color]
global PROCESS_ARTIST_COLORS_KEY global PROCESS_ARTIST_COLORS_KEY
PROCESS_ARTIST_COLORS_KEY = instance_key PROCESS_ARTIST_COLORS_KEY = instance_key
try: for artist in tqdm(all_artists, desc="Processing missing artist colors"):
for artist in tqdm(all_artists, desc="Processing missing artist colors"): artisthash = artist.artisthash
if PROCESS_ARTIST_COLORS_KEY != instance_key: if PROCESS_ARTIST_COLORS_KEY != instance_key:
raise PopulateCancelledError( raise PopulateCancelledError(
"A newer 'ProcessArtistColors' instance is running. Stopping this one." "A newer 'ProcessArtistColors' instance is running. Stopping this one."
) )
# exists = adb.exists(artist.artisthash, cur=cur) record = LibDataTable.find_one(artisthash, "artist")
artist = ArtistData.find_one(artist.artisthash)
if artist and artist.color is not None:
continue
colors = process_color(artist.artisthash, is_album=False) if (record is not None) and (record.color is not None):
continue
if colors is None: colors = process_color(artisthash, is_album=False)
continue
artist.set_colors(colors) if colors is None:
adb.insert_one_artist(cur, artist.artisthash, colors) continue
finally:
cur.close() artist = ArtistStore.artistmap.get(artisthash)
if artist:
artist.set_color(colors[0])
# INFO: Write to the database.
if record is None:
LibDataTable.insert_one(
{"itemhash": artisthash, "color": colors[0], "itemtype": "artist"}
)
else:
LibDataTable.update_one(artisthash, {"color": colors[0]})
-4
View File
@@ -96,10 +96,6 @@ def check_folder_type(group_: dict):
key: str = group_["folder"] key: str = group_["folder"]
tracks: list[Track] = group_["tracks"] tracks: list[Track] = group_["tracks"]
time: float = group_["time"] time: float = group_["time"]
print(f"Checking folder: {key}")
print(f"Tracks: {len(tracks)}")
existing_artist_hashes: set[str] = set(ArtistStore.artistmap.keys()) existing_artist_hashes: set[str] = set(ArtistStore.artistmap.keys())
existing_album_hashes: set[str] = set(AlbumStore.albummap.keys()) existing_album_hashes: set[str] = set(AlbumStore.albummap.keys())
+4 -2
View File
@@ -1,4 +1,4 @@
from app.lib.mapstuff import map_favorites, map_scrobble_data from app.lib.mapstuff import map_album_colors, map_artist_colors, map_favorites, map_scrobble_data
from app.lib.populate import CordinateMedia from app.lib.populate import CordinateMedia
from app.lib.tagger import IndexTracks from app.lib.tagger import IndexTracks
from app.store.folder import FolderStore from app.store.folder import FolderStore
@@ -16,7 +16,9 @@ class IndexEverything:
FolderStore.load_filepaths() FolderStore.load_filepaths()
map_scrobble_data() map_scrobble_data()
map_favorites() map_favorites()
# CordinateMedia(instance_key=str(time())) map_artist_colors()
map_album_colors()
CordinateMedia(instance_key=str(time()))
gc.collect() gc.collect()
+21 -1
View File
@@ -1,4 +1,4 @@
from app.db.userdata import FavoritesTable, ScrobbleTable from app.db.userdata import LibDataTable, FavoritesTable, ScrobbleTable
from app.store.albums import AlbumStore from app.store.albums import AlbumStore
from app.store.artists import ArtistStore from app.store.artists import ArtistStore
from app.store.tracks import TrackStore from app.store.tracks import TrackStore
@@ -66,3 +66,23 @@ def map_favorites():
track = TrackStore.trackhashmap.get(entry.hash) track = TrackStore.trackhashmap.get(entry.hash)
if track: if track:
track.toggle_favorite_user(entry.userid) track.toggle_favorite_user(entry.userid)
def map_artist_colors():
colors = LibDataTable.get_all_colors(type="artist")
for color in colors:
artist = ArtistStore.artistmap.get(color["itemhash"])
if artist:
artist.set_color(color["color"])
def map_album_colors():
colors = LibDataTable.get_all_colors(type="album")
for color in colors:
album = AlbumStore.albummap.get(color["itemhash"])
if album:
album.set_color(color["color"])
+2 -1
View File
@@ -8,7 +8,7 @@ from requests import ReadTimeout
from app import settings from app import settings
from app.db.sqlite.tracks import SQLiteTrackMethods from app.db.sqlite.tracks import SQLiteTrackMethods
from app.lib.artistlib import CheckArtistImages from app.lib.artistlib import CheckArtistImages
from app.lib.colorlib import ProcessArtistColors from app.lib.colorlib import ProcessAlbumColors, ProcessArtistColors
from app.lib.errors import PopulateCancelledError from app.lib.errors import PopulateCancelledError
from app.lib.taglib import extract_thumb from app.lib.taglib import extract_thumb
from app.logger import log from app.logger import log
@@ -40,6 +40,7 @@ class CordinateMedia:
try: try:
ProcessTrackThumbnails(instance_key) ProcessTrackThumbnails(instance_key)
ProcessAlbumColors(instance_key)
ProcessArtistColors(instance_key) ProcessArtistColors(instance_key)
except PopulateCancelledError as e: except PopulateCancelledError as e:
log.warn(e) log.warn(e)
+15 -10
View File
@@ -3,7 +3,6 @@ from app import settings
from app.config import UserConfig from app.config import UserConfig
from app.db.libdata import TrackTable from app.db.libdata import TrackTable
# from app.lib.populate import CordinateMedia
from app.lib.taglib import extract_thumb, get_tags from app.lib.taglib import extract_thumb, get_tags
from app.models.album import Album from app.models.album import Album
from app.models.artist import Artist from app.models.artist import Artist
@@ -29,7 +28,6 @@ class IndexTracks:
global POPULATE_KEY global POPULATE_KEY
POPULATE_KEY = instance_key POPULATE_KEY = instance_key
# dirs_to_scan = sdb.get_root_dirs()
dirs_to_scan = UserConfig().rootDirs dirs_to_scan = UserConfig().rootDirs
if len(dirs_to_scan) == 0: if len(dirs_to_scan) == 0:
@@ -159,12 +157,12 @@ def create_albums():
"playcount": track.playcount, "playcount": track.playcount,
"playduration": track.playduration, "playduration": track.playduration,
"title": track.album, "title": track.album,
"trackcount": 1, "tracks": {track.trackhash},
"extra": {}, "extra": {},
} }
else: else:
album = albums[track.albumhash] album = albums[track.albumhash]
album["trackcount"] += 1 album["tracks"].add(track.trackhash)
album["playcount"] += track.playcount album["playcount"] += track.playcount
album["playduration"] += track.playduration album["playduration"] += track.playduration
album["lastplayed"] = max(album["lastplayed"], track.lastplayed) album["lastplayed"] = max(album["lastplayed"], track.lastplayed)
@@ -186,8 +184,12 @@ def create_albums():
album["base_title"], _ = get_base_album_title(album["og_title"]) album["base_title"], _ = get_base_album_title(album["og_title"])
del genres del genres
trackhashes = album.pop("tracks")
album["trackcount"] = len(trackhashes)
return [Album(**album) for album in albums.values()] albums[album["albumhash"]] = (Album(**album), trackhashes)
return list(albums.values())
# class IndexArtists: # class IndexArtists:
@@ -225,7 +227,7 @@ def create_artists():
"extra": {}, "extra": {},
} }
else: else:
artist = artists[thisartist["artisthash"]] artist: dict = artists[thisartist["artisthash"]]
artist["duration"] += track.duration artist["duration"] += track.duration
artist["playcount"] += track.playcount artist["playcount"] += track.playcount
artist["playduration"] += track.playduration artist["playduration"] += track.playduration
@@ -235,6 +237,8 @@ def create_artists():
artist["created_date"] = min(artist["created_date"], track.last_mod) artist["created_date"] = min(artist["created_date"], track.last_mod)
artist["names"].add(thisartist["name"]) artist["names"].add(thisartist["name"])
artist.setdefault("albums", set())
if thisartist.get("in_track", True): if thisartist.get("in_track", True):
artist["tracks"].add(track.trackhash) artist["tracks"].add(track.trackhash)
@@ -257,12 +261,13 @@ def create_artists():
# INFO: Delete temporary keys # INFO: Delete temporary keys
del artist["names"] del artist["names"]
del artist["tracks"]
del artist["albums"] tracks = artist.pop("tracks")
albums = artist.pop("albums")
# INFO: Delete local variables # INFO: Delete local variables
del genres del genres
return [Artist(**artist) for artist in artists.values()] artists[artist["artisthash"]] = (Artist(**artist), tracks, albums)
return list(artists.values())
+1
View File
@@ -55,6 +55,7 @@ class Artist:
id: int = -1 id: int = -1
image: str = "" image: str = ""
color: str = ""
fav_userids: list[int] = dataclasses.field(default_factory=list) fav_userids: list[int] = dataclasses.field(default_factory=list)
@property @property
+1
View File
@@ -34,6 +34,7 @@ def serialize_for_card(album: Album):
"type", "type",
"playduration", "playduration",
"genrehashes", "genrehashes",
"fav_userids",
"extra", "extra",
"id", "id",
"lastplayed", "lastplayed",
+7 -22
View File
@@ -4,7 +4,6 @@ from pprint import pprint
import random import random
from typing import Iterable from typing import Iterable
from app.db.sqlite.albumcolors import SQLiteAlbumMethods as aldb
from app.lib.tagger import create_albums from app.lib.tagger import create_albums
from app.models import Album, Track from app.models import Album, Track
from app.store.artists import ArtistStore from app.store.artists import ArtistStore
@@ -21,9 +20,9 @@ ALBUM_LOAD_KEY = ""
class AlbumMapEntry: class AlbumMapEntry:
def __init__(self, album: Album) -> None: def __init__(self, album: Album, trackhashes: set[str]) -> None:
self.album = album self.album = album
self.trackhashes: set[str] = set() self.trackhashes = trackhashes
@property @property
def basetitle(self): def basetitle(self):
@@ -40,6 +39,9 @@ class AlbumMapEntry:
self.album.toggle_favorite_user(userid) self.album.toggle_favorite_user(userid)
def set_color(self, color: str):
self.album.color = color
class AlbumStore: class AlbumStore:
albums: list[Album] = CustomList() albums: list[Album] = CustomList()
@@ -67,26 +69,9 @@ class AlbumStore:
print("Loading albums... ", end="") print("Loading albums... ", end="")
cls.albummap = { cls.albummap = {
album.albumhash: AlbumMapEntry(album=album) for album in create_albums() album.albumhash: AlbumMapEntry(album=album, trackhashes=trackhashes)
for album, trackhashes in create_albums()
} }
tracks = remove_duplicates(TrackStore.get_flat_list())
tracks = sorted(tracks, key=lambda t: t.albumhash)
grouped = groupby(tracks, lambda t: t.albumhash)
for albumhash, tracks in grouped:
cls.albummap[albumhash].trackhashes = {t.trackhash for t in tracks}
# db_albums: list[tuple] = aldb.get_all_albums()
# for album in db_albums:
# albumhash = album[1]
# colors = json.loads(album[2])
# for _al in cls.albums:
# if _al.albumhash == albumhash:
# _al.set_colors(colors)
# break
print("Done!") print("Done!")
@classmethod @classmethod
+18 -18
View File
@@ -1,27 +1,22 @@
import json import json
from typing import Iterable from typing import Iterable
from app.db.sqlite.artistcolors import SQLiteArtistMethods as ardb
from app.lib.tagger import create_artists from app.lib.tagger import create_artists
from app.models import Artist from app.models import Artist
from app.utils import flatten
from app.utils.auth import get_current_userid from app.utils.auth import get_current_userid
from app.utils.bisection import use_bisection
from app.utils.customlist import CustomList from app.utils.customlist import CustomList
from app.utils.progressbar import tqdm
from .tracks import TrackStore
# from .albums import AlbumStore
from .tracks import TrackStore from .tracks import TrackStore
ARTIST_LOAD_KEY = "" ARTIST_LOAD_KEY = ""
class ArtistMapEntry: class ArtistMapEntry:
def __init__(self, artist: Artist) -> None: def __init__(
self, artist: Artist, albumhashes: set[str], trackhashes: set[str]
) -> None:
self.artist = artist self.artist = artist
self.albumhashes: set[str] = set() self.albumhashes: set[str] = albumhashes
self.trackhashes: set[str] = set() self.trackhashes: set[str] = trackhashes
def increment_playcount(self, duration: int, timestamp: int): def increment_playcount(self, duration: int, timestamp: int):
self.artist.lastplayed = timestamp self.artist.lastplayed = timestamp
@@ -34,6 +29,9 @@ class ArtistMapEntry:
self.artist.toggle_favorite_user(userid) self.artist.toggle_favorite_user(userid)
def set_color(self, color: str):
self.artist.color = color
class ArtistStore: class ArtistStore:
artists: list[Artist] = CustomList() artists: list[Artist] = CustomList()
@@ -51,17 +49,19 @@ class ArtistStore:
cls.artistmap.clear() cls.artistmap.clear()
cls.artistmap = { cls.artistmap = {
artist.artisthash: ArtistMapEntry(artist=artist) artist.artisthash: ArtistMapEntry(
for artist in create_artists() artist=artist, albumhashes=albumhashes, trackhashes=trackhashes
)
for artist, trackhashes, albumhashes in create_artists()
} }
for track in TrackStore.get_flat_list(): # for track in TrackStore.get_flat_list():
if instance_key != ARTIST_LOAD_KEY: # if instance_key != ARTIST_LOAD_KEY:
return # return
for hash in track.artisthashes: # for hash in track.artisthashes:
cls.artistmap[hash].trackhashes.add(track.trackhash) # cls.artistmap[hash].trackhashes.add(track.trackhash)
cls.artistmap[hash].albumhashes.add(track.albumhash) # cls.artistmap[hash].albumhashes.add(track.albumhash)
print("Done!") print("Done!")
# for artist in ardb.get_all_artists(): # for artist in ardb.get_all_artists():
-2
View File
@@ -21,9 +21,7 @@ import setproctitle
from app.api import create_api from app.api import create_api
from app.arg_handler import ProcessArgs from app.arg_handler import ProcessArgs
from app.lib.mapstuff import map_favorites, map_scrobble_data
from app.lib.index import IndexEverything from app.lib.index import IndexEverything
from app.lib.watchdogg import Watcher as WatchDog
from app.plugins.register import register_plugins from app.plugins.register import register_plugins
from app.settings import FLASKVARS, TCOLOR, Info from app.settings import FLASKVARS, TCOLOR, Info
from app.setup import load_into_mem, run_setup from app.setup import load_into_mem, run_setup