ffmpeg_web_local_app/source/main.cpp
#include "crow/common.h"
#include "crow/json.h"
#include "crow/websocket.h"
#include <crow/http_response.h>
#include <fmt/base.h>
#include <crow.h>
#include <fmt/core.h>
#include <string>
#include <thread>
#include "utils.cpp"
bool is_port_ready(const char* host, int port) {
int socket_fd = socket(AF_INET, SOCK_STREAM, 0);
if (socket_fd < 0)
return false;
sockaddr_in address{};
address.sin_family = AF_INET;
address.sin_port = htons(port);
if (inet_pton(AF_INET, host, &address.sin_addr) != 1) {
close(socket_fd);
return false;
}
bool is_ready = connect(
socket_fd,
reinterpret_cast<sockaddr*>(&address),
sizeof(address)
) == 0;
close(socket_fd);
return is_ready;
}
std::string genPassword(const unsigned int len) {
const std::string caratteri = "abcdefghijklmnopqrstuvwxyz";
std::string password;
std::srand(static_cast<unsigned int>(std::time(0)));
for (unsigned int i = 0; i < len; ++i) {
int indice = std::rand() % caratteri.length();
password += caratteri[indice];
}
return password;
}
void disable(crow::websocket::connection& c, const std::string& pin ,const std::string& id)
{
crow::json::wvalue json;
json["action"]= "disable";
json["id"]= id;
json["pin"]=pin;
c.send_text(json.dump());
}
void enable(crow::websocket::connection& c, const std::string& pin ,const std::string& id)
{
crow::json::wvalue json;
json["action"]= "enable";
json["id"]= id;
json["pin"]=pin;
c.send_text(json.dump());
}
void write_html(crow::websocket::connection& c, const std::string& pin ,const std::string& id, const std::string& html)
{
crow::json::wvalue json;
json["action"]= "write_html";
json["id"]= id;
json["html"]=html;
json["pin"]=pin;
c.send_text(json.dump());
}
void append_html(crow::websocket::connection& c, const std::string& pin ,const std::string& id, const std::string& html)
{
crow::json::wvalue json;
json["action"]= "append_html";
json["id"]= id;
json["html"]=html;
json["pin"]=pin;
c.send_text(json.dump());
}
void add_class(crow::websocket::connection& c, const std::string& pin ,const std::string& id,const std::string& cl)
{
crow::json::wvalue json;
json["action"]= "add_class";
json["id"]= id;
json["pin"]=pin;
json["class"]=cl;
c.send_text(json.dump());
}
void remove_class(crow::websocket::connection& c, const std::string& pin ,const std::string& id,const std::string& cl)
{
crow::json::wvalue json;
json["action"]= "remove_class";
json["id"]= id;
json["pin"]=pin;
json["class"]=cl;
c.send_text(json.dump());
}
void router(crow::websocket::connection& conn, const std::string& data,const std::string& pin)
{
auto json = crow::json::load(data);
std::string op=json["op"].s();
std::string file=json["file"].s();
const std::string npin =json["pin"].s();
disable(conn,pin, "btn_convert");
if (npin!=pin)
{
fmt::println("Invalid pin");
add_class(conn, pin, "output", "out_error");
write_html(conn,pin, "output", "Your pin is wrong!");
return;
}
if (op=="h264")
{
remove_class(conn,pin,"output","out_error");
std::string msg = fmt::format("Si richiede di convertire il file {} in {}",file,op);
write_html(conn,pin, "output", msg);
}else{
add_class(conn, pin, "output", "out_error");
write_html(conn,pin,"output","Error! The request operation is wrong!");
}
enable(conn,pin, "btn_convert");
append_html(conn,pin,"output","<p>This is appended!</p>");
}
int main()
{
crow::SimpleApp app;
const auto pin = genPassword(15);
CROW_WEBSOCKET_ROUTE(app, "/ws")
.onopen([&](crow::websocket::connection& conn){
fmt::println("Gui connected.");
})
.onclose([&](crow::websocket::connection& conn, const std::string& reason, uint16_t){
fmt::println("Gui disconnected.");
})
.onmessage([&](crow::websocket::connection& conn, const std::string& data, bool is_binary){
router(conn,data,pin);
});
CROW_ROUTE(app, "/")
([](){
crow::response res;
res.code = 302;
res.set_header("Location", "/home");
return res;
});
CROW_ROUTE(app, "/convert/<string>")([&](std::string npin){
crow::response res;
if (npin != pin)
{
res.code = 403;
auto t = crow::mustache::load_text("pin_error.html");
auto page = crow::mustache::compile(t);
crow::mustache::context ctx;
return page.render(ctx);
app.stop();
}
res.code = 200;
res.set_header("Content-Type", "text/html");
auto t = crow::mustache::load_text("convert.html");
auto page = crow::mustache::compile(t);
crow::mustache::context ctx;
ctx["pin"] = pin;
return page.render(ctx);
});
CROW_ROUTE(app, "/home/<string>")([&](std::string npin){
crow::response res;
if (npin != pin)
{
res.code = 403;
auto t = crow::mustache::load_text("pin_error.html");
auto page = crow::mustache::compile(t);
crow::mustache::context ctx;
return page.render(ctx);
app.stop();
}
res.code = 200;
res.set_header("Content-Type", "text/html");
auto t = crow::mustache::load_text("home.html");
auto page = crow::mustache::compile(t);
crow::mustache::context ctx;
ctx["pin"] = pin;
return page.render(ctx);
});
CROW_ROUTE(app, "/wstest/<string>")([&](std::string npin){
crow::response res;
if (npin != pin)
{
res.code = 403;
auto t = crow::mustache::load_text("pin_error.html");
auto page = crow::mustache::compile(t);
crow::mustache::context ctx;
return page.render(ctx);
app.stop();
}
res.code = 200;
res.set_header("Content-Type", "text/html");
auto t = crow::mustache::load_text("wstest.html");
auto page = crow::mustache::compile(t);
crow::mustache::context ctx;
return page.render(ctx);
});
CROW_ROUTE(app, "/file_dialog").methods(crow::HTTPMethod::POST)([&](const crow::request& req){
crow::response res;
auto json = crow::json::load(req.body);
const std::string npin=json["pin"].s();
std::string folder=json["dir"].s();
if (folder.empty()) folder=get_home();
if (npin != pin)
{
// return crow::response(403,"Pin is wrong, forbidden!");
crow::json::wvalue::list err;
err.push_back({
{"error", "Pin is wrong"}
});
return crow::response(403,crow::json::wvalue(err).dump());
}
if (!json){
// return crow::response(400, "JSON not valid");
crow::json::wvalue::list invalid;
invalid.push_back({
{"error", "Invalid json request"}
});
return crow::response(403,crow::json::wvalue(invalid).dump());
}
// return crow::response(200, open_dir(folder));
auto r= open_dir(folder);
return crow::response(200,crow::json::wvalue(r));
});
std::thread server([&]{
app.bindaddr("127.0.0.1").port(8080).multithreaded().run();
});
while (!is_port_ready("127.0.0.1", 8080)) {
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
auto cmd=fmt::format("xdg-open http://127.0.0.1:8080/home/{}",pin);
std::system(cmd.c_str());
server.join();
}