__filename__ = "webapp_podcast.py"
__author__ = "Bob Mottram"
__license__ = "AGPL3+"
__version__ = "1.6.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Web Interface Columns"
import os
import html
import datetime
import urllib.parse
from shutil import copyfile
from utils import resembles_url
from utils import get_nickname_from_actor
from utils import get_domain_from_actor
from utils import data_dir
from utils import get_url_from_post
from utils import get_config_param
from utils import remove_html
from media import path_is_audio
from content import safe_web_text
from webapp_utils import get_broken_link_substitute
from webapp_utils import html_header_with_external_style
from webapp_utils import html_footer
from webapp_utils import html_keyboard_navigation
from session import get_json_valid
from session import get_json
MAX_LINK_LENGTH = 40
def _html_podcast_chapters(link_url: str,
                           session, session_onion, session_i2p,
                           http_prefix: str, domain: str,
                           podcast_properties: {},
                           debug: bool,
                           mitm_servers: []) -> str:
    """Returns html for chapters of a podcast
    """
    if not podcast_properties:
        return ''
    key = 'chapters'
    if not podcast_properties.get(key):
        return ''
    if not isinstance(podcast_properties[key], dict):
        return ''
    if podcast_properties[key].get('url'):
        url_str = get_url_from_post(podcast_properties[key]['url'])
        chapters_url = remove_html(url_str)
    elif podcast_properties[key].get('uri'):
        chapters_url = podcast_properties[key]['uri']
    else:
        return ''
    html_str = ''
    if podcast_properties[key].get('type'):
        url_type = podcast_properties[key]['type']
        curr_session = session
        if chapters_url.endswith('.onion'):
            curr_session = session_onion
        elif chapters_url.endswith('.i2p'):
            curr_session = session_i2p
        as_header = {
            'Accept': url_type
        }
        if 'json' in url_type:
            chapters_json = \
                get_json(None, curr_session, chapters_url,
                         as_header, None, debug, mitm_servers, __version__,
                         http_prefix, domain)
            if not get_json_valid(chapters_json):
                return ''
            if not chapters_json.get('chapters'):
                return ''
            if not isinstance(chapters_json['chapters'], list):
                return ''
            chapters_html = ''
            for chapter in chapters_json['chapters']:
                if not isinstance(chapter, dict):
                    continue
                if not chapter.get('title'):
                    continue
                if not chapter.get('startTime'):
                    continue
                chapter_title = chapter['title']
                chapter_url = ''
                if chapter.get('url'):
                    url_str = get_url_from_post(chapter['url'])
                    chapter_url = remove_html(url_str)
                    chapter_title = \
                        '' + \
                        chapter['title'] + '<\a>'
                start_sec = chapter['startTime']
                skip_url = link_url + '#t=' + str(start_sec)
                start_time_str = \
                    ' ' + \
                    str(datetime.timedelta(seconds=start_sec)) + \
                    ' '
                if chapter.get('img'):
                    chapters_html += \
                        '    
\n' + \
                        '      ' + start_time_str + '\n' + \
                        '       \n'
            if chapters_html:
                html_str = \
                    '\n' + \
                    '  \n' + chapters_html + '   \n
\n'
    return html_str
def _html_podcast_transcripts(podcast_properties: {}, translate: {}) -> str:
    """Returns html for transcripts of a podcast
    """
    if not podcast_properties:
        return ''
    key = 'transcripts'
    if not podcast_properties.get(key):
        return ''
    if not isinstance(podcast_properties[key], list):
        return ''
    ctr = 1
    html_str = ''
    for _ in podcast_properties[key]:
        transcript_url = None
        if podcast_properties[key].get('url'):
            url_str = get_url_from_post(podcast_properties[key]['url'])
            transcript_url = remove_html(url_str)
        elif podcast_properties[key].get('uri'):
            transcript_url = podcast_properties[key]['uri']
        if not transcript_url:
            continue
        if ctr > 1:
            html_str += ''
        html_str += translate['Transcript']
        if ctr > 1:
            html_str += ' ' + str(ctr)
        html_str += ' \n'
        ctr += 1
    return html_str
def _html_podcast_social_interactions(podcast_properties: {},
                                      translate: {},
                                      nickname: str) -> str:
    """Returns html for social interactions with a podcast
    """
    if not podcast_properties:
        return ''
    key = 'discussion'
    if not podcast_properties.get(key):
        key = 'socialInteract'
        if not podcast_properties.get(key):
            return ''
    if not isinstance(podcast_properties[key], dict):
        return ''
    if podcast_properties[key].get('uri'):
        episode_post_url = podcast_properties[key]['uri']
    elif podcast_properties[key].get('url'):
        url_str = get_url_from_post(podcast_properties[key]['url'])
        episode_post_url = remove_html(url_str)
    elif podcast_properties[key].get('text'):
        episode_post_url = podcast_properties[key]['text']
    else:
        return ''
    actor_str = ''
    podcast_account_id = None
    if podcast_properties[key].get('accountId'):
        podcast_account_id = podcast_properties[key]['accountId']
    elif podcast_properties[key].get('podcastAccountUrl'):
        podcast_account_id = \
            podcast_properties[key]['podcastAccountUrl']
    if podcast_account_id:
        actor_handle = podcast_account_id
        if actor_handle.startswith('@'):
            actor_handle = actor_handle[1:]
        actor_str = '?actor=' + actor_handle
    podcast_str = \
        '\n' + \
        '  💬 ' + \
        translate['Leave a comment'] + ' \n' + \
        '  \n' + \
        '  ' + \
        translate['View comments'] + ' \n   \n' + \
        ' \n'
    return podcast_str
def _html_podcast_performers(podcast_properties: {}) -> str:
    """Returns html for performers of a podcast
    """
    if not podcast_properties:
        return ''
    key = 'persons'
    if not podcast_properties.get(key):
        return ''
    if not isinstance(podcast_properties[key], list):
        return ''
    # list of performers
    podcast_str = '\n'
    return podcast_str
def _html_podcast_soundbites(link_url: str, extension: str,
                             podcast_properties: {},
                             translate: {}) -> str:
    """Returns html for podcast soundbites
    """
    if not podcast_properties:
        return ''
    if not podcast_properties.get('soundbites'):
        return ''
    podcast_str = '\n'
    return podcast_str
def html_podcast_episode(translate: {},
                         base_dir: str, nickname: str, domain: str,
                         newswire_item: [],
                         text_mode_banner: str,
                         session, session_onion, session_i2p,
                         http_prefix: str, debug: bool,
                         mitm_servers: []) -> str:
    """Returns html for a podcast episode, an item from the newswire
    """
    css_filename = base_dir + '/epicyon-podcast.css'
    if os.path.isfile(base_dir + '/podcast.css'):
        css_filename = base_dir + '/podcast.css'
    dir_str = data_dir(base_dir)
    if os.path.isfile(dir_str + '/podcast-background-custom.jpg'):
        if not os.path.isfile(dir_str + '/podcast-background.jpg'):
            copyfile(dir_str + '/podcast-background.jpg',
                     dir_str + '/podcast-background.jpg')
    instance_title = get_config_param(base_dir, 'instanceTitle')
    preload_images: list[str] = []
    podcast_str = \
        html_header_with_external_style(css_filename, instance_title, None,
                                        preload_images)
    podcast_properties = newswire_item[8]
    image_url = ''
    image_src = 'src'
    if podcast_properties.get('images'):
        if podcast_properties['images'].get('srcset'):
            image_url = podcast_properties['images']['srcset']
            image_src = 'srcset'
    if not image_url and podcast_properties.get('image'):
        image_url = podcast_properties['image']
    link_url = newswire_item[1]
    podcast_str += html_keyboard_navigation(text_mode_banner, {}, {},
                                            None, None, None, False)
    podcast_str += '\n'
    podcast_str += '  
\n'
    podcast_str += '  
\n'
    audio_extension = None
    if path_is_audio(link_url):
        if '.mp3' in link_url:
            audio_extension = 'mpeg'
        elif '.opus' in link_url:
            audio_extension = 'opus'
        elif '.spx' in link_url:
            audio_extension = 'spx'
        elif '.flac' in link_url:
            audio_extension = 'flac'
        elif '.wav' in link_url:
            audio_extension = 'wav'
        else:
            audio_extension = 'ogg'
    else:
        if podcast_properties.get('linkMimeType'):
            if 'audio' in podcast_properties['linkMimeType']:
                audio_extension = \
                    podcast_properties['linkMimeType'].split('/')[1]
    # show widgets for soundbites
    if audio_extension:
        podcast_str += _html_podcast_soundbites(link_url, audio_extension,
                                                podcast_properties,
                                                translate)
        # podcast player widget
        podcast_str += \
            '  \n' + \
            '  \n' + \
            '    ' + \
            translate['Your browser does not support the audio element.'] + \
            '\n    \n   \n'
    elif podcast_properties.get('linkMimeType'):
        if '/youtube' in podcast_properties['linkMimeType']:
            url = link_url.replace('/watch?v=', '/embed/')
            if '&' in url:
                url = url.split('&')[0]
            if '?utm_' in url:
                url = url.split('?utm_')[0]
            podcast_str += \
                '  \n' + \
                "  \n   \n"
        elif 'video' in podcast_properties['linkMimeType']:
            video_mime_type = podcast_properties['linkMimeType']
            video_msg = 'Your browser does not support the video element.'
            podcast_str += \
                '  \n' + \
                '  \n' + \
                '    \n' + \
                '' + \
                translate[video_msg] + \
                '  \n   \n   \n'
    podcast_title = \
        remove_html(html.unescape(urllib.parse.unquote_plus(newswire_item[0])))
    if podcast_title:
        podcast_str += \
            '' + \
            '' + \
            podcast_title + \
            '  
\n'
    if podcast_properties.get('author'):
        author = podcast_properties['author']
        podcast_str += '' + author + '
\n'
    transcripts = _html_podcast_transcripts(podcast_properties, translate)
    if transcripts:
        podcast_str += '' + transcripts + '
\n'
    if newswire_item[4]:
        podcast_description = \
            html.unescape(urllib.parse.unquote_plus(newswire_item[4]))
        podcast_description = safe_web_text(podcast_description)
        if podcast_description:
            podcast_str += \
                '' + \
                podcast_description + ' 
\n'
    # donate button
    if podcast_properties.get('funding'):
        if podcast_properties['funding'].get('url'):
            url_str = get_url_from_post(podcast_properties['funding']['url'])
            donate_url = remove_html(url_str)
            podcast_str += \
                '' + \
                translate['Donate'] + ' 
\n'
    fediverse_handle = ''
    if len(newswire_item) > 9:
        fediverse_handle = newswire_item[9]
        podcast_nickname = get_nickname_from_actor(fediverse_handle)
        podcast_domain, _ = get_domain_from_actor(fediverse_handle)
        if podcast_nickname and podcast_domain:
            podcast_str += \
                '@' + \
                podcast_nickname + '@' + podcast_domain + ' 
\n'
    extra_links: list[str] = []
    if len(newswire_item) > 10:
        extra_links = newswire_item[10]
        if extra_links:
            links_text = ''
            for link_str in extra_links:
                link_str = remove_html(link_str)
                if not resembles_url(link_str):
                    continue
                if link_str in podcast_str:
                    continue
                if not links_text:
                    links_text = '\n'
                link_url = link_str
                # check that the link is not too long so that it does not
                # mess up display on mobile
                if len(link_str) > MAX_LINK_LENGTH:
                    link_str = link_str[:MAX_LINK_LENGTH-1]
                links_text += \
                    '' + link_str + ' 
\n'
                podcast_str += links_text
    if podcast_properties['categories']:
        tags_str = ''
        for tag in podcast_properties['categories']:
            tag = tag.replace('#', '')
            tag_link = '/users/' + nickname + '/tags/' + tag
            tags_str += \
                '#' + \
                '' + tag + ' ' + \
                '  '
        podcast_str += '' + tags_str.strip() + '
\n'
    podcast_str += _html_podcast_performers(podcast_properties)
    podcast_str += \
        _html_podcast_social_interactions(podcast_properties, translate,
                                          nickname)
    podcast_str += \
        _html_podcast_chapters(link_url,
                               session, session_onion, session_i2p,
                               http_prefix, domain,
                               podcast_properties, debug, mitm_servers)
    podcast_str += '   \n'
    podcast_str += '