diff --git a/CMakeLists.txt b/CMakeLists.txt index fb2a450..1331ab5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,6 +15,7 @@ pkg_check_modules(LIBSECRET REQUIRED libsecret-1) add_library(launchpad SHARED src/launchpad.cpp src/archive.cpp + src/archive_permission.cpp src/utils.cpp src/person.cpp src/distribution.cpp @@ -32,7 +33,7 @@ target_compile_definitions(launchpad PRIVATE BUILDING_LAUNCHPAD) set_target_properties(launchpad PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION 0 - PUBLIC_HEADER "src/launchpad.h;src/callablewrapper.h;src/archive.h;src/utils.h;src/person.h;src/distribution.h;src/authentication.h;src/source_package_publishing_history.h;src/build.h" + PUBLIC_HEADER "src/launchpad.h;src/callablewrapper.h;src/archive.h;src/archive_permission.h;src/utils.h;src/person.h;src/distribution.h;src/authentication.h;src/source_package_publishing_history.h;src/build.h" CXX_VISIBILITY_PRESET hidden VISIBILITY_INLINES_HIDDEN YES ) diff --git a/src/archive.cpp b/src/archive.cpp index 3468708..807fa4f 100644 --- a/src/archive.cpp +++ b/src/archive.cpp @@ -135,6 +135,29 @@ std::string archive::build_archive_endpoint() const { return "~" + url_encode(owner_name) + "/" + url_encode(ppa_name); } +std::generator archive::getAllPermissions() const { + std::map params = {{"ws.op", "getAllPermissions"}}; + + auto response = lp->api_get(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 = archive_permission::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; + } + } +} + std::generator archive::getPublishedSources(const std::string& status) const { std::map params; params["ws.op"] = "getPublishedSources"; diff --git a/src/archive.h b/src/archive.h index 90f7828..31266f3 100644 --- a/src/archive.h +++ b/src/archive.h @@ -78,6 +78,7 @@ public: // Public functions std::generator getPublishedSources(const std::string& status) const; + std::generator archive::getAllPermissions() const; launchpad* lp; diff --git a/src/archive_permission.cpp b/src/archive_permission.cpp new file mode 100644 index 0000000..ad69f23 --- /dev/null +++ b/src/archive_permission.cpp @@ -0,0 +1,88 @@ +// Copyright (C) 2024 Simon Quigley +// +// 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 . + +#include "archive_permission.h" +#include "launchpad.h" +#include +#include +#include + +archive_permission::archive_permission() + : explicit_(false), + lp(nullptr) {} + +archive_permission::~archive_permission() {} + +std::optional archive_permission::parse(const std::string& json_data) { + archive_permission ap; + ap.parse_json(json_data); + return ap; +} + +void archive_permission::parse_json(const std::string& json_data) { + if (json_data.empty()) { + std::cerr << "Error: Empty JSON data for archive_permission::parse_json." << std::endl; + return; + } + + try { + auto data = nlohmann::json::parse(json_data); + + // Map JSON keys to lambdas to parse + std::map> json_map = { + {"archive_link", [this](const nlohmann::json& val) { archive_link = val.get(); }}, + {"component_name", [this](const nlohmann::json& val) { component_name = val.get(); }}, + {"date_created", [this](const nlohmann::json& val) { date_created = val.get(); }}, + {"distro_series_name", [this](const nlohmann::json& val) { distro_series_name = val.get(); }}, + {"distroseries_link", [this](const nlohmann::json& val) { distroseries_link = val.get(); }}, + {"explicit", [this](const nlohmann::json& val) { explicit_ = val.get(); }}, + {"package_set_name", [this](const nlohmann::json& val) { package_set_name = val.get(); }}, + {"permission", [this](const nlohmann::json& val) { permission = val.get(); }}, + {"person_link", [this](const nlohmann::json& val) { person_link = val.get(); }}, + {"pocket", [this](const nlohmann::json& val) { pocket = val.get(); }}, + {"source_package_name", [this](const nlohmann::json& val) { source_package_name = val.get(); }} + }; + + std::map> readonly_map = { + {"http_etag", [this](const nlohmann::json& val) { http_etag = val.get(); }}, + {"resource_type_link", [this](const nlohmann::json& val) { resource_type_link = val.get(); }}, + {"self_link", [this](const nlohmann::json& val) { self_link = val.get(); }} + }; + + 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) { + // If parsing fails for a field, just continue + continue; + } + } + } catch (const nlohmann::json::parse_error& e) { + std::cerr << "JSON parse error in archive_permission::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; + } +} + +void archive_permission::set_lp(launchpad* lp_ptr) { + lp = lp_ptr; +} diff --git a/src/archive_permission.h b/src/archive_permission.h new file mode 100644 index 0000000..dfabf7d --- /dev/null +++ b/src/archive_permission.h @@ -0,0 +1,66 @@ +// Copyright (C) 2024 Simon Quigley +// +// 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 . + +#ifndef ARCHIVE_PERMISSION_H +#define ARCHIVE_PERMISSION_H + +#include +#include +#include + +class launchpad; + +#ifndef LAUNCHPAD_API +#ifdef BUILDING_LAUNCHPAD + #define LAUNCHPAD_API __attribute__((visibility("default"))) +#else + #define LAUNCHPAD_API +#endif +#endif + +class LAUNCHPAD_API archive_permission { +public: + archive_permission(); + ~archive_permission(); + + static std::optional parse(const std::string& json_data); + + void set_lp(launchpad* lp_ptr); + + // Public member variables (fields) + // Writable fields + std::string archive_link; + std::string component_name; + std::string date_created; + std::string distro_series_name; + std::string distroseries_link; + bool explicit_; + std::string package_set_name; + std::string permission; + std::string person_link; + std::string pocket; + std::string source_package_name; + + // Read-only fields + std::string http_etag; + std::string resource_type_link; + std::string self_link; + +private: + void parse_json(const std::string& json_data); + launchpad* lp; +}; + +#endif // ARCHIVE_PERMISSION_H