diff --git a/.github/workflows/docker-image-beta.yml b/.github/workflows/docker-image-beta.yml index e3910c0..de314bd 100644 --- a/.github/workflows/docker-image-beta.yml +++ b/.github/workflows/docker-image-beta.yml @@ -20,7 +20,7 @@ jobs: tags: | type-raw,value=beta flavor: | - latest=true + latest=false - name: Set up QEMU uses: docker/setup-qemu-action@v2 with: diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 2b8578f..912b846 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -33,7 +33,6 @@ jobs: with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - registry: docker.io - name: Login to GHCR uses: docker/login-action@v2 with: diff --git a/main.go b/main.go index 559f7e4..1cf0b1c 100644 --- a/main.go +++ b/main.go @@ -24,22 +24,18 @@ func main() { // Create and define file for logging file, err := os.OpenFile("config/wrapperr.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0666) if err != nil { - log.Println("Failed to load configuration file. Error: ") - log.Println(err) + log.Println("Failed to load configuration file. Error: " + err.Error()) - fmt.Println("Failed to load configuration file. Error: ") - fmt.Println(err) + fmt.Println("Failed to load configuration file. Error: " + err.Error()) os.Exit(1) } config, err := files.GetConfig() if err != nil { - log.Println("Failed to load configuration file. Error: ") - log.Println(err) + log.Println("Failed to load configuration file. Error: " + err.Error()) - fmt.Println("Failed to load configuration file. Error: ") - fmt.Println(err) + fmt.Println("Failed to load configuration file. Error: " + err.Error()) os.Exit(1) } @@ -48,19 +44,16 @@ func main() { if config.Timezone != "" { loc, err := time.LoadLocation(config.Timezone) if err != nil { - fmt.Println("Failed to set time zone from config. Error: ") - fmt.Println(err) + fmt.Println("Failed to set time zone from config. Error: " + err.Error()) fmt.Println("Removing value...") - log.Println("Failed to set time zone from config. Error: ") - log.Println(err) + log.Println("Failed to set time zone from config. Error: " + err.Error()) log.Println("Removing value...") config.Timezone = "" err = files.SaveConfig(config) if err != nil { - log.Println("Failed to set new time zone in the config. Error: ") - log.Println(err) + log.Println("Failed to set new time zone in the config. Error: " + err.Error()) log.Println("Exiting...") os.Exit(1) } @@ -124,8 +117,31 @@ func main() { // Get stats route router.HandleFunc(root+"/api/get/statistics", routes.ApiWrapperGetStatistics) - // Static routes - router.PathPrefix(root).Handler(http.StripPrefix(root, http.FileServer(http.Dir("./web/")))) + // Assets route + assetsFileServer := http.FileServer(http.Dir("./web/assets/")) + router.PathPrefix(root + "/assets").Handler(http.StripPrefix(root+"/assets", assetsFileServer)) + + // JS route + jsFileServer := http.FileServer(http.Dir("./web/js/")) + router.PathPrefix(root + "/js").Handler(http.StripPrefix(root+"/js", jsFileServer)) + + // HTML frontpage route + router.HandleFunc(root+"/", func(w http.ResponseWriter, r *http.Request) { + // Using the http.ServeFile function to serve the frontpage.html file + http.ServeFile(w, r, "./web/html/frontpage.html") + }) + + // HTML admin route + router.HandleFunc(root+"/admin", func(w http.ResponseWriter, r *http.Request) { + // Using the http.ServeFile function to serve the admin.html file + http.ServeFile(w, r, "./web/html/admin.html") + }) + + // TXT robots route + router.HandleFunc(root+"/robots.txt", func(w http.ResponseWriter, r *http.Request) { + // Using the http.ServeFile function to serve the robots.txt file + http.ServeFile(w, r, "./web/txt/robots.txt") + }) // Start web-server log.Fatal(http.ListenAndServe(":"+strconv.Itoa(port), router)) diff --git a/models/models.go b/models/models.go index cf4ab96..7e048f5 100644 --- a/models/models.go +++ b/models/models.go @@ -422,25 +422,26 @@ type WrapperrDay struct { } type TautulliEntry struct { - Date int `json:"date"` - Duration int `json:"duration"` - RowID int `json:"row_id"` - FriendlyName string `json:"friendly_name"` - FullTitle string `json:"full_title"` - GrandparentRatingKey int `json:"grandparent_rating_key"` - GrandparentTitle string `json:"grandparent_title"` - OriginalTitle string `json:"original_title"` - MediaType string `json:"media_type"` - ParentRatingKey int `json:"parent_rating_key"` - ParentTitle string `json:"parent_title"` - PausedCounter int `json:"paused_counter"` - PercentComplete int `json:"percent_complete"` - RatingKey int `json:"rating_key"` - Title string `json:"title"` - User string `json:"user"` - UserID int `json:"user_id"` - Year int `json:"year"` - Plays int `json:"plays"` + Date int `json:"date"` + Duration int `json:"duration"` + RowID int `json:"row_id"` + FriendlyName string `json:"friendly_name"` + FullTitle string `json:"full_title"` + GrandparentRatingKey int `json:"grandparent_rating_key"` + GrandparentTitle string `json:"grandparent_title"` + OriginalTitle string `json:"original_title"` + MediaType string `json:"media_type"` + ParentRatingKey int `json:"parent_rating_key"` + ParentTitle string `json:"parent_title"` + PausedCounter int `json:"paused_counter"` + PercentComplete int `json:"percent_complete"` + RatingKey int `json:"rating_key"` + Title string `json:"title"` + User string `json:"user"` + UserID int `json:"user_id"` + Year int `json:"year"` + OriginallyAvailableAt string `json:"originally_available_at"` + Plays int `json:"plays"` } type WrapperrYearUserEntry struct { diff --git a/modules/tautulli.go b/modules/tautulli.go index 0ea4449..3ee2bd9 100644 --- a/modules/tautulli.go +++ b/modules/tautulli.go @@ -15,39 +15,56 @@ import ( func TautulliTestConnection(TautulliPort int, TautulliIP string, TautulliHttps bool, TautulliRoot string, TautulliApiKey string) (bool, error) { - url_string, err := utilities.BuildURL(TautulliPort, TautulliIP, TautulliHttps, TautulliRoot) + urlString, err := utilities.BuildURL(TautulliPort, TautulliIP, TautulliHttps, TautulliRoot) if err != nil { - log.Println(err) + errString := strings.Replace(err.Error(), TautulliApiKey, "REDACTED", -1) + log.Println("Failed to build Tautulli connection URL. Error: " + errString) return false, errors.New("Failed to build Tautulli connection URL.") } - url_string = url_string + "api/v2/" + "?apikey=" + TautulliApiKey + "&cmd=status" + urlString = urlString + "api/v2/" + "?apikey=" + TautulliApiKey + "&cmd=status" params := url.Values{} payload := strings.NewReader(params.Encode()) - req, err := http.NewRequest("GET", url_string, payload) + req, err := http.NewRequest("GET", urlString, payload) if err != nil { - log.Println(err) - return false, errors.New("Failed to reach Tautulli server.") + errString := strings.Replace(err.Error(), TautulliApiKey, "REDACTED", -1) + log.Println("Failed to reach Tautulli server. Error: " + errString) + return false, errors.New("Failed to reach Tautulli server. Error: " + errString) } req.Header.Add("Accept", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { - log.Println(err) - return false, errors.New("Failed to reach Tautulli server.") + errString := strings.Replace(err.Error(), TautulliApiKey, "REDACTED", -1) + log.Println("Failed to reach Tautulli server. Error: " + errString) + return false, errors.New("Failed to reach Tautulli server. Error: " + errString) } defer res.Body.Close() body, err := ioutil.ReadAll(res.Body) + if err != nil { + errString := strings.Replace(err.Error(), TautulliApiKey, "REDACTED", -1) + log.Println("Failed to read Tautulli server response. Error: " + errString) + return false, errors.New("Failed to read Tautulli response. Error: " + errString) + } else if res.StatusCode != 200 { + errString := "Tautulli didn't respond with status code 200, got: " + res.Status + " instead." + reply := string(body) + replyString := strings.Replace(reply, TautulliApiKey, "REDACTED", -1) + log.Println("Failed to connect to Tautulli server. \n\nReply: " + replyString + ". +n\nError: " + errString) + return false, errors.New("Failed to connect to Tautulli server. \n\nReply: " + replyString + ". \n\nError: " + errString) + } var body_reply models.TautulliStatusReply - json.Unmarshal(body, &body_reply) + err = json.Unmarshal(body, &body_reply) if err != nil { - log.Println(err) - return false, errors.New("Failed to parse Tautulli response.") + errString := strings.Replace(err.Error(), TautulliApiKey, "REDACTED", -1) + reply := string(body) + replyString := strings.Replace(reply, TautulliApiKey, "REDACTED", -1) + log.Println("Failed to parse Tautulli server response. \n\nReply: " + replyString + ". +n\nError: " + errString) + return false, errors.New("Failed to parse Tautulli server response. \n\nReply: " + replyString + ". \n\nError: " + errString) } var tautulli_status bool = false @@ -56,6 +73,12 @@ func TautulliTestConnection(TautulliPort int, TautulliIP string, TautulliHttps b tautulli_status = true + } else if body_reply.Response.Result == "error" { + + errString := strings.Replace(body_reply.Response.Message, TautulliApiKey, "REDACTED", -1) + log.Println("Tautulli server responsed with an error. Error: " + errString) + return false, errors.New("Tautulli server responsed with an error. Error: " + errString) + } return tautulli_status, nil diff --git a/routes/no_auth.go b/routes/no_auth.go index bde7ee6..cabcbb7 100644 --- a/routes/no_auth.go +++ b/routes/no_auth.go @@ -304,8 +304,7 @@ func ApiGetTautulliConncection(w http.ResponseWriter, r *http.Request) { tautulli_state, err := modules.TautulliTestConnection(tautulli_connection.TautulliPort, tautulli_connection.TautulliIP, tautulli_connection.TautulliHttps, tautulli_connection.TautulliRoot, tautulli_connection.TautulliApiKey) if err != nil { - log.Println(err) - utilities.RespondDefaultError(w, r, errors.New("Failed to reach Tautulli server."), 500) + utilities.RespondDefaultError(w, r, err, 500) return } diff --git a/routes/statistics.go b/routes/statistics.go index 4cd9085..ed2d4b4 100644 --- a/routes/statistics.go +++ b/routes/statistics.go @@ -376,25 +376,27 @@ func WrapperrDownloadDays(ID int, wrapperr_data []models.WrapperrDay, loop_inter // Loop through retrieved data from Tautulli for j := 0; j < len(tautulli_data); j++ { if tautulli_data[j].MediaType == "movie" || tautulli_data[j].MediaType == "episode" || tautulli_data[j].MediaType == "track" { + tautulli_entry := models.TautulliEntry{ - Date: tautulli_data[j].Date, - RowID: tautulli_data[j].RowID, - Duration: tautulli_data[j].Duration, - FriendlyName: tautulli_data[j].FriendlyName, - FullTitle: tautulli_data[j].FullTitle, - GrandparentRatingKey: tautulli_data[j].GrandparentRatingKey, - GrandparentTitle: tautulli_data[j].GrandparentTitle, - OriginalTitle: tautulli_data[j].OriginalTitle, - MediaType: tautulli_data[j].MediaType, - ParentRatingKey: tautulli_data[j].ParentRatingKey, - ParentTitle: tautulli_data[j].ParentTitle, - PausedCounter: tautulli_data[j].PausedCounter, - PercentComplete: tautulli_data[j].PercentComplete, - RatingKey: tautulli_data[j].RatingKey, - Title: tautulli_data[j].Title, - User: tautulli_data[j].User, - UserID: tautulli_data[j].UserID, - Year: tautulli_data[j].Year, + Date: tautulli_data[j].Date, + RowID: tautulli_data[j].RowID, + Duration: tautulli_data[j].Duration, + FriendlyName: tautulli_data[j].FriendlyName, + FullTitle: tautulli_data[j].FullTitle, + GrandparentRatingKey: tautulli_data[j].GrandparentRatingKey, + GrandparentTitle: tautulli_data[j].GrandparentTitle, + OriginalTitle: tautulli_data[j].OriginalTitle, + MediaType: tautulli_data[j].MediaType, + ParentRatingKey: tautulli_data[j].ParentRatingKey, + ParentTitle: tautulli_data[j].ParentTitle, + PausedCounter: tautulli_data[j].PausedCounter, + PercentComplete: tautulli_data[j].PercentComplete, + RatingKey: tautulli_data[j].RatingKey, + Title: tautulli_data[j].Title, + User: tautulli_data[j].User, + UserID: tautulli_data[j].UserID, + Year: tautulli_data[j].Year, + OriginallyAvailableAt: tautulli_data[j].OriginallyAvailableAt, } // Append to day data @@ -490,7 +492,7 @@ func WrapperrLoopData(user_id int, config *models.WrapperrConfig, wrapperr_data // Look for movie within pre-defined array for d := 0; d < len(wrapperr_user_movie); d++ { - if wrapperr_user_movie[d].Year == wrapperr_data[i].Data[j].Year && wrapperr_user_movie[d].Title == wrapperr_data[i].Data[j].Title { + if ((wrapperr_user_movie[d].Year == wrapperr_data[i].Data[j].Year && wrapperr_data[i].Data[j].OriginallyAvailableAt == "") || wrapperr_user_movie[d].OriginallyAvailableAt == wrapperr_data[i].Data[j].OriginallyAvailableAt) && wrapperr_user_movie[d].Title == wrapperr_data[i].Data[j].Title { wrapperr_user_movie[d].Plays += 1 wrapperr_user_movie[d].Duration += wrapperr_data[i].Data[j].Duration wrapperr_user_movie[d].PausedCounter += wrapperr_data[i].Data[j].PausedCounter @@ -515,7 +517,8 @@ func WrapperrLoopData(user_id int, config *models.WrapperrConfig, wrapperr_data // Look for episode within pre-defined array for d := 0; d < len(wrapperr_user_episode); d++ { - if wrapperr_user_episode[d].Year == wrapperr_data[i].Data[j].Year && wrapperr_user_episode[d].Title == wrapperr_data[i].Data[j].Title { + + if ((wrapperr_user_episode[d].Year == wrapperr_data[i].Data[j].Year && wrapperr_data[i].Data[j].OriginallyAvailableAt == "") || wrapperr_user_episode[d].OriginallyAvailableAt == wrapperr_data[i].Data[j].OriginallyAvailableAt) && wrapperr_user_episode[d].Title == wrapperr_data[i].Data[j].Title && wrapperr_user_episode[d].ParentTitle == wrapperr_data[i].Data[j].ParentTitle && wrapperr_user_episode[d].GrandparentTitle == wrapperr_data[i].Data[j].GrandparentTitle { wrapperr_user_episode[d].Plays += 1 wrapperr_user_episode[d].Duration += wrapperr_data[i].Data[j].Duration wrapperr_user_episode[d].PausedCounter += wrapperr_data[i].Data[j].PausedCounter @@ -558,7 +561,7 @@ func WrapperrLoopData(user_id int, config *models.WrapperrConfig, wrapperr_data // Look for track within pre-defined array for d := 0; d < len(wrapperr_user_track); d++ { - if wrapperr_user_track[d].Year == wrapperr_data[i].Data[j].Year && wrapperr_user_track[d].Title == wrapperr_data[i].Data[j].Title { + if ((wrapperr_user_track[d].Year == wrapperr_data[i].Data[j].Year && wrapperr_data[i].Data[j].OriginallyAvailableAt == "") || wrapperr_user_track[d].OriginallyAvailableAt == wrapperr_data[i].Data[j].OriginallyAvailableAt) && wrapperr_user_track[d].Title == wrapperr_data[i].Data[j].Title { wrapperr_user_track[d].Plays += 1 wrapperr_user_track[d].Duration += wrapperr_data[i].Data[j].Duration wrapperr_user_track[d].PausedCounter += wrapperr_data[i].Data[j].PausedCounter @@ -580,7 +583,7 @@ func WrapperrLoopData(user_id int, config *models.WrapperrConfig, wrapperr_data // Look for album within pre-defined array for d := 0; d < len(wrapperr_user_album); d++ { - if wrapperr_user_album[d].Year == wrapperr_data[i].Data[j].Year && wrapperr_user_album[d].ParentTitle == wrapperr_data[i].Data[j].ParentTitle { + if ((wrapperr_user_album[d].Year == wrapperr_data[i].Data[j].Year && wrapperr_data[i].Data[j].OriginallyAvailableAt == "") || wrapperr_user_album[d].OriginallyAvailableAt == wrapperr_data[i].Data[j].OriginallyAvailableAt) && wrapperr_user_album[d].ParentTitle == wrapperr_data[i].Data[j].ParentTitle { wrapperr_user_album[d].Plays += 1 wrapperr_user_album[d].Duration += wrapperr_data[i].Data[j].Duration wrapperr_user_album[d].PausedCounter += wrapperr_data[i].Data[j].PausedCounter @@ -627,7 +630,7 @@ func WrapperrLoopData(user_id int, config *models.WrapperrConfig, wrapperr_data // Look for movie within pre-defined array for d := 0; d < len(wrapperr_year_movie); d++ { - if wrapperr_year_movie[d].Year == wrapperr_data[i].Data[j].Year && wrapperr_year_movie[d].Title == wrapperr_data[i].Data[j].Title { + if ((wrapperr_year_movie[d].Year == wrapperr_data[i].Data[j].Year && wrapperr_data[i].Data[j].OriginallyAvailableAt == "") || wrapperr_year_movie[d].OriginallyAvailableAt == wrapperr_data[i].Data[j].OriginallyAvailableAt) && wrapperr_year_movie[d].Title == wrapperr_data[i].Data[j].Title { wrapperr_year_movie[d].Plays += 1 wrapperr_year_movie[d].Duration += wrapperr_data[i].Data[j].Duration wrapperr_year_movie[d].PausedCounter += wrapperr_data[i].Data[j].PausedCounter @@ -677,7 +680,7 @@ func WrapperrLoopData(user_id int, config *models.WrapperrConfig, wrapperr_data // Look for show within pre-defined array for d := 0; d < len(wrapperr_year_show); d++ { - if wrapperr_year_show[d].Year == wrapperr_data[i].Data[j].Year && wrapperr_year_show[d].GrandparentTitle == wrapperr_data[i].Data[j].GrandparentTitle { + if wrapperr_year_show[d].GrandparentTitle == wrapperr_data[i].Data[j].GrandparentTitle { wrapperr_year_show[d].Plays += 1 wrapperr_year_show[d].Duration += wrapperr_data[i].Data[j].Duration wrapperr_year_show[d].PausedCounter += wrapperr_data[i].Data[j].PausedCounter @@ -859,7 +862,7 @@ func WrapperrLoopData(user_id int, config *models.WrapperrConfig, wrapperr_data count += 1 } - // Find longest pause + // Find the longest duration spent on a certain episode sortutil.DescByField(wrapperr_user_episode, "Duration") wrapperr_reply.User.UserShows.Data.EpisodeDurationLongest.Duration = wrapperr_user_episode[0].Duration wrapperr_reply.User.UserShows.Data.EpisodeDurationLongest.GrandparentTitle = wrapperr_user_episode[0].GrandparentTitle diff --git a/web/admin/index.html b/web/html/admin.html similarity index 94% rename from web/admin/index.html rename to web/html/admin.html index 73afb63..b375c9c 100644 --- a/web/admin/index.html +++ b/web/html/admin.html @@ -9,12 +9,12 @@ Wrapperr - - + + - - + + @@ -38,8 +38,8 @@ diff --git a/web/index.html b/web/html/frontpage.html similarity index 98% rename from web/index.html rename to web/html/frontpage.html index 4a16f54..6a154f5 100644 --- a/web/index.html +++ b/web/html/frontpage.html @@ -12,10 +12,10 @@ - - - - + + + + diff --git a/web/admin.js b/web/js/admin.js similarity index 97% rename from web/admin.js rename to web/js/admin.js index db80746..e66bfe9 100644 --- a/web/admin.js +++ b/web/js/admin.js @@ -24,7 +24,7 @@ function login_menu() { html += ''; html += '
'; - html += ''; + html += ''; html += '
'; html += ''; @@ -103,7 +103,7 @@ function set_password_form() { html += ''; html += '
'; - html += ''; + html += ''; html += '
'; html += ''; @@ -168,7 +168,7 @@ function update_password_form() { topFunction(); var html = '
'; - html += ''; + html += ''; html += '
'; html += '
'; @@ -197,7 +197,7 @@ function update_password_form() { html += '
'; html += '
'; - html += ''; + html += ''; html += '
'; html += ''; @@ -303,11 +303,11 @@ function sign_out() { function admin_menu() { var html = '
'; - html += ''; + html += ''; html += '
'; html += '
'; - html += ''; + html += ''; html += '
'; html += '
'; @@ -315,23 +315,23 @@ function admin_menu() { html += '
'; html += '
'; - html += ''; + html += ''; html += '
'; html += '
'; - html += ''; + html += ''; html += '
'; html += '
'; - html += ''; + html += ''; html += '
'; html += '
'; - html += ''; + html += ''; html += '
'; html += '
'; - html += ''; + html += ''; html += '
'; document.getElementById("setup").innerHTML = html; @@ -366,7 +366,7 @@ function set_tautulli_settings() { var html = '
'; html += '
'; - html += ''; + html += ''; html += '
'; html += '
'; @@ -379,7 +379,7 @@ function set_tautulli_settings() { if(tautulli.length > 1) { html += '
'; - html += ''; + html += ''; html += '
'; } @@ -440,7 +440,7 @@ function set_tautulli_settings() { html += '
'; html += '
'; - html += ''; + html += ''; html += '
'; html += '
'; @@ -450,7 +450,7 @@ function set_tautulli_settings() { } html += '
'; - html += ''; + html += ''; html += '
'; html += '
'; @@ -467,7 +467,7 @@ function set_tautulli_settings() { html += '
'; html += '
'; - html += ''; + html += ''; html += '
'; html += ''; @@ -684,7 +684,7 @@ function set_wrapperr_settings() { topFunction(); var html = '
'; - html += ''; + html += ''; html += '
'; html += '
'; @@ -732,7 +732,7 @@ function set_wrapperr_settings() { html += '
'; html += '
'; - html += ''; + html += ''; html += '
'; html += '
'; @@ -817,7 +817,7 @@ function set_wrapperr_settings() { html += '
'; html += '
'; - html += ''; + html += ''; html += '
'; html += ''; @@ -954,7 +954,7 @@ function set_wrapperr_customization() { topFunction(); var html = '
'; - html += ''; + html += ''; html += '
'; html += '
'; @@ -1196,7 +1196,7 @@ function set_wrapperr_customization() { html += '
'; html += '
'; - html += ''; + html += ''; html += '
'; html += '
'; @@ -1342,7 +1342,7 @@ function set_wrapperr_customization() { html += '
'; html += '
'; - html += ''; + html += ''; html += '
'; html += '
'; @@ -1466,7 +1466,7 @@ function set_wrapperr_customization() { html += '
'; html += '
'; - html += ''; + html += ''; html += '
'; html += '
'; @@ -1593,7 +1593,7 @@ function set_wrapperr_customization() { html += '
'; html += '
'; - html += ''; + html += ''; html += '
'; html += '
'; @@ -1712,7 +1712,7 @@ function set_wrapperr_customization() { html += '
'; html += '
'; - html += ''; + html += ''; html += '
'; html += '
'; @@ -1729,7 +1729,7 @@ function set_wrapperr_customization() { html += '
'; html += '
'; - html += ''; + html += ''; html += '
'; html += ''; @@ -2071,7 +2071,7 @@ function set_wrapperr_customization_call() { function caching_menu() { var html = '
'; - html += ''; + html += ''; html += '
'; html += '
'; @@ -2106,7 +2106,7 @@ function caching_menu() {
- +
@@ -2118,7 +2118,7 @@ function caching_menu() {
- +
@@ -2158,7 +2158,7 @@ function cache_initiate() {
- +

Caching log:

@@ -2268,7 +2268,7 @@ function get_stats(days) { function log_menu() { var html = '
'; - html += ''; + html += ''; html += '
'; html += '
'; @@ -2303,7 +2303,7 @@ function log_menu() {
- +
@@ -2475,9 +2475,17 @@ function get_wrapper_version() { }; xhttp.withCredentials = true; + // Get the root without "/admin" root = window.location.pathname.replace('/admin', '') - xhttp.open("post", window.location.origin + "/" + root + "api/get/wrapperr-version"); + // Maybe add trailing slash depending on the end of "window.location.origin" + var trailingslash = "" + if(window.location.origin.charAt(window.location.origin.length-1) != "/") { + trailingslash = "/" + } + + // Reach the API to get URL base + xhttp.open("post", window.location.origin + "/" + root + trailingslash + "api/get/wrapperr-version"); xhttp.send(); return; } diff --git a/web/functions.js b/web/js/functions.js similarity index 100% rename from web/functions.js rename to web/js/functions.js diff --git a/web/get_functions.js b/web/js/get_functions.js similarity index 100% rename from web/get_functions.js rename to web/js/get_functions.js diff --git a/web/get_stats.js b/web/js/get_stats.js similarity index 100% rename from web/get_stats.js rename to web/js/get_stats.js diff --git a/web/index.js b/web/js/index.js similarity index 100% rename from web/index.js rename to web/js/index.js diff --git a/web/robots.txt b/web/robots.txt deleted file mode 100644 index 5260874..0000000 --- a/web/robots.txt +++ /dev/null @@ -1,11 +0,0 @@ -# Folders -User-agent: * -Disallow: /api/ -Disallow: /assets/ -Disallow: /config/ -Disallow: /docker/ -# File types -Disallow: /*.json -Disallow: /*.php -Disallow: /*.js -Disallow: /*.md diff --git a/web/txt/robots.txt b/web/txt/robots.txt new file mode 100644 index 0000000..77470cb --- /dev/null +++ b/web/txt/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Disallow: / \ No newline at end of file