from datetime import date, datetime from typing import Dict import pytz import sentry_sdk from apollo_main_db.apollo.models import ApolloGlobalTrackPrioritiesHistory, ApolloGlobalTrackPrioritiesHistoryTrack from apollo_main_db.spotify.models import SpotifyViewPlaylist from sentry_sdk.utils import BadDsn import config import dsp_api import main_db import redis_db import utils from logger import logger try: sentry_sdk.init(dsn=config.SENTRY_DSN, environment=config.ENVIRONMENT) except BadDsn: pass @utils.handle_errors() def update_gtp_tracks( current_date: date, gtp_playlist: SpotifyViewPlaylist, playlist_track_map: Dict[str, str] ): """Update GTP tracks in DB. Args: current_date: Today date. gtp_playlist: GTP playlist DB record. playlist_track_map: Mapping of current playlist tracks (ID to ISRC). """ history_track_map = {} with main_db.session_scope() as session: history = main_db.get_history(session, current_date, gtp_playlist.category_id) # if playlist ID was changed in DB for specific type then we should delete all the current today records if history and history.playlist_id != gtp_playlist.playlist_id: logger.debug( f"Incorrect playlist ID {history.playlist_id} for type {history.type_id}" + f", should be {gtp_playlist.playlist_id}, removing incorrect" ) for track in history.tracks: session.delete(track) session.delete(history) history = None # if nothing was found then create a new base record if not history: logger.debug(f"History does not exist for type {gtp_playlist.category_id}, creating a new record") history = ApolloGlobalTrackPrioritiesHistory() history.playlist_id = gtp_playlist.playlist_id history.type_id = gtp_playlist.category_id history.date = current_date session.add(history) session.flush() else: logger.debug(f"History {history.id}, {len(history.tracks)} tracks") history_track_map = {t.track_id: t for t in history.tracks} # find missing and add them to DB for track_id, isrc in playlist_track_map.items(): if track_id not in history_track_map: track = ApolloGlobalTrackPrioritiesHistoryTrack() track.history = history track.track_id = track_id track.isrc = isrc session.add(track) # find extra and remove from DB for track_id, track in history_track_map.items(): if track_id not in playlist_track_map: session.delete(track) def main(): """Get GTP playlists tracks and save them to DB. Job entry point. """ lock = None try: if config.Redis.LOCK_ENABLED: lock = redis_db.get_redis_lock() if not lock.acquire(blocking=False): logger.info("Can not get lock") return current_date = datetime.now(pytz.timezone("EST")).date() logger.debug(f"Updating GTP playlists tracks for {current_date}") gtp_playlist_list = main_db.get_playlists() for gtp_playlist in gtp_playlist_list: playlist_track_list = dsp_api.get_playlist_tracks(gtp_playlist.playlist_id) logger.debug(f"Playlist {gtp_playlist.playlist_id} has {len(playlist_track_list)} tracks") update_gtp_tracks(current_date, gtp_playlist, playlist_track_list) except Exception as ex: sentry_sdk.capture_exception(ex) raise finally: if config.Redis.LOCK_ENABLED and lock: lock.release() if __name__ == '__main__': main()