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"
}
This commit is contained in:
Ken Moore
2016-03-25 19:36:25 -04:00
parent cbeb80aee1
commit 5e0cc42ab2
3 changed files with 77 additions and 20 deletions

View File

@@ -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;

View File

@@ -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<confs.length(); i++){
QStringList repoinfo = General::readTextFile(confdir.absoluteFilePath(confs[i])).join("\n").split("}");
for(int j=0; j<repoinfo.length(); j++){
QString repo = repoinfo[j].section(":",0,0);
if(QFile::exists(dbdir.arg(repo))){ found << repo; }
}
}
return QJsonArray::fromStringList(found);
}

View File

@@ -20,8 +20,8 @@ class PKG{
public:
static QJsonObject pkg_info(QStringList origins, QString repo, QString category = "", bool fullresults = true);
static QStringList pkg_search(QString repo, QString searchterm, QString category = "");
static QJsonObject list_categories(QString repo);
static QJsonObject list_repos();
static QJsonArray list_categories(QString repo);
static QJsonArray list_repos();
};
} //end of sysadm namespace