|
|
|
@ -56,54 +56,6 @@ void DistroqueryAPI::sendErrorResponse(string message) {
|
|
|
|
|
exit(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
json DistroqueryAPI::getPackageSourceDetailsById(configTag* ct, long id) {
|
|
|
|
|
json j;
|
|
|
|
|
string sql;
|
|
|
|
|
sqlite3_stmt *stmt;
|
|
|
|
|
|
|
|
|
|
auto db = openRepositoryDatabase(ct);
|
|
|
|
|
if (!db) {
|
|
|
|
|
j["error"] = "error opening sources database for repository " + string(ct->tag);
|
|
|
|
|
return j;
|
|
|
|
|
}
|
|
|
|
|
sql = "SELECT * FROM sources,packagers WHERE sources.id=" + to_string(id) +
|
|
|
|
|
" AND sources.id_packager=packagers.id";
|
|
|
|
|
if (!sqlite3_prepare_v2(db, sql.c_str(), sql.length(), &stmt, NULL) == SQLITE_OK) {
|
|
|
|
|
j["error"] = "error preparing query '" + sql + "'";
|
|
|
|
|
return j;
|
|
|
|
|
}
|
|
|
|
|
if (sqlite3_step(stmt) == SQLITE_ROW) {
|
|
|
|
|
j["id"] = sqlite3_column_int(stmt,sqlite3_find_column_id(stmt, NULL, "id"));
|
|
|
|
|
j["name"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "name")));
|
|
|
|
|
j["summary"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "summary")));
|
|
|
|
|
j["epoch"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "epoch")));
|
|
|
|
|
j["version"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "version")));
|
|
|
|
|
j["release"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "release")));
|
|
|
|
|
j["description"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "description")));
|
|
|
|
|
j["group"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "groupdescr")));
|
|
|
|
|
j["license"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "license")));
|
|
|
|
|
j["url"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "url")));
|
|
|
|
|
//get_favicon_from_url((const char*)sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, NULL, "url")),buffer,PATH_MAX);
|
|
|
|
|
j["size"] = sqlite3_column_int(stmt,sqlite3_find_column_id(stmt, NULL, "size"));
|
|
|
|
|
j["maintainer"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, "packagers", "name")));
|
|
|
|
|
// Convert buildtime to ISO-8601
|
|
|
|
|
auto itt = (time_t)sqlite3_column_int(stmt,sqlite3_find_column_id(stmt, NULL, "buildtime"));
|
|
|
|
|
ostringstream ss;
|
|
|
|
|
ss << std::put_time(gmtime(&itt), "%FT%TZ");
|
|
|
|
|
j["buildtime"] = ss.str();
|
|
|
|
|
// Download URL
|
|
|
|
|
j["download_url"] = string(ct->download_prefix) + ct->download_dir + "/SRPMS.base/" +
|
|
|
|
|
string(j["name"]) + "-" + string(j["version"]) + "-" + string(j["release"]) + ".src.rpm";
|
|
|
|
|
// Source URL
|
|
|
|
|
string name = string(j["name"]);
|
|
|
|
|
j["source_url"] = "https://src.openmamba.org/rpms/" + replaceAll(name, "+", "Plus");
|
|
|
|
|
} else {
|
|
|
|
|
j["error"] = "no results from query '" + sql + "'";
|
|
|
|
|
return j;
|
|
|
|
|
}
|
|
|
|
|
return j;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
json DistroqueryAPI::getRepositoryPackages(string repository, int per_page, int page, string query) {
|
|
|
|
|
json j;
|
|
|
|
|
string sql;
|
|
|
|
@ -196,11 +148,60 @@ json DistroqueryAPI::getRepositoryPackages(string repository, int per_page, int
|
|
|
|
|
return j;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
json DistroqueryAPI::getBuiltPackagesFromSourceID(configTag* ct, long id) {
|
|
|
|
|
json j = json::array();
|
|
|
|
|
json DistroqueryAPI::getPackageSourceDetailsById(configTag* ct, long id) {
|
|
|
|
|
json j;
|
|
|
|
|
string sql;
|
|
|
|
|
sqlite3_stmt *stmt;
|
|
|
|
|
|
|
|
|
|
auto db = openRepositoryDatabase(ct);
|
|
|
|
|
if (!db) {
|
|
|
|
|
j["error"] = "error opening sources database for repository " + string(ct->tag);
|
|
|
|
|
return j;
|
|
|
|
|
}
|
|
|
|
|
sql = "SELECT * FROM sources,packagers WHERE sources.id=" + to_string(id) +
|
|
|
|
|
" AND sources.id_packager=packagers.id";
|
|
|
|
|
if (!sqlite3_prepare_v2(db, sql.c_str(), sql.length(), &stmt, NULL) == SQLITE_OK) {
|
|
|
|
|
j["error"] = "error preparing query '" + sql + "': " + sqlite3_errmsg(db);
|
|
|
|
|
return j;
|
|
|
|
|
}
|
|
|
|
|
if (sqlite3_step(stmt) == SQLITE_ROW) {
|
|
|
|
|
j["id"] = sqlite3_column_int(stmt,sqlite3_find_column_id(stmt, NULL, "id"));
|
|
|
|
|
j["name"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "name")));
|
|
|
|
|
j["summary"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "summary")));
|
|
|
|
|
j["epoch"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "epoch")));
|
|
|
|
|
j["version"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "version")));
|
|
|
|
|
j["release"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "release")));
|
|
|
|
|
j["description"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "description")));
|
|
|
|
|
j["group"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "groupdescr")));
|
|
|
|
|
j["license"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "license")));
|
|
|
|
|
j["url"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "url")));
|
|
|
|
|
//get_favicon_from_url((const char*)sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, NULL, "url")),buffer,PATH_MAX);
|
|
|
|
|
j["size"] = sqlite3_column_int(stmt,sqlite3_find_column_id(stmt, NULL, "size"));
|
|
|
|
|
j["maintainer"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, "packagers", "name")));
|
|
|
|
|
// Convert buildtime to ISO-8601
|
|
|
|
|
auto itt = (time_t)sqlite3_column_int(stmt,sqlite3_find_column_id(stmt, NULL, "buildtime"));
|
|
|
|
|
ostringstream ss;
|
|
|
|
|
ss << std::put_time(gmtime(&itt), "%FT%TZ");
|
|
|
|
|
j["buildtime"] = ss.str();
|
|
|
|
|
// Download URL
|
|
|
|
|
j["download_url"] = string(ct->download_prefix) + ct->download_dir + "/SRPMS.base/" +
|
|
|
|
|
string(j["name"]) + "-" + string(j["version"]) + "-" + string(j["release"]) + ".src.rpm";
|
|
|
|
|
// Source URL
|
|
|
|
|
string name = string(j["name"]);
|
|
|
|
|
j["source_url"] = "https://src.openmamba.org/rpms/" + replaceAll(name, "+", "Plus");
|
|
|
|
|
} else {
|
|
|
|
|
j["error"] = "no results from query '" + sql + "'";
|
|
|
|
|
return j;
|
|
|
|
|
}
|
|
|
|
|
return j;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
json DistroqueryAPI::getBuiltPackagesFromSourceID(configTag* ct, long id) {
|
|
|
|
|
json j = {};
|
|
|
|
|
string sql;
|
|
|
|
|
sqlite3_stmt *stmt;
|
|
|
|
|
|
|
|
|
|
json archs = {};
|
|
|
|
|
for (auto arch: ct->arch) {
|
|
|
|
|
if (arch == NULL) break;
|
|
|
|
|
auto db = openRepositoryDatabase(ct, arch);
|
|
|
|
@ -213,18 +214,91 @@ json DistroqueryAPI::getBuiltPackagesFromSourceID(configTag* ct, long id) {
|
|
|
|
|
sql = "SELECT * FROM packages WHERE id_source = " + to_string(id) + " ORDER BY name";
|
|
|
|
|
if (sqlite3_prepare_v2(db, sql.c_str(), sql.length(), &stmt, NULL) == SQLITE_OK) {
|
|
|
|
|
while (sqlite3_step(stmt) == SQLITE_ROW) {
|
|
|
|
|
if (!archs.contains(arch)) {
|
|
|
|
|
archs[arch] = json::array();
|
|
|
|
|
}
|
|
|
|
|
json package = {};
|
|
|
|
|
package["arch"] = arch;
|
|
|
|
|
package["name"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "name")));
|
|
|
|
|
j.push_back(package);
|
|
|
|
|
archs[arch].push_back(package);
|
|
|
|
|
}
|
|
|
|
|
sqlite3_finalize(stmt);
|
|
|
|
|
} else {
|
|
|
|
|
j = {};
|
|
|
|
|
j["error"] = "error preparing query '" + sql + "'";
|
|
|
|
|
j["error"] = "error preparing query '" + sql + "': " + sqlite3_errmsg(db);
|
|
|
|
|
return j;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
j["archs"] = archs;
|
|
|
|
|
return j;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
json DistroqueryAPI::getProvidersForRequirement(string repository, string requirement, string flags, string version) {
|
|
|
|
|
json j;
|
|
|
|
|
sqlite3_stmt *stmt;
|
|
|
|
|
|
|
|
|
|
struct configTag* ct = findRepositoryByTag(repository.c_str());
|
|
|
|
|
if (ct == NULL) {
|
|
|
|
|
j["error"] = "repository with tag '" + repository + "' does not exist";
|
|
|
|
|
return j;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
auto db = openRepositoryDatabase(ct);
|
|
|
|
|
if (!db) {
|
|
|
|
|
j["error"] = "error opening sources database for repository " + string(ct->tag);
|
|
|
|
|
return j;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
string sql = "SELECT u.* FROM (";
|
|
|
|
|
|
|
|
|
|
int intflags = rpmSenseStringToFlags(flags);
|
|
|
|
|
|
|
|
|
|
int a = 0;
|
|
|
|
|
for (auto arch: ct->arch) {
|
|
|
|
|
if (arch == NULL) break;
|
|
|
|
|
attachCtDatabases(ct, db, arch);
|
|
|
|
|
int i = 0;
|
|
|
|
|
while (ct->repository[i]) {
|
|
|
|
|
if (a + i > 0) sql += " UNION ";
|
|
|
|
|
sql += "SELECT *,'" + string(ct->repository[i]->tag) + "' AS repository,'" +
|
|
|
|
|
arch + "' AS arch "
|
|
|
|
|
"FROM '" + string(ct->repository[i]->tag) + "_" + arch + "'.provides,'" +
|
|
|
|
|
string(ct->repository[i]->tag) + "_" + arch + "'.packages "
|
|
|
|
|
"WHERE providename='" + requirement + "' AND packages.id=provides.id_package";
|
|
|
|
|
if (flags != "") {
|
|
|
|
|
sql += " AND provideflags='" + to_string(intflags) + "' AND provideversion='" + version + "'";
|
|
|
|
|
}
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
a++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sql += ") AS u ORDER BY providename COLLATE NOCASE ASC";
|
|
|
|
|
|
|
|
|
|
json archs = {};
|
|
|
|
|
|
|
|
|
|
if (sqlite3_prepare_v2(db, sql.c_str(), sql.length(), &stmt, NULL) == SQLITE_OK) {
|
|
|
|
|
json providers = json::array();
|
|
|
|
|
while (sqlite3_step(stmt) == SQLITE_ROW) {
|
|
|
|
|
string arch = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "arch")));
|
|
|
|
|
if (!archs.contains(arch)) {
|
|
|
|
|
archs[arch] = json::array();
|
|
|
|
|
}
|
|
|
|
|
json provider = {};
|
|
|
|
|
provider["repository"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "repository")));
|
|
|
|
|
provider["name"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "name")));
|
|
|
|
|
provider["flags"] = rpmSenseFlagsToString(sqlite3_column_int(stmt,sqlite3_find_column_id(stmt, NULL, "provideflags")));
|
|
|
|
|
provider["version"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt,sqlite3_find_column_id(stmt, NULL, "provideversion")));
|
|
|
|
|
archs[arch].push_back(provider);
|
|
|
|
|
}
|
|
|
|
|
//j["providers"] = providers;
|
|
|
|
|
sqlite3_finalize(stmt);
|
|
|
|
|
} else {
|
|
|
|
|
j = {};
|
|
|
|
|
j["error"] = "error preparing query '" + sql + "': " + sqlite3_errmsg(db);
|
|
|
|
|
return j;
|
|
|
|
|
}
|
|
|
|
|
j["providers"] = {};
|
|
|
|
|
j["providers"]["archs"] = archs;
|
|
|
|
|
return j;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -267,6 +341,8 @@ json DistroqueryAPI::getPackageSourceDetails(string repository, string package)
|
|
|
|
|
buildrequire["name"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt2,sqlite3_find_column_id(stmt2, NULL, "buildrequirename")));
|
|
|
|
|
buildrequire["flags"] = rpmSenseFlagsToString(sqlite3_column_int(stmt2,sqlite3_find_column_id(stmt2, NULL, "buildrequireflags")));
|
|
|
|
|
buildrequire["version"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt2,sqlite3_find_column_id(stmt2, NULL, "buildrequireversion")));
|
|
|
|
|
json jproviders = getProvidersForRequirement(repository, buildrequire["name"], buildrequire["flags"], buildrequire["version"]);
|
|
|
|
|
buildrequire["providers"] = jproviders["providers"];
|
|
|
|
|
j["buildrequires"].push_back(buildrequire);
|
|
|
|
|
}
|
|
|
|
|
sqlite3_finalize(stmt2);
|
|
|
|
@ -275,6 +351,26 @@ json DistroqueryAPI::getPackageSourceDetails(string repository, string package)
|
|
|
|
|
// Children
|
|
|
|
|
j["children"] = getBuiltPackagesFromSourceID(ct, id);
|
|
|
|
|
|
|
|
|
|
// Changelog
|
|
|
|
|
sql = "SELECT * FROM changelog,packagers WHERE id_source=" + to_string(id) +
|
|
|
|
|
" AND id_packager=packagers.id";
|
|
|
|
|
j["changelog"] = json::array();
|
|
|
|
|
if (sqlite3_prepare_v2(db, sql.c_str(), sql.length(), &stmt2, NULL) == SQLITE_OK) {
|
|
|
|
|
while (sqlite3_step(stmt2) == SQLITE_ROW) {
|
|
|
|
|
json change = {};
|
|
|
|
|
// Convert buildtime to ISO-8601
|
|
|
|
|
auto itt = (time_t)sqlite3_column_int(stmt2,sqlite3_find_column_id(stmt2, NULL, "time"));
|
|
|
|
|
ostringstream ss;
|
|
|
|
|
ss << std::put_time(gmtime(&itt), "%FT%TZ");
|
|
|
|
|
change["date"] = ss.str();
|
|
|
|
|
change["packager"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt2,sqlite3_find_column_id(stmt2, "packagers", "name")));
|
|
|
|
|
change["release"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt2,sqlite3_find_column_id(stmt2, NULL, "release")));
|
|
|
|
|
change["text"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt2,sqlite3_find_column_id(stmt2, NULL, "text")));
|
|
|
|
|
j["changelog"].push_back(change);
|
|
|
|
|
}
|
|
|
|
|
sqlite3_finalize(stmt2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
j["error"] = "error preparing query '" + sql + "'";
|
|
|
|
|
return j;
|
|
|
|
@ -504,6 +600,18 @@ void DistroqueryAPI::getApiResponse(string path_info) {
|
|
|
|
|
details = getPackageDetails(path_split[1], package, path_split[3]);
|
|
|
|
|
}
|
|
|
|
|
cout << details.dump();
|
|
|
|
|
} else if (path_split[0] == "providers") {
|
|
|
|
|
// API service: package
|
|
|
|
|
if (path_split.size() != 3 && path_split.size() != 5)
|
|
|
|
|
sendErrorResponse("expected 3 or 5 arguments for " + path_split[0]);
|
|
|
|
|
json providers;
|
|
|
|
|
if (path_split.size() == 3)
|
|
|
|
|
providers = getProvidersForRequirement(path_split[1], urlDecode(path_split[2]),
|
|
|
|
|
"", "");
|
|
|
|
|
else if (path_split.size() == 5)
|
|
|
|
|
providers = getProvidersForRequirement(path_split[1], urlDecode(path_split[2]),
|
|
|
|
|
urlDecode(path_split[3]), urlDecode(path_split[4]));
|
|
|
|
|
cout << providers.dump();
|
|
|
|
|
} else {
|
|
|
|
|
sendErrorResponse("invalid request for service '" + path_split[0]);
|
|
|
|
|
}
|
|
|
|
|