From ef3ccfa68698ef947752b5d4aa2887d617c91745 Mon Sep 17 00:00:00 2001 From: Hepatica Date: Sun, 18 Aug 2024 06:36:39 +0200 Subject: [PATCH] Clean + adjusting client layer --- Client/index.html | 446 ++++++++++++++++ Client/scripts.js | 492 ++++++++++++++++++ SpCloud.drawio | 82 ++- SpCloudMain/Controllers/PublishController.cpp | 8 +- SpCloudMain/Service/DiscordService.cpp | 2 +- SpCloudMain/Service/FileProcessingService.cpp | 33 +- SpCloudMain/SpCloudMain.cpp | 2 +- 7 files changed, 1011 insertions(+), 54 deletions(-) create mode 100644 Client/index.html create mode 100644 Client/scripts.js diff --git a/Client/index.html b/Client/index.html new file mode 100644 index 0000000..10b1042 --- /dev/null +++ b/Client/index.html @@ -0,0 +1,446 @@ + + + + + + + SpCloud + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+ + + + + + + + + + + + + + + + + +
+

SpCloud

+
+ +

+
+
+ +
+

Окно для загрузки архива приложения

+
+ + + +
+ +
+ +
+ + + + + + + + + + +
NameAppUrlCpuUsageMemoryUsageTarget
+
+
+

Нагрузка сервера в данный момент

+

CPU/RAM/Memory (N/A)

+
+ +
+ + + + + \ No newline at end of file diff --git a/Client/scripts.js b/Client/scripts.js new file mode 100644 index 0000000..9ee289d --- /dev/null +++ b/Client/scripts.js @@ -0,0 +1,492 @@ +function fetchAndDisplayAppNamesForDelete() { + const myHeaders = new Headers(); + myHeaders.append("Authorization", getCookie("auth_token")); + + const requestOptions = { + method: "GET", + headers: myHeaders, + redirect: "follow" + }; + + fetch("https://spcloudcore.almavid.ru/apps", requestOptions) + .then((response) => response.json()) + .then((result) => { + const apps = result.documents; + const appNameSelect = document.getElementById('deleteAppName'); + + // Clear existing options + appNameSelect.innerHTML = ''; + + // Populate the select dropdown with app names + apps.forEach(app => { + const option = document.createElement('option'); + option.value = app.name; + option.textContent = app.name; + appNameSelect.appendChild(option); + }); + }) + .catch((error) => console.error('Error:', error)); +} + +// Open Delete Modal and populate app names +document.querySelector('.delete-button').addEventListener('click', function () { + fetchAndDisplayAppNamesForDelete(); + document.getElementById('deleteModal').style.display = "block"; +}); + +// Close Delete Modal +document.querySelector('#deleteModal .close').onclick = function () { + document.getElementById('deleteModal').style.display = "none"; +} + +// Handle Deletion +document.getElementById("deleteBtn").addEventListener("click", function () { + showLoading(); + + + var deleteAppName = document.getElementById("deleteAppName").value; + + if (!deleteAppName) { + alert("Please select an application to delete."); + return; + } + + var userConfirmed = confirm("Are you sure you want to delete the application '" + deleteAppName + " ?"); + + if (!userConfirmed) { + + alert("Application deletion cancelled."); + + return; + } + + const myHeaders = new Headers(); + myHeaders.append("Authorization", getCookie("auth_token")); + + const formdata = new FormData(); + formdata.append("UserId", getCookie("discord_id")); + formdata.append("Name", deleteAppName); + + const requestOptions = { + method: "DELETE", + headers: myHeaders, + body: formdata, + redirect: "follow" + }; + + fetch("https://spcloudcore.almavid.ru/delete", requestOptions) + .then((response) => response.text()) + .then((result) => { + hideLoading(); + + console.log(result); + alert(result); + + fetchAndDisplayAppData(); + + document.getElementById('deleteModal').style.display = "none"; // Close the modal after successful deletion + }) + .catch((error) => { + hideLoading(); + console.error(error); + alert("Error deleting application."); + }); +}); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +function showLoading() { + document.getElementById('globalLoading').style.display = 'flex'; +} + +function hideLoading() { + document.getElementById('globalLoading').style.display = 'none'; +} +// Get the modal +function fetchAndDisplayAppNames() { + const myHeaders = new Headers(); + myHeaders.append("Authorization", getCookie("auth_token")); + + const requestOptions = { + method: "GET", + headers: myHeaders, + redirect: "follow" + }; + + fetch("https://spcloudcore.almavid.ru/apps", requestOptions) + .then((response) => response.json()) + .then((result) => { + const apps = result.documents; + const appNameSelect = document.getElementById('updateAppName'); + + // Clear existing options + appNameSelect.innerHTML = ''; + + // Populate the select dropdown with app names + apps.forEach(app => { + const option = document.createElement('option'); + option.value = app.name; + option.textContent = app.name; + appNameSelect.appendChild(option); + }); + }) + .catch((error) => console.error('Error:', error)); +} + + + + + + + + + + + + + + + + +// Get the update modal +var updateModal = document.getElementById("updateModal"); + +// Get the button that opens the update modal +var updateBtnOpen = document.querySelector('.update-button'); + +document.querySelector('.update-button').addEventListener('click', function () { + fetchAndDisplayAppNames(); + document.getElementById('updateModal').style.display = "block"; +}); + +// Get the element that closes the update modal +var updateSpanClose = updateModal.querySelector('.close'); + +// When the user clicks the button, open the update modal +updateBtnOpen.onclick = function () { + updateModal.style.display = "block"; +} + +// When the user clicks on (x), close the update modal +updateSpanClose.onclick = function () { + updateModal.style.display = "none"; +} + +// When the user clicks anywhere outside of the update modal, close it +window.onclick = function (event) { + if (event.target == updateModal) { + updateModal.style.display = "none"; + } +} + +// Form submission logic for updating the application +document.getElementById("updateBtn").addEventListener("click", function () { + + showLoading(); + var updateFileInput = document.getElementById("updateFileInput"); + var updateAppName = document.getElementById("updateAppName").value; + + if (updateFileInput.files.length === 0) { + alert("Please select a file."); + return; + } + + const myHeaders = new Headers(); + myHeaders.append("Authorization", getCookie("auth_token")); + + const formdata = new FormData(); + formdata.append("File", updateFileInput.files[0]); + formdata.append("UserId", getCookie("discord_id")); + formdata.append("Name", updateAppName); + + const requestOptions = { + method: "PUT", + headers: myHeaders, + body: formdata, + redirect: "follow" + }; + + fetch("https://spcloudcore.almavid.ru/update", requestOptions) + .then((response) => response.text()) + .then((result) => { + hideLoading(); + console.log(result); + alert(result); + fetchAndDisplayAppData(); + + updateModal.style.display = "none"; + }) + .catch((error) => { + hideLoading(); + console.error(error); + alert("Error updating application."); + }); +}); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +var modal = document.getElementById("uploadModal"); + +// Get the button that opens the modal +var btn = document.querySelector('.upload-button'); + +// Get the element that closes the modal +var span = document.getElementsByClassName("close")[0]; + +// When the user clicks the button, open the modal +btn.onclick = function () { + modal.style.display = "block"; +} + +// When the user clicks on (x), close the modal +span.onclick = function () { + modal.style.display = "none"; +} + +// When the user clicks anywhere outside of the modal, close it +window.onclick = function (event) { + if (event.target == modal) { + modal.style.display = "none"; + } +} + + + + + +document.getElementById("uploadBtn").addEventListener("click", function () { + showLoading(); + var fileInput = document.getElementById("fileInput"); + var appName = document.getElementById("appName").value; + var appTarget = document.getElementById("appTarget").value; + + if (fileInput.files.length === 0) { + alert("Please select a file."); + return; + } + + const myHeaders = new Headers(); + myHeaders.append("Authorization", getCookie("auth_token")); + + const formdata = new FormData(); + formdata.append("File", fileInput.files[0]); + formdata.append("UserId", getCookie("discord_id")); + formdata.append("Name", appName); + formdata.append("Target", appTarget); + + const requestOptions = { + method: "POST", + headers: myHeaders, + body: formdata, + redirect: "follow" + }; + + fetch("https://spcloudcore.almavid.ru/publish", requestOptions) + .then((response) => response.text()) + .then((result) => { + hideLoading(); + + alert(result); + + fetchAndDisplayAppData(); + + modal.style.display = "none"; + }) + .catch((error) => { + hideLoading(); + + console.error(error); + alert("Error uploading file."); + }); +}); + + + + + + + + + + + +function getQueryParam(param) { + const urlParams = new URLSearchParams(window.location.search); + return urlParams.get(param); +} + +const code = getQueryParam('code'); + +if (code) { + const myHeaders = new Headers(); + myHeaders.append("Content-Type", "application/json"); + + const raw = JSON.stringify({ + "code": code + }); + + const requestOptions = { + method: "POST", + headers: myHeaders, + body: raw, + redirect: "follow" + }; + + fetch("https://spcloudcore.almavid.ru/login", requestOptions) + .then(response => response.json()) + .then(result => { + const discordId = result.document.discord_id; + const authToken = result.document.auth_token; + const username = result.document.username; + + setCookie("discord_id", discordId, 730); + setCookie("auth_token", authToken, 730); + setCookie("username", username, 730); + + console.log("Cookies set: discord_id and auth_token"); + + displayUsername(username); + + }) + .catch(error => console.error('Error:', error)); +} + +function setCookie(name, value, days) { + const date = new Date(); + date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); // Convert days to milliseconds + const expires = "expires=" + date.toUTCString(); + document.cookie = name + "=" + value + ";" + expires + ";path=/"; +} + +function getCookie(name) { + const value = `; ${document.cookie}`; + const parts = value.split(`; ${name}=`); + if (parts.length === 2) return parts.pop().split(';').shift(); +} + +function fetchAndDisplayAppData() { + const myHeaders = new Headers(); + myHeaders.append("Authorization", getCookie("auth_token")); + + const requestOptions = { + method: "GET", + headers: myHeaders, + redirect: "follow" + }; + + fetch("https://spcloudcore.almavid.ru/apps", requestOptions) + .then((response) => response.json()) + .then((result) => { + const apps = result.documents; + const table = document.querySelector('.server-stats table'); + + // Clear existing table rows (except headers) + table.querySelectorAll('tr:not(:first-child)').forEach(row => row.remove()); + + // Loop through each app and create a new table row + apps.forEach(app => { + const row = table.insertRow(); + + const nameCell = row.insertCell(0); + const urlCell = row.insertCell(1); + const cpuUsageCell = row.insertCell(2); + const memoryUsageCell = row.insertCell(3); + const targetCell = row.insertCell(4); + + // Populate cells with app data + nameCell.textContent = app.name; // Ensure the name is displayed + urlCell.textContent = app.url; + cpuUsageCell.textContent = "N/A"; // Placeholder as no CPU usage info is provided + memoryUsageCell.textContent = "N/A"; // Placeholder as no Memory usage info is provided + targetCell.textContent = app.target; // Assuming all services are active as status is not provided + }); + }) + .catch((error) => console.error('Error:', error)); +} + +fetchAndDisplayAppData(); + +function displayUsername(username) { + const usernameElement = document.querySelector('.username'); + if (usernameElement) { + usernameElement.textContent = username; + } +} + +const storedUsername = getCookie("username"); +if (storedUsername) { + displayUsername(storedUsername); +} + + + diff --git a/SpCloud.drawio b/SpCloud.drawio index 91ec9e6..ff1ad36 100644 --- a/SpCloud.drawio +++ b/SpCloud.drawio @@ -1,6 +1,6 @@ - + - + @@ -56,25 +56,25 @@ - + - + - + - + - + @@ -119,7 +119,7 @@ - + @@ -149,10 +149,10 @@ - + - + @@ -160,26 +160,74 @@ - + - + - + - - + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SpCloudMain/Controllers/PublishController.cpp b/SpCloudMain/Controllers/PublishController.cpp index fd4c5ba..d4c6a46 100644 --- a/SpCloudMain/Controllers/PublishController.cpp +++ b/SpCloudMain/Controllers/PublishController.cpp @@ -45,9 +45,9 @@ public: file_processing->unzip(filename, this->publish_app_path + app_final_file_path); - check_port_and_increase_if_not_available(); + check_port_and_increase_if_not_available();// - file_processing->adjust_nginx_configuration_and_reloud(app->get_name(), std::to_string(last_available_port)); + file_processing->adjust_nginx_configuration_and_reloud(app->get_name(), std::to_string(last_available_port));// file_processing->create_service_file(this->publish_app_path, app_final_file_path, std::to_string(last_available_port)); @@ -63,9 +63,9 @@ public: file_processing->delete_file(filename); - app->set_url("https://" + app->get_name() + ".almavid.ru/"); + app->set_url("https://" + app->get_name() + ".almavid.ru/");// - app->set_url_on_local_machine("http://localhost:" + std::to_string(last_available_port)); + app->set_url_on_local_machine("http://localhost:" + std::to_string(last_available_port));// app->set_service_name(app_final_file_path); diff --git a/SpCloudMain/Service/DiscordService.cpp b/SpCloudMain/Service/DiscordService.cpp index 0ee9cd4..0257780 100644 --- a/SpCloudMain/Service/DiscordService.cpp +++ b/SpCloudMain/Service/DiscordService.cpp @@ -27,7 +27,7 @@ public: "--data-urlencode \"client_secret=S_vG4frjIxWoi8mic_GlcxUO0aWxXwRJ\" " "--data-urlencode \"grant_type=authorization_code\" " "--data-urlencode \"code=" + auth_code_processed + "\" " - "--data-urlencode \"redirect_uri=https://www.sp-donate.ru/pay/Hepatir\""; + "--data-urlencode \"redirect_uri=https://spcloud.almavid.ru\""; auto code_request = std::async(std::launch::async, &DiscordService::execute_command, this, command); diff --git a/SpCloudMain/Service/FileProcessingService.cpp b/SpCloudMain/Service/FileProcessingService.cpp index 7db59e7..b70dd22 100644 --- a/SpCloudMain/Service/FileProcessingService.cpp +++ b/SpCloudMain/Service/FileProcessingService.cpp @@ -247,49 +247,20 @@ public: serviceFile << "[Service]\n"; serviceFile << "ExecStart=" << exec_start_command << "\n"; - //serviceFile << "ExecStart=/usr/bin/dotnet /home/danilt2000/SpCloud/" + name + "/" + dll_file_name + "\n"; - //serviceFile << "ExecStart=/home/danilt2000/SpCloud/SpCloudMain/build/SpCloudMain\n"; serviceFile << "WorkingDirectory=/home/danilt2000/SpCloud/" + name + "\n"; - //serviceFile << "WorkingDirectory=/home/danilt2000/SpCloud/SpCloudMain/build\n"; serviceFile << "Restart=always\n"; serviceFile << "User=danilt2000\n"; + serviceFile << "Environment=ASPNETCORE_URLS=http://0.0.0.0:" + port + "\n"; + serviceFile << "Environment=PATH=/usr/bin\n"; serviceFile << "Environment=NODE_ENV=production\n\n"; serviceFile << "[Install]\n"; serviceFile << "WantedBy=multi-user.target\n"; - //Todo check service ->sudo systemctl status .service - serviceFile.close(); - //std::string command_reload = "sudo systemctl daemon-reload"; - - ///*std::thread commandThreadReload(&CommandService::execute_command, command_reload); - - //commandThreadReload.join();*/ - - - //std::string command_enable = "sudo systemctl enable " + name + ".service"; - - //std::string command_start = "sudo systemctl start " + name + ".service"; - ////std::thread commandThreadStart(&CommandService::execute_command, commandThreadStart); - - ////commandThreadStart.join(); - - //auto request_reload = std::async(std::launch::async, &FileProcessingService::execute_command, this, command_reload); - - //std::string response_reload = request_reload.get(); - - //auto request_enable = std::async(std::launch::async, &FileProcessingService::execute_command, this, command_enable); - - //std::string response_enable = request_enable.get(); - - //auto request_start = std::async(std::launch::async, &FileProcessingService::execute_command, this, command_start); - - //std::string response_start = request_start.get(); - std::string command_reload = "sudo systemctl daemon-reload"; std::string command_enable = "sudo systemctl enable " + name + ".service"; std::string command_start = "sudo systemctl start " + name + ".service"; diff --git a/SpCloudMain/SpCloudMain.cpp b/SpCloudMain/SpCloudMain.cpp index 3f61c25..e7fb38d 100644 --- a/SpCloudMain/SpCloudMain.cpp +++ b/SpCloudMain/SpCloudMain.cpp @@ -81,7 +81,7 @@ int main() mongo_service.increase_user_app_count_(app->get_user_id()); - res.set_content("App is running on address:" + app->get_url(), "text/plain"); + res.set_content("App is running " + app->get_url(), "text/plain"); delete app; });