Skip to content

Commit

Permalink
removed namespace
Browse files Browse the repository at this point in the history
  • Loading branch information
opokatech committed Apr 4, 2024
1 parent d7a02fc commit 980f146
Show file tree
Hide file tree
Showing 27 changed files with 603 additions and 667 deletions.
1 change: 0 additions & 1 deletion TODO
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
- examples of configuration (nginx, cron)
- make cross compilation work again
- consider removing ECB namespace
23 changes: 10 additions & 13 deletions src/Currency_Value.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,15 @@

#include <string>

namespace ECB
// Represents a currency and its value.
struct Currency_Value
{
// Represents a currency and its value.
struct Currency_Value
{
std::string currency;
double value{};
std::string currency;
double value{};

bool operator==(const Currency_Value &other) const
{
static constexpr double EPSILON = 0.001;
return currency == other.currency && (std::abs(value - other.value) <= EPSILON);
}
};
} // namespace ECB
bool operator==(const Currency_Value &other) const
{
static constexpr double EPSILON = 0.001;
return currency == other.currency && (std::abs(value - other.value) <= EPSILON);
}
};
135 changes: 66 additions & 69 deletions src/Data_Loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,98 +7,95 @@
#include <cstring>
#include <fstream>

namespace ECB
std::vector<Record> Data_Loader::load_from_file(const std::string &file_name)
{
std::vector<Record> Data_Loader::load_from_file(const std::string &file_name)
try
{
try
{
std::ifstream file(file_name);
std::string content(std::istreambuf_iterator<char>{file}, {});
file.close();
std::ifstream file(file_name);
std::string content(std::istreambuf_iterator<char>{file}, {});
file.close();

return load_from_xml_string(content);
}
catch (...)
{
Log::error("Error loading from a file '{}'\n", file_name);
}
return {};
return load_from_xml_string(content);
}
catch (...)
{
Log::error("Error loading from a file '{}'\n", file_name);
}
return {};
}

std::vector<Record> Data_Loader::load_from_url(const std::string &url, std::string_view save_to_file)
std::vector<Record> Data_Loader::load_from_url(const std::string &url, std::string_view save_to_file)
{
try
{
try
{
auto r = cpr::Get(cpr::Url{url}, cpr::VerifySsl{false});
auto r = cpr::Get(cpr::Url{url}, cpr::VerifySsl{false});

if (r.status_code == 200)
{
if (!save_to_file.empty())
{
std::ofstream file(save_to_file.data());
file << r.text;
file.close();
}
return load_from_xml_string(r.text);
}
else
if (r.status_code == 200)
{
if (!save_to_file.empty())
{
Log::error("Failed getting data from url '{}', status code = {}\n", url, r.status_code);
std::ofstream file(save_to_file.data());
file << r.text;
file.close();
}
return load_from_xml_string(r.text);
}
catch (...)
else
{
Log::error("Error loading from url '{}'\n", url);
Log::error("Failed getting data from url '{}', status code = {}\n", url, r.status_code);
}
return {};
}

std::vector<Record> Data_Loader::load_from_xml_string(const std::string &data)
catch (...)
{
std::vector<Record> records;
Log::error("Error loading from url '{}'\n", url);
}
return {};
}

pugi::xml_document doc;
std::vector<Record> Data_Loader::load_from_xml_string(const std::string &data)
{
std::vector<Record> records;

// std::cout << "Parsing historical data from file '" << file_name << "'... " << std::flush;
// auto time_start = std::chrono::steady_clock::now();
// auto parse_result = doc.load_file(file_name.c_str());
auto parse_result = doc.load_string(data.c_str());
// auto time_end = std::chrono::steady_clock::now();
// auto parse_duration = std::chrono::duration<double>(time_end - time_start);
// std::cout << "done (time: " << parse_duration.count() << "). Result: " << parse_result.description() <<
// std::endl;
pugi::xml_document doc;

if (!parse_result)
{
Log::error("Error parsing xml: {}\n", parse_result.description());
return records;
}
// std::cout << "Parsing historical data from file '" << file_name << "'... " << std::flush;
// auto time_start = std::chrono::steady_clock::now();
// auto parse_result = doc.load_file(file_name.c_str());
auto parse_result = doc.load_string(data.c_str());
// auto time_end = std::chrono::steady_clock::now();
// auto parse_duration = std::chrono::duration<double>(time_end - time_start);
// std::cout << "done (time: " << parse_duration.count() << "). Result: " << parse_result.description() <<
// std::endl;

auto root = doc.first_child(); // "gesmes:Envelope" is the name
auto cube = root.child("Cube"); // root of all currency data
if (!parse_result)
{
Log::error("Error parsing xml: {}\n", parse_result.description());
return records;
}

static const std::string BASE{"EUR"};
for (const auto &day_node: cube.children()) // each child is also "Cube"
{
std::string time = day_node.attribute("time").as_string();
auto root = doc.first_child(); // "gesmes:Envelope" is the name
auto cube = root.child("Cube"); // root of all currency data

Time_Point tp{time};
std::vector<Currency_Value> rates;
static const std::string BASE{"EUR"};
for (const auto &day_node: cube.children()) // each child is also "Cube"
{
std::string time = day_node.attribute("time").as_string();

Time_Point tp{time};
std::vector<Currency_Value> rates;

for (const auto &symbol_node: day_node.children())
for (const auto &symbol_node: day_node.children())
{
if (strcmp(symbol_node.name(), "Cube") == 0)
{
if (strcmp(symbol_node.name(), "Cube") == 0)
{
const Currency_Value cv{symbol_node.attribute("currency").as_string(),
symbol_node.attribute("rate").as_double()};
rates.emplace_back(cv);
}
const Currency_Value cv{symbol_node.attribute("currency").as_string(),
symbol_node.attribute("rate").as_double()};
rates.emplace_back(cv);
}

records.emplace_back(tp, BASE, rates);
}

return records;
records.emplace_back(tp, BASE, rates);
}
}; // namespace ECB

return records;
}
30 changes: 13 additions & 17 deletions src/Data_Loader.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,20 @@

#include <vector>

namespace ECB
class Data_Loader
{
class Data_Loader
{
public:
Data_Loader() = delete;
public:
Data_Loader() = delete;

// Load data from a file and return a vector of records.
// Returns an empty vector if the data could not be loaded.
static std::vector<Record> load_from_file(const std::string &file_name);
// Load data from a file and return a vector of records.
// Returns an empty vector if the data could not be loaded.
static std::vector<Record> load_from_file(const std::string &file_name);

// Load data from a url and return a vector of records.
// Returns an empty vector if the data could not be loaded.
static std::vector<Record> load_from_url(const std::string &url, std::string_view save_to_file = "");
// Load data from a url and return a vector of records.
// Returns an empty vector if the data could not be loaded.
static std::vector<Record> load_from_url(const std::string &url, std::string_view save_to_file = "");

private:
// Load data from a string and return a vector of records.
static std::vector<Record> load_from_xml_string(const std::string &data);
};

} // namespace ECB
private:
// Load data from a string and return a vector of records.
static std::vector<Record> load_from_xml_string(const std::string &data);
};
95 changes: 46 additions & 49 deletions src/Log.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,60 +3,57 @@
#include "spdlog/sinks/basic_file_sink.h"
#include "spdlog/sinks/stdout_color_sinks.h"

namespace ECB
{
// static members
std::shared_ptr<spdlog::logger> Log::logger_ = nullptr;
// static members
std::shared_ptr<spdlog::logger> Log::logger_ = nullptr;

void Log::init(const std::string &logFile)
{
std::vector<spdlog::sink_ptr> sinks;
void Log::init(const std::string &logFile)
{
std::vector<spdlog::sink_ptr> sinks;

auto consoleLogger = std::make_shared<spdlog::sinks::stderr_color_sink_mt>();
// timestamp with ms, colored log level, message
consoleLogger->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%^%l%$] %v");
sinks.push_back(consoleLogger);
auto consoleLogger = std::make_shared<spdlog::sinks::stderr_color_sink_mt>();
// timestamp with ms, colored log level, message
consoleLogger->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%^%l%$] %v");
sinks.push_back(consoleLogger);

if (!logFile.empty())
if (!logFile.empty())
{
constexpr bool TRUNCATE = true;
try
{
constexpr bool TRUNCATE = true;
try
{
auto fileLogger = std::make_shared<spdlog::sinks::basic_file_sink_mt>(logFile, TRUNCATE);
// timestamp with ms, log level, message
fileLogger->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%l] %v");
sinks.push_back(fileLogger);
}
catch (const spdlog::spdlog_ex &ex)
{
spdlog::error("Failed to create file logger: {}", ex.what());
}
auto fileLogger = std::make_shared<spdlog::sinks::basic_file_sink_mt>(logFile, TRUNCATE);
// timestamp with ms, log level, message
fileLogger->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%l] %v");
sinks.push_back(fileLogger);
}
catch (const spdlog::spdlog_ex &ex)
{
spdlog::error("Failed to create file logger: {}", ex.what());
}

logger_ = std::make_shared<spdlog::logger>("logger", sinks.begin(), sinks.end());
spdlog::register_logger(logger_);
}

void Log::setLevel(const std::string &level)
{
constexpr auto DEFAULT_LEVEL = spdlog::level::info;
spdlog::level::level_enum finalLevel = DEFAULT_LEVEL;

if (level == "off")
finalLevel = spdlog::level::off;
else if (level == "error")
finalLevel = spdlog::level::err;
else if (level == "warning")
finalLevel = spdlog::level::warn;
else if (level == "info")
finalLevel = spdlog::level::info;

setLevel(finalLevel);
}
logger_ = std::make_shared<spdlog::logger>("logger", sinks.begin(), sinks.end());
spdlog::register_logger(logger_);
}

void Log::setLevel(spdlog::level::level_enum level)
{
if (logger_ != nullptr)
logger_->set_level(level);
}
} // namespace ECB
void Log::setLevel(const std::string &level)
{
constexpr auto DEFAULT_LEVEL = spdlog::level::info;
spdlog::level::level_enum finalLevel = DEFAULT_LEVEL;

if (level == "off")
finalLevel = spdlog::level::off;
else if (level == "error")
finalLevel = spdlog::level::err;
else if (level == "warning")
finalLevel = spdlog::level::warn;
else if (level == "info")
finalLevel = spdlog::level::info;

setLevel(finalLevel);
}

void Log::setLevel(spdlog::level::level_enum level)
{
if (logger_ != nullptr)
logger_->set_level(level);
}
Loading

0 comments on commit 980f146

Please sign in to comment.