166 lines
7.9 KiB
C++
166 lines
7.9 KiB
C++
// Copyright (C) 2024 Simon Quigley <tsimonq2@ubuntu.com>
|
|
//
|
|
// 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/>.
|
|
|
|
#include "archive.h"
|
|
#include "utils.h"
|
|
#include "launchpad.h"
|
|
#include "source_package_publishing_history.h"
|
|
#include <iostream>
|
|
#include <nlohmann/json.hpp>
|
|
|
|
archive::archive()
|
|
: authorized_size(0),
|
|
build_debug_symbols(false),
|
|
description(""),
|
|
displayname(""),
|
|
distribution_link(""),
|
|
external_dependencies(""),
|
|
metadata_overrides(nlohmann::json::object()),
|
|
name(""),
|
|
owner_link(""),
|
|
permit_obsolete_series_uploads(false),
|
|
is_private(false),
|
|
publish(false),
|
|
publish_debug_symbols(false),
|
|
publishing_method(""),
|
|
relative_build_score(0),
|
|
repository_format(""),
|
|
require_virtualized(false),
|
|
signing_key_fingerprint(""),
|
|
suppress_subscription_notifications(false),
|
|
owner_name(""),
|
|
ppa_name(""),
|
|
lp(nullptr) {}
|
|
|
|
archive::~archive() {}
|
|
|
|
std::optional<archive> archive::parse(const std::string& json_data) {
|
|
archive a;
|
|
a.parse_json(json_data);
|
|
return a;
|
|
}
|
|
|
|
void archive::parse_json(const std::string& json_data) {
|
|
if (json_data.empty()) {
|
|
std::cerr << "Error: Empty JSON data for archive::parse_json." << std::endl;
|
|
return;
|
|
}
|
|
|
|
try {
|
|
auto data = nlohmann::json::parse(json_data);
|
|
|
|
// Map JSON keys to member variable setters
|
|
std::map<std::string, std::function<void(const nlohmann::json&)>> json_map = {
|
|
{"authorized_size", [this](const nlohmann::json& val) { authorized_size = val.get<int>(); }},
|
|
{"build_debug_symbols", [this](const nlohmann::json& val) { build_debug_symbols = val.get<bool>(); }},
|
|
{"description", [this](const nlohmann::json& val) { description = val.get<std::string>(); }},
|
|
{"displayname", [this](const nlohmann::json& val) { displayname = val.get<std::string>(); }},
|
|
{"distribution_link", [this](const nlohmann::json& val) { distribution_link = val.get<std::string>(); }},
|
|
{"external_dependencies", [this](const nlohmann::json& val) { external_dependencies = val.get<std::string>(); }},
|
|
{"metadata_overrides", [this](const nlohmann::json& val) { metadata_overrides = val; }},
|
|
{"name", [this](const nlohmann::json& val) { name = val.get<std::string>(); }},
|
|
{"owner_link", [this](const nlohmann::json& val) { owner_link = val.get<std::string>(); }},
|
|
{"permit_obsolete_series_uploads", [this](const nlohmann::json& val) { permit_obsolete_series_uploads = val.get<bool>(); }},
|
|
{"private", [this](const nlohmann::json& val) { is_private = val.get<bool>(); }},
|
|
{"publish", [this](const nlohmann::json& val) { publish = val.get<bool>(); }},
|
|
{"publish_debug_symbols", [this](const nlohmann::json& val) { publish_debug_symbols = val.get<bool>(); }},
|
|
{"publishing_method", [this](const nlohmann::json& val) { publishing_method = val.get<std::string>(); }},
|
|
{"relative_build_score", [this](const nlohmann::json& val) { relative_build_score = val.get<int>(); }},
|
|
{"repository_format", [this](const nlohmann::json& val) { repository_format = val.get<std::string>(); }},
|
|
{"require_virtualized", [this](const nlohmann::json& val) { require_virtualized = val.get<bool>(); }},
|
|
{"signing_key_fingerprint", [this](const nlohmann::json& val) { signing_key_fingerprint = val.get<std::string>(); }},
|
|
{"suppress_subscription_notifications", [this](const nlohmann::json& val) { suppress_subscription_notifications = val.get<bool>(); }}
|
|
};
|
|
|
|
// Handle read-only fields separately
|
|
std::map<std::string, std::function<void(const nlohmann::json&)>> readonly_map = {
|
|
{"dependencies_collection_link", [this](const nlohmann::json& val) { dependencies_collection_link = val.get<std::string>(); }},
|
|
{"enabled_restricted_processors_collection_link", [this](const nlohmann::json& val) { enabled_restricted_processors_collection_link = val.get<std::string>(); }},
|
|
{"http_etag", [this](const nlohmann::json& val) { http_etag = val.get<std::string>(); }},
|
|
{"processors_collection_link", [this](const nlohmann::json& val) { processors_collection_link = val.get<std::string>(); }},
|
|
{"reference", [this](const nlohmann::json& val) { reference = val.get<std::string>(); }},
|
|
{"resource_type_link", [this](const nlohmann::json& val) { resource_type_link = val.get<std::string>(); }},
|
|
{"self_link", [this](const nlohmann::json& val) { self_link = val.get<std::string>(); }},
|
|
{"status", [this](const nlohmann::json& val) { status = val.get<std::string>(); }},
|
|
{"web_link", [this](const nlohmann::json& val) { web_link = val.get<std::string>(); }}
|
|
};
|
|
|
|
// Process all keys in the JSON object
|
|
for (auto& [key, value] : data.items()) {
|
|
try {
|
|
if (json_map.find(key) != json_map.end()) {
|
|
json_map[key](value);
|
|
json_map.erase(key);
|
|
} else if (readonly_map.find(key) != readonly_map.end()) {
|
|
readonly_map[key](value);
|
|
readonly_map.erase(key);
|
|
}
|
|
} catch (const std::exception& e) {
|
|
continue;
|
|
}
|
|
}
|
|
|
|
// Special handling for owner_name and ppa_name
|
|
std::string link = owner_link;
|
|
size_t pos = link.find("~");
|
|
if (pos != std::string::npos) {
|
|
owner_name = link.substr(pos + 1);
|
|
if (!owner_name.empty() && owner_name.back() == '/') {
|
|
owner_name.pop_back();
|
|
}
|
|
}
|
|
ppa_name = name;
|
|
|
|
} catch (const nlohmann::json::parse_error& e) {
|
|
std::cerr << "JSON parse error in archive::parse_json: " << e.what() << std::endl;
|
|
std::cerr << "Input JSON was: " << json_data << std::endl;
|
|
} catch (const std::exception& e) {
|
|
std::cerr << "Unexpected error during JSON parsing: " << e.what() << std::endl;
|
|
}
|
|
}
|
|
|
|
std::string archive::build_archive_endpoint() const {
|
|
return "~" + url_encode(owner_name) + "/" + url_encode(ppa_name);
|
|
}
|
|
|
|
std::generator<source_package_publishing_history> archive::getPublishedSources(const std::string& status) const {
|
|
std::map<std::string, std::string> params;
|
|
params["ws.op"] = "getPublishedSources";
|
|
params["status"] = status;
|
|
|
|
auto response = lp->api_get(this->self_link, params);
|
|
auto data = nlohmann::json::parse(response.value());
|
|
while (response.has_value() && data.contains("next_collection_link") && data["next_collection_link"] != "") {
|
|
try {
|
|
if (data.contains("entries") && data["entries"].is_array()) {
|
|
for (auto& entry : data["entries"]) {
|
|
auto s_opt = source_package_publishing_history::parse(entry.dump());
|
|
if (!s_opt) continue;
|
|
s_opt->set_lp(lp);
|
|
co_yield s_opt.value();
|
|
}
|
|
}
|
|
response = lp->api_get(data["next_collection_link"]);
|
|
data = nlohmann::json::parse(response.value());
|
|
} catch (const std::exception& e) {
|
|
std::cerr << "Error parsing published sources: " << e.what() << std::endl;
|
|
}
|
|
}
|
|
}
|
|
|
|
void archive::set_lp(launchpad* lp_ptr) {
|
|
lp = lp_ptr;
|
|
}
|