# This is a script to updated a broswer source with the current youtube live chat URL
# Adapted from code by hmeneses on OBS Forums - the part that grabs the URL from the youtube page.
# 
# By Malcolm E. Greene Jr - HighMoon
#FreePalestine
#v1.0

import obspython as obs
import urllib.request
import urllib.error

url = ""
retry_interval = 15
source_name_browser = ""

def script_load(settings):
    global url
    global retry_interval
    global source_name_browser
    
    url = obs.obs_data_get_string(settings, "ytc_url")
    retry_interval = obs.obs_data_get_int(settings, "ytc_retry_interval")
    source_name_browser = obs.obs_data_get_string(settings, "ytc_browser_source")
    obs.obs_frontend_add_event_callback(on_event)
    
    obs.script_log(obs.LOG_INFO, "YouTube Chat URL update script loaded.")

def on_event(event):
    if event == obs.OBS_FRONTEND_EVENT_STREAMING_STARTED:
        obs.script_log(obs.LOG_INFO, "Streaming started, updating in "+str(retry_interval)+" seconds...")
        obs.timer_add(updateURL, retry_interval * 1000)

def updateURL():
    global url
    global retry_interval
    global source_name_browser

    obs.script_log(obs.LOG_INFO, "Updating YouTube Chat URL...")
    
    try:
        # From here
        with urllib.request.urlopen(url) as response:
             data = response.read()
             txt = str(data)
             x = txt.find("\"videoId\"")
             y = x + 23
             y = txt[x:y]
             z = y.find(":") + 1
             extractvid = y[z:]
             newvid = extractvid.replace("\"","")
             newchatUrl = "https://www.youtube.com/live_chat?dark_theme=1&is_popout=1&v="+newvid
        # To here is hmeneses code 
             obs.script_log(obs.LOG_INFO, "New Chat URL:"+newchatUrl)
        
    except urllib.error.URLError as err:
        obs.script_log(obs.LOG_WARNING, "Error opening URL '" + url + "': " + err.reason + "\n Check your channel URL and refresh the script.")
        obs.remove_current_callback()
        obs.timer_remove(updateURL)    
        pass
    
    source = obs.obs_get_source_by_name(source_name_browser)
    settings = obs.obs_source_get_settings(source)
    oldURL = obs.obs_data_get_string(settings,"url")
    obs.script_log(obs.LOG_INFO, "Current Browser Source URL: "+oldURL)
    
    if newchatUrl == oldURL:
        obs.obs_data_release(settings)
        obs.obs_source_release(source)
        obs.timer_remove(updateURL)    
        obs.script_log(obs.LOG_INFO, "URL has not changed... checking again in "+str(retry_interval)+" seconds.")
        obs.timer_add(updateURL, retry_interval * 1000)
    else:
        obs.obs_data_set_string(settings, "url", newchatUrl)
        obs.obs_source_update(source, settings)
        obs.obs_data_release(settings)
        obs.obs_source_release(source)
        obs.timer_remove(updateURL)    
        obs.script_log(obs.LOG_INFO, "URL updated successfully!")

def script_description():
    return "This scipt updated a browser source to the current YouTube Live Chat URL. \nIf the URL hasn't changed it will retry every X seconds."

def script_update(settings):
    global url
    global retry_interval
    global source_name_browser
    
    url = obs.obs_data_get_string(settings, "ytc_url")
    retry_interval = obs.obs_data_get_int(settings, "ytc_retry_interval")
    source_name_browser = obs.obs_data_get_string(settings, "ytc_browser_source")

def script_properties():
    props = obs.obs_properties_create()

    obs.obs_properties_add_text(props, "ytc_url", "Channel live URL: \n Example: \n https://www.youtube.com/*YourChannelHere*/live", obs.OBS_TEXT_DEFAULT)
    q = obs.obs_properties_add_list(props, "ytc_browser_source", "Browser Source", obs.OBS_COMBO_TYPE_EDITABLE, obs.OBS_COMBO_FORMAT_STRING)

    sources = obs.obs_enum_sources()
    if sources is not None:
        for source in sources:
            source_id = obs.obs_source_get_id(source)
            if source_id == "browser_source":
                nameb = obs.obs_source_get_name(source)
                obs.obs_property_list_add_string(q, nameb, nameb)

        obs.source_list_release(sources)

    obs.obs_properties_add_int(props, "ytc_retry_interval", "Retry Interval (15 to 60 seconds) \n Used if URL didn't change.", 15, 60, 1)
    obs.obs_properties_add_button(props, "ytc_refresh_button", "Start Refresh", refresh_pressed)
    obs.obs_properties_add_button(props, "ytc_stop_button", "Stop Updates", kill_timer)
    
    return props

def kill_timer(props, prop):
    obs.script_log(obs.LOG_INFO, "Stopping Updates!")
    obs.timer_remove(updateURL)

def refresh_pressed(props, prop):
    updateURL()
