Files
odr_console/data_collectors.cpp
egutierrez d3af7d54ff chore: auto-commit (6 archivos)
- CMakeLists.txt
- main.cpp
- data_collectors.cpp
- data_collectors.h
- runner.cpp
- runner.h

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 13:30:27 +02:00

78 lines
2.4 KiB
C++

#include "data_collectors.h"
#include <filesystem>
#include <fstream>
namespace fs = std::filesystem;
namespace {
std::string trim(std::string s) {
auto issp = [](unsigned char c) { return std::isspace(c); };
while (!s.empty() && issp((unsigned char)s.back())) s.pop_back();
size_t i = 0;
while (i < s.size() && issp((unsigned char)s[i])) ++i;
return s.substr(i);
}
// Strip wrapping quotes if present.
std::string unquote(std::string s) {
if (s.size() >= 2) {
char a = s.front(), b = s.back();
if ((a == '"' && b == '"') || (a == '\'' && b == '\'')) {
return s.substr(1, s.size() - 2);
}
}
return s;
}
// Parsing minimo: busca lineas top-level `id:`, `name:`, `description:`.
// Suficiente para metadata de collectors. Si la app necesita mas, anadir yaml-cpp.
void parse_manifest(const fs::path& yaml_path, Collector& c) {
std::ifstream f(yaml_path);
if (!f.is_open()) return;
std::string line;
while (std::getline(f, line)) {
std::string t = trim(line);
if (t.empty() || t[0] == '#') continue;
// Ignora lineas indentadas (sub-keys de listas/dicts).
if (line.size() > t.size() && line[0] == ' ') continue;
auto colon = t.find(':');
if (colon == std::string::npos) continue;
std::string key = trim(t.substr(0, colon));
std::string val = trim(t.substr(colon + 1));
val = unquote(val);
if (key == "id" && !val.empty()) c.id = val;
else if (key == "name" && !val.empty()) c.name = val;
else if (key == "description" && !val.empty()) c.description = val;
}
}
} // namespace
bool collectors_discover(const std::string& collectors_root,
std::vector<Collector>& out) {
out.clear();
std::error_code ec;
if (!fs::is_directory(collectors_root, ec)) return false;
for (auto& entry : fs::directory_iterator(collectors_root, ec)) {
if (ec) break;
if (!entry.is_directory()) continue;
Collector c;
c.dir = entry.path().string();
c.id = entry.path().filename().string();
c.run_py = (entry.path() / "run.py").string();
c.has_run = fs::exists(c.run_py);
fs::path manifest = entry.path() / "manifest.yaml";
if (fs::exists(manifest)) parse_manifest(manifest, c);
if (c.name.empty()) c.name = c.id;
out.push_back(std::move(c));
}
return true;
}