From: Michael Tremer Date: Wed, 21 Apr 2021 15:15:38 +0000 (+0000) Subject: archive: Show progress when extracting X-Git-Tag: 0.9.28~1285^2~283 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4f85d6ee653e1a1dc136a6f7a42d0aa5b88ce3cd;p=pakfire.git archive: Show progress when extracting Signed-off-by: Michael Tremer --- diff --git a/src/libpakfire/archive.c b/src/libpakfire/archive.c index eb83d1b6c..37d437cef 100644 --- a/src/libpakfire/archive.c +++ b/src/libpakfire/archive.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -152,13 +153,18 @@ static la_ssize_t pakfire_archive_read_callback(struct archive* a, } } -static struct archive* pakfire_archive_open_payload(PakfireArchive archive, struct archive* a) { +static struct archive* pakfire_archive_open_payload(PakfireArchive archive, + struct archive* a, size_t* size) { // Find the payload struct archive_entry* entry; int r = find_archive_entry(&entry, a, PAKFIRE_ARCHIVE_FN_PAYLOAD); if (r) return NULL; + // Store size + if (size) + *size = archive_entry_size(entry); + // Allocate a new archive object struct archive* payload = archive_read_new(); if (!payload) @@ -728,7 +734,7 @@ PAKFIRE_EXPORT int pakfire_archive_read(PakfireArchive archive, const char* file if (r) goto ERROR; - payload = pakfire_archive_open_payload(archive, a); + payload = pakfire_archive_open_payload(archive, a, NULL); if (!payload) goto ERROR; @@ -784,8 +790,56 @@ struct pakfire_archive_extractor { struct archive* writer; const char* prefix; PakfireFilelist filelist; + struct pakfire_progressbar* progressbar; }; +static int pakfire_archive_extract_progressbar( + PakfireArchive archive, struct pakfire_progressbar** progressbar) { + char* name = pakfire_archive_get(archive, "package", "name"); + char* arch = pakfire_archive_get(archive, "package", "arch"); + + char* e = pakfire_archive_get(archive, "package", "epoch"); + char* v = pakfire_archive_get(archive, "package", "version"); + char* r = pakfire_archive_get(archive, "package", "release"); + char* evr = pakfire_package_join_evr(e, v, r); + + int err = pakfire_progressbar_create(progressbar, NULL); + if (err) + goto ERROR; + + // Add progressbar widgets + err = pakfire_progressbar_add_string(*progressbar, "%s-%s.%s", name, evr, arch); + if (err) + goto ERROR; + + err = pakfire_progressbar_add_bar(*progressbar); + if (err) + goto ERROR; + + err = pakfire_progressbar_add_percentage(*progressbar); + if (err) + goto ERROR; + + // Success + err = 0; + +ERROR: + if (name) + free(name); + if (arch) + free(arch); + if (e) + free(e); + if (v) + free(v); + if (r) + free(r); + if (evr) + free(evr); + + return err; +} + static int pakfire_archive_extract_entry(PakfireArchive archive, struct archive* a, struct archive_entry* entry, void* data) { struct pakfire_archive_extractor* extractor = (struct pakfire_archive_extractor*)data; @@ -794,6 +848,13 @@ static int pakfire_archive_extract_entry(PakfireArchive archive, char buffer[PATH_MAX]; int r = 1; + // How much of the archive has been read? + size_t bytes_read = archive_filter_bytes(a, -1); + + // Update progress + if (extractor->progressbar) + pakfire_progressbar_update(extractor->progressbar, bytes_read); + // Create a new file object if there is a filelist if (extractor->filelist) { r = pakfire_file_create(&file, archive->pakfire); @@ -863,9 +924,11 @@ ERROR: } PAKFIRE_EXPORT int pakfire_archive_extract(PakfireArchive archive, const char* prefix) { + struct pakfire_progressbar* progressbar = NULL; struct archive* a = NULL; struct archive* payload = NULL; struct archive* writer = NULL; + size_t size; int r; // Use default path if nothing is set @@ -881,13 +944,18 @@ PAKFIRE_EXPORT int pakfire_archive_extract(PakfireArchive archive, const char* p goto ERROR; } + // Create a progressbar + r = pakfire_archive_extract_progressbar(archive, &progressbar); + if (r) + goto ERROR; + // Open the archive r = archive_open(archive, &a); if (r) goto ERROR; // Open payload - payload = pakfire_archive_open_payload(archive, a); + payload = pakfire_archive_open_payload(archive, a, &size); if (!payload) goto ERROR; @@ -897,22 +965,34 @@ PAKFIRE_EXPORT int pakfire_archive_extract(PakfireArchive archive, const char* p goto ERROR; struct pakfire_archive_extractor extractor = { - .writer = writer, - .prefix = prefix, - .filelist = archive->filelist, + .writer = writer, + .prefix = prefix, + .filelist = archive->filelist, + .progressbar = progressbar, }; + // Start the progressbar + r = pakfire_progressbar_start(progressbar, size); + if (r) + goto ERROR; + // Extract everything r = pakfire_archive_walk_entries(archive, payload, pakfire_archive_extract_entry, &extractor); ERROR: + // Finish progressbar + if (progressbar) + pakfire_progressbar_finish(progressbar); + // Destroy the filelist on error if (r) { pakfire_filelist_unref(archive->filelist); archive->filelist = NULL; } + if (progressbar) + pakfire_progressbar_unref(progressbar); if (writer) archive_write_free(writer); if (payload)