"""Logic module that generate HLS stream for v2 assets and falls back on v1 logic if needed.""" import time from typing import Any from assets import config from assets.constants import ( asset_status as asset_status_constants, asset_types, asset_upload_types, error, ) from assets.exceptions import ( AssetEncodingInProgress, AssetFinalNotFound, WrongAssetStatus, ) from assets.models import asset_access_log, asset_final, asset_status, asset_upload from assets.models.asset_upload_type import resolve_asset_upload_type_id from assets.utils import wowza from assets.utils.url_formatter import format_url def get_track_wowza_stream_url_with_correction_assets( track_id: int, user_id: str | None, ip_address: str | None = None, referrer: str | None = None, is_correction_mode: bool = False, profile_type: str | None = None, identity_uuid: str | None = None, ) -> dict[str, Any]: """Get track HLS Wowza stream url with secure access token. Args: track_id (int): Unique track id user_id (str): Unique user id ip_address (str): Client ip address referrer (str): The request's referrer. is_correction_mode (bool): Checks if track is in correction mode or not. (Correction asset flag.) profile_type (str): Profile type identity_uuid (str): Identity UUID Returns: dict: Wowza HLS stream url """ user_id_to_log = identity_uuid if profile_type and identity_uuid else user_id stereo_type_id = resolve_asset_upload_type_id(asset_upload_types.STEREO) asset_uploads_response = asset_upload.get_latest_asset_upload( track_id=track_id, is_correction_mode=is_correction_mode, asset_upload_type_id=stereo_type_id, ) asset_upload_id = asset_uploads_response[0]["id"] try: asset_final_item = asset_final.get_asset_final_by_asset_upload_id_and_type( asset_upload_id, asset_types.TYPE_FILE_MP3_192 ) except AssetFinalNotFound as e: # we have a v2 asset upload but no asset final. # check asset_status asset_status_item = asset_status.get_last_asset_status(asset_upload_id) if ( asset_status_item["status"] in asset_status_constants.PROCESSING_FAILED_ASSET_STATUSES ): raise WrongAssetStatus( error.ERROR_ASSET_WRONG_STATUS.format( status=asset_status_item["status"] ) ) from e else: # the asset is still in progress. A 204 response is perhaps more # appropriate than a 400. raise AssetEncodingInProgress( asset_status_constants.ASSET_ENCODING_IN_PROGRESS.format( status=asset_status_item["status"] ) ) from e # generate HLS URL for v2 MP3 mp3_file = asset_final_item["filename"] app_prefix = get_app_prefix(user_id, referrer, profile_type) url_prefix = format_url([app_prefix, "_definst_", "amazons3/mp3:"]) file_path = asset_final_item["bucket"] full_path = "{}{}/{}".format(url_prefix, file_path, mp3_file) start_time = int(time.time()) end_time = start_time + int(config.WOWZA_TOKEN_TTL_IN_SECONDS) start_time = start_time - config.WOWZA_GRACE_PERIOD secure_access_token = wowza.get_wowza_secure_access_token( url_prefix, file_path, mp3_file, start_time, end_time, config.WOWZA_SHARED_SECRET_V2, ) wowza_host = config.WOWZA_URL_V2 referrer_map = { "promo.qaawal.com": "https://qa-aws-wowza.qaawal.com", "promo.qaorch.com": "https://qa-aws-wowza.qaorch.com", "promo.qapdesuite.com": "https://qa-aws-wowza.qaorch.com", "promo.awal.com": "https://prod-aws-wowza.awal.com", "promo.theorchard.com": "https://prod-aws-wowza.theorchard.com", "promo.sonymusic.com": "https://prod-aws-wowza.sonymusic.com", } for mapped_referrer, wowza_url in referrer_map.items(): if referrer == mapped_referrer: wowza_host = wowza_url full_url = "{host}/{path}/playlist.m3u8?wowzatokenendtime={end}&wowzatokenstarttime={start}&wowzatokenhash={hash}".format( host=wowza_host, path=full_path, end=end_time, start=start_time, hash=secure_access_token, ) result = {"url": full_url} asset_access_log_data = { "orchard_user_id": user_id_to_log, "track_id": track_id, "activity_type": "streaming", "ip_address": ip_address, } asset_access_log.create_asset_access_log(asset_access_log_data) return result def get_app_prefix( user_id: str | None, referrer: str | None, profile_type: str | None ) -> str: """Get the application prefix.""" return f"{config.WOWZA_PATH_PREFIX_V2}{get_app_modifier(user_id, referrer, profile_type)}" def get_app_modifier( user_id: str | None, referrer: str | None, profile_type: str | None ) -> str: """Get app modifier.""" if profile_type == "ContentProfile": if referrer and "://content." in referrer: return "contentreview" return "local" if user_id == config.SYSTEM_ORCHARD_USER_ID: referrer_map = { "promo.qaawal.com": "promoawal", "promo.qaorch.com": "promo", "promo.awal.com": "promoawal", "promo.theorchard.com": "promo", "promo.sonymusic.com": "promosme", } for mapped_referrer, modifier in referrer_map.items(): if referrer and mapped_referrer in referrer: return modifier return "promo" elif user_id and user_id.startswith("oa:"): return "oa" elif referrer: referrer_map = { "localhost": "local", "qa-frontend-distribution-standalone": "standalone", "workstation74": "qaworkstation74", "workstation-cf": "workstationcf", "workstation.awal.com": "workstationawal", "workstation.sonymusic.com": "workstationsme", } for mapped_referrer, modifier in referrer_map.items(): if mapped_referrer in referrer: return modifier return ""