From 5e0cc42ab24bbe60fc12acee8c0ae2ead3f680b2 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Fri, 25 Mar 2016 19:36:25 -0400 Subject: [PATCH] Add two more API calls for sysadm/pkg 1) "action"="list_categories" (optional argument: "repo"). This will list all the known categories within the given repository (local repository used by default if none specified). WARNING: Just because a category is listed from here does not mean there are packages existing within that category. This might be corrected later on to only return categories where packages reside. 2) "action"="list_repos" (no other arguments). This will scan the pkg repo config files and return any repos that pkg is currently aware of. NOTE: All of the repos returns by this function are valid as the optional "repo" argument for the other sysadm/pkg API calls. API Call #1: REST Request: ------------------------------- PUT /sysadm/pkg { "repo" : "local", "action" : "list_categories" } WebSocket Request: ------------------------------- { "id" : "fooid", "args" : { "action" : "list_categories", "repo" : "local" }, "namespace" : "sysadm", "name" : "pkg" } Response: ------------------------------- { "args": { "list_categories": [ "ports-mgmt", "x11", "gnome", "textproc", "devel", "python", "misc", "print", "graphics", "security", "x11-fonts", "lang", "ipv6", "perl5", "converters", "math", "x11-toolkits", "sysutils", "dns", "net", "accessibility", "databases", "shells", "x11-themes", "multimedia", "audio", "www", "ftp", "net-im", "archivers", "comms", "java", "deskutils", "kde", "mail", "editors", "emulators", "games", "irc", "japanese", "news", "x11-servers", "tk", "net-mgmt", "ruby", "x11-drivers", "x11-wm", "x11-clocks", "kld", "tcl", "enlightenment", "linux" ] }, "id": "fooid", "name": "response", "namespace": "sysadm" } API Call #2 REST Request: ------------------------------- PUT /sysadm/pkg { "action" : "list_repos" } WebSocket Request: ------------------------------- { "id" : "fooid", "namespace" : "sysadm", "name" : "pkg", "args" : { "action" : "list_repos" } } Response: ------------------------------- { "args": { "list_repos": [ "local", "pcbsd-major" ] }, "id": "fooid", "name": "response", "namespace": "sysadm" } --- src/server/WebBackend.cpp | 31 +++++++++++----- src/server/library/sysadm-pkg.cpp | 62 +++++++++++++++++++++++++++---- src/server/library/sysadm-pkg.h | 4 +- 3 files changed, 77 insertions(+), 20 deletions(-) diff --git a/src/server/WebBackend.cpp b/src/server/WebBackend.cpp index ec11252..2122dbf 100644 --- a/src/server/WebBackend.cpp +++ b/src/server/WebBackend.cpp @@ -702,24 +702,24 @@ RestOutputStruct::ExitCode WebSocket::EvaluateSysadmPkgRequest(const QJsonValue //OPTIONAL: "category" (only used if "pkg_origins" is not specified) QString cat; if(in_args.toObject().contains("category")){ cat = in_args.toObject().value("category").toString(); } - - //Parse + //OPTIONAL: "pkg_origins" (defaults to everything for listing functions) + QStringList pkgs; + if(in_args.toObject().contains("pkg_origins")){ + if(in_args.toObject().value("pkg_origins").isString()){ pkgs << in_args.toObject().value("pkg_origins").toString(); } + else if(in_args.toObject().value("pkg_origins").isArray()){ pkgs = JsonArrayToStringList(in_args.toObject().value("pkg_origins").toArray()); } + } + + //Parse the action and perform accordingly if(act=="pkg_info"){ - //OPTIONAL: "pkg_origins" (defaults to everything for listing functions) - QStringList pkgs; - if(in_args.toObject().contains("pkg_origins")){ - if(in_args.toObject().value("pkg_origins").isString()){ pkgs << in_args.toObject().value("pkg_origins").toString(); } - else if(in_args.toObject().value("pkg_origins").isArray()){ pkgs = JsonArrayToStringList(in_args.toObject().value("pkg_origins").toArray()); } - } //OPTIONAL: "result" - bool fullresults = true; + bool fullresults = false; if(in_args.toObject().contains("result")){ fullresults = (in_args.toObject().value("result").toString()=="full"); } + //Now run the info fetch routine QJsonObject info = sysadm::PKG::pkg_info(pkgs, repo, cat, fullresults); if(!info.isEmpty()){ out->insert("pkg_info",info); } else{ return RestOutputStruct::NOCONTENT; } - }else if(act=="pkg_search"){ //REQUIRED QString srch; @@ -732,6 +732,17 @@ RestOutputStruct::ExitCode WebSocket::EvaluateSysadmPkgRequest(const QJsonValue }else{ return RestOutputStruct::NOCONTENT; } + + }else if(act=="list_categories"){ + QJsonArray cats = sysadm::PKG::list_categories(repo); + if(!cats.isEmpty()){ out->insert("list_categories", cats); } + else{ return RestOutputStruct::NOCONTENT; } + + }else if(act=="list_repos"){ + QJsonArray repos = sysadm::PKG::list_repos(); + if(!repos.isEmpty()){ out->insert("list_repos", repos); } + else{ return RestOutputStruct::NOCONTENT; } + }else{ //unknown action return RestOutputStruct::BADREQUEST; diff --git a/src/server/library/sysadm-pkg.cpp b/src/server/library/sysadm-pkg.cpp index bc7cf25..12ddb85 100644 --- a/src/server/library/sysadm-pkg.cpp +++ b/src/server/library/sysadm-pkg.cpp @@ -79,9 +79,9 @@ QJsonObject PKG::pkg_info(QStringList origins, QString repo, QString category, b //new database needs to be loaded qDebug() << "New DB Connection"; DB = QSqlDatabase::addDatabase("QSQLITE"); - DB.setConnectOptions("QSQLITE_OPEN_READONLY=1"); + /*DB.setConnectOptions("QSQLITE_OPEN_READONLY=1"); DB.setHostName("localhost"); - DB.setDatabaseName(dbname); + DB.setDatabaseName(dbname);*/ } if(DB.databaseName()!=dbname){ if(DB.isOpen()){ DB.close(); } @@ -204,9 +204,9 @@ QStringList PKG::pkg_search(QString repo, QString searchterm, QString category){ //new database needs to be loaded qDebug() << "New DB Connection"; DB = QSqlDatabase::addDatabase("QSQLITE"); - DB.setConnectOptions("QSQLITE_OPEN_READONLY=1"); + /*DB.setConnectOptions("QSQLITE_OPEN_READONLY=1"); DB.setHostName("localhost"); - DB.setDatabaseName(dbname); + DB.setDatabaseName(dbname);*/ } if(DB.databaseName()!=dbname){ if(DB.isOpen()){ DB.close(); } @@ -247,10 +247,56 @@ QStringList PKG::pkg_search(QString repo, QString searchterm, QString category){ return found; } -QJsonObject PKG::list_categories(QString repo){ - return QJsonObject(); +QJsonArray PKG::list_categories(QString repo){ + QString dbname = getRepoFile(repo); + //qDebug() << "Database:" << dbname;// << conn; + //Open the local database + QSqlDatabase DB; + if(QSqlDatabase::contains()){ + //database already loaded + qDebug() << "Existing DB Connection"; + DB = QSqlDatabase::database(); + }else{ + //new database needs to be loaded + qDebug() << "New DB Connection"; + DB = QSqlDatabase::addDatabase("QSQLITE"); + /*DB.setConnectOptions("QSQLITE_OPEN_READONLY=1"); + DB.setHostName("localhost"); + DB.setDatabaseName(dbname);*/ + } + if(DB.databaseName()!=dbname){ + if(DB.isOpen()){ DB.close(); } + DB.setConnectOptions("QSQLITE_OPEN_READONLY=1"); + DB.setHostName("localhost"); + DB.setDatabaseName(dbname); + } + qDebug() << "Open Database:" << DB.databaseName() << dbname; + if( !DB.open() ){ + //qDebug() << " - could not be opened"; + return QJsonArray(); + } + QString q_string = "SELECT name FROM categories"; + QSqlQuery query(q_string); + QStringList found; + while(query.next()){ + found << query.value("name").toString(); //need the origin for later + } + if(!found.isEmpty()){ return QJsonArray::fromStringList(found); } + else{ return QJsonArray(); } } -QJsonObject PKG::list_repos(){ - return QJsonObject(); +QJsonArray PKG::list_repos(){ + QString dbdir = "/var/db/pkg/repo-%1.sqlite"; + QDir confdir("/usr/local/etc/pkg/repos"); + QStringList confs = confdir.entryList(QStringList() << "*.conf", QDir::Files); + QStringList found; + found << "local"; //There is always a local database (for installed pkgs) + for(int i=0; i