""" Global track priorities utilities. """ import math from collections import defaultdict from datetime import date, timedelta from sqlalchemy import and_, func from sqlalchemy.orm.query import aliased from typing import Dict, Iterable from apollo_main_db.apollo.models import ApolloGlobalTrackPrioritiesHistory, ApolloGlobalTrackPrioritiesHistoryTrack from src.db.base import session def get_gtp_history_records(type_id: int, gtp_date: date) -> Iterable: """Get GTP history track records. Args: type_id: GTP list type ID. gtp_date: Chosen GTP date. Returns: GTP history records. """ history_subquery = ( session.query(func.max(ApolloGlobalTrackPrioritiesHistory.id)) .filter(ApolloGlobalTrackPrioritiesHistory.type_id == type_id) .filter(ApolloGlobalTrackPrioritiesHistory.date <= gtp_date) .subquery() ) return ( session.query( ApolloGlobalTrackPrioritiesHistory.date, ApolloGlobalTrackPrioritiesHistoryTrack.track_id, ApolloGlobalTrackPrioritiesHistoryTrack.isrc, ) .select_from(ApolloGlobalTrackPrioritiesHistory) .outerjoin( ApolloGlobalTrackPrioritiesHistoryTrack, ApolloGlobalTrackPrioritiesHistoryTrack.history_id == ApolloGlobalTrackPrioritiesHistory.id, ) .filter(ApolloGlobalTrackPrioritiesHistory.id == history_subquery) .all() ) def check_re_entry(gtp_date: date, isrc_list: Iterable[str]): """Check what tracks re-entry. Args: gtp_date: GTP date. isrc_list: ISRC list. Returns: List of re-entered ISRC> """ current_start_date = gtp_date if gtp_date.weekday() == 6 else (gtp_date - timedelta(days=(gtp_date.weekday() + 1))) previous_start_date = current_start_date - timedelta(days=7) prev_week_history = aliased(ApolloGlobalTrackPrioritiesHistory) prev_week_tracks = aliased(ApolloGlobalTrackPrioritiesHistoryTrack) prev_week_check = ( session.query(prev_week_history) .join(prev_week_tracks, prev_week_history.id == prev_week_tracks.history_id) .filter(prev_week_history.date < current_start_date) .filter(prev_week_history.date >= previous_start_date) .filter(prev_week_tracks.isrc == ApolloGlobalTrackPrioritiesHistoryTrack.isrc) .exists() ) results = ( session.query(ApolloGlobalTrackPrioritiesHistoryTrack.isrc) .distinct() .join( ApolloGlobalTrackPrioritiesHistory, and_( ApolloGlobalTrackPrioritiesHistory.id == ApolloGlobalTrackPrioritiesHistoryTrack.history_id, ApolloGlobalTrackPrioritiesHistory.date < previous_start_date, ), ) .filter(ApolloGlobalTrackPrioritiesHistoryTrack.isrc.in_(isrc_list)) .filter(~prev_week_check) .all() ) return [r[0] for r in results] def get_gtp_weeks(gtp_date: date, isrc_list: Iterable[str]) -> Dict[str, int]: """Get weeks count in GTP by ISRC. Args: gtp_date: GTP date. isrc_list: ISRC list of tracks for gtp_date (it won't work correctly for other ISRC). Returns: ISRC to weeks count mapping. """ track_dates = ( session.query(ApolloGlobalTrackPrioritiesHistoryTrack.isrc, ApolloGlobalTrackPrioritiesHistory.date) .select_from(ApolloGlobalTrackPrioritiesHistoryTrack) .join( ApolloGlobalTrackPrioritiesHistory, ApolloGlobalTrackPrioritiesHistory.id == ApolloGlobalTrackPrioritiesHistoryTrack.history_id, ) .filter(ApolloGlobalTrackPrioritiesHistoryTrack.isrc.in_(isrc_list)) .filter(ApolloGlobalTrackPrioritiesHistory.date <= gtp_date) .all() ) isrc_dates = defaultdict(list) for item in track_dates: if item.date.weekday() == 6: item_date = item.date + timedelta(days=1) else: item_date = item.date - timedelta(days=item.date.weekday()) isrc_dates[item.isrc].append(item_date) result = {} for isrc, dates in isrc_dates.items(): dates = sorted(dates, reverse=True) max_date = gtp_date min_date = max_date for _date in dates: if (min_date - timedelta(days=7)) > _date: break min_date = _date result[isrc] = (math.floor((max_date - min_date).days / 7) if max_date > min_date else 0) + 1 return result