update firmware added
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
CXX=g++
|
CXX=g++
|
||||||
STRIP=strip
|
STRIP=strip
|
||||||
CXXFLAGS=-Wall -I src/libs -I src -std=c++20
|
CXXFLAGS=-Wall -I src/libs -I src -std=c++20 -lpthread
|
||||||
SOURCES=src/openrouter.cpp \
|
SOURCES=src/openrouter.cpp \
|
||||||
src/security/cors.cpp \
|
src/security/cors.cpp \
|
||||||
src/settings/settings.cpp \
|
src/settings/settings.cpp \
|
||||||
|
|||||||
+5
-1
@@ -1,4 +1,8 @@
|
|||||||
project('openrouter', 'cpp', default_options: ['cpp_std=c++20', 'cpp_args=-Wall'])
|
project(
|
||||||
|
'openrouter',
|
||||||
|
'cpp',
|
||||||
|
default_options: ['cpp_std=c++20', 'cpp_args=-Wall -lpthread'],
|
||||||
|
)
|
||||||
include_dirs = include_directories('src', 'src/libs')
|
include_dirs = include_directories('src', 'src/libs')
|
||||||
executable(
|
executable(
|
||||||
'openrouter',
|
'openrouter',
|
||||||
|
|||||||
@@ -20,8 +20,6 @@ namespace api
|
|||||||
|
|
||||||
void restore(const httplib::Request& request, httplib::Response& response)
|
void restore(const httplib::Request& request, httplib::Response& response)
|
||||||
{
|
{
|
||||||
std::size_t size = request.files.size();
|
|
||||||
bool ret = request.has_file("restore_settings");
|
|
||||||
const httplib::MultipartFormData& file = request.get_file_value("restore_settings");
|
const httplib::MultipartFormData& file = request.get_file_value("restore_settings");
|
||||||
if (file.content_type == JSON_TYPE) {
|
if (file.content_type == JSON_TYPE) {
|
||||||
nlohmann::json new_config = nlohmann::json::parse(file.content);
|
nlohmann::json new_config = nlohmann::json::parse(file.content);
|
||||||
|
|||||||
@@ -3,6 +3,13 @@
|
|||||||
#include <auth/auth.hpp>
|
#include <auth/auth.hpp>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <colors.h>
|
#include <colors.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <json.hpp>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#define DEFAULT_TMP_FILE_NAME "/tmp/image"
|
||||||
|
#define DEFAULT_DST_FILE_NAME "/images/image"
|
||||||
|
#define BLOCK_SIZE 131072
|
||||||
|
|
||||||
namespace api
|
namespace api
|
||||||
{
|
{
|
||||||
@@ -11,6 +18,27 @@ namespace api
|
|||||||
namespace update
|
namespace update
|
||||||
{
|
{
|
||||||
static int update_progress = 0;
|
static int update_progress = 0;
|
||||||
|
static bool compare = false;
|
||||||
|
|
||||||
|
bool compareFile(std::string tmpfilename, std::string dstfilename) {
|
||||||
|
FILE *tmp = fopen(tmpfilename.c_str(), "r");
|
||||||
|
FILE *dst = fopen(dstfilename.c_str(), "r");
|
||||||
|
char tmpbuffer[BLOCK_SIZE];
|
||||||
|
char dstbuffer[BLOCK_SIZE];
|
||||||
|
|
||||||
|
do {
|
||||||
|
size_t tmpread = fread(tmpbuffer, 1, BLOCK_SIZE, tmp);
|
||||||
|
size_t dstread = fread(dstbuffer, 1, BLOCK_SIZE, dst);
|
||||||
|
if (tmpread != dstread || memcmp(tmpbuffer, dstbuffer, tmpread)) {
|
||||||
|
fclose(tmp);
|
||||||
|
fclose(dst);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} while (!feof(tmp) || !feof(dst));
|
||||||
|
fclose(tmp);
|
||||||
|
fclose(dst);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void upload(const httplib::Request& request, httplib::Response& response)
|
void upload(const httplib::Request& request, httplib::Response& response)
|
||||||
{
|
{
|
||||||
@@ -30,7 +58,7 @@ namespace api
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const httplib::MultipartFormData& file = request.get_file_value("image");
|
const httplib::MultipartFormData& file = request.get_file_value("image");
|
||||||
std::ofstream tmp_image_file("/tmp/image");
|
std::ofstream tmp_image_file(DEFAULT_TMP_FILE_NAME);
|
||||||
tmp_image_file << file.content;
|
tmp_image_file << file.content;
|
||||||
tmp_image_file.close();
|
tmp_image_file.close();
|
||||||
response.set_content(R"({"status":true})", JSON_TYPE);
|
response.set_content(R"({"status":true})", JSON_TYPE);
|
||||||
@@ -39,6 +67,68 @@ namespace api
|
|||||||
void update(const httplib::Request& request, httplib::Response& response)
|
void update(const httplib::Request& request, httplib::Response& response)
|
||||||
{
|
{
|
||||||
std::cout << GREEN << request.path << RESET << " " << request.method << std::endl;
|
std::cout << GREEN << request.path << RESET << " " << request.method << std::endl;
|
||||||
|
response.set_header("Access-Control-Allow-Origin", "*");
|
||||||
|
if (request.body.empty())
|
||||||
|
{
|
||||||
|
response.set_content(ACCESS_REQUIRED_STRING, JSON_TYPE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
nlohmann::json json_body = nlohmann::json::parse(request.body);
|
||||||
|
if (json_body["token"] == nullptr)
|
||||||
|
{
|
||||||
|
response.set_content(ACCESS_REQUIRED_STRING, JSON_TYPE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!authenticate(json_body["token"]))
|
||||||
|
{
|
||||||
|
response.set_content(R"({"access":"reject"})", JSON_TYPE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool needAutoReboot = json_body["needAutoReboot"];
|
||||||
|
update_progress = 0;
|
||||||
|
compare = false;
|
||||||
|
int file_image_size = std::filesystem::file_size(DEFAULT_TMP_FILE_NAME);
|
||||||
|
int block_count = file_image_size / BLOCK_SIZE;
|
||||||
|
int remainder = file_image_size % BLOCK_SIZE;
|
||||||
|
|
||||||
|
int skip = 0;
|
||||||
|
|
||||||
|
char buffer[BLOCK_SIZE];
|
||||||
|
std::ifstream tmp(DEFAULT_TMP_FILE_NAME);
|
||||||
|
std::ofstream dst(DEFAULT_DST_FILE_NAME);
|
||||||
|
|
||||||
|
while (skip < block_count) {
|
||||||
|
tmp.read(buffer, BLOCK_SIZE);
|
||||||
|
dst.write(buffer, BLOCK_SIZE);
|
||||||
|
update_progress = 100 * skip / block_count;
|
||||||
|
skip++;
|
||||||
|
std::cout << update_progress << "% was copied" << std::endl;
|
||||||
|
memset(buffer, 0, BLOCK_SIZE);
|
||||||
|
}
|
||||||
|
if (remainder > 0) {
|
||||||
|
tmp.read(buffer, remainder);
|
||||||
|
dst.write(buffer, remainder);
|
||||||
|
update_progress = 100;
|
||||||
|
std::cout << update_progress << "% was copied" << std::endl;
|
||||||
|
}
|
||||||
|
update_progress = 100;
|
||||||
|
std::cout << update_progress << "% was copied" << std::endl;
|
||||||
|
tmp.close();
|
||||||
|
dst.close();
|
||||||
|
compare = compareFile(DEFAULT_TMP_FILE_NAME, DEFAULT_DST_FILE_NAME);
|
||||||
|
if (!compare) {
|
||||||
|
std::cout << "files not equvalents: writing file error." << std::endl;
|
||||||
|
response.set_content(R"({"success":false})", JSON_TYPE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::remove(DEFAULT_TMP_FILE_NAME);
|
||||||
|
if (needAutoReboot) {
|
||||||
|
std::cout << "reboot" << std::endl;
|
||||||
|
std::system("sleep 2; reboot;");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
response.set_content(R"({"success":true})", JSON_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void progress(const httplib::Request& request, httplib::Response& response)
|
void progress(const httplib::Request& request, httplib::Response& response)
|
||||||
|
|||||||
+55
-9
@@ -12,6 +12,11 @@ const upload_percents = document.querySelector("#uploadpercent");
|
|||||||
|
|
||||||
const update_image_button = document.querySelector("#update_image_button");
|
const update_image_button = document.querySelector("#update_image_button");
|
||||||
const updateprogress = document.querySelector("#updateprogress");
|
const updateprogress = document.querySelector("#updateprogress");
|
||||||
|
const updatebar = document.querySelector("#updatebar");
|
||||||
|
const updatepercent = document.querySelector("#updatepercent");
|
||||||
|
|
||||||
|
let progress = 0;
|
||||||
|
let progress_interval;
|
||||||
|
|
||||||
checker.addEventListener("click", () => {
|
checker.addEventListener("click", () => {
|
||||||
auto_reboot_flag.checked = !auto_reboot_flag.checked;
|
auto_reboot_flag.checked = !auto_reboot_flag.checked;
|
||||||
@@ -31,7 +36,28 @@ upload_image_button.addEventListener("click", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
update_image_button.addEventListener("click", () => {
|
update_image_button.addEventListener("click", () => {
|
||||||
|
updatebar.style.width = "0%";
|
||||||
|
updatepercent.innerHTML = "Updated: 0 %";
|
||||||
updateprogress.classList.remove("hidden");
|
updateprogress.classList.remove("hidden");
|
||||||
|
start_progress();
|
||||||
|
fetch(routes.update_image(), {
|
||||||
|
method: "Post",
|
||||||
|
body: `{"token":"${localStorage.getItem("token")}", "needAutoReboot": ${auto_reboot_flag.checked}}`,
|
||||||
|
})
|
||||||
|
.then((data) => data.json())
|
||||||
|
.then((jsondata) => {
|
||||||
|
if (jsondata.success === true) {
|
||||||
|
stop_progress();
|
||||||
|
notification("Updated successful", "success");
|
||||||
|
updatebar.style.width = "100%";
|
||||||
|
updatepercent.innerHTML = "Updated: 100 %";
|
||||||
|
} else {
|
||||||
|
stop_progress();
|
||||||
|
updatebar.style.width = "100%";
|
||||||
|
updatepercent.innerHTML = "Updated: 100 %";
|
||||||
|
notification("Unexpected error", "error");
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
const upload_firmware_image = async () => {
|
const upload_firmware_image = async () => {
|
||||||
@@ -41,7 +67,7 @@ const upload_firmware_image = async () => {
|
|||||||
let image = upload_image_input.files[0];
|
let image = upload_image_input.files[0];
|
||||||
let formData = new FormData();
|
let formData = new FormData();
|
||||||
formData.append("image", image);
|
formData.append("image", image);
|
||||||
formData.append("token", localStorage.getItem('token'))
|
formData.append("token", localStorage.getItem("token"));
|
||||||
var request = new XMLHttpRequest();
|
var request = new XMLHttpRequest();
|
||||||
request.upload.addEventListener("progress", (e) => {
|
request.upload.addEventListener("progress", (e) => {
|
||||||
var file1Size = image.size;
|
var file1Size = image.size;
|
||||||
@@ -58,20 +84,17 @@ const upload_firmware_image = async () => {
|
|||||||
});
|
});
|
||||||
request.onreadystatechange = () => {
|
request.onreadystatechange = () => {
|
||||||
if (request.readyState === 4) {
|
if (request.readyState === 4) {
|
||||||
console.log(request.responseText)
|
console.log(request.responseText);
|
||||||
const jsondata = JSON.parse(request.responseText)
|
const jsondata = JSON.parse(request.responseText);
|
||||||
if (jsondata.status === true) {
|
if (jsondata.status === true) {
|
||||||
update_image_button.classList.remove('hidden')
|
update_image_button.classList.remove("hidden");
|
||||||
update_block.classList.remove("hidden");
|
update_block.classList.remove("hidden");
|
||||||
} else {
|
} else {
|
||||||
notification('Upload error', 'error')
|
notification("Upload error", "error");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
request.open(
|
request.open("post", routes.upload_image());
|
||||||
"post",
|
|
||||||
routes.upload_image(),
|
|
||||||
);
|
|
||||||
request.timeout = 450000;
|
request.timeout = 450000;
|
||||||
request.send(formData);
|
request.send(formData);
|
||||||
};
|
};
|
||||||
@@ -81,3 +104,26 @@ upload_image_input.addEventListener("change", (event) => {
|
|||||||
upload_firmware_image();
|
upload_firmware_image();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const start_progress = () => {
|
||||||
|
updatebar.style.width = "0%";
|
||||||
|
progress = 0;
|
||||||
|
updatepercent.innerHTML = "Updated: 0 %";
|
||||||
|
updateprogress.classList.remove("hidden");
|
||||||
|
progress_interval = setInterval(() => {
|
||||||
|
fetch(routes.update_progress())
|
||||||
|
.then((data) => data.json())
|
||||||
|
.then((jsondata) => {
|
||||||
|
progress = jsondata.progress;
|
||||||
|
updatebar.style.width = `${progress}%`;
|
||||||
|
updatepercent.innerHTML = `Updated: ${progress} %`;
|
||||||
|
if (progress === 100) {
|
||||||
|
stop_progress();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, 500);
|
||||||
|
};
|
||||||
|
|
||||||
|
const stop_progress = () => {
|
||||||
|
clearInterval(progress_interval);
|
||||||
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user