"""Megaphone API Wrapper.""" from flask import g from podcast.models import category as category_model from podcast.models.api_episode import ApiEpisode from podcast.models.api_network import ApiNetwork from podcast.models.api_podcast import ApiPodcast def create_megaphone_insertion_data(insertion_points, duration_in_ms): """Create megaphone insertion data.""" pre = [x for x in insertion_points if x['point_type'] == 'pre'] post = [x for x in insertion_points if x['point_type'] == 'post'] mids = [x for x in insertion_points if x['point_type'] == 'mid'] insertion_mid_points = [] for mid in mids: for _ in range(mid['count']): insertion_mid_points.append(mid['timecode']) duration_in_sec = duration_in_ms / 1000 if duration_in_ms else 0 return { 'insertion_points': insertion_mid_points, 'pre_count': pre[0]['count'] if len(pre) > 0 else 0, 'pre_offset': pre[0]['timecode'] if len(pre) > 0 else 0, 'post_count': post[0]['count'] if len(post) > 0 else 0, 'post_offset': duration_in_sec - float(post[0]['timecode']) if len(post) > 0 else 0, } def call_episode_api(data, megaphone_podcast_id, megaphone_episode_id, network_id, episode_id): """Call megaphone's episode api.""" if not megaphone_episode_id: g.log.info(f'Create episode: {episode_id} in megaphone with request data: {data}') return ApiEpisode(network_id).create(megaphone_podcast_id, data) else: g.log.info(f'Update episode: {episode_id} in megaphone with request data: {data}') return ApiEpisode(network_id).update(megaphone_podcast_id, megaphone_episode_id, data) def create_or_update_episode(megaphone_podcast_id, episode_data, assets, network_id): """Create or Update episode in Megaphone. Args: megaphone_podcast_id (str): Megaphone Podcast id episode_data (object): episode payload to send to Megaphone. assets (list): list of assets related to the episode. network_id (int): Indentifier of network in Podcast application Returns: response.Response: Success or error message """ insertion_data = create_megaphone_insertion_data( episode_data['insertion_points'], assets['audio_duration'] if 'audio_duration' in assets else None ) if episode_data['content'] == 'clean': explicit_value = 'clean' elif episode_data['content'] == 'explicit': explicit_value = 'yes' else: explicit_value = 'no' megaphone_data = { 'externalId': episode_data['uuid'], 'guid': episode_data['uuid'], 'title': episode_data['title'], 'explicit': explicit_value, 'summary': episode_data['description'], 'episodeNumber': episode_data['episode_number'], 'seasonNumber': episode_data['season_number'], 'pubdate': _get_utc_pubdate(episode_data['published_date']), 'preCount': insertion_data['pre_count'], 'preOffset': insertion_data['pre_offset'], 'postCount': insertion_data['post_count'], 'postOffset': insertion_data['post_offset'], 'expectedAdhash': get_ad_hash(episode_data), 'insertionPoints': insertion_data['insertion_points'], 'backgroundImageFileUrl': assets['x_large_image_url'] if 'x_large_image_url' in assets else None, 'draft': episode_data['draft'], 'retainAdLocations': True } if 'episode_type' in episode_data and episode_data['episode_type']: megaphone_data['episodeType'] = episode_data['episode_type'] if not is_megaphone_audio_processing(megaphone_podcast_id, episode_data['megaphone_id'], network_id): backgroundAudioFileUrl = assets['audio_url'] if 'audio_url' in assets else None megaphone_data['backgroundAudioFileUrl'] = backgroundAudioFileUrl return call_episode_api( megaphone_data, megaphone_podcast_id, episode_data['megaphone_id'], network_id, episode_data['id'] ) def reupload_episode_mp3(megaphone_podcast_id, megaphone_episode_id, network_id, audio_url, episode_id): """Reupload episode mp3 in megaphone. Args: megaphone_podcast_id (str): Megaphone Podcast id megaphone_episode_id (str): Megaphone Episode id network_id (int): Identifier of network in Podcast application audio_url (str): episode mp3 url. episode_id (int): Episode id Returns: response.Response: Success or error message """ megaphone_data = { 'backgroundAudioFileUrl': audio_url, 'retainAdLocations': True } return call_episode_api(megaphone_data, megaphone_podcast_id, megaphone_episode_id, network_id, episode_id) def delete_episode(podcast_megaphone_id, episode_megaphone_id, network_id): """Delete episode on megaphone side. Args: podcast_megaphone_id (str): Identifier of podcast in megaphone episode_megaphone_id (str): Identifier of episode in megaphone network_id (int): Indentifier of network in Podcast application Returns response.Response: containing the megaphone's api response in the message """ return ApiEpisode(network_id).delete(podcast_megaphone_id, episode_megaphone_id) def _call_podcast_api(data, megaphone_podcast_id, network_id): if not megaphone_podcast_id: return ApiPodcast(network_id).create(data) else: return ApiPodcast(network_id).update(megaphone_podcast_id, data) def is_megaphone_audio_processing(podcast_megaphone_id, episode_megaphone_id, network_id): """Get if episode audio is processing in megaphone.""" if not episode_megaphone_id: return False episode = ApiEpisode(network_id).get(podcast_megaphone_id, episode_megaphone_id) return episode['audioFileProcessing'] def create_or_update_podcast(megaphone_id, podcast_data, asset): """Create or update podcast in megaphone. Args: megaphone_id (str): Megaphone's Podcast identifier podcast_data (dict): Podcast data to process asset (dict): Artwork asset object Returns: response.Response containing the response megaphone_response. """ megaphone_data = { 'itunesCategories': _get_categories(podcast_data['categories']), 'summary': podcast_data['description'], 'externalId': podcast_data['id'], 'title': podcast_data['title'], 'slug': podcast_data['slug'], 'author': podcast_data['host'], 'ownerName': podcast_data['owner'], 'copyright': podcast_data['copyright'], 'link': podcast_data['link'], 'ownerEmail': podcast_data['email'], 'explicit': podcast_data['explicit'] == 'explicit', 'language': podcast_data['language'], 'podcastType': podcast_data['show_type'], 'backgroundImageFileUrl': asset.get('x_large_image_url') } network_id = podcast_data['network_id'] return _call_podcast_api(megaphone_data, megaphone_id, network_id) def delete_podcast(megaphone_id, network_id): """Delete podcast and its episodes on megaphone side. Args: megaphone_id (str): Identifier of podcast in megaphone network_id (int): Identifier of the network in Podcast application Returns response.Response: containing the megaphone's api response in the message """ return ApiPodcast(network_id).delete(megaphone_id) def _get_categories(category_ids): categories_response = category_model.get_categories_by_ids(category_ids) return categories_response['items'] def _get_utc_pubdate(pubdate): if not pubdate: return None return pubdate.isoformat() + '.000Z' def get_ad_hash(episode): """Get Ad hash.""" pre = '0' * episode.get('planned_pre_roll_count', 0) mid = '1' * episode.get('planned_mid_roll_count', 0) post = '2' * episode.get('planned_post_roll_count', 0) return pre + mid + post def create_network(name, code): """Create a network.""" return ApiNetwork(is_org=True).create(name, code) def delete_network(megaphone_id): """Delete a network.""" return ApiNetwork(is_org=True).delete(megaphone_id)