ffmpeg_web_local_app/source/main.cpp


Home Back
#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();
    
}

 

Powered by Code, a simple repository browser by Fabio Di Matteo