Support for multiple Tautulli servers

This commit is contained in:
aunefyren 2022-11-27 18:12:11 +01:00
parent 64fd99302a
commit ffdbf848ca
8 changed files with 377 additions and 141 deletions

4
.dockerignore Normal file
View file

@ -0,0 +1,4 @@
config/*
!config/README.md
wrapperr.exe
wrapperr

View file

@ -110,5 +110,10 @@
"wrapped_start": 1640991600,
"wrapped_end": 1672527540,
"wrapperr_port" : 8282,
"application_name" : "Wrapperr"
"application_name" : "Wrapperr",
"use_cache": true,
"use_logs": true,
"create_share_links": true,
"plex_auth": true,
"winter_theme": true
}

View file

@ -161,26 +161,59 @@ func GetConfig() (*WrapperrConfig, error) {
}
}
// Load config file
file, err := os.Open(config_path)
if err != nil {
log.Println("Get config file threw error trying to open the file.")
return nil, err
}
defer file.Close()
// Parse config file
decoder := json.NewDecoder(file)
config := WrapperrConfig{}
err = decoder.Decode(&config)
if err != nil {
log.Println("Get config file threw error trying to parse the file.")
return nil, err
log.Println("Failed to parse config file. Replacing, but saving backup.")
new_save_loc := config_path + "." + uuid.NewString() + ".replaced"
err = os.Rename(config_path, new_save_loc)
if err != nil {
log.Println("Failed to rename old config file.")
return nil, err
} else {
log.Println("Old config file saved to '" + new_save_loc + "'.")
}
// Load default config file
file, err = os.Open(default_config_path)
if err != nil {
log.Println("Get config file threw error trying to open the template file.")
return nil, err
}
defer file.Close()
// Parse default config file
decoder = json.NewDecoder(file)
config = WrapperrConfig{}
err = decoder.Decode(&config)
if err != nil {
log.Println("Get config file threw error trying to parse the template file.")
return nil, err
}
}
// Load default config file
file, err = os.Open(default_config_path)
if err != nil {
log.Println("Get config file threw error trying to open the template file.")
return nil, err
}
defer file.Close()
// Parse default config file
decoder = json.NewDecoder(file)
config_default := WrapperrConfig{}
err = decoder.Decode(&config_default)
@ -224,6 +257,17 @@ func GetConfig() (*WrapperrConfig, error) {
config.WrappedEnd = config_default.WrappedEnd // If no start time, set to 31 Dec
}
if config.TautulliConfig == nil {
config.TautulliConfig = []TautulliConfig{}
NewTautulliConfig := TautulliConfig{
TautulliLength: config_default.TautulliConfig[0].TautulliLength,
TautulliPort: config_default.TautulliConfig[0].TautulliPort,
}
config.TautulliConfig = append(config.TautulliConfig, NewTautulliConfig)
}
// Set Tautulli length to 5000 if zero is set
if config.TautulliConfig[0].TautulliLength == 0 {
config.TautulliConfig[0].TautulliLength = config_default.TautulliConfig[0].TautulliLength

View file

@ -58,6 +58,26 @@ type WrapperrConfig struct {
WinterTheme bool `json:"winter_theme"`
}
type WrapperrConfigLegacy struct {
TautulliConfig TautulliConfigLegacy `json:"tautulli_config"`
WrapperrCustomize WrapperrCustomize `json:"wrapperr_customize"`
WrapperrVersion string `json:"wrapperr_version"`
Timezone string `json:"timezone"`
ApplicationName string `json:"application_name"`
ApplicationURL string `json:"application_url"`
UseCache bool `json:"use_cache"`
UseLogs bool `json:"use_logs"`
ClientKey string `json:"client_key"`
WrapperrRoot string `json:"wrapperr_root"`
PrivateKey string `json:"private_key"`
CreateShareLinks bool `json:"create_share_links"`
WrappedStart int `json:"wrapped_start"`
WrappedEnd int `json:"wrapped_end"`
WrapperrPort int `json:"wrapperr_port"`
PlexAuth bool `json:"plex_auth"`
WinterTheme bool `json:"winter_theme"`
}
type TautulliConfig struct {
TautulliApiKey string `json:"tautulli_apikey"`
TautulliIP string `json:"tautulli_ip"`
@ -71,6 +91,18 @@ type TautulliConfig struct {
TautulliID int `json:"tautulli_id"`
}
type TautulliConfigLegacy struct {
TautulliApiKey string `json:"tautulli_apikey"`
TautulliIP string `json:"tautulli_ip"`
TautulliPort int `json:"tautulli_port"`
TautulliLength int `json:"tautulli_length"`
TautulliRoot string `json:"tautulli_root"`
TautulliLibraries string `json:"tautulli_libraries"`
TautulliGrouping bool `json:"tautulli_grouping"`
TautulliHttps bool `json:"tautulli_https"`
TautulliID int `json:"tautulli_id"`
}
type WrapperrCustomize struct {
WrapperrFrontPageTitle string `json:"wrapperr_front_page_title"`
WrapperrFrontPageSubtitle string `json:"wrapperr_front_page_subtitle"`
@ -382,9 +414,10 @@ type TautulliGetUsersReply struct {
}
type WrapperrDay struct {
Date string `json:"date"`
Data []TautulliEntry `json:"data"`
DataComplete bool `json:"data_complete"`
Date string `json:"date"`
Data []TautulliEntry `json:"data"`
DataComplete bool `json:"data_complete"`
TautulliServers []string `json:"tautulli_servers"`
}
type TautulliEntry struct {

View file

@ -40,6 +40,7 @@ func ApiWrapperGetStatistics(w http.ResponseWriter, r *http.Request) {
// Check every Tautulli server
for i := 0; i < len(config.TautulliConfig); i++ {
log.Println("Checking Tautulli server '" + config.TautulliConfig[i].TautulliName + "'." + ip_string)
tautulli_state, err := TautulliTestConnection(config.TautulliConfig[i].TautulliPort, config.TautulliConfig[i].TautulliIP, config.TautulliConfig[i].TautulliHttps, config.TautulliConfig[i].TautulliRoot, config.TautulliConfig[i].TautulliApiKey)
if err != nil {
log.Println(err)
@ -243,6 +244,9 @@ func WrapperrDownloadDays(ID int, wrapperr_data []WrapperrDay, loop_interval int
// Go through each Tautulli server
for q := 0; q < len(config.TautulliConfig); q++ {
// Log Tautulli server
log.Println("Checking Tautulli server '" + config.TautulliConfig[q].TautulliName + "'.")
// Define object with end date from wrapped period
end_loop_date := time.Unix(int64(config.WrappedEnd), 0)
@ -271,13 +275,15 @@ func WrapperrDownloadDays(ID int, wrapperr_data []WrapperrDay, loop_interval int
// Clean array to populate with results
wrapperr_day := WrapperrDay{
Date: current_loop_date,
Data: nil,
DataComplete: true,
Date: current_loop_date,
Data: nil,
DataComplete: true,
TautulliServers: []string{},
}
found_date = false
found_date_index = 0
tautulli_server_processed := false
for j := 0; j < len(wrapperr_data); j++ {
time_temp, err := time.Parse("2006-01-02", wrapperr_data[j].Date)
@ -288,16 +294,30 @@ func WrapperrDownloadDays(ID int, wrapperr_data []WrapperrDay, loop_interval int
if time_temp.Format("2006-01-02") == loop_time.Format("2006-01-02") {
found_date_index = j
found_date = true
for y := 0; y < len(wrapperr_data[j].TautulliServers); y++ {
if wrapperr_data[j].TautulliServers[y] == config.TautulliConfig[q].TautulliName {
tautulli_server_processed = true
}
}
wrapperr_day.TautulliServers = wrapperr_data[j].TautulliServers
break
}
}
if found_date && wrapperr_data[found_date_index].DataComplete {
if found_date && wrapperr_data[found_date_index].DataComplete && tautulli_server_processed {
continue
} else if found_date && !wrapperr_data[found_date_index].DataComplete {
log.Println("Date " + current_loop_date + " from server '" + config.TautulliConfig[q].TautulliName + "' marked as incomplete in cache. Refreshing.")
} else if !found_date {
// Remove server downloads for date as it is incomplete
wrapperr_day.TautulliServers = []string{}
} else if !found_date || !tautulli_server_processed {
log.Println("Downloading day: " + current_loop_date + " from server '" + config.TautulliConfig[q].TautulliName + "'.")
} else {
log.Println("Unknown date error from server '" + config.TautulliConfig[q].TautulliName + "'. Skipping.")
@ -361,6 +381,14 @@ func WrapperrDownloadDays(ID int, wrapperr_data []WrapperrDay, loop_interval int
wrapperr_day.DataComplete = false
}
if wrapperr_day.TautulliServers == nil || len(wrapperr_day.TautulliServers) == 0 {
var servers []string
servers = append(servers, config.TautulliConfig[q].TautulliName)
wrapperr_day.TautulliServers = servers
} else {
wrapperr_day.TautulliServers = append(wrapperr_day.TautulliServers, config.TautulliConfig[q].TautulliName)
}
if found_date {
wrapperr_data[found_date_index] = wrapperr_day
} else {

View file

@ -348,7 +348,7 @@ function admin_menu() {
document.getElementById("caching_menu").style.opacity = '0.5';
}
if(tautulli_ip === '' || tautulli_apikey === '' || tautulli_length === '' || tautulli_port == 0 || tautulli_length == 0) {
if(tautulli[0].tautulli_ip === '' || tautulli[0].tautulli_apikey === '' || tautulli[0].tautulli_length === '' || tautulli[0].tautulli_port == 0 || tautulli[0].tautulli_length == 0) {
document.getElementById("set_tautulli_settings").style.border = '0.15em dashed var(--red)';
document.getElementById("caching_menu").disabled = true;
document.getElementById("caching_menu").style.opacity = '0.5';
@ -364,7 +364,8 @@ function set_tautulli_settings() {
topFunction();
var html = '<div class="form-group newline">';
var html = '<div>';
html += '<div class="form-group newline">';
html += '<button class="form-control btn" name="admin_menu_return_button" id="admin_menu_return_button" onclick="get_config(get_cookie(\'wrapperr-admin\'));"><img src="../assets/trash.svg" class="btn_logo"></img><p2 id="admin_menu_return_button_text">Return</p2></button>';
html += '</div>';
@ -374,59 +375,86 @@ function set_tautulli_settings() {
html += '<form id="set_tautulli_form" onsubmit="return false;">'
html += '<div class="form-group">';
html += '<label for="tautulli_apikey" title="The API key is needed for Plex-Wrapped to interact with Tautulli. Commonly found at Tautulli->Settings->Web Interface->API Key.">Tautulli API key:</label>';
html += '<input type="text" class="form-control" id="tautulli_apikey" value="' + tautulli_apikey + '" autocomplete="off" required placeholder="" /><br>';
html += '</div>';
for(var i = 0; i < tautulli.length; i++) {
html += '<div class="form-group">';
html += '<label for="tautulli_ip" title="The IP address or domain that connects to Tautulli. No subfolders, as this is another setting, but subdomains can be defined.">IP or domain for Tautulli connection:</label>';
html += '<input type="text" class="form-control" id="tautulli_ip" value="' + tautulli_ip + '" required placeholder="" /><br>';
html += '</div>';
if(tautulli.length > 1) {
html += '<div class="form-group newline">';
html += '<button style="" type="button" class="form-control btn" id="remove_tautulli_ ' + i + '" onclick="remove_tautulli_server(' + i + ');"><img src="../assets/trash.svg" class="btn_logo"><p2 id="test_tautulli_text">Remove Tautulli server</p2></button>';
html += '</div>';
}
html += '<div class="form-group">';
html += '<label for="tautulli_port" title="The port Tautulli uses for connections. Typically 80 or 443 if a domain is used.">Port for Tautulli:</label>';
html += '<input type="number" class="form-control" id="tautulli_port" value="' + tautulli_port + '" placeholder="" required /><br>';
html += '</div>';
html += '<div class="form-group">';
html += '<label for="tautulli_name_' + i + '" title="Just what we shall name your server.">Tautulli Server name:</label>';
html += '<input type="text" class="form-control" id="tautulli_name_' + i + '" value="' + tautulli[i].tautulli_name + '" autocomplete="off" required placeholder="" /><br>';
html += '</div>';
html += '<div class="form-group">';
html += '<label for="tautulli_length" title="The max amount of entries Tautulli responds with during API calls. Typically doesn\'t need to be changed, but if you have more than 5000 entries in a day, they won\'t be loaded.">Tautlli item length:</label>';
html += '<input type="number" min="0" class="form-control" id="tautulli_length" value="' + tautulli_length + '" autocomplete="off" placeholder="" required /><br>';
html += '</div>';
html += '<div class="form-group">';
html += '<label for="tautulli_apikey_' + i + '" title="The API key is needed for Plex-Wrapped to interact with Tautulli. Commonly found at Tautulli->Settings->Web Interface->API Key.">Tautulli API key:</label>';
html += '<input type="text" class="form-control" id="tautulli_apikey_' + i + '" value="' + tautulli[i].tautulli_apikey + '" autocomplete="off" required placeholder="" /><br>';
html += '</div>';
html += '<div class="form-group">';
html += '<label for="tautulli_root" title="Subfolder for Tautulli, no slashes needed at the beginning or end. It is the folder accessed after the main IP/domain. For example: \'tautulli.com/subfolder\' would mean you enter \'subfolder\' here.">Tautulli URL Base: (Optional)</label>';
html += '<input type="text" class="form-control" id="tautulli_root" value="' + tautulli_root + '" autocomplete="off" placeholder=""/><br>';
html += '</div>';
html += '<div class="form-group">';
html += '<label for="tautulli_ip_' + i + '" title="The IP address or domain that connects to Tautulli. No subfolders, as this is another setting, but subdomains can be defined.">IP or domain for Tautulli connection:</label>';
html += '<input type="text" class="form-control" id="tautulli_ip_' + i + '" value="' + tautulli[i].tautulli_ip + '" required placeholder="" /><br>';
html += '</div>';
html += '<div class="form-group">';
html += '<label for="tautulli_libraries" title="Comma separated list of ID\'s to use for statistics. If none are given, it will search all.">Library ID\'s to use: (Optional)</label>';
html += '<input type="text" class="form-control" id="tautulli_libraries" value="' + tautulli_libraries + '" autocomplete="off" placeholder=""/><br>';
html += '<div class="form-group">';
html += '<label for="tautulli_port_' + i + '" title="The port Tautulli uses for connections. Typically 80 or 443 if a domain is used.">Port for Tautulli:</label>';
html += '<input type="number" class="form-control" id="tautulli_port_' + i + '" value="' + tautulli[i].tautulli_port + '" placeholder="" required /><br>';
html += '</div>';
html += '<div class="form-group">';
html += '<label for="tautulli_length_' + i + '" title="The max amount of entries Tautulli responds with during API calls. Typically doesn\'t need to be changed, but if you have more than 5000 entries in a day, they won\'t be loaded.">Tautlli item length:</label>';
html += '<input type="number" min="0" class="form-control" id="tautulli_length_' + i + '" value="' + tautulli[i].tautulli_length + '" autocomplete="off" placeholder="" required /><br>';
html += '</div>';
html += '<div class="form-group">';
html += '<label for="tautulli_root_' + i + '" title="Subfolder for Tautulli, no slashes needed at the beginning or end. It is the folder accessed after the main IP/domain. For example: \'tautulli.com/subfolder\' would mean you enter \'subfolder\' here.">Tautulli URL Base: (Optional)</label>';
html += '<input type="text" class="form-control" id="tautulli_root_' + i + '" value="' + tautulli[i].tautulli_root + '" autocomplete="off" placeholder=""/><br>';
html += '</div>';
html += '<div class="form-group">';
html += '<label for="tautulli_libraries_' + i + '" title="Comma separated list of ID\'s to use for statistics. If none are given, it will search all.">Library ID\'s to use: (Optional)</label>';
html += '<input type="text" class="form-control" id="tautulli_libraries_' + i + '" value="' + tautulli[i].tautulli_libraries + '" autocomplete="off" placeholder=""/><br>';
html += '</div>';
html += '<div class="form-group newline">';
html += '</div>';
html += '<div class="form-group">';
html += '<label for="tautulli_https_' + i + '" title="Enable if your connection uses HTTPS.">Use HTTPS:</label>';
html += '<input type="checkbox" class="form-control" id="tautulli_https_' + i + '" ';
if(tautulli[i].tautulli_https) {
html += 'checked="' + tautulli[i].tautulli_https + '" ';
}
html += '/><br>';
html += '</div>';
html += '<div class="form-group">';
html += '<label for="tautulli_grouping_' + i + '" title="If Tautulli should group related plays into one entry.">Use Tautulli grouping:</label>';
html += '<input type="checkbox" class="form-control" id="tautulli_grouping_' + i + '" ';
if(tautulli[i].tautulli_grouping) {
html += 'checked="' + tautulli[i].tautulli_grouping + '" ';
}
html += '/><br>';
html += '</div>';
html += '<div class="form-group newline">';
html += '<button style="background-color: lightgrey;" type="button" class="form-control btn" id="test_connection_' + i + '" onclick="test_tautulli_connection(' + i + ')"><img src="../assets/synchronize.svg" class="btn_logo"><p2 id="test_tautulli_text">Test Tautulli connection</p2></button>';
html += '</div>';
html += '<div class="form-group newline">';
html += '<hr>';
html += '</div>';
}
html += '<div class="form-group newline">';
html += '<button style="" type="button" class="form-control btn" id="add_tautulli_server" onclick="additional_tautulli_server();"><img src="../assets/plus.svg" class="btn_logo"><p2 id="test_tautulli_text">Add Tautulli server</p2></button>';
html += '</div>';
html += '<div class="form-group newline">';
html += '</div>';
html += '<div class="form-group">';
html += '<label for="tautulli_https" title="Enable if your connection uses HTTPS.">Use HTTPS:</label>';
html += '<input type="checkbox" class="form-control" id="tautulli_https" ';
if(tautulli_https) {
html += 'checked="' + tautulli_https + '" ';
}
html += '/><br>';
html += '</div>';
html += '<div class="form-group">';
html += '<label for="tautulli_grouping" title="If Tautulli should group related plays into one entry.">Use Tautulli grouping:</label>';
html += '<input type="checkbox" class="form-control" id="tautulli_grouping" ';
if(tautulli_grouping) {
html += 'checked="' + tautulli_grouping + '" ';
}
html += '/><br>';
html += '</div>';
html += '<div class="form-group newline">';
html += '<button style="background-color: lightgrey;" type="button" class="form-control btn" id="test_connection" onclick="test_tautulli_connection()"><img src="../assets/synchronize.svg" class="btn_logo"><p2 id="test_tautulli_text">Test Tautulli connection</p2></button>';
html += '<hr>';
html += '</div>';
html += '<div class="form-group newline" title="Clear the cache now to include the newest settings.">';
@ -440,75 +468,182 @@ function set_tautulli_settings() {
html += '</form>';
html += '</div>';
document.getElementById("setup").innerHTML = html;
}
function additional_tautulli_server() {
tautulli_apikey = ""
tautulli_ip = ""
tautulli_port = ""
tautulli_length = 5000
tautulli_root = ""
tautulli_libraries = ""
tautulli_grouping = true
tautulli_https = false
tautulli_name = ""
tautulli_object = {
"tautulli_apikey" : tautulli_apikey,
"tautulli_ip" : tautulli_ip,
"tautulli_port" : tautulli_port,
"tautulli_length" : tautulli_length,
"tautulli_root" : tautulli_root,
"tautulli_libraries" : tautulli_libraries,
"tautulli_grouping" : tautulli_grouping,
"tautulli_https" : tautulli_https,
"tautulli_name" : ""
};
tautulli.push(tautulli_object);
set_tautulli_settings();
return;
}
function remove_tautulli_server(index) {
if(tautulli.length < 2) {
return
}
tautullinew = []
for(var i = 0; i < tautulli.length; i++) {
if(i !== index) {
tautullinew.push(tautulli[i])
}
}
tautulli = tautullinew
set_tautulli_settings();
return;
}
function set_tautulli_settings_call() {
document.getElementById("set_tautulli_form_button").disabled = true;
document.getElementById("set_tautulli_form_button").style.opacity = '0.5';
tautulli_apikey = document.getElementById('tautulli_apikey').value;
tautulli_ip = document.getElementById('tautulli_ip').value;
tautulli_port = parseInt(document.getElementById('tautulli_port').value);
tautulli_length = parseInt(document.getElementById('tautulli_length').value);
tautulli_root = document.getElementById('tautulli_root').value;
tautulli_libraries = document.getElementById('tautulli_libraries').value;
tautulli_grouping = document.getElementById('tautulli_grouping').checked;
tautulli_https = document.getElementById('tautulli_https').checked;
var tautulli_settings_array = []
for(var i = 0; i < 100; i++) {
try {
tautulli_apikey = document.getElementById('tautulli_apikey_' + i).value;
} catch {
break;
}
tautulli_apikey = document.getElementById('tautulli_apikey_' + i).value;
tautulli_ip = document.getElementById('tautulli_ip_' + i).value;
tautulli_port = parseInt(document.getElementById('tautulli_port_' + i).value);
tautulli_length = parseInt(document.getElementById('tautulli_length_' + i).value);
tautulli_root = document.getElementById('tautulli_root_' + i).value;
tautulli_libraries = document.getElementById('tautulli_libraries_' + i).value;
tautulli_grouping = document.getElementById('tautulli_grouping_' + i).checked;
tautulli_https = document.getElementById('tautulli_https_' + i).checked;
tautulli_name = document.getElementById('tautulli_name_' + i).value;
if(tautulli_apikey === '') {
document.getElementById("set_tautulli_form_button").disabled = false;
document.getElementById("set_tautulli_form_button").style.opacity = '1';
alert('API key is required for Tautulli to function.');
document.getElementById('tautulli_apikey_' + i).focus();
return;
}
if(tautulli_apikey === '') {
document.getElementById("set_tautulli_form_button").disabled = false;
document.getElementById("set_tautulli_form_button").style.opacity = '1';
alert('Server name is required for Tautulli to function.');
document.getElementById('tautulli_name_' + i).focus();
return;
}
if(tautulli_ip === '') {
document.getElementById("set_tautulli_form_button").disabled = false;
document.getElementById("set_tautulli_form_button").style.opacity = '1';
alert('Tautulli IP is required for Tautulli to function.');
document.getElementById('tautulli_ip_' + i).focus();
return;
}
if(tautulli_length == 0) {
document.getElementById("set_tautulli_form_button").disabled = false;
document.getElementById("set_tautulli_form_button").style.opacity = '1';
alert('Tautulli item length is required for Tautulli to function.');
document.getElementById('tautulli_length_' + i).focus();
return;
}
if(tautulli_port == 0) {
document.getElementById("set_tautulli_form_button").disabled = false;
document.getElementById("set_tautulli_form_button").style.opacity = '1';
alert('Tautulli port is required for Tautulli to function. Use 80 for HTTP, 443 for HTTPS.');
document.getElementById('tautulli_port_' + i).focus();
return;
}
tautulli_object = {
"tautulli_apikey" : tautulli_apikey,
"tautulli_ip" : tautulli_ip,
"tautulli_port" : tautulli_port,
"tautulli_length" : tautulli_length,
"tautulli_root" : tautulli_root,
"tautulli_libraries" : tautulli_libraries,
"tautulli_grouping" : tautulli_grouping,
"tautulli_https" : tautulli_https,
"tautulli_name" : tautulli_name
};
tautulli_settings_array.push(tautulli_object)
}
if(tautulli_settings_array.length < 1) {
alert("Failed to save Tautulli settings.")
document.getElementById("set_tautulli_form_button").disabled = false;
document.getElementById("set_tautulli_form_button").style.opacity = '1';
return
}
var name_array = []
for(var i = 0; i < tautulli_settings_array.length; i++) {
var found_name = false
for(var j = 0; j < name_array.length; j++) {
if(tautulli_settings_array[i].tautulli_name == name_array[j]) {
found_name = true
}
}
if(found_name) {
alert("Tautulli server names must be unique.")
document.getElementById("set_tautulli_form_button").disabled = false;
document.getElementById("set_tautulli_form_button").style.opacity = '1';
return
} else {
name_array.push(tautulli_settings_array[i].tautulli_name)
}
}
clear_cache = document.getElementById('clear_cache').checked;
if(tautulli_apikey === '') {
document.getElementById("set_tautulli_form_button").disabled = false;
document.getElementById("set_tautulli_form_button").style.opacity = '1';
alert('API key is required for Tautulli to function.');
document.getElementById('tautulli_apikey').focus();
return;
}
if(tautulli_ip === '') {
document.getElementById("set_tautulli_form_button").disabled = false;
document.getElementById("set_tautulli_form_button").style.opacity = '1';
alert('Tautulli IP is required for Tautulli to function.');
document.getElementById('tautulli_ip').focus();
return;
}
if(tautulli_length == 0) {
document.getElementById("set_tautulli_form_button").disabled = false;
document.getElementById("set_tautulli_form_button").style.opacity = '1';
alert('Tautulli item length is required for Tautulli to function.');
document.getElementById('tautulli_length').focus();
return;
}
if(tautulli_port == 0) {
document.getElementById("set_tautulli_form_button").disabled = false;
document.getElementById("set_tautulli_form_button").style.opacity = '1';
alert('Tautulli port is required for Tautulli to function. Use 80 for HTTP, 443 for HTTPS.');
document.getElementById('tautulli_port').focus();
return;
}
tautulli_settings_form = {
"clear_cache" : clear_cache,
"data_type" : "tautulli_config",
"tautulli_config" : {
"tautulli_apikey" : tautulli_apikey,
"tautulli_ip" : tautulli_ip,
"tautulli_port" : tautulli_port,
"tautulli_length" : tautulli_length,
"tautulli_root" : tautulli_root,
"tautulli_libraries" : tautulli_libraries,
"tautulli_grouping" : tautulli_grouping,
"tautulli_https" : tautulli_https
},
"tautulli_config" : tautulli_settings_array,
"wrapperr_data" : {},
"wrapperr_customize" : {}
};
var tautulli_settings_data = JSON.stringify(tautulli_settings_form);
console.log(tautulli_settings_data)
//return;
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4) {
@ -2214,18 +2349,18 @@ function log_form(log_lines_array, limit) {
log_results.scrollTop = log_results.scrollHeight;
}
function test_tautulli_connection() {
document.getElementById("test_connection").disabled = true;
document.getElementById("test_connection").style.opacity = '0.5';
function test_tautulli_connection(tautulli_id) {
document.getElementById("test_connection_" + tautulli_id).disabled = true;
document.getElementById("test_connection_" + tautulli_id).style.opacity = '0.5';
var button = document.getElementById('test_connection');
var button = document.getElementById('test_connection_' + tautulli_id);
button.style.backgroundColor = 'lightgrey';
https_temp = document.getElementById('tautulli_https').checked;
ip_temp = document.getElementById('tautulli_ip').value;
root_temp = document.getElementById('tautulli_root').value;
port_temp = parseInt(document.getElementById('tautulli_port').value);
api_temp = document.getElementById('tautulli_apikey').value;
https_temp = document.getElementById('tautulli_https_' + tautulli_id).checked;
ip_temp = document.getElementById('tautulli_ip_' + tautulli_id).value;
root_temp = document.getElementById('tautulli_root_' + tautulli_id).value;
port_temp = parseInt(document.getElementById('tautulli_port_' + tautulli_id).value);
api_temp = document.getElementById('tautulli_apikey_' + tautulli_id).value;
config_form = {"tautulli_https" : https_temp, "tautulli_apikey" : api_temp, "tautulli_port" : port_temp, "tautulli_root" : root_temp, "tautulli_ip" : ip_temp};
@ -2240,27 +2375,27 @@ function test_tautulli_connection() {
console.log('Failed to parse API response. Response: ' + this.responseText)
alert('Failed to parse API response.');
button.style.backgroundColor = 'var(--red)';
document.getElementById("test_connection").disabled = false;
document.getElementById("test_connection").style.opacity = '1';
document.getElementById("test_connection_" + tautulli_id).disabled = false;
document.getElementById("test_connection_" + tautulli_id).style.opacity = '1';
return;
}
if(result.error) {
button.style.backgroundColor = 'var(--red)';
document.getElementById("test_connection").disabled = false;
document.getElementById("test_connection").style.opacity = '1';
document.getElementById("test_connection_" + tautulli_id).disabled = false;
document.getElementById("test_connection_" + tautulli_id).style.opacity = '1';
alert(result.message);
return
}
if(result.data) {
button.style.backgroundColor = 'var(--green)';
document.getElementById("test_connection").disabled = false;
document.getElementById("test_connection").style.opacity = '1';
document.getElementById("test_connection_" + tautulli_id).disabled = false;
document.getElementById("test_connection_" + tautulli_id).style.opacity = '1';
} else {
button.style.backgroundColor = 'var(--red)';
document.getElementById("test_connection").disabled = false;
document.getElementById("test_connection").style.opacity = '1';
document.getElementById("test_connection_" + tautulli_id).disabled = false;
document.getElementById("test_connection_" + tautulli_id).style.opacity = '1';
}
}
};
@ -2388,14 +2523,7 @@ function get_config(cookie) {
alert(result.message);
location.reload();
} else {
tautulli_apikey = result.data.tautulli_config.tautulli_apikey;
tautulli_ip = result.data.tautulli_config.tautulli_ip;
tautulli_port = result.data.tautulli_config.tautulli_port;
tautulli_length = result.data.tautulli_config.tautulli_length;
tautulli_root = result.data.tautulli_config.tautulli_root;
tautulli_libraries = result.data.tautulli_config.tautulli_libraries;
tautulli_grouping = result.data.tautulli_config.tautulli_grouping;
tautulli_https = result.data.tautulli_config.tautulli_https;
tautulli = result.data.tautulli_config;
timezone = result.data.timezone;
create_share_links = result.data.create_share_links;

View file

@ -51,14 +51,7 @@ var root = "../";
var first_time = false;
var wrapperr_version = '';
var tautulli_apikey = '';
var tautulli_ip = '';
var tautulli_port = '';
var tautulli_length = '';
var tautulli_root = '';
var tautulli_libraries = '';
var tautulli_grouping = '';
var tautulli_https = '';
var tautulli_apikey = [];
var password = '';
var username = '';

1
web/assets/plus.svg Normal file
View file

@ -0,0 +1 @@
<?xml version="1.0"?><svg fill="#000000" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="192px" height="192px"> <path d="M12,2C6.477,2,2,6.477,2,12s4.477,10,10,10s10-4.477,10-10S17.523,2,12,2z M16,13h-3v3c0,0.552-0.448,1-1,1h0 c-0.552,0-1-0.448-1-1v-3H8c-0.552,0-1-0.448-1-1v0c0-0.552,0.448-1,1-1h3V8c0-0.552,0.448-1,1-1h0c0.552,0,1,0.448,1,1v3h3 c0.552,0,1,0.448,1,1v0C17,12.552,16.552,13,16,13z"/></svg>

After

Width:  |  Height:  |  Size: 423 B