from apollo_utils.core.constants.dsp import DSP from apollo_utils.core.constants.market import Market from datetime import date, timedelta from sqlalchemy import and_, or_ from sqlalchemy.orm import Query from typing import Iterable, List, Optional from apollo_main_db import AppleMusicWeeklyTopPlaylistTrackSummary from apollo_main_db.apollo import PlaylistBlacklist from apollo_main_db.apple import AppleWeeklyTopPlaylistLatest from apollo_main_db.spotify import SpotifyWeeklyTopPlaylistLatest, SpotifyWeeklyTopPlaylistTrackSummary from src.constants.playlists import WEEKLY_TOP_PLAYLIST_CUSTOM_COUNTRY_CODES from src.db.base import session as db_session from src.legacy.redis_db import keys as redis_keys from src.legacy.redis_db.decorators import cache_value WEEKLY_TOP_PLAYLISTS_HISTORY_TABLE = { DSP.APPLE: AppleMusicWeeklyTopPlaylistTrackSummary, DSP.SPOTIFY: SpotifyWeeklyTopPlaylistTrackSummary } WEEKLY_TOP_PLAYLISTS_TABLE = {DSP.APPLE: AppleWeeklyTopPlaylistLatest, DSP.SPOTIFY: SpotifyWeeklyTopPlaylistLatest} def get_base_top_playlist_history_dates_query( dsp: DSP, playlists_ids: Iterable[str] | None, track_isrc_map: dict[str, str], period: Optional[int] = None, country_code: str | None = None, ) -> Query: """Returns playlist history query with playlist_id, isrc, entry_date, exit_date. Filter by date range and lists of playlist ID and track isrc. Args: dsp: DSP. playlists_ids: Playlist ID list or None. track_isrc_map: Track ISRC to first streams date mapping. period: Load intervals for the period in days. country_code: Weekly top country code. Returns: Query. """ weekly_top_playlist_history_table = WEEKLY_TOP_PLAYLISTS_HISTORY_TABLE[dsp] track_filters = [] for track_isrc, first_stream_date in track_isrc_map.items(): current_filters = [ weekly_top_playlist_history_table.isrc == track_isrc, weekly_top_playlist_history_table.exit_date >= first_stream_date, ] if period: end_date = date.fromisoformat(first_stream_date) + timedelta(days=period) current_filters.append(weekly_top_playlist_history_table.entry_date <= end_date) track_filters.append(and_(*current_filters)) # For each track and playlist pair retrieve list of dates when the track was included in the playlist. history_query = ( db_session.query( weekly_top_playlist_history_table.playlist_id, weekly_top_playlist_history_table.isrc, weekly_top_playlist_history_table.entry_date, weekly_top_playlist_history_table.exit_date, ) .distinct() .filter(or_(*track_filters)) ) if playlists_ids is None: weekly_top_playlist_table = WEEKLY_TOP_PLAYLISTS_TABLE[dsp] history_query = ( history_query .join( weekly_top_playlist_table, weekly_top_playlist_table.playlist_id == weekly_top_playlist_history_table.playlist_id, ) ) if country_code == Market.GLOBAL or country_code is None: # This based on logic of AP-1717 where we use custom global market playlists history_query = history_query.filter( weekly_top_playlist_table.country_code.in_(WEEKLY_TOP_PLAYLIST_CUSTOM_COUNTRY_CODES[dsp]) ) else: history_query = history_query.filter(weekly_top_playlist_table.country_code == country_code) else: history_query = history_query.filter(weekly_top_playlist_history_table.playlist_id.in_(playlists_ids)) return history_query @cache_value(redis_keys.BLACKLISTED_PLAYLISTS, redis_keys.BLACKLISTED_PLAYLISTS_TTL) def get_blacklisted_ids() -> List[str]: """Returns set of blacklisted playlists ids.""" query = db_session.query(PlaylistBlacklist.playlist_id).all() return [str(q.playlist_id) for q in query]