forked from EvergreenCrypto/docker-finance
root: macro: layout reorg, related refactor
This commit is contained in:
366
container/src/root/macro/web/internal/crypto.C
Normal file
366
container/src/root/macro/web/internal/crypto.C
Normal file
@@ -0,0 +1,366 @@
|
||||
// docker-finance | modern accounting for the power-user
|
||||
//
|
||||
// Copyright (C) 2021-2024 Aaron Fiore (Founder, Evergreen Crypto LLC)
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
//! \file
|
||||
//! \author Aaron Fiore (Founder, Evergreen Crypto LLC)
|
||||
//! \note File intended to be loaded into ROOT.cern framework / Cling interpreter
|
||||
//! \since docker-finance 1.0.0
|
||||
|
||||
#ifndef CONTAINER_SRC_ROOT_MACRO_WEB_INTERNAL_CRYPTO_C_
|
||||
#define CONTAINER_SRC_ROOT_MACRO_WEB_INTERNAL_CRYPTO_C_
|
||||
|
||||
#include <TCanvas.h>
|
||||
#include <TGraph.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <iomanip>
|
||||
#include <random>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "../../common/crypto.hh"
|
||||
#include "../../common/utility.hh"
|
||||
|
||||
//! \namespace docker_finance
|
||||
//! \since docker-finance 1.0.0
|
||||
namespace docker_finance
|
||||
{
|
||||
//! \namespace docker_finance::macro
|
||||
//! \brief ROOT macros
|
||||
//! \since docker-finance 1.0.0
|
||||
namespace macro
|
||||
{
|
||||
//! \namespace docker_finance::macro::internal
|
||||
//! \brief ROOT macros for internal use only
|
||||
//! \since docker-finance 1.0.0
|
||||
namespace internal
|
||||
{
|
||||
//! \ingroup cpp_macro_impl
|
||||
//! \brief Cryptographical macro class
|
||||
//! \since docker-finance 1.0.0
|
||||
class Crypto final
|
||||
{
|
||||
public:
|
||||
Crypto() = default;
|
||||
~Crypto() = default;
|
||||
|
||||
Crypto(const Crypto&) = default;
|
||||
Crypto& operator=(const Crypto&) = default;
|
||||
|
||||
Crypto(Crypto&&) = default;
|
||||
Crypto& operator=(Crypto&&) = default;
|
||||
|
||||
private:
|
||||
//! \since docker-finance 1.0.0
|
||||
struct CanvasData
|
||||
{
|
||||
::Int_t n{}; // points
|
||||
std::vector<::Double_t> x, y;
|
||||
std::string title, label;
|
||||
};
|
||||
|
||||
private:
|
||||
//! \brief The "random device" implementation
|
||||
//! \since docker-finance 1.0.0
|
||||
template <typename t_gen, typename t_num>
|
||||
struct GeneratorImpl
|
||||
{
|
||||
explicit GeneratorImpl(const t_gen& gen) : m_gen(gen) {}
|
||||
|
||||
//! \brief As expected from std::random_device except secure numbers are generated
|
||||
t_num operator()() const { return m_gen(); }
|
||||
|
||||
//! \brief As implemented in std::random_device
|
||||
t_num min() const { return std::numeric_limits<t_num>::min(); }
|
||||
|
||||
//! \brief As implemented in std::random_device
|
||||
t_num max() const { return std::numeric_limits<t_num>::max(); }
|
||||
|
||||
t_gen m_gen;
|
||||
};
|
||||
|
||||
//! \brief The "random device" facade
|
||||
//! \since docker-finance 1.0.0
|
||||
template <typename t_gen, typename t_num>
|
||||
struct Generator
|
||||
{
|
||||
explicit Generator(const t_gen& gen) : m_impl(gen) {}
|
||||
|
||||
const auto& operator()() const { return m_impl; }
|
||||
|
||||
GeneratorImpl<t_gen, t_num> m_impl;
|
||||
};
|
||||
|
||||
protected:
|
||||
//! \brief Make graph of values from given canvas data
|
||||
//! \param canvas Previously instantiated canvas
|
||||
//! \param data Populated canvas data for graph
|
||||
static void graph_value(::TCanvas* canvas, const Crypto::CanvasData& data)
|
||||
{
|
||||
// Graph: w/ lines
|
||||
auto* gr1 = new ::TGraph(data.n, data.x.data(), data.y.data());
|
||||
|
||||
gr1->SetTitle(std::string(data.title + data.label).c_str());
|
||||
gr1->SetMarkerColor(kBlue);
|
||||
gr1->SetMarkerStyle(kFullDotSmall);
|
||||
|
||||
gr1->GetXaxis()->SetTitle("Count");
|
||||
gr1->GetXaxis()->SetRangeUser(
|
||||
0, *std::max_element(data.x.cbegin(), data.x.cend()));
|
||||
|
||||
gr1->GetYaxis()->SetTitle("Value [0..0xffffffff]");
|
||||
gr1->GetYaxis()->SetRangeUser(
|
||||
0, *std::max_element(data.y.cbegin(), data.y.cend()));
|
||||
|
||||
canvas->cd(1)->SetGridx();
|
||||
canvas->cd(1)->SetGridy();
|
||||
|
||||
gStyle->SetLineStyle(kDotted);
|
||||
gStyle->SetLineWidth(1);
|
||||
|
||||
gr1->Draw("APL");
|
||||
|
||||
// Graph: w/ bar
|
||||
canvas->cd(2)->SetGridy();
|
||||
gr1->Draw("AB");
|
||||
}
|
||||
|
||||
//! \brief Make graph of value occurrences from given canvas data
|
||||
//! \param canvas Previously instantiated canvas
|
||||
//! \param data Populated canvas data for graph
|
||||
static void graph_frequency(::TCanvas* canvas, const Crypto::CanvasData& data)
|
||||
{
|
||||
// x = [0..0xffffffff]
|
||||
// y = frequency of number (max = nbins)
|
||||
std::vector<::Double_t> x1;
|
||||
std::vector<::Double_t> y1;
|
||||
|
||||
std::map<::Double_t, ::Double_t> map;
|
||||
for (const auto& y : data.y)
|
||||
{
|
||||
++map[y]; // y = x
|
||||
}
|
||||
|
||||
// .first = rand value
|
||||
// .second = frequency
|
||||
for (const auto& [x, y] : map)
|
||||
{
|
||||
x1.push_back(x);
|
||||
y1.push_back(y);
|
||||
}
|
||||
|
||||
auto* gr2 = new ::TGraph(data.n, x1.data(), y1.data());
|
||||
gr2->SetTitle(std::string(data.title + data.label).c_str());
|
||||
|
||||
gr2->GetXaxis()->SetTitle("Value [0..0xffffffff]");
|
||||
gr2->GetXaxis()->SetRangeUser(0, *std::max_element(x1.cbegin(), x1.cend()));
|
||||
|
||||
gr2->GetYaxis()->SetTitle("Count");
|
||||
gr2->GetYaxis()->SetTickLength(0);
|
||||
gr2->GetYaxis()->SetRangeUser(0, *std::max_element(y1.cbegin(), y1.cend()));
|
||||
|
||||
canvas->cd(3);
|
||||
gr2->Draw("AB");
|
||||
}
|
||||
|
||||
//! \brief Make 2D graph of prime numbers within given canvas data
|
||||
//! \param canvas Previously instantiated canvas
|
||||
//! \param data Populated canvas data for graph
|
||||
static void graph_prime(::TCanvas* canvas, const Crypto::CanvasData& data)
|
||||
{
|
||||
canvas->cd(4);
|
||||
auto* gr1 = new ::TGraph2D();
|
||||
|
||||
size_t primes{};
|
||||
bool is_prime{true};
|
||||
|
||||
for (size_t n{}; n < data.n; n++)
|
||||
{
|
||||
const auto y = static_cast<uint32_t>(data.y.at(n));
|
||||
is_prime = true;
|
||||
|
||||
if (y < 2)
|
||||
is_prime = false;
|
||||
|
||||
for (size_t i{2}; i <= std::sqrt(y); ++i)
|
||||
{
|
||||
if (!(y % i))
|
||||
{
|
||||
is_prime = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_prime)
|
||||
{
|
||||
auto x = n;
|
||||
auto z = y;
|
||||
gr1->SetPoint(n, x, y, z);
|
||||
primes++;
|
||||
}
|
||||
}
|
||||
|
||||
gr1->SetTitle(
|
||||
std::string(data.title + data.label + " (" + primes + " primes)")
|
||||
.c_str());
|
||||
gStyle->SetPalette(1);
|
||||
gr1->SetMarkerStyle(20);
|
||||
gr1->Draw("pcol");
|
||||
}
|
||||
|
||||
//! \brief Make histogram of values from given canvas data / random number generator
|
||||
//! \param canvas Previously instantiated canvas
|
||||
//! \param data Populated canvas data for graph
|
||||
//! \param generator Random number generator to use
|
||||
template <typename t_generator>
|
||||
static void histo_gauss(
|
||||
::TCanvas* canvas,
|
||||
const Crypto::CanvasData& data,
|
||||
const t_generator& generator)
|
||||
{
|
||||
canvas->cd(1);
|
||||
canvas->SetGridx();
|
||||
canvas->SetGridy();
|
||||
|
||||
auto* h1 = new ::TH1D(
|
||||
data.title.c_str(),
|
||||
std::string(data.title + data.label).c_str(),
|
||||
data.n,
|
||||
-5.0,
|
||||
5.0); // TODO(unassigned): looks the best, would prefer more mathematical soundness
|
||||
|
||||
// Shove a CSPRNG into a Gaussian distribution
|
||||
const Crypto::Generator<decltype(generator), uint32_t> gen(generator);
|
||||
std::normal_distribution dist{0.0, 1.0};
|
||||
|
||||
for (size_t i{}; i < data.n; ++i)
|
||||
{
|
||||
h1->Fill(dist(gen()));
|
||||
}
|
||||
|
||||
h1->Draw();
|
||||
}
|
||||
|
||||
static void fun_facts(::TCanvas* canvas, const Crypto::CanvasData& data)
|
||||
{
|
||||
// TODO(unassigned): percent of prime / composite
|
||||
|
||||
canvas->cd(2);
|
||||
auto* pt = new ::TPaveText(.05, .1, .95, .9);
|
||||
|
||||
// odd/even
|
||||
size_t is_odd{};
|
||||
for (const auto& y : data.y)
|
||||
{
|
||||
if (static_cast<uint32_t>(y) % 2)
|
||||
{
|
||||
is_odd++;
|
||||
}
|
||||
}
|
||||
|
||||
// miles
|
||||
uint64_t miles{};
|
||||
for (const auto& y : data.y)
|
||||
{
|
||||
miles += y;
|
||||
}
|
||||
|
||||
miles /= 24901;
|
||||
|
||||
// TODO(unassigned): would be nice to have some RNG-related info
|
||||
pt->AddText(std::string{"Fun facts"}
|
||||
.c_str()); // TODO(unassigned): make this small text
|
||||
pt->AddText(std::string{
|
||||
"There are " + std::to_string(is_odd) + " odd numbers and "
|
||||
+ std::to_string(data.y.size() - is_odd) + " even numbers"}
|
||||
.c_str());
|
||||
pt->AddText(std::string{
|
||||
"If the total values generated were miles, you could circle the earth "
|
||||
+ std::to_string(miles) + " times!"}
|
||||
.c_str());
|
||||
pt->Draw();
|
||||
}
|
||||
|
||||
public:
|
||||
// TODO(unassigned): put in a `Random` subdir to separate from other functions
|
||||
static void rng_sample(const std::string& size)
|
||||
{
|
||||
Crypto::CanvasData data{};
|
||||
|
||||
// TODO(unassigned): sanitize because:
|
||||
// 1. only unsigned is desired
|
||||
// 2. server will crash if too large...
|
||||
data.n = std::stoi(size);
|
||||
data.x.resize(data.n);
|
||||
data.y.resize(data.n);
|
||||
|
||||
auto random =
|
||||
([](Crypto::CanvasData /* make copy */ data, const auto& generator) {
|
||||
auto* c1 = new ::TCanvas(
|
||||
std::string{"c1_" + data.title}.c_str(), "RNG analysis");
|
||||
|
||||
// TODO(unassigned): shift plots to the right so there's more space on the left and less on the right
|
||||
c1->Divide(2, 2);
|
||||
c1->SetFillColorAlpha(kBlue, 0.35);
|
||||
|
||||
// Create graph data
|
||||
for (size_t i{}; i < data.n; i++)
|
||||
{
|
||||
data.x.at(i) = i;
|
||||
data.y.at(i) = generator();
|
||||
}
|
||||
|
||||
Crypto::graph_value(c1, data);
|
||||
Crypto::graph_frequency(c1, data);
|
||||
Crypto::graph_prime(c1, data);
|
||||
|
||||
auto* c2 = new ::TCanvas(
|
||||
std::string{"c2_" + data.title}.c_str(), "RNG analysis");
|
||||
|
||||
// TODO(unassigned): shift plots to the right so there's more space on the left and less on the right
|
||||
c2->Divide(0, 2);
|
||||
Crypto::histo_gauss<decltype(generator)>(c2, data, generator);
|
||||
Crypto::fun_facts(c2, data);
|
||||
});
|
||||
|
||||
const std::string timestamp{utility::make_timestamp()};
|
||||
|
||||
data.title = "Botan_RNG_" + timestamp;
|
||||
random(
|
||||
data, []() -> uint32_t { return crypto::botan::g_Random->generate(); });
|
||||
|
||||
data.title = "Crypto++_RNG_" + timestamp;
|
||||
random(data, []() -> uint32_t {
|
||||
return crypto::cryptopp::g_Random->generate();
|
||||
});
|
||||
|
||||
data.title = "libsodium_RNG_" + timestamp;
|
||||
random(data, []() -> uint32_t {
|
||||
return crypto::libsodium::g_Random->generate();
|
||||
});
|
||||
|
||||
// TODO(unassigned): when clicking reload to create another sample, it doesn't do a clean refresh of the canvas
|
||||
}
|
||||
};
|
||||
} // namespace internal
|
||||
} // namespace macro
|
||||
} // namespace docker_finance
|
||||
|
||||
#endif // CONTAINER_SRC_ROOT_MACRO_WEB_INTERNAL_CRYPTO_C_
|
||||
|
||||
// # vim: sw=2 sts=2 si ai et
|
||||
230
container/src/root/macro/web/internal/meta.C
Normal file
230
container/src/root/macro/web/internal/meta.C
Normal file
@@ -0,0 +1,230 @@
|
||||
// docker-finance | modern accounting for the power-user
|
||||
//
|
||||
// Copyright (C) 2021-2024 Aaron Fiore (Founder, Evergreen Crypto LLC)
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
//! \file
|
||||
//! \author Aaron Fiore (Founder, Evergreen Crypto LLC)
|
||||
//! \note File intended to be loaded into ROOT.cern framework / Cling interpreter
|
||||
//! \since docker-finance 1.0.0
|
||||
|
||||
#ifndef CONTAINER_SRC_ROOT_MACRO_WEB_INTERNAL_META_C_
|
||||
#define CONTAINER_SRC_ROOT_MACRO_WEB_INTERNAL_META_C_
|
||||
|
||||
#include <TCanvas.h>
|
||||
#include <TGraph.h>
|
||||
#include <TPie.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "../../common/utility.hh"
|
||||
|
||||
//! \namespace docker_finance
|
||||
//! \since docker-finance 1.0.0
|
||||
namespace docker_finance
|
||||
{
|
||||
//! \namespace docker_finance::macro
|
||||
//! \brief ROOT macros
|
||||
//! \since docker-finance 1.0.0
|
||||
namespace macro
|
||||
{
|
||||
//! \namespace docker_finance::macro::internal
|
||||
//! \brief ROOT macros for internal use only
|
||||
//! \since docker-finance 1.0.0
|
||||
namespace internal
|
||||
{
|
||||
//! \brief Meta processing macro class
|
||||
//! \ingroup cpp_macro_impl
|
||||
//! \since docker-finance 1.0.0
|
||||
class Meta final
|
||||
{
|
||||
public:
|
||||
Meta() = default;
|
||||
~Meta() = default;
|
||||
|
||||
Meta(const Meta&) = default;
|
||||
Meta& operator=(const Meta&) = default;
|
||||
|
||||
Meta(Meta&&) = default;
|
||||
Meta& operator=(Meta&&) = default;
|
||||
|
||||
private:
|
||||
//! \since docker-finance 1.0.0
|
||||
struct CanvasData
|
||||
{
|
||||
std::string column;
|
||||
std::pair<std::string, std::string> title; // canvas, object
|
||||
std::map<std::string, uint64_t> row;
|
||||
};
|
||||
|
||||
private:
|
||||
//! \brief Make pie graph from given CSV data
|
||||
//! \param csv Imported CSV data
|
||||
//! \param data Populated canvas data for canvas creation
|
||||
static void make_pie(
|
||||
std::shared_ptr<ROOT::RDataFrame> csv,
|
||||
const Meta::CanvasData& data)
|
||||
{
|
||||
// Setup pie data
|
||||
std::vector<const char*> labels;
|
||||
std::vector<::Float_t> values;
|
||||
std::vector<::Int_t> colors;
|
||||
|
||||
// Populate all pie data from map
|
||||
for (auto it = data.row.cbegin(); it != data.row.cend(); ++it)
|
||||
{
|
||||
const auto& label = it->first;
|
||||
const auto& frequency = it->second;
|
||||
|
||||
std::cout << "label (row's value) = " << label
|
||||
<< " | frequency (row's value frequency) = " << frequency
|
||||
<< "\n";
|
||||
|
||||
labels.push_back(label.c_str());
|
||||
values.push_back(frequency);
|
||||
colors.push_back(std::distance(data.row.cbegin(), it));
|
||||
}
|
||||
|
||||
// Make canvas and graph
|
||||
auto* canvas = new ::TCanvas(
|
||||
std::string{data.title.first + "_tpie"}.c_str(),
|
||||
std::string{"Metadata (" + data.column + ")"}.c_str());
|
||||
|
||||
canvas->Draw();
|
||||
|
||||
auto* pie = new ::TPie(
|
||||
"pie",
|
||||
data.title.second.c_str(),
|
||||
values.size(),
|
||||
values.data(),
|
||||
colors.data());
|
||||
|
||||
pie->SetLabels(labels.data());
|
||||
pie->SetLabelsOffset(-.1);
|
||||
|
||||
// TODO(unassigned): why does changing these options have no apparent effect?
|
||||
// pie->Draw("3DTNOL");
|
||||
// pie->Draw("TNOL");
|
||||
pie->Draw();
|
||||
|
||||
// TODO(unassigned): put count and percentages over the slices
|
||||
|
||||
// Make legend
|
||||
auto* legend = pie->MakeLegend();
|
||||
legend->SetHeader(data.column.c_str(), "C");
|
||||
legend->Draw();
|
||||
}
|
||||
|
||||
//! \brief Make graph from given CSV data
|
||||
//! \param csv Imported CSV data
|
||||
//! \param data Populated canvas data for canvas creation
|
||||
static void make_graph(
|
||||
std::shared_ptr<ROOT::RDataFrame> csv,
|
||||
const Meta::CanvasData& data)
|
||||
{
|
||||
// Graph data
|
||||
auto defined = csv->Define(
|
||||
"DateAdded",
|
||||
"std::tm time{}; std::istringstream ss(date_added);"
|
||||
"ss >> std::get_time(&time, \"%Y-%m-%d %H:%M:%S\");"
|
||||
"return std::mktime(&time);"); // Seconds from epoch
|
||||
|
||||
// TODO(unassigned): empty row will return "nan"
|
||||
auto date = defined.Take<std::time_t>("DateAdded");
|
||||
auto col = defined.Take<std::string>(data.column);
|
||||
|
||||
// Canvas
|
||||
auto* canvas = new ::TCanvas(
|
||||
std::string{data.title.first + "_tgraph"}.c_str(),
|
||||
std::string{"Metadata (" + data.column + ")"}.c_str());
|
||||
|
||||
canvas->Draw();
|
||||
|
||||
// Graph
|
||||
std::vector<::Float_t> x, y;
|
||||
|
||||
for (size_t i{}; i < data.row.size(); i++)
|
||||
x.push_back(date->at(i));
|
||||
|
||||
for (const auto& [label, frequency] : data.row)
|
||||
y.push_back(frequency);
|
||||
|
||||
auto* graph = new ::TGraph(x.size(), x.data(), y.data());
|
||||
graph->SetTitle(data.title.second.c_str());
|
||||
graph->SetMinimum(0);
|
||||
graph->SetFillColor(kBlue);
|
||||
graph->GetXaxis()->SetTimeDisplay(1);
|
||||
graph->GetXaxis()->SetTimeFormat("%Y-%m-%d %H:%M:%S");
|
||||
graph->GetXaxis()->SetTimeOffset(0, "local");
|
||||
graph->Draw("B");
|
||||
}
|
||||
|
||||
public:
|
||||
//! \brief Sample metadata from given CSV column
|
||||
//! \param column Existing CSV metadata column
|
||||
static void meta_sample(const std::string& column)
|
||||
{
|
||||
// Import meta file
|
||||
const std::string path{utility::get_env("global_conf_meta")};
|
||||
auto csv =
|
||||
std::make_shared<ROOT::RDataFrame>(ROOT::RDF::FromCSV(path.c_str()));
|
||||
|
||||
// Ensure viable header
|
||||
std::string available{"\n\t"};
|
||||
for (const auto& col : csv->GetColumnNames())
|
||||
available += "\n\t" + col;
|
||||
available += "\n";
|
||||
|
||||
if (!csv->HasColumn(column))
|
||||
throw std::runtime_error(
|
||||
std::string{"\n\nAvailable columns: " + available}.c_str());
|
||||
|
||||
// Aggregate all rows of given column
|
||||
auto count = csv->Count();
|
||||
if (!*count)
|
||||
throw std::runtime_error("Empty CSV");
|
||||
|
||||
// Prepare canvas data
|
||||
Meta::CanvasData data;
|
||||
|
||||
const std::string timestamp{utility::make_timestamp()},
|
||||
parent{utility::get_env("global_parent_profile")},
|
||||
child{utility::get_env("global_child_profile")};
|
||||
|
||||
data.column = column;
|
||||
data.title.first = timestamp + "_meta_" + data.column;
|
||||
data.title.second =
|
||||
std::string{"Meta [" + parent + "/" + child + "] | " + timestamp};
|
||||
|
||||
// Map row values and frequency
|
||||
auto col = csv->Take<std::string>(data.column);
|
||||
for (size_t i{}; i < *count; i++)
|
||||
++data.row[col->at(i)];
|
||||
|
||||
// Execute
|
||||
Meta::make_pie(csv, data);
|
||||
Meta::make_graph(csv, data);
|
||||
}
|
||||
};
|
||||
} // namespace internal
|
||||
} // namespace macro
|
||||
} // namespace docker_finance
|
||||
|
||||
#endif // CONTAINER_SRC_ROOT_MACRO_WEB_INTERNAL_META_C_
|
||||
|
||||
// # vim: sw=2 sts=2 si ai et
|
||||
92
container/src/root/macro/web/server.C
Normal file
92
container/src/root/macro/web/server.C
Normal file
@@ -0,0 +1,92 @@
|
||||
// docker-finance | modern accounting for the power-user
|
||||
//
|
||||
// Copyright (C) 2021-2024 Aaron Fiore (Founder, Evergreen Crypto LLC)
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
//! \file
|
||||
//! \author Aaron Fiore (Founder, Evergreen Crypto LLC)
|
||||
//! \note File intended to be loaded into ROOT.cern framework / Cling interpreter
|
||||
//! \since docker-finance 1.0.0
|
||||
|
||||
#ifndef CONTAINER_SRC_ROOT_MACRO_WEB_SERVER_C_
|
||||
#define CONTAINER_SRC_ROOT_MACRO_WEB_SERVER_C_
|
||||
|
||||
#include <THttpServer.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "../common/common.hh"
|
||||
|
||||
//! \namespace docker_finance
|
||||
//! \since docker-finance 1.0.0
|
||||
namespace docker_finance
|
||||
{
|
||||
//! \namespace docker_finance::macro
|
||||
//! \brief ROOT macros
|
||||
//! \since docker-finance 1.0.0
|
||||
namespace macro
|
||||
{
|
||||
//! \namespace docker_finance::macro::internal
|
||||
//! \brief ROOT macros for internal use only
|
||||
//! \since docker-finance 1.0.0
|
||||
namespace internal
|
||||
{
|
||||
//! \brief HTTP Server instance
|
||||
//! \note In namespace scope because of ROOT's static functions requirement
|
||||
//! \since docker-finance 1.0.0
|
||||
auto g_HTTPServer = std::make_unique<::THttpServer>("http:8080");
|
||||
} // namespace internal
|
||||
|
||||
//! \brief Web server managing class
|
||||
//! \ingroup cpp_macro
|
||||
//! \since docker-finance 1.0.0
|
||||
class Web final
|
||||
{
|
||||
public:
|
||||
Web() = default;
|
||||
~Web() = default;
|
||||
|
||||
Web(const Web&) = delete;
|
||||
Web& operator=(const Web&) = delete;
|
||||
|
||||
Web(Web&&) = default;
|
||||
Web& operator=(Web&&) = default;
|
||||
|
||||
private:
|
||||
//! \brief ROOT HTTP server command registrar
|
||||
//! \details Registers internal macros
|
||||
static void register_commands()
|
||||
{
|
||||
::docker_finance::macro::internal::Command::load({"web/internal/crypto.C"});
|
||||
internal::g_HTTPServer->RegisterCommand(
|
||||
"/rng_sample",
|
||||
"::docker_finance::macro::internal::Crypto::rng_sample(\"%arg1%\")");
|
||||
|
||||
::docker_finance::macro::internal::Command::load({"web/internal/meta.C"});
|
||||
internal::g_HTTPServer->RegisterCommand(
|
||||
"/meta_sample",
|
||||
"::docker_finance::macro::internal::Meta::meta_sample(\"%arg1%\")");
|
||||
}
|
||||
|
||||
public:
|
||||
//! \brief Start webserver
|
||||
static void run() { Web::register_commands(); }
|
||||
};
|
||||
} // namespace macro
|
||||
} // namespace docker_finance
|
||||
|
||||
#endif // CONTAINER_SRC_ROOT_MACRO_WEB_SERVER_C_
|
||||
|
||||
// # vim: sw=2 sts=2 si ai et
|
||||
Reference in New Issue
Block a user