522 lines
23 KiB
C++
522 lines
23 KiB
C++
#include "distro_series.h"
|
|
#include "launchpad.h"
|
|
#include "utils.h"
|
|
#include <iostream>
|
|
#include <nlohmann/json.hpp>
|
|
|
|
distro_series::distro_series()
|
|
: active(false),
|
|
advertise_by_hash(false),
|
|
backports_not_automatic(false),
|
|
include_long_descriptions(false),
|
|
language_pack_full_export_requested(false),
|
|
proposed_not_automatic(false),
|
|
publish_by_hash(false),
|
|
publish_i18n_index(false),
|
|
strict_supported_component_dependencies(false),
|
|
supported(false),
|
|
lp(nullptr) {}
|
|
|
|
distro_series::~distro_series() {}
|
|
|
|
std::optional<distro_series> distro_series::parse(const std::string& json_data) {
|
|
distro_series ds;
|
|
ds.parse_json(json_data);
|
|
return ds;
|
|
}
|
|
|
|
void distro_series::parse_json(const std::string& json_data) {
|
|
if (json_data.empty()) {
|
|
std::cerr << "Error: Empty JSON data for distro_series::parse_json." << std::endl;
|
|
return;
|
|
}
|
|
try {
|
|
auto data = nlohmann::json::parse(json_data);
|
|
|
|
auto get_bool = [&](const std::string& key, bool& field) {
|
|
if (data.contains(key) && data[key].is_boolean()) field = data[key].get<bool>();
|
|
};
|
|
auto get_str = [&](const std::string& key, std::string& field) {
|
|
if (data.contains(key) && data[key].is_string()) field = data[key].get<std::string>();
|
|
};
|
|
auto get_str_vec = [&](const std::string& key, std::vector<std::string>& field) {
|
|
if (data.contains(key) && data[key].is_array()) {
|
|
field.clear();
|
|
for (auto& e : data[key]) {
|
|
if (e.is_string()) field.push_back(e.get<std::string>());
|
|
}
|
|
}
|
|
};
|
|
|
|
get_bool("active", active);
|
|
get_bool("advertise_by_hash", advertise_by_hash);
|
|
get_str("all_milestones_collection_link", all_milestones_collection_link);
|
|
get_str("all_specifications_collection_link", all_specifications_collection_link);
|
|
get_str("architectures_collection_link", architectures_collection_link);
|
|
get_bool("backports_not_automatic", backports_not_automatic);
|
|
get_str("bug_reported_acknowledgement", bug_reported_acknowledgement);
|
|
get_str("bug_reporting_guidelines", bug_reporting_guidelines);
|
|
get_str("changeslist", changeslist);
|
|
get_str_vec("component_names", component_names);
|
|
get_str("date_created", date_created);
|
|
get_str("datereleased", datereleased);
|
|
get_str("description", description);
|
|
get_str("displayname", displayname);
|
|
get_str("distribution_link", distribution_link);
|
|
get_str("driver_link", driver_link);
|
|
get_str("drivers_collection_link", drivers_collection_link);
|
|
get_str("fullseriesname", fullseriesname);
|
|
get_str("http_etag", http_etag);
|
|
get_bool("include_long_descriptions", include_long_descriptions);
|
|
get_str_vec("index_compressors", index_compressors);
|
|
get_bool("language_pack_full_export_requested", language_pack_full_export_requested);
|
|
get_str("main_archive_link", main_archive_link);
|
|
get_str("name", name);
|
|
get_str("nominatedarchindep_link", nominatedarchindep_link);
|
|
get_str_vec("official_bug_tags", official_bug_tags);
|
|
get_str("owner_link", owner_link);
|
|
get_str("previous_series_link", previous_series_link);
|
|
get_bool("proposed_not_automatic", proposed_not_automatic);
|
|
get_bool("publish_by_hash", publish_by_hash);
|
|
get_bool("publish_i18n_index", publish_i18n_index);
|
|
get_str("registrant_link", registrant_link);
|
|
get_str("resource_type_link", resource_type_link);
|
|
get_str("self_link", self_link);
|
|
get_str("status", status);
|
|
get_bool("strict_supported_component_dependencies", strict_supported_component_dependencies);
|
|
get_str_vec("suite_names", suite_names);
|
|
get_str("summary", summary);
|
|
get_bool("supported", supported);
|
|
get_str("title", title);
|
|
get_str("translations_usage", translations_usage);
|
|
get_str("valid_specifications_collection_link", valid_specifications_collection_link);
|
|
get_str("version", version);
|
|
get_str("web_link", web_link);
|
|
|
|
// These additional fields might not be present in the JSON, but we define them if they exist
|
|
// They are listed as additional read-only fields in the header, but were not found in the JSON keys above
|
|
// We'll just attempt to parse them similarly if they exist
|
|
get_str("active_milestones_collection_link", active_milestones_collection_link);
|
|
get_str("archive_mirrors_collection_link", archive_mirrors_collection_link);
|
|
get_str("archives_collection_link", archives_collection_link);
|
|
get_str("series_collection_link", series_collection_link);
|
|
get_str("vulnerabilities_collection_link", vulnerabilities_collection_link);
|
|
get_str("webhooks_collection_link", webhooks_collection_link);
|
|
|
|
} catch (const nlohmann::json::parse_error& e) {
|
|
std::cerr << "JSON parse error in distro_series::parse_json: " << e.what() << std::endl;
|
|
} catch (const std::exception& e) {
|
|
std::cerr << "Unexpected error during JSON parsing: " << e.what() << std::endl;
|
|
}
|
|
}
|
|
|
|
void distro_series::set_lp(launchpad* lp_ptr) {
|
|
lp = lp_ptr;
|
|
}
|
|
|
|
std::optional<distro_series> distro_series::get() const {
|
|
if (self_link.empty()) return std::nullopt;
|
|
auto resp = lp->api_get(self_link);
|
|
if(!resp)return std::nullopt;
|
|
return parse(resp.value());
|
|
}
|
|
|
|
bool distro_series::patch(const nlohmann::json& data) const {
|
|
if (self_link.empty()) return false;
|
|
auto resp = lp->api_patch(self_link, data);
|
|
return resp.has_value();
|
|
}
|
|
|
|
bool distro_series::put(const nlohmann::json& data) const {
|
|
if (self_link.empty()) return false;
|
|
std::string endpoint = self_link + "?ws.op=replace";
|
|
auto resp = lp->api_patch(endpoint, data);
|
|
return resp.has_value();
|
|
}
|
|
|
|
std::generator<nlohmann::json> distro_series::getBuildRecords(const std::string& build_state, const std::string& pocket, const std::string& source_name) const {
|
|
if (!lp) co_return;
|
|
if (self_link.empty()) co_return;
|
|
|
|
std::map<std::string,std::string> params;
|
|
params["ws.op"] = "getBuildRecords";
|
|
if(!build_state.empty()) params["build_state"]=build_state;
|
|
if(!pocket.empty()) params["pocket"]=pocket;
|
|
if(!source_name.empty()) params["source_name"]=source_name;
|
|
|
|
auto response=lp->api_get(self_link, params);
|
|
if(!response) co_return;
|
|
auto data=nlohmann::json::parse(response.value());
|
|
while(true) {
|
|
if(data.contains("entries") && data["entries"].is_array()) {
|
|
for(auto&e:data["entries"]){
|
|
co_yield e;
|
|
}
|
|
}
|
|
if(!data.contains("next_collection_link") || data["next_collection_link"].is_null() || data["next_collection_link"]=="") break;
|
|
response=lp->api_get(data["next_collection_link"].get<std::string>());
|
|
if(!response)break;
|
|
data=nlohmann::json::parse(response.value());
|
|
}
|
|
}
|
|
|
|
std::generator<distro_series> distro_series::getDerivedSeries() const {
|
|
if(!lp || self_link.empty()) co_return;
|
|
std::map<std::string,std::string> params;
|
|
params["ws.op"]="getDerivedSeries";
|
|
auto response=lp->api_get(self_link,params);
|
|
if(!response) co_return;
|
|
auto data=nlohmann::json::parse(response.value());
|
|
|
|
while(true){
|
|
if(data.contains("entries") && data["entries"].is_array()){
|
|
for(auto&e:data["entries"]){
|
|
auto ds_opt = parse(e.dump());
|
|
if(ds_opt){
|
|
ds_opt->set_lp(lp);
|
|
co_yield ds_opt.value();
|
|
}
|
|
}
|
|
}
|
|
if(!data.contains("next_collection_link")||data["next_collection_link"].is_null()||data["next_collection_link"]=="")break;
|
|
response=lp->api_get(data["next_collection_link"].get<std::string>());
|
|
if(!response)break;
|
|
data=nlohmann::json::parse(response.value());
|
|
}
|
|
}
|
|
|
|
std::generator<nlohmann::json> distro_series::getDifferenceComments(const std::string& since, const std::string& source_package_name) const {
|
|
if(!lp||self_link.empty()) co_return;
|
|
std::map<std::string,std::string> params;
|
|
params["ws.op"]="getDifferenceComments";
|
|
if(!since.empty()) params["since"]=since;
|
|
if(!source_package_name.empty()) params["source_package_name"]=source_package_name;
|
|
|
|
auto response=lp->api_get(self_link,params);
|
|
if(!response) co_return;
|
|
auto data=nlohmann::json::parse(response.value());
|
|
|
|
while(true){
|
|
if(data.contains("entries") && data["entries"].is_array()){
|
|
for(auto&e:data["entries"]){
|
|
co_yield e;
|
|
}
|
|
}
|
|
if(!data.contains("next_collection_link")||data["next_collection_link"].is_null()||data["next_collection_link"]=="")break;
|
|
response=lp->api_get(data["next_collection_link"].get<std::string>());
|
|
if(!response)break;
|
|
data=nlohmann::json::parse(response.value());
|
|
}
|
|
}
|
|
|
|
std::generator<nlohmann::json> distro_series::getDifferencesTo(const std::optional<std::string>& parent_series,
|
|
const std::optional<std::string>& difference_type,
|
|
const std::optional<std::string>& source_package_name_filter,
|
|
const std::optional<std::string>& status,
|
|
bool child_version_higher) const {
|
|
if(!lp||self_link.empty()) co_return;
|
|
std::map<std::string,std::string> params;
|
|
params["ws.op"]="getDifferencesTo";
|
|
if(parent_series.has_value()) params["parent_series"]=parent_series.value();
|
|
if(difference_type.has_value()) params["difference_type"]=difference_type.value();
|
|
if(source_package_name_filter.has_value()) params["source_package_name_filter"]=source_package_name_filter.value();
|
|
if(status.has_value()) params["status"]=status.value();
|
|
if(child_version_higher) params["child_version_higher"]="true";
|
|
|
|
auto response=lp->api_get(self_link,params);
|
|
if(!response) co_return;
|
|
auto data=nlohmann::json::parse(response.value());
|
|
// Usually differences might have entries too
|
|
while(true){
|
|
if(data.contains("entries")&&data["entries"].is_array()){
|
|
for(auto&e:data["entries"]){
|
|
co_yield e;
|
|
}
|
|
}
|
|
if(!data.contains("next_collection_link")||data["next_collection_link"].is_null()||data["next_collection_link"]=="")break;
|
|
response=lp->api_get(data["next_collection_link"].get<std::string>());
|
|
if(!response)break;
|
|
data=nlohmann::json::parse(response.value());
|
|
}
|
|
}
|
|
|
|
std::optional<nlohmann::json> distro_series::getDistroArchSeries(const std::string& archtag) const {
|
|
if(!lp||self_link.empty())return std::nullopt;
|
|
std::map<std::string,std::string> params;
|
|
params["ws.op"]="getDistroArchSeries";
|
|
params["archtag"]=archtag;
|
|
auto response=lp->api_get(self_link,params);
|
|
if(!response)return std::nullopt;
|
|
return nlohmann::json::parse(response.value());
|
|
}
|
|
|
|
std::generator<nlohmann::json> distro_series::getPackageUploads(const std::optional<std::string>& archive,
|
|
const std::optional<std::string>& created_since_date,
|
|
const std::optional<std::string>& custom_type,
|
|
bool exact_match,
|
|
const std::optional<std::string>& name,
|
|
const std::optional<std::string>& pocket,
|
|
const std::optional<std::string>& status,
|
|
const std::optional<std::string>& version) const {
|
|
if(!lp||self_link.empty()) co_return;
|
|
std::map<std::string,std::string> params;
|
|
params["ws.op"]="getPackageUploads";
|
|
if(archive.has_value()) params["archive"]=archive.value();
|
|
if(created_since_date.has_value()) params["created_since_date"]=created_since_date.value();
|
|
if(custom_type.has_value()) params["custom_type"]=custom_type.value();
|
|
if(exact_match) params["exact_match"]="true";
|
|
if(name.has_value()) params["name"]=name.value();
|
|
if(pocket.has_value()) params["pocket"]=pocket.value();
|
|
if(status.has_value()) params["status"]=status.value();
|
|
if(version.has_value()) params["version"]=version.value();
|
|
|
|
auto response=lp->api_get(self_link,params);
|
|
if(!response) co_return;
|
|
auto data=nlohmann::json::parse(response.value());
|
|
|
|
while(true){
|
|
if(data.contains("entries") && data["entries"].is_array()){
|
|
for(auto&e:data["entries"]) {
|
|
co_yield e;
|
|
}
|
|
}
|
|
if(!data.contains("next_collection_link")||data["next_collection_link"].is_null()||data["next_collection_link"]=="") break;
|
|
response=lp->api_get(data["next_collection_link"].get<std::string>());
|
|
if(!response)break;
|
|
data=nlohmann::json::parse(response.value());
|
|
}
|
|
}
|
|
|
|
std::generator<distro_series> distro_series::getParentSeries() const {
|
|
if(!lp||self_link.empty()) co_return;
|
|
std::map<std::string,std::string> params;
|
|
params["ws.op"]="getParentSeries";
|
|
auto response=lp->api_get(self_link,params);
|
|
if(!response) co_return;
|
|
auto data=nlohmann::json::parse(response.value());
|
|
while(true) {
|
|
if(data.contains("entries")&&data["entries"].is_array()){
|
|
for(auto&e:data["entries"]){
|
|
auto ds_opt=parse(e.dump());
|
|
if(ds_opt){
|
|
ds_opt->set_lp(lp);
|
|
co_yield ds_opt.value();
|
|
}
|
|
}
|
|
}
|
|
if(!data.contains("next_collection_link")||data["next_collection_link"].is_null()||data["next_collection_link"]=="")break;
|
|
response=lp->api_get(data["next_collection_link"].get<std::string>());
|
|
if(!response)break;
|
|
data=nlohmann::json::parse(response.value());
|
|
}
|
|
}
|
|
|
|
std::optional<nlohmann::json> distro_series::getSourcePackage(const std::string& name_) const {
|
|
if(!lp||self_link.empty())return std::nullopt;
|
|
std::map<std::string,std::string> params;
|
|
params["ws.op"]="getSourcePackage";
|
|
params["name"]=name_;
|
|
auto resp=lp->api_get(self_link,params);
|
|
if(!resp)return std::nullopt;
|
|
return nlohmann::json::parse(resp.value());
|
|
}
|
|
|
|
std::optional<nlohmann::json> distro_series::getSpecification(const std::string& name_) const {
|
|
if(!lp||self_link.empty())return std::nullopt;
|
|
std::map<std::string,std::string> params;
|
|
params["ws.op"]="getSpecification";
|
|
params["name"]=name_;
|
|
auto resp=lp->api_get(self_link,params);
|
|
if(!resp)return std::nullopt;
|
|
return nlohmann::json::parse(resp.value());
|
|
}
|
|
|
|
std::optional<nlohmann::json> distro_series::getSubscription(const std::string& person) const {
|
|
if(!lp||self_link.empty())return std::nullopt;
|
|
std::map<std::string,std::string> params;
|
|
params["ws.op"]="getSubscription";
|
|
params["person"]=person;
|
|
auto resp=lp->api_get(self_link,params);
|
|
if(!resp)return std::nullopt;
|
|
return nlohmann::json::parse(resp.value());
|
|
}
|
|
|
|
std::generator<nlohmann::json> distro_series::getSubscriptions() const {
|
|
if(!lp||self_link.empty()) co_return;
|
|
std::map<std::string,std::string> params;
|
|
params["ws.op"]="getSubscriptions";
|
|
auto response=lp->api_get(self_link,params);
|
|
if(!response) co_return;
|
|
auto data=nlohmann::json::parse(response.value());
|
|
while(true) {
|
|
if(data.contains("entries")&&data["entries"].is_array()){
|
|
for(auto&e:data["entries"]){
|
|
co_yield e;
|
|
}
|
|
}
|
|
if(!data.contains("next_collection_link")||data["next_collection_link"].is_null()||data["next_collection_link"]=="")break;
|
|
response=lp->api_get(data["next_collection_link"].get<std::string>());
|
|
if(!response)break;
|
|
data=nlohmann::json::parse(response.value());
|
|
}
|
|
}
|
|
|
|
std::generator<nlohmann::json> distro_series::getTranslationImportQueueEntries(const std::optional<std::string>& import_status,
|
|
const std::optional<std::string>& file_extension) const {
|
|
if(!lp||self_link.empty()) co_return;
|
|
std::map<std::string,std::string>params;
|
|
params["ws.op"]="getTranslationImportQueueEntries";
|
|
if(import_status.has_value()) params["import_status"]=import_status.value();
|
|
if(file_extension.has_value()) params["file_extension"]=file_extension.value();
|
|
|
|
auto response=lp->api_get(self_link,params);
|
|
if(!response)co_return;
|
|
auto data=nlohmann::json::parse(response.value());
|
|
while(true){
|
|
if(data.contains("entries")&&data["entries"].is_array()){
|
|
for(auto&e:data["entries"]){
|
|
co_yield e;
|
|
}
|
|
}
|
|
if(!data.contains("next_collection_link")||data["next_collection_link"].is_null()||data["next_collection_link"]=="")break;
|
|
response=lp->api_get(data["next_collection_link"].get<std::string>());
|
|
if(!response)break;
|
|
data=nlohmann::json::parse(response.value());
|
|
}
|
|
}
|
|
|
|
std::optional<nlohmann::json> distro_series::getTranslationTemplateStatistics() const {
|
|
if(!lp||self_link.empty())return std::nullopt;
|
|
std::map<std::string,std::string>params;
|
|
params["ws.op"]="getTranslationTemplateStatistics";
|
|
auto resp=lp->api_get(self_link,params);
|
|
if(!resp)return std::nullopt;
|
|
return nlohmann::json::parse(resp.value());
|
|
}
|
|
|
|
std::generator<nlohmann::json> distro_series::getTranslationTemplates() const {
|
|
if(!lp||self_link.empty()) co_return;
|
|
std::map<std::string,std::string>params;
|
|
params["ws.op"]="getTranslationTemplates";
|
|
auto response=lp->api_get(self_link,params);
|
|
if(!response)co_return;
|
|
auto data=nlohmann::json::parse(response.value());
|
|
while(true){
|
|
if(data.contains("entries")&&data["entries"].is_array()){
|
|
for(auto&e:data["entries"]){
|
|
co_yield e;
|
|
}
|
|
}
|
|
if(!data.contains("next_collection_link")||data["next_collection_link"].is_null()||data["next_collection_link"]=="") break;
|
|
response=lp->api_get(data["next_collection_link"].get<std::string>());
|
|
if(!response) break;
|
|
data=nlohmann::json::parse(response.value());
|
|
}
|
|
}
|
|
|
|
std::generator<nlohmann::json> distro_series::searchTasks(const std::map<std::string,std::string>& params_in) const {
|
|
if(!lp||self_link.empty()) co_return;
|
|
std::map<std::string,std::string> params = params_in;
|
|
params["ws.op"]="searchTasks";
|
|
auto response=lp->api_get(self_link,params);
|
|
if(!response) co_return;
|
|
auto data=nlohmann::json::parse(response.value());
|
|
while(true){
|
|
if(data.contains("entries")&&data["entries"].is_array()){
|
|
for(auto&e:data["entries"]){
|
|
co_yield e;
|
|
}
|
|
}
|
|
if(!data.contains("next_collection_link")||data["next_collection_link"].is_null()||data["next_collection_link"]=="")break;
|
|
response=lp->api_get(data["next_collection_link"].get<std::string>());
|
|
if(!response)break;
|
|
data=nlohmann::json::parse(response.value());
|
|
}
|
|
}
|
|
|
|
std::optional<nlohmann::json> distro_series::userHasBugSubscriptions() const {
|
|
if(!lp||self_link.empty())return std::nullopt;
|
|
std::map<std::string,std::string>params;
|
|
params["ws.op"]="userHasBugSubscriptions";
|
|
auto resp=lp->api_get(self_link,params);
|
|
if(!resp)return std::nullopt;
|
|
return nlohmann::json::parse(resp.value());
|
|
}
|
|
|
|
bool distro_series::addBugSubscription(const std::optional<std::string>& subscriber) const {
|
|
if(!lp||self_link.empty())return false;
|
|
std::map<std::string,std::string>params;
|
|
params["ws.op"]="addBugSubscription";
|
|
if(subscriber.has_value()) params["subscriber"]=subscriber.value();
|
|
auto resp=lp->api_post(self_link,params);
|
|
return resp.has_value();
|
|
}
|
|
|
|
bool distro_series::addBugSubscriptionFilter(const std::optional<std::string>& subscriber) const {
|
|
if(!lp||self_link.empty())return false;
|
|
std::map<std::string,std::string>params;
|
|
params["ws.op"]="addBugSubscriptionFilter";
|
|
if(subscriber.has_value())params["subscriber"]=subscriber.value();
|
|
auto resp=lp->api_post(self_link,params);
|
|
return resp.has_value();
|
|
}
|
|
|
|
bool distro_series::initDerivedDistroSeries(const std::optional<std::string>& archindep_archtag,
|
|
const std::vector<std::string>& architectures,
|
|
const std::vector<std::string>& overlay_components,
|
|
const std::vector<std::string>& overlay_pockets,
|
|
const std::vector<std::string>& overlays,
|
|
const std::vector<std::string>& packagesets,
|
|
const std::vector<std::string>& parents,
|
|
bool rebuild) const {
|
|
if(!lp||self_link.empty())return false;
|
|
std::map<std::string,std::string>params;
|
|
params["ws.op"]="initDerivedDistroSeries";
|
|
if(archindep_archtag.has_value()) params["archindep_archtag"]=archindep_archtag.value();
|
|
|
|
auto join_list = [](const std::vector<std::string>& vec){
|
|
std::string joined;
|
|
for (auto& v:vec) {
|
|
joined+=v+",";
|
|
}
|
|
if(!joined.empty()) joined.pop_back();
|
|
return joined;
|
|
};
|
|
|
|
if(!architectures.empty()) params["architectures"]=join_list(architectures);
|
|
if(!overlay_components.empty()) params["overlay_components"]=join_list(overlay_components);
|
|
if(!overlay_pockets.empty()) params["overlay_pockets"]=join_list(overlay_pockets);
|
|
if(!overlays.empty()) params["overlays"]=join_list(overlays);
|
|
if(!packagesets.empty()) params["packagesets"]=join_list(packagesets);
|
|
if(!parents.empty()) params["parents"]=join_list(parents);
|
|
if(rebuild) params["rebuild"]="true";
|
|
|
|
auto resp=lp->api_post(self_link,params);
|
|
return resp.has_value();
|
|
}
|
|
|
|
std::optional<nlohmann::json> distro_series::newMilestone(const std::string& name,
|
|
const std::optional<std::string>& code_name,
|
|
const std::optional<std::string>& date_targeted,
|
|
const std::optional<std::string>& summary) const {
|
|
if(!lp||self_link.empty())return std::nullopt;
|
|
std::map<std::string,std::string>params;
|
|
params["ws.op"]="newMilestone";
|
|
params["name"]=name;
|
|
if(code_name.has_value()) params["code_name"]=code_name.value();
|
|
if(date_targeted.has_value()) params["date_targeted"]=date_targeted.value();
|
|
if(summary.has_value()) params["summary"]=summary.value();
|
|
auto resp=lp->api_post(self_link,params);
|
|
if(!resp)return std::nullopt;
|
|
return nlohmann::json::parse(resp.value());
|
|
}
|
|
|
|
bool distro_series::removeBugSubscription(const std::optional<std::string>& subscriber) const {
|
|
if(!lp||self_link.empty())return false;
|
|
std::map<std::string,std::string>params;
|
|
params["ws.op"]="removeBugSubscription";
|
|
if(subscriber.has_value()) params["subscriber"]=subscriber.value();
|
|
auto resp=lp->api_post(self_link,params);
|
|
return resp.has_value();
|
|
}
|