#include "data_collectors.h" #include #include 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& 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; }