"""Artists logic.""" from typing import List, Optional from sqlalchemy import and_ from shared.query_builders.label_artists_query_builder import LabelArtistsQueryBuilder from shared.schemas import ArtistSchema, ArtistImageSchema from db import db from models import Image, Polymorphable from models import Artist, ProjectTargetItem from models.projects import Project from models.project_entity_type import ProjectEntityType class ArtistsRepository: artist_entity_types = [ProjectEntityType.PRIMARY_ARTIST.value, ProjectEntityType.FEATURED_ARTIST.value] def __get_artist(self, id: str) -> Optional[Artist]: return Artist.query.filter(Artist.external_id == id).one_or_none() def __create_image(self, image: Optional[ArtistImageSchema]): return Image(url=image.url, width=image.width, height=image.height) def __create_artist(self, artist: ArtistSchema) -> Artist: artist_model = Artist(artist.id, artist.name) if artist.image: artist_model.images = [self.__create_image(artist.image)] return artist_model def __update_artist(self, artist: Artist, updated_artist: ArtistSchema) -> Artist: [db.session.delete(image) for image in artist.images] if updated_artist.image: artist.images = [self.__create_image(updated_artist.image)] artist.name = updated_artist.name return artist def get_or_create_artists(self, artists: List[ArtistSchema]) -> List[Artist]: result = [] for artist in artists: artist_model = self.__get_artist(artist.id) if not artist_model: artist_model = self.__create_artist(artist) db.session.add(artist_model) else: self.__update_artist(artist_model, artist) result.append(artist_model) db.session.commit() for artist in result: if artist.id is None: db.session.refresh(artist) Artist.index_model(artist) return result def get_artist_by_external_id(self, artist_id: str) -> Optional[Artist]: return self.__get_artist(artist_id) def get_artists(self, name_part: str) -> List[Artist]: is_in_use_subquery = Project.query.join(Project.target_items).filter(Polymorphable.id == Artist.id).exists() query = Artist.query.filter(is_in_use_subquery) if name_part: query = query.filter(Artist.name.ilike("%{}%".format(name_part))) return query.all() def create_artist(self, artist: ArtistSchema) -> Artist: artist_model = db.session.query(Artist).filter(Artist.external_id == artist.id).one_or_none() if not artist_model: artist_model = self.__create_artist(artist) db.session.add(artist_model) db.session.commit() return artist_model def get_all_primary_artists(self) -> List[Artist]: return ( db.session.query(Artist) .join( ProjectTargetItem, and_( Artist.id == ProjectTargetItem.entity_id, ProjectTargetItem.entity_type == ProjectEntityType.PRIMARY_ARTIST.value, ), ) .filter(and_(Artist.external_id.isnot(None), Artist.is_unknown.is_(False))) ).all() def get_artists_is_unknown(self, external_ids): return ( db.session.query(Artist.external_id, Artist.is_unknown) .filter(Artist.external_id.in_(external_ids)) .all() ) def get_label_artists(self, label_id: int, artists_ids: List[str] = None): builder = LabelArtistsQueryBuilder(label_id) if artists_ids is not None: builder.external_id_in(artists_ids) return builder.items_query().all()