]> git.ipfire.org Git - pakfire.git/commitdiff
libpakfire: Implement dumping a transaction
authorMichael Tremer <michael.tremer@ipfire.org>
Wed, 7 Jun 2017 20:54:06 +0000 (22:54 +0200)
committerMichael Tremer <michael.tremer@ipfire.org>
Wed, 7 Jun 2017 20:54:06 +0000 (22:54 +0200)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/_pakfire/request.c
src/_pakfire/transaction.c
src/libpakfire/include/pakfire/transaction.h
src/libpakfire/libpakfire.sym
src/libpakfire/transaction.c

index dc786baac002043fff8023b23df6d242fc659851..6d04d024ef2f8551736138bc352c5e583329452a 100644 (file)
@@ -194,16 +194,11 @@ static PyObject* Request_solve(RequestObject* self) {
        int ret = pakfire_request_solve(self->request, 0);
 
        if (ret)
-               Py_RETURN_FALSE;
-
-       Py_RETURN_TRUE;
-}
+               Py_RETURN_NONE;
 
-static PyObject* Request_get_transaction(RequestObject* self) {
+       // Allocate the transaction and return it
        PakfireTransaction transaction = pakfire_request_get_transaction(self->request);
-
-       if (!transaction)
-               Py_RETURN_NONE;
+       assert(transaction);
 
        return new_transaction(self, transaction);
 }
@@ -269,12 +264,6 @@ static struct PyMethodDef Request_methods[] = {
                METH_NOARGS,
                NULL
        },
-       {
-               "get_transaction",
-               (PyCFunction)Request_get_transaction,
-               METH_NOARGS,
-               NULL
-       },
        { NULL }
 };
 
index d6032a23416a7357ec73e4c7fbe805d9a6594089..6004f84dbd014c665d82b6be589f952357997fc3 100644 (file)
@@ -104,15 +104,22 @@ static PyObject* Transaction_get_installsizechange(TransactionObject* self) {
        return PyLong_FromLong(installsizechange);
 }
 
-#if 0
-static PyObject* Transaction_get_installs(TransactionObject* self) {
-       PakfirePackageList packagelist = pakfire_transaction_get_packages(self->transaction,
-               SOLVER_TRANSACTION_INSTALL);
+static PyObject* Transaction_dump(TransactionObject* self) {
+       char* string = pakfire_transaction_dump(self->transaction, 80);
+       assert(string);
 
-       PyObject* list = PyList_FromPackageList(self->request->pool, packagelist);
-       return list;
+       return PyUnicode_FromString(string);
 }
-#endif
+
+static struct PyMethodDef Transaction_methods[] = {
+       {
+               "dump",
+               (PyCFunction)Transaction_dump,
+               METH_NOARGS,
+               NULL
+       },
+       { NULL },
+};
 
 static struct PyGetSetDef Transaction_getsetters[] = {
        {
@@ -134,6 +141,7 @@ PyTypeObject TransactionType = {
        tp_dealloc:         (destructor)Transaction_dealloc,
        tp_init:            (initproc)Transaction_init,
        tp_doc:             "Transaction object",
+       tp_methods:         Transaction_methods,
        tp_getset:          Transaction_getsetters,
        tp_iter:            (getiterfunc)Transaction_iter,
 };
index 3ead26303287a206e5ef392568deb4a07f136f53..68995447798318196ec1115e77f8ae10d6c7b2fd 100644 (file)
 PakfireTransaction pakfire_transaction_create(PakfirePool pool, Transaction* trans);
 void pakfire_transaction_free(PakfireTransaction transaction);
 
-int pakfire_transaction_count(PakfireTransaction transaction);
+size_t pakfire_transaction_count(PakfireTransaction transaction);
 
-int pakfire_transaction_installsizechange(PakfireTransaction transaction);
+ssize_t pakfire_transaction_installsizechange(PakfireTransaction transaction);
 
 PakfireStep pakfire_transaction_get_step(PakfireTransaction transaction, int index);
 PakfirePackageList pakfire_transaction_get_packages(PakfireTransaction transaction, int type);
 
+char* pakfire_transaction_dump(PakfireTransaction transaction, size_t width);
+
 #ifdef PAKFIRE_PRIVATE
 
 struct _PakfireTransaction {
index b6baf71d0417ac10f145fb3a52a10861197d4ed0..dee81712c821de8f1b6318ee582cbc5343f4d513 100644 (file)
@@ -264,6 +264,7 @@ global:
 
        # transaction
        pakfire_transaction_create;
+       pakfire_transaction_dump;
        pakfire_transaction_free;
        pakfire_transaction_get_packages;
        pakfire_transaction_get_step;
index df15f80df0b6a9edf377fe5d8f1c3e93df0aaccb..2d6f84dd342c490785db1dd84ef39fe74fd250bc 100644 (file)
 #                                                                             #
 #############################################################################*/
 
+#include <assert.h>
 #include <solv/transaction.h>
 
+#include <pakfire/i18n.h>
 #include <pakfire/package.h>
 #include <pakfire/packagelist.h>
+#include <pakfire/repo.h>
 #include <pakfire/step.h>
 #include <pakfire/transaction.h>
 #include <pakfire/types.h>
@@ -47,18 +50,45 @@ void pakfire_transaction_free(PakfireTransaction transaction) {
        pakfire_free(transaction);
 }
 
-int pakfire_transaction_count(PakfireTransaction transaction) {
+size_t pakfire_transaction_count(PakfireTransaction transaction) {
        return transaction->transaction->steps.count;
 }
 
-int pakfire_transaction_installsizechange(PakfireTransaction transaction) {
-       int sizechange = transaction_calc_installsizechange(transaction->transaction);
-       printf("SIZECHANGE %d\n", sizechange);
+ssize_t pakfire_transaction_installsizechange(PakfireTransaction transaction) {
+       ssize_t sizechange = transaction_calc_installsizechange(transaction->transaction);
 
        // Convert from kbytes to bytes
        return sizechange * 1024;
 }
 
+ssize_t pakfire_transaction_downloadsize(PakfireTransaction transaction) {
+       PakfirePool pool = pakfire_transaction_pool(transaction);
+       ssize_t size = 0;
+
+       for (int i = 0; i < transaction->transaction->steps.count; i++) {
+               Id p = transaction->transaction->steps.elements[i];
+               Id t = transaction_type(transaction->transaction, p,
+                       SOLVER_TRANSACTION_SHOW_OBSOLETES |
+                       SOLVER_TRANSACTION_CHANGE_IS_REINSTALL |
+                       SOLVER_TRANSACTION_SHOW_ALL |
+                       SOLVER_TRANSACTION_SHOW_ACTIVE);
+
+               // Erasing a package does not require us to download it
+               if (t == SOLVER_TRANSACTION_ERASE)
+                       continue;
+
+               // Get the package for this step
+               PakfirePackage pkg = pakfire_package_create(pool, p);
+
+               if (!pakfire_package_is_cached(pkg))
+                       size += pakfire_package_get_downloadsize(pkg);
+
+               pakfire_package_free(pkg);
+       }
+
+       return size;
+}
+
 PakfireStep pakfire_transaction_get_step(PakfireTransaction transaction, int index) {
        Transaction* trans = transaction->transaction;
 
@@ -70,14 +100,16 @@ PakfireStep pakfire_transaction_get_step(PakfireTransaction transaction, int ind
 
 PakfirePackageList pakfire_transaction_get_packages(PakfireTransaction transaction, int type) {
        PakfirePool pool = pakfire_transaction_pool(transaction);
-       Transaction* trans = transaction->transaction;
 
        PakfirePackageList packagelist = pakfire_packagelist_create();
 
-       for (int i = 0; i < trans->steps.count; i++) {
-               Id p = trans->steps.elements[i];
-               Id t = transaction_type(trans, p,
-                       SOLVER_TRANSACTION_SHOW_ACTIVE|SOLVER_TRANSACTION_CHANGE_IS_REINSTALL);
+       for (int i = 0; i < transaction->transaction->steps.count; i++) {
+               Id p = transaction->transaction->steps.elements[i];
+               Id t = transaction_type(transaction->transaction, p,
+                       SOLVER_TRANSACTION_SHOW_OBSOLETES |
+                       SOLVER_TRANSACTION_CHANGE_IS_REINSTALL |
+                       SOLVER_TRANSACTION_SHOW_ALL |
+                       SOLVER_TRANSACTION_SHOW_ACTIVE);
 
                if (t == type) {
                        PakfirePackage package = pakfire_package_create(pool, p);
@@ -85,5 +117,150 @@ PakfirePackageList pakfire_transaction_get_packages(PakfireTransaction transacti
                }
        }
 
+       // Sort list in place
+       pakfire_packagelist_sort(packagelist);
+
        return packagelist;
 }
+
+static void pakfire_transaction_add_headline(char** str, size_t width, const char* headline) {
+       assert(headline);
+
+       asprintf(str, "%s%s\n", *str, headline);
+}
+
+static void pakfire_transaction_add_newline(char** str, size_t width) {
+       asprintf(str, "%s\n", *str);
+}
+
+static void pakfire_transaction_add_line(char** str, size_t width, const char* name,
+               const char* arch, const char* version, const char* repo, const char* size) {
+       // XXX need to adapt to size
+       asprintf(str, "%s %-21s %-8s %-21s %-18s %6s \n", *str, name, arch, version, repo, size);
+}
+
+static void pakfire_transaction_add_package(char** str, size_t width, PakfirePackage pkg) {
+       PakfireRepo repo = pakfire_package_get_repo(pkg);
+
+       unsigned long long size = pakfire_package_get_size(pkg);
+       char* size_str = pakfire_format_size(size);
+
+       pakfire_transaction_add_line(str, width,
+               pakfire_package_get_name(pkg),
+               pakfire_package_get_arch(pkg),
+               pakfire_package_get_evr(pkg),
+               pakfire_repo_get_name(repo),
+               size_str
+       );
+
+       pakfire_repo_free(repo);
+       pakfire_free(size_str);
+}
+
+static void pakfire_transaction_add_separator(char** str, size_t width) {
+       while (width-- > 0)
+               asprintf(str, "%s=", *str);
+
+       // newline
+       asprintf(str, "%s\n", *str);
+}
+
+static size_t pakfire_transaction_add_section(char** str, size_t width, PakfireTransaction transaction,
+               const char* headline, int type) {
+       PakfirePackageList list = pakfire_transaction_get_packages(transaction, type);
+
+       // Nothing to do if there are no packages in this stage
+       size_t c = pakfire_packagelist_count(list);
+       if (c == 0)
+               goto END;
+
+       // Headline
+       pakfire_transaction_add_headline(str, width, headline);
+
+       // List each package
+       for (unsigned int i = 0; i < c; i++) {
+               PakfirePackage pkg = pakfire_packagelist_get(list, i);
+               pakfire_transaction_add_package(str, width, pkg);
+       }
+
+       // newline
+       pakfire_transaction_add_newline(str, width);
+
+END:
+       pakfire_packagelist_free(list);
+
+       return c;
+}
+
+static void pakfire_transaction_add_summary_line(char** str, size_t width, const char* headline, size_t pkgs) {
+       if (pkgs > 0)
+               asprintf(str, "%s%-20s %-4zu %s\n", *str, headline, pkgs, _("package(s)"));
+}
+
+static void pakfire_transaction_add_usage_line(char** str, size_t width, const char* headline, ssize_t size) {
+       char* s = pakfire_format_size(size);
+
+       asprintf(str, "%s%-21s: %s\n", *str, headline, s);
+
+       pakfire_free(s);
+}
+
+char* pakfire_transaction_dump(PakfireTransaction transaction, size_t width) {
+       char* string = "";
+
+       // Header
+       pakfire_transaction_add_separator(&string, width);
+       pakfire_transaction_add_line(&string, width,
+               _("Package"),
+               _("Arch"),
+               _("Version"),
+               _("Repository"),
+               _("Size")
+       );
+       pakfire_transaction_add_separator(&string, width);
+
+       // Show what we are doing
+       size_t installing = pakfire_transaction_add_section(&string, width, transaction,
+               _("Installing:"), SOLVER_TRANSACTION_INSTALL);
+       size_t reinstalling = pakfire_transaction_add_section(&string, width, transaction,
+               _("Reinstalling:"), SOLVER_TRANSACTION_REINSTALL);
+       size_t updating = pakfire_transaction_add_section(&string, width, transaction,
+               _("Updating:"), SOLVER_TRANSACTION_UPGRADE);
+       size_t downgrading = pakfire_transaction_add_section(&string, width, transaction,
+               _("Downgrading:"), SOLVER_TRANSACTION_DOWNGRADE);
+       size_t removing = pakfire_transaction_add_section(&string, width, transaction,
+               _("Removing:"), SOLVER_TRANSACTION_ERASE);
+       size_t obsoleting = pakfire_transaction_add_section(&string, width, transaction,
+               _("Obsoleting:"), SOLVER_TRANSACTION_OBSOLETES);
+
+       // Summary
+       pakfire_transaction_add_headline(&string, width, _("Transaction Summary"));
+       pakfire_transaction_add_separator(&string, width);
+
+       pakfire_transaction_add_summary_line(&string, width, _("Installing:"), installing);
+       pakfire_transaction_add_summary_line(&string, width, _("Reinstalling:"), reinstalling);
+       pakfire_transaction_add_summary_line(&string, width, _("Updating:"), updating);
+       pakfire_transaction_add_summary_line(&string, width, _("Downgrading:"), downgrading);
+       pakfire_transaction_add_summary_line(&string, width, _("Removing:"), removing);
+       pakfire_transaction_add_summary_line(&string, width, _("Obsoleting:"), obsoleting);
+
+       // How much do we need to download?
+       size_t downloadsize = pakfire_transaction_downloadsize(transaction);
+       if (downloadsize > 0)
+               pakfire_transaction_add_usage_line(&string, width,
+                       _("Total Download Size"), downloadsize);
+
+       // How much more space do we need?
+       ssize_t sizechange = pakfire_transaction_installsizechange(transaction);
+
+       pakfire_transaction_add_usage_line(&string, width,
+               (sizechange >= 0) ? _("Installed Size") : _("Freed Size"), sizechange);
+
+       // Remove trailing newline
+       size_t l = strlen(string) - 1;
+
+       if (l > 0 && string[l] == '\n')
+               string[l] = '\0';
+
+       return string;
+}