[pacman-dev] TotalDownload option.
Sample output: $ sudo pacman -S gcc gcc-fortran gcc-libs resolving dependencies... done. looking for inter-conflicts... done. Targets: gcc-libs-4.2.2-2 [1.06 MB] gcc-4.2.2-3 [8.92 MB] gcc-fortran-4.2.2-1 [2.91 MB] Total Package Size: 12.89 MB Total Download Size: 12.89 MB Proceed with installation? [Y/n] :: Retrieving packages from core... gcc-libs-4.2.2-2-i686 1081.1K 503.8K/s 00:00:02 [#--------------------] 8% gcc-4.2.2-3-i686 10.0M 302.1K/s 00:00:34 [################-----] 77% :: Retrieving packages from extra... gcc-fortran-4.2.2-1-... 12.9M 338.0K/s 00:00:39 [#####################] 100% checking package integrity... done. (3/3) checking for file conflicts [#####################] 100% (1/3) upgrading gcc-libs [#####################] 100% (2/3) upgrading gcc [#####################] 100% (3/3) upgrading gcc-fortran [#####################] 100%
This will be used in the next commit. Signed-off-by: Nathan Jones <nathanj@insightbb.com> --- doc/pacman.conf.5.txt | 4 ++++ lib/libalpm/alpm.h | 1 + lib/libalpm/handle.c | 6 ++++++ lib/libalpm/handle.h | 2 ++ src/pacman/pacman.c | 3 +++ 5 files changed, 16 insertions(+), 0 deletions(-) diff --git a/doc/pacman.conf.5.txt b/doc/pacman.conf.5.txt index 06ba81d..c9783c8 100644 --- a/doc/pacman.conf.5.txt +++ b/doc/pacman.conf.5.txt @@ -109,6 +109,10 @@ Options Download delta files instead of complete packages if possible. Requires the xdelta program to be installed. +*TotalDownload*:: + When downloading, display the completed percentage as the percent of + the entire download list list rather than the percent of each + individual download target. Repository Sections ------------------- diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h index 20d7787..5170c15 100644 --- a/lib/libalpm/alpm.h +++ b/lib/libalpm/alpm.h @@ -139,6 +139,7 @@ void alpm_option_set_xfercommand(const char *cmd); unsigned short alpm_option_get_nopassiveftp(); void alpm_option_set_nopassiveftp(unsigned short nopasv); void alpm_option_set_usedelta(unsigned short usedelta); +void alpm_option_set_totaldownload(unsigned short totaldownload); pmdb_t *alpm_option_get_localdb(); alpm_list_t *alpm_option_get_syncdbs(); diff --git a/lib/libalpm/handle.c b/lib/libalpm/handle.c index af54949..fed4d9c 100644 --- a/lib/libalpm/handle.c +++ b/lib/libalpm/handle.c @@ -65,6 +65,7 @@ pmhandle_t *_alpm_handle_new() handle->lockfile = NULL; handle->logfile = NULL; handle->usedelta = 0; + handle->totaldownload = 0; return(handle); } @@ -482,4 +483,9 @@ void SYMEXPORT alpm_option_set_usedelta(unsigned short usedelta) handle->usedelta = usedelta; } +void SYMEXPORT alpm_option_set_totaldownload(unsigned short totaldownload) +{ + handle->totaldownload = totaldownload; +} + /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/handle.h b/lib/libalpm/handle.h index 0874ecd..f2c0453 100644 --- a/lib/libalpm/handle.h +++ b/lib/libalpm/handle.h @@ -62,6 +62,8 @@ typedef struct _pmhandle_t { time_t upgradedelay; /* Time to wait before upgrading a package */ char *xfercommand; /* External download command */ unsigned short usedelta; /* Download deltas if possible */ + unsigned short totaldownload;/* When downloading, display the percent + downloaded of the total download list */ } pmhandle_t; /* global handle variable */ diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c index 9c650f2..795f1e0 100644 --- a/src/pacman/pacman.c +++ b/src/pacman/pacman.c @@ -572,6 +572,9 @@ static int _parseconfig(const char *file, const char *givensection, } else if(strcmp(key, "UseDelta") == 0 || strcmp(upperkey, "USEDELTA") == 0) { alpm_option_set_usedelta(1); pm_printf(PM_LOG_DEBUG, "config: usedelta\n"); + } else if(strcmp(key, "TotalDownload") == 0 || strcmp(upperkey, "TOTALDOWNLOAD") == 0) { + alpm_option_set_totaldownload(1); + pm_printf(PM_LOG_DEBUG, "config: totaldownload\n"); } else { pm_printf(PM_LOG_ERROR, _("config file %s, line %d: directive '%s' not recognized.\n"), file, linenum, key); -- 1.5.3.5
Setting this option will change the download progress to show the amount downloaded, download rate, ETA, and download percent of the entire download list rather than per each individual file. This closes FS#7205. Signed-off-by: Nathan Jones <nathanj@insightbb.com> --- lib/libalpm/alpm.h | 3 +- lib/libalpm/db.c | 3 +- lib/libalpm/server.c | 63 ++++++++++++++++++++++++++++++++++++++++-------- lib/libalpm/server.h | 6 +++- lib/libalpm/sync.c | 12 ++++++++- src/pacman/callback.c | 28 ++++++++++++++++----- src/pacman/callback.h | 2 +- 7 files changed, 93 insertions(+), 24 deletions(-) diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h index 5170c15..11f340e 100644 --- a/lib/libalpm/alpm.h +++ b/lib/libalpm/alpm.h @@ -81,7 +81,8 @@ int alpm_logaction(char *fmt, ...); * Downloading */ -typedef void (*alpm_cb_download)(const char *filename, int xfered, int total); +typedef void (*alpm_cb_download)(const char *filename, int xfered, int total, + int done); /* * Options diff --git a/lib/libalpm/db.c b/lib/libalpm/db.c index c06db3b..c81732e 100644 --- a/lib/libalpm/db.c +++ b/lib/libalpm/db.c @@ -257,7 +257,8 @@ int SYMEXPORT alpm_db_update(int force, pmdb_t *db) dbpath = alpm_option_get_dbpath(); - ret = _alpm_downloadfiles_forreal(db->servers, dbpath, files, lastupdate, newmtime); + ret = _alpm_downloadfiles_forreal(db->servers, dbpath, files, lastupdate, + newmtime, NULL, 0); FREELIST(files); if(ret == 1) { /* mtimes match, do nothing */ diff --git a/lib/libalpm/server.c b/lib/libalpm/server.c index d4c0a05..5216641 100644 --- a/lib/libalpm/server.c +++ b/lib/libalpm/server.c @@ -133,13 +133,19 @@ static struct url *url_for_file(pmserver_t *server, const char *filename) /* * Download a list of files from a list of servers * - if one server fails, we try the next one in the list + * - if *dl_total is non-NULL, then it will be used as the starting + * download amount when TotalDownload is set. It will also be + * set to the final download amount for the calling function to use. + * - totalsize is the total download size for use when TotalDownload + * is set. Use 0 if the total download size is not known. * * RETURN: 0 for successful download, 1 on error */ int _alpm_downloadfiles(alpm_list_t *servers, const char *localpath, - alpm_list_t *files) + alpm_list_t *files, int *dl_total, unsigned long totalsize) { - return(_alpm_downloadfiles_forreal(servers, localpath, files, NULL, NULL)); + return(_alpm_downloadfiles_forreal(servers, localpath, files, NULL, NULL, + dl_total, totalsize)); } /* @@ -150,15 +156,21 @@ int _alpm_downloadfiles(alpm_list_t *servers, const char *localpath, * "YYYYMMDDHHMMSS" to match the form of ftplib's FtpModDate() function. * - if *mtime2 is non-NULL, then it will be filled with the mtime * of the remote file (from MDTM FTP cmd or Last-Modified HTTP header). + * - if *dl_total is non-NULL, then it will be used as the starting + * download amount when TotalDownload is set. It will also be + * set to the final download amount for the calling function to use. + * - totalsize is the total download size for use when TotalDownload + * is set. Use 0 if the total download size is not known. * * RETURN: 0 for successful download * 1 if the mtimes are identical * -1 on error */ int _alpm_downloadfiles_forreal(alpm_list_t *servers, const char *localpath, - alpm_list_t *files, const char *mtime1, char *mtime2) + alpm_list_t *files, const char *mtime1, char *mtime2, int *dl_total, + unsigned long totalsize) { - int dltotal_bytes = 0; + int dl_thisfile = 0; alpm_list_t *lp; int done = 0; alpm_list_t *complete = NULL; @@ -206,12 +218,15 @@ int _alpm_downloadfiles_forreal(alpm_list_t *servers, const char *localpath, if(stat(output, &st) == 0 && st.st_size > 0) { _alpm_log(PM_LOG_DEBUG, "existing file found, using it\n"); fileurl->offset = (off_t)st.st_size; - dltotal_bytes = st.st_size; + dl_thisfile = st.st_size; + if (dl_total != NULL) { + *dl_total += st.st_size; + } localf = fopen(output, "a"); chk_resume = 1; } else { fileurl->offset = (off_t)0; - dltotal_bytes = 0; + dl_thisfile = 0; } /* libdownload does not reset the error code, reset it in the case of previous errors */ @@ -267,7 +282,7 @@ int _alpm_downloadfiles_forreal(alpm_list_t *servers, const char *localpath, if(localf == NULL) { _alpm_rmrf(output); fileurl->offset = (off_t)0; - dltotal_bytes = 0; + dl_thisfile = 0; localf = fopen(output, "w"); if(localf == NULL) { /* still null? */ _alpm_log(PM_LOG_ERROR, _("cannot write to file '%s'\n"), output); @@ -280,7 +295,13 @@ int _alpm_downloadfiles_forreal(alpm_list_t *servers, const char *localpath, } /* Progress 0 - initialize */ - if(handle->dlcb) handle->dlcb(pkgname, 0, ust.size); + if(handle->dlcb) { + if(handle->totaldownload && dl_total != NULL && totalsize > 0) { + handle->dlcb(pkgname, *dl_total, totalsize, 0); + } else { + handle->dlcb(pkgname, 0, ust.size, 0); + } + } int nread = 0; char buffer[PM_DLBUF_LEN]; @@ -310,10 +331,30 @@ int _alpm_downloadfiles_forreal(alpm_list_t *servers, const char *localpath, if(nwritten != nread) { } - dltotal_bytes += nread; + dl_thisfile += nread; + if (dl_total != NULL) { + *dl_total += nread; + } + + if(handle->dlcb) { + if(handle->totaldownload && dl_total != NULL && totalsize > 0) { + handle->dlcb(pkgname, *dl_total, totalsize, 0); + } else { + handle->dlcb(pkgname, dl_thisfile, ust.size, 0); + } + } + } - if(handle->dlcb) handle->dlcb(pkgname, dltotal_bytes, ust.size); + /* this file has finished, let pacman know to go to a new line + * by setting the done parameter */ + if(handle->dlcb) { + if(handle->totaldownload && dl_total != NULL && totalsize > 0) { + handle->dlcb(pkgname, *dl_total, totalsize, 1); + } else { + handle->dlcb(pkgname, dl_thisfile, ust.size, 1); + } } + downloadFreeURL(fileurl); fclose(localf); fclose(dlf); @@ -429,7 +470,7 @@ char SYMEXPORT *alpm_fetch_pkgurl(const char *url) alpm_list_t *files = alpm_list_add(NULL, filename); /* download the file */ - if(_alpm_downloadfiles(servers, cachedir, files)) { + if(_alpm_downloadfiles(servers, cachedir, files, NULL, 0)) { _alpm_log(PM_LOG_WARNING, _("failed to download %s\n"), url); return(NULL); } diff --git a/lib/libalpm/server.h b/lib/libalpm/server.h index 462d9b2..914ee6d 100644 --- a/lib/libalpm/server.h +++ b/lib/libalpm/server.h @@ -37,9 +37,11 @@ struct __pmserver_t { pmserver_t *_alpm_server_new(const char *url); void _alpm_server_free(pmserver_t *server); -int _alpm_downloadfiles(alpm_list_t *servers, const char *localpath, alpm_list_t *files); +int _alpm_downloadfiles(alpm_list_t *servers, const char *localpath, + alpm_list_t *files, int *dl_total, unsigned long totalsize); int _alpm_downloadfiles_forreal(alpm_list_t *servers, const char *localpath, - alpm_list_t *files, const char *mtime1, char *mtime2); + alpm_list_t *files, const char *mtime1, char *mtime2, + int *dl_total, unsigned long totalsize); #endif /* _ALPM_SERVER_H */ diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c index 7791e74..1441e60 100644 --- a/lib/libalpm/sync.c +++ b/lib/libalpm/sync.c @@ -991,6 +991,7 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data) pmtrans_t *tr = NULL; int replaces = 0, retval = 0; const char *cachedir = NULL; + int dltotal = 0, dl = 0; ALPM_LOG_FUNC; @@ -999,6 +1000,15 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data) cachedir = _alpm_filecache_setup(); trans->state = STATE_DOWNLOADING; + + /* Sum up the download sizes. This has to be in its own loop because + * the download loop is grouped by db. */ + for(j = trans->packages; j; j = j->next) { + pmsyncpkg_t *sync = j->data; + pmpkg_t *spkg = sync->pkg; + dltotal += alpm_pkg_download_size(spkg, db_local); + } + /* group sync records by repository and download */ for(i = handle->dbs_sync; i; i = i->next) { pmdb_t *current = i->data; @@ -1062,7 +1072,7 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data) if(files) { EVENT(trans, PM_TRANS_EVT_RETRIEVE_START, current->treename, NULL); - if(_alpm_downloadfiles(current->servers, cachedir, files)) { + if(_alpm_downloadfiles(current->servers, cachedir, files, &dl, dltotal)) { _alpm_log(PM_LOG_WARNING, _("failed to retrieve some files from %s\n"), current->treename); RET_ERR(PM_ERR_RETRIEVE, -1); diff --git a/src/pacman/callback.c b/src/pacman/callback.c index 5160b3b..525945d 100644 --- a/src/pacman/callback.c +++ b/src/pacman/callback.c @@ -85,7 +85,7 @@ static float get_update_timediff(int first_call) } /* refactored from cb_trans_progress */ -static void fill_progress(const int percent, const int proglen) +static void fill_progress(const int percent, const int proglen, const int done) { const unsigned int hashlen = proglen - 8; const unsigned int hash = percent * hashlen / 100; @@ -142,7 +142,7 @@ static void fill_progress(const int percent, const int proglen) printf(" %3d%%", percent); } - if(percent == 100) { + if(done) { printf("\n"); } else { printf("\r"); @@ -351,6 +351,7 @@ void cb_trans_progress(pmtransprog_t event, const char *pkgname, int percent, int tmp, digits, oprlen, textlen, pkglen; char *opr = NULL; wchar_t *wcopr = NULL; + int done = 0; if(config->noprogressbar) { return; @@ -436,11 +437,12 @@ void cb_trans_progress(pmtransprog_t event, const char *pkgname, int percent, free(wcopr); /* call refactored fill progress function */ - fill_progress(percent, getcols() - infolen); + done = percent == 100 ? 1 : 0; + fill_progress(percent, getcols() - infolen, done); } /* callback to handle display of download progress */ -void cb_dl_progress(const char *filename, int xfered, int total) +void cb_dl_progress(const char *filename, int xfered, int total, int done) { const int infolen = 50; char *fname, *p; @@ -450,10 +452,22 @@ void cb_dl_progress(const char *filename, int xfered, int total) int percent; char rate_size = 'K', xfered_size = 'K'; + /* If the download list starts with a resumed .part file, and the + * TotalDownload option is set, it is possible for the xfered amount + * to start at a value greater than 0. This variable will ensure that + * initial_time is always initialized. */ + static short has_init = 0; + if(config->noprogressbar) { return; } + if (!has_init) { + gettimeofday(&initial_time, NULL); + timediff = get_update_timediff(1); + has_init = 1; + } + /* this is basically a switch on xferred: 0, total, and anything else */ if(xfered == 0) { /* set default starting values */ @@ -463,7 +477,7 @@ void cb_dl_progress(const char *filename, int xfered, int total) timediff = get_update_timediff(1); rate = 0.0; eta_s = 0; - } else if(xfered == total) { + } else if(xfered == total || done) { /* compute final values */ struct timeval current_time; float diff_sec, diff_usec; @@ -472,7 +486,7 @@ void cb_dl_progress(const char *filename, int xfered, int total) diff_sec = current_time.tv_sec - initial_time.tv_sec; diff_usec = current_time.tv_usec - initial_time.tv_usec; timediff = diff_sec + (diff_usec / 1000000.0); - rate = total / (timediff * 1024.0); + rate = xfered / (timediff * 1024.0); /* round elapsed time to the nearest second */ eta_s = (int)(timediff + 0.5); @@ -541,7 +555,7 @@ void cb_dl_progress(const char *filename, int xfered, int total) free(fname); - fill_progress(percent, getcols() - infolen); + fill_progress(percent, getcols() - infolen, done); return; } diff --git a/src/pacman/callback.h b/src/pacman/callback.h index 742cd94..ac9ef40 100644 --- a/src/pacman/callback.h +++ b/src/pacman/callback.h @@ -35,7 +35,7 @@ void cb_trans_progress(pmtransprog_t event, const char *pkgname, int percent, int howmany, int remain); /* callback to handle display of download progress */ -void cb_dl_progress(const char *filename, int xfered, int total); +void cb_dl_progress(const char *filename, int xfered, int total, int done); /* callback to handle messages/notifications from pacman library */ void cb_log(pmloglevel_t level, char *fmt, va_list args); -- 1.5.3.5
On Nov 8, 2007 8:56 PM, Nathan Jones <nathanj@insightbb.com> wrote:
Setting this option will change the download progress to show the amount downloaded, download rate, ETA, and download percent of the entire download list rather than per each individual file.
This closes FS#7205.
Signed-off-by: Nathan Jones <nathanj@insightbb.com>
I've applied these patches on my working branch. I personally like this feature a lot. I do feel a bit unsettled with the dl_total pointer param though. It seems... I dunno, hacky to me, but it doesn't seem like there's a super-elegant solution anywhere.... /me shrugs
On Nov 8, 2007 7:56 PM, Nathan Jones <nathanj@insightbb.com> wrote:
Proceed with installation? [Y/n] :: Retrieving packages from core... gcc-libs-4.2.2-2-i686 1081.1K 503.8K/s 00:00:02 [#--------------------] 8% gcc-4.2.2-3-i686 10.0M 302.1K/s 00:00:34 [################-----] 77% :: Retrieving packages from extra... gcc-fortran-4.2.2-1-... 12.9M 338.0K/s 00:00:39 [#####################] 100%
How about having the way the progress hashes were previously done retained and only change the percent numbers? This way you get the best of both worlds - progress for the current package as well as total progress. Otherwise, like gcc-libs above, there is going to be very little visual feedback while smaller packages are downloaded. That's what I think I would like best anyway... otherwise it feels too incomplete to see all of these "------" for packages. My two American cents, which are rapidly becoming worthless. Scott
On Nov 9, 2007 12:55 AM, Scott Horowitz <stonecrest@gmail.com> wrote:
On Nov 8, 2007 7:56 PM, Nathan Jones <nathanj@insightbb.com> wrote:
Proceed with installation? [Y/n] :: Retrieving packages from core... gcc-libs-4.2.2-2-i686 1081.1K 503.8K/s 00:00:02 [#--------------------] 8% gcc-4.2.2-3-i686 10.0M 302.1K/s 00:00:34 [################-----] 77% :: Retrieving packages from extra... gcc-fortran-4.2.2-1-... 12.9M 338.0K/s 00:00:39 [#####################] 100%
How about having the way the progress hashes were previously done retained and only change the percent numbers? This way you get the best of both worlds - progress for the current package as well as total progress. Otherwise, like gcc-libs above, there is going to be very little visual feedback while smaller packages are downloaded. That's what I think I would like best anyway... otherwise it feels too incomplete to see all of these "------" for packages.
My two American cents, which are rapidly becoming worthless.
Ooo. I like this, so we are up to 4 cents on it. -Dan
On Nov 9, 2007 10:25 AM, Dan McGee <dpmcgee@gmail.com> wrote:
On Nov 9, 2007 12:55 AM, Scott Horowitz <stonecrest@gmail.com> wrote:
On Nov 8, 2007 7:56 PM, Nathan Jones <nathanj@insightbb.com> wrote:
Proceed with installation? [Y/n] :: Retrieving packages from core... gcc-libs-4.2.2-2-i686 1081.1K 503.8K/s 00:00:02 [#--------------------] 8% gcc-4.2.2-3-i686 10.0M 302.1K/s 00:00:34 [################-----] 77% :: Retrieving packages from extra... gcc-fortran-4.2.2-1-... 12.9M 338.0K/s 00:00:39 [#####################] 100%
How about having the way the progress hashes were previously done retained and only change the percent numbers? This way you get the best of both worlds - progress for the current package as well as total progress. Otherwise, like gcc-libs above, there is going to be very little visual feedback while smaller packages are downloaded. That's what I think I would like best anyway... otherwise it feels too incomplete to see all of these "------" for packages.
My two American cents, which are rapidly becoming worthless.
Ooo. I like this, so we are up to 4 cents on it.
Be careful, we'll need at least 10 other people to put money in to rival one Canadian's two cents.
Ok, here's the updated version: $ sudo pacman -S gcc gcc-libs gcc-fortran resolving dependencies... done. looking for inter-conflicts... done. Targets: gcc-libs-4.2.2-2 [1.06 MB] gcc-4.2.2-3 [8.92 MB] gcc-fortran-4.2.2-1 [2.91 MB] Total Package Size: 12.89 MB Total Download Size: 12.89 MB Proceed with installation? [Y/n] :: Retrieving packages from core... gcc-libs-4.2.2-2-i686 1081.1K 665.7K/s 00:00:02 [#####################] 8% gcc-4.2.2-3-i686 10.0M 1009.0K/s 00:00:10 [#####################] 77% :: Retrieving packages from extra... gcc-fortran-4.2.2-1-... 12.9M 926.2K/s 00:00:14 [#####################] 100% checking package integrity... done. (3/3) checking for file conflicts [#####################] 100% (1/3) upgrading gcc-libs [#####################] 100% (2/3) upgrading gcc [#####################] 100% (3/3) upgrading gcc-fortran [#####################] 100% I changed the download callback function to take both the current file and the entire list xfered/totals, which gets rid of that done parameter and cleans up the code a bit. Graphical clients could probably use both since it's easier to draw two progress bars in a GUI. I haven't tested this code as much as my other patch so watch out for any bugs.
On Nov 10, 2007 9:54 AM, Nathan Jones <nathanj@insightbb.com> wrote:
Ok, here's the updated version:
$ sudo pacman -S gcc gcc-libs gcc-fortran resolving dependencies... done. looking for inter-conflicts... done.
Targets: gcc-libs-4.2.2-2 [1.06 MB] gcc-4.2.2-3 [8.92 MB] gcc-fortran-4.2.2-1 [2.91 MB]
Total Package Size: 12.89 MB Total Download Size: 12.89 MB
Proceed with installation? [Y/n] :: Retrieving packages from core... gcc-libs-4.2.2-2-i686 1081.1K 665.7K/s 00:00:02 [#####################] 8% gcc-4.2.2-3-i686 10.0M 1009.0K/s 00:00:10 [#####################] 77% :: Retrieving packages from extra... gcc-fortran-4.2.2-1-... 12.9M 926.2K/s 00:00:14 [#####################] 100% checking package integrity... done. (3/3) checking for file conflicts [#####################] 100% (1/3) upgrading gcc-libs [#####################] 100% (2/3) upgrading gcc [#####################] 100% (3/3) upgrading gcc-fortran [#####################] 100%
I changed the download callback function to take both the current file and the entire list xfered/totals, which gets rid of that done parameter and cleans up the code a bit. Graphical clients could probably use both since it's easier to draw two progress bars in a GUI.
I haven't tested this code as much as my other patch so watch out for any bugs.
_______________________________________________ pacman-dev mailing list pacman-dev@archlinux.org http://archlinux.org/mailman/listinfo/pacman-dev
IMO it is a bit confusing to see the progress bar completed while the percentage isn't 100%, especially when people don't expect this behaviour. It would be better if there was some indication that the percentage is the total progress. It would be best is there was a "total" progress bar underneath or something, to actually separate them, but that would probably require too many alterations to the code for the little benefit it would give.
On Sat, 10 Nov 2007, Xilon wrote:
On Nov 10, 2007 9:54 AM, Nathan Jones <nathanj@insightbb.com> wrote:
Ok, here's the updated version:
$ sudo pacman -S gcc gcc-libs gcc-fortran resolving dependencies... done. looking for inter-conflicts... done.
Targets: gcc-libs-4.2.2-2 [1.06 MB] gcc-4.2.2-3 [8.92 MB] gcc-fortran-4.2.2-1 [2.91 MB]
Total Package Size: 12.89 MB Total Download Size: 12.89 MB
Proceed with installation? [Y/n] :: Retrieving packages from core... gcc-libs-4.2.2-2-i686 1081.1K 665.7K/s 00:00:02 [#####################] 8% gcc-4.2.2-3-i686 10.0M 1009.0K/s 00:00:10 [#####################] 77% :: Retrieving packages from extra... gcc-fortran-4.2.2-1-... 12.9M 926.2K/s 00:00:14 [#####################] 100% checking package integrity... done. (3/3) checking for file conflicts [#####################] 100% (1/3) upgrading gcc-libs [#####################] 100% (2/3) upgrading gcc [#####################] 100% (3/3) upgrading gcc-fortran [#####################] 100%
I changed the download callback function to take both the current file and the entire list xfered/totals, which gets rid of that done parameter and cleans up the code a bit. Graphical clients could probably use both since it's easier to draw two progress bars in a GUI.
I haven't tested this code as much as my other patch so watch out for any bugs.
_______________________________________________ pacman-dev mailing list pacman-dev@archlinux.org http://archlinux.org/mailman/listinfo/pacman-dev
IMO it is a bit confusing to see the progress bar completed while the percentage isn't 100%, especially when people don't expect this behaviour. It would be better if there was some indication that the percentage is the total progress. It would be best is there was a "total" progress bar underneath or something, to actually separate them, but that would probably require too many alterations to the code for the little benefit it would give.
Why not put two percentages: one for the current package progress and one for the total packages percent? I'm not sure how to display them in a way that'll be user-friendly. -- This message has been scanned for viruses and dangerous content by MailScanner, and is believed to be clean.
On Sat, Nov 10, 2007 at 12:14:27AM -0500, Eric Belanger wrote:
On Sat, 10 Nov 2007, Xilon wrote:
On Nov 10, 2007 9:54 AM, Nathan Jones <nathanj@insightbb.com> wrote:
:: Retrieving packages from core... gcc-libs-4.2.2-2-i686 1081.1K 665.7K/s 00:00:02 [#####################] 8% gcc-4.2.2-3-i686 10.0M 1009.0K/s 00:00:10 [#####################] 77% :: Retrieving packages from extra... gcc-fortran-4.2.2-1-... 12.9M 926.2K/s 00:00:14 [#####################] 100% checking package integrity... done. (3/3) checking for file conflicts [#####################] 100% (1/3) upgrading gcc-libs [#####################] 100% (2/3) upgrading gcc [#####################] 100% (3/3) upgrading gcc-fortran [#####################] 100%
IMO it is a bit confusing to see the progress bar completed while the percentage isn't 100%, especially when people don't expect this behaviour.
Remember that the user has to explicitly enable the TotalDownload option to get this behavior. The pacman.conf man page will state that the progress bar is still the percentage of the current file. If the user is confused he can just go back to the old way.
It would be better if there was some indication that the percentage is the total progress. It would be best is there was a "total" progress bar underneath or something, to actually separate them, but that would probably require too many alterations to the code for the little benefit it would give.
pacman emits a carriage return (not a newline) after the download line to return to the beginning of the line. I don't know how to print two lines and return to the beginning of the first.
Why not put two percentages: one for the current package progress and one for the total packages percent? I'm not sure how to display them in a way that'll be user-friendly.
Here are two possibilities. I personally don't like either of them, but I'll change it if I get enough pennies thrown at me again. Proceed with installation? [Y/n] :: Retrieving packages from core... gcc-libs-4.2.2-2-i686 1081.1K 665.7K/s 00:00:02 [#################] 100% 8% gcc-4.2.2-3-i686 10.0M 1009.0K/s 00:00:10 [########100%#########] 77% :: Retrieving packages from extra... gcc-fortran-4.2.2-1-... 12.9M 926.2K/s 00:00:14 [#########75%#####----] 95%
2007/11/11, Nathan Jones <nathanj@insightbb.com>:
On Sat, Nov 10, 2007 at 12:14:27AM -0500, Eric Belanger wrote:
Why not put two percentages: one for the current package progress and one for the total packages percent? I'm not sure how to display them in a way that'll be user-friendly.
Here are two possibilities. I personally don't like either of them, but I'll change it if I get enough pennies thrown at me again.
Proceed with installation? [Y/n] :: Retrieving packages from core... gcc-libs-4.2.2-2-i686 1081.1K 665.7K/s 00:00:02 [#################] 100% 8% gcc-4.2.2-3-i686 10.0M 1009.0K/s 00:00:10 [########100%#########] 77% :: Retrieving packages from extra... gcc-fortran-4.2.2-1-... 12.9M 926.2K/s 00:00:14 [#########75%#####----] 95%
Hm, I don't like % between ##, I think this would be ok: gcc-libs-4.2.2-2-i686 1081.1K 665.7K/s 00:00:02 [#################] 100% | 8% ... gcc-fortran-4.2.2-1-... 12.9M 926.2K/s 00:00:14 [#################----] 75% | 95% and finished by gcc-fortran-4.2.2-1-... 12.9M 926.2K/s 00:00:14 [#####################] 100% | 100% P.S.: Take a look at this feature request: http://bugs.archlinux.org/task/8331 ;-) (though it is not related to TotalDownload but it's about progress too) -- Roman Kyrylych (Роман Кирилич)
On Sun, Nov 11, 2007 at 04:08:22PM +0200, Roman Kyrylych wrote:
Hm, I don't like % between ##, I think this would be ok: gcc-libs-4.2.2-2-i686 1081.1K 665.7K/s 00:00:02 [#################] 100% | 8%
Is the newline made on purpose? I think it looks nicer on the same line. And as Nathan said, I don't know either if it's possible to do it on multiple lines. Otherwise, that's also what I was thinking from the beginning. Just displaying the two percentages. IMO, this should make everyone happy, and make the need of the TotalDownload option less important.
P.S.: Take a look at this feature request: http://bugs.archlinux.org/task/8331 ;-) (though it is not related to TotalDownload but it's about progress too)
Yep, I was also wondering how this TotalDownload stuff fit with the ideas from bug 8331.
On Nov 11, 2007 9:06 AM, Xavier <shiningxc@gmail.com> wrote:
On Sun, Nov 11, 2007 at 04:08:22PM +0200, Roman Kyrylych wrote:
Hm, I don't like % between ##, I think this would be ok: gcc-libs-4.2.2-2-i686 1081.1K 665.7K/s 00:00:02 [#################] 100% | 8%
Is the newline made on purpose? I think it looks nicer on the same line. And as Nathan said, I don't know either if it's possible to do it on multiple lines. Otherwise, that's also what I was thinking from the beginning. Just displaying the two percentages. IMO, this should make everyone happy, and make the need of the TotalDownload option less important.
Ha! This is a great example why I think we shouldn't do two percentages. We already are cramming too much info on one line, and adding another 7 chars to that line will be hard to do (almost every package name will get cut off). -Dan
On Sun, Nov 11, 2007 at 09:27:33AM -0600, Dan McGee wrote:
On Nov 11, 2007 9:06 AM, Xavier <shiningxc@gmail.com> wrote:
On Sun, Nov 11, 2007 at 04:08:22PM +0200, Roman Kyrylych wrote:
Hm, I don't like % between ##, I think this would be ok: gcc-libs-4.2.2-2-i686 1081.1K 665.7K/s 00:00:02 [#################] 100% | 8%
Is the newline made on purpose? I think it looks nicer on the same line. And as Nathan said, I don't know either if it's possible to do it on multiple lines. Otherwise, that's also what I was thinking from the beginning. Just displaying the two percentages. IMO, this should make everyone happy, and make the need of the TotalDownload option less important.
Ha! This is a great example why I think we shouldn't do two percentages. We already are cramming too much info on one line, and adding another 7 chars to that line will be hard to do (almost every package name will get cut off).
Ok good point, but since we are short on space, are all the informations currently displayed more interesting than the total percent? For example, the -i686 suffix in package name isn't very useful. And there are 3 different options only for showing the progress of the current package : remaining time, progress bar, and percentage. These take a lot of space : 00:00:02 [#################] 100% Actually, I'm commenting this, but I don't really care, so feel free to ignore the above. I'm happy with the current pacman output. The only thing I'm less happy with are the bugs I mentioned previously, but it doesn't have anything to do with the download output: http://www.archlinux.org/pipermail/pacman-dev/2007-September/009317.html http://www.archlinux.org/pipermail/pacman-dev/2007-October/009552.html
2007/11/11, Xavier <shiningxc@gmail.com>:
On Sun, Nov 11, 2007 at 09:27:33AM -0600, Dan McGee wrote:
On Nov 11, 2007 9:06 AM, Xavier <shiningxc@gmail.com> wrote:
On Sun, Nov 11, 2007 at 04:08:22PM +0200, Roman Kyrylych wrote:
Hm, I don't like % between ##, I think this would be ok: gcc-libs-4.2.2-2-i686 1081.1K 665.7K/s 00:00:02 [#################] 100% | 8%
Is the newline made on purpose? I think it looks nicer on the same line. And as Nathan said, I don't know either if it's possible to do it on multiple lines. Otherwise, that's also what I was thinking from the beginning. Just displaying the two percentages. IMO, this should make everyone happy, and make the need of the TotalDownload option less important.
Ha! This is a great example why I think we shouldn't do two percentages. We already are cramming too much info on one line, and adding another 7 chars to that line will be hard to do (almost every package name will get cut off).
Ok good point, but since we are short on space, are all the informations currently displayed more interesting than the total percent? For example, the -i686 suffix in package name isn't very useful. And there are 3 different options only for showing the progress of the current package : remaining time, progress bar, and percentage. These take a lot of space : 00:00:02 [#################] 100%
Sure it was not done on purpose, I wanted it to be one line. That's stupid Gmail text input. To get more space we can always shrink ###-bar. It's 21 chars long on standard 80-char wide terminal. I think it could easily be 15-16 chars wide. :: Retrieving packages from extra... hal-info 28,2K 37,2K/s 00:00:01 [################] 100% 100% Here I've removed 5 #s and added " 100%" on the right (global progress) so everything looks ok on standard 80-char wide terminal.
Actually, I'm commenting this, but I don't really care, so feel free to ignore the above. I'm happy with the current pacman output. The only thing I'm less happy with are the bugs I mentioned previously, but it doesn't have anything to do with the download output: http://www.archlinux.org/pipermail/pacman-dev/2007-September/009317.html http://www.archlinux.org/pipermail/pacman-dev/2007-October/009552.html
-- Roman Kyrylych (Роман Кирилич)
On Nov 11, 2007 7:21 AM, Nathan Jones <nathanj@insightbb.com> wrote:
On Sat, Nov 10, 2007 at 12:14:27AM -0500, Eric Belanger wrote:
On Sat, 10 Nov 2007, Xilon wrote:
On Nov 10, 2007 9:54 AM, Nathan Jones <nathanj@insightbb.com> wrote:
:: Retrieving packages from core... gcc-libs-4.2.2-2-i686 1081.1K 665.7K/s 00:00:02 [#####################] 8% gcc-4.2.2-3-i686 10.0M 1009.0K/s 00:00:10 [#####################] 77% :: Retrieving packages from extra... gcc-fortran-4.2.2-1-... 12.9M 926.2K/s 00:00:14 [#####################] 100% checking package integrity... done. (3/3) checking for file conflicts [#####################] 100% (1/3) upgrading gcc-libs [#####################] 100% (2/3) upgrading gcc [#####################] 100% (3/3) upgrading gcc-fortran [#####################] 100%
IMO it is a bit confusing to see the progress bar completed while the percentage isn't 100%, especially when people don't expect this behaviour.
Remember that the user has to explicitly enable the TotalDownload option to get this behavior. The pacman.conf man page will state that the progress bar is still the percentage of the current file. If the user is confused he can just go back to the old way.
It would be better if there was some indication that the percentage is the total progress. It would be best is there was a "total" progress bar underneath or something, to actually separate them, but that would probably require too many alterations to the code for the little benefit it would give.
pacman emits a carriage return (not a newline) after the download line to return to the beginning of the line. I don't know how to print two lines and return to the beginning of the first.
Why not put two percentages: one for the current package progress and one for the total packages percent? I'm not sure how to display them in a way that'll be user-friendly.
Here are two possibilities. I personally don't like either of them, but I'll change it if I get enough pennies thrown at me again.
I like this new set of patches, and as Nathan stated, a user has to explicitly enable TotalDownload so they will not be confused with what is going on. For now I'll pull these set of patches; if we want to change something we can patch things up again in the future. -Dan
On Nov 9, 2007 10:14 PM, Eric Belanger <belanger@astro.umontreal.ca> wrote:
Why not put two percentages: one for the current package progress and one for the total packages percent? I'm not sure how to display them in a way that'll be user-friendly.
I fail to see how one percentage value that is the total is too confusing, but two percentage values, one that is the package and one that is the total, are not? I personally think we're getting carried away. In the words of Einstein, "As simple as possible, but no simpler". I think it will be painfully obvious that the percentage is the total across packages, especially since the user had to enable the TotalDownload option. Scott
On Nov 11, 2007 12:43 PM, Scott Horowitz <stonecrest@gmail.com> wrote:
In the words of Einstein, "As simple as possible, but no simpler".
I prefer Occam here - the simplest solution is usually the best.
This will be used in the next commit. Signed-off-by: Nathan Jones <nathanj@insightbb.com> --- doc/pacman.conf.5.txt | 5 +++++ src/pacman/conf.h | 3 +++ src/pacman/pacman.c | 3 +++ 3 files changed, 11 insertions(+), 0 deletions(-) diff --git a/doc/pacman.conf.5.txt b/doc/pacman.conf.5.txt index 06ba81d..7589b47 100644 --- a/doc/pacman.conf.5.txt +++ b/doc/pacman.conf.5.txt @@ -109,6 +109,11 @@ Options Download delta files instead of complete packages if possible. Requires the xdelta program to be installed. +*TotalDownload*:: + When downloading, display the amount downloaded, download rate, ETA, + and completed percentage of the entire download list list rather + than the percent of each individual download target. The progress + bar is still based solely on the current file download. Repository Sections ------------------- diff --git a/src/pacman/conf.h b/src/pacman/conf.h index 7249f06..b7844d7 100644 --- a/src/pacman/conf.h +++ b/src/pacman/conf.h @@ -65,6 +65,9 @@ typedef struct __config_t { unsigned short chomp; /* I Love Candy! */ unsigned short usecolor; /* enable colorful output */ unsigned short showsize; /* show individual package sizes */ + unsigned short totaldownload; /* When downloading, display the amount + downloaded, rate, ETA, and percent + downloaded of the total download list */ } config_t; /* Operations */ diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c index 9c650f2..41fbe6d 100644 --- a/src/pacman/pacman.c +++ b/src/pacman/pacman.c @@ -572,6 +572,9 @@ static int _parseconfig(const char *file, const char *givensection, } else if(strcmp(key, "UseDelta") == 0 || strcmp(upperkey, "USEDELTA") == 0) { alpm_option_set_usedelta(1); pm_printf(PM_LOG_DEBUG, "config: usedelta\n"); + } else if(strcmp(key, "TotalDownload") == 0 || strcmp(upperkey, "TOTALDOWNLOAD") == 0) { + config->totaldownload = 1; + pm_printf(PM_LOG_DEBUG, "config: totaldownload\n"); } else { pm_printf(PM_LOG_ERROR, _("config file %s, line %d: directive '%s' not recognized.\n"), file, linenum, key); -- 1.5.3.5
Setting this option will change the download progress to show the amount downloaded, download rate, ETA, and download percent of the entire download list rather than per each individual file. The progress bar is still based on the completion of the current file regardless if the TotalDownload option is set. This closes FS#7205. Signed-off-by: Nathan Jones <nathanj@insightbb.com> --- lib/libalpm/alpm.h | 3 +- lib/libalpm/db.c | 3 +- lib/libalpm/server.c | 47 +++++++++++++++++++++++++++-------- lib/libalpm/server.h | 6 +++- lib/libalpm/sync.c | 12 ++++++++- src/pacman/callback.c | 64 +++++++++++++++++++++++++++++++++--------------- src/pacman/callback.h | 3 +- 7 files changed, 101 insertions(+), 37 deletions(-) diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h index 20d7787..e30bbfc 100644 --- a/lib/libalpm/alpm.h +++ b/lib/libalpm/alpm.h @@ -81,7 +81,8 @@ int alpm_logaction(char *fmt, ...); * Downloading */ -typedef void (*alpm_cb_download)(const char *filename, int xfered, int total); +typedef void (*alpm_cb_download)(const char *filename, int file_xfered, + int file_total, int list_xfered, int list_total); /* * Options diff --git a/lib/libalpm/db.c b/lib/libalpm/db.c index c06db3b..c81732e 100644 --- a/lib/libalpm/db.c +++ b/lib/libalpm/db.c @@ -257,7 +257,8 @@ int SYMEXPORT alpm_db_update(int force, pmdb_t *db) dbpath = alpm_option_get_dbpath(); - ret = _alpm_downloadfiles_forreal(db->servers, dbpath, files, lastupdate, newmtime); + ret = _alpm_downloadfiles_forreal(db->servers, dbpath, files, lastupdate, + newmtime, NULL, 0); FREELIST(files); if(ret == 1) { /* mtimes match, do nothing */ diff --git a/lib/libalpm/server.c b/lib/libalpm/server.c index d4c0a05..7a3339e 100644 --- a/lib/libalpm/server.c +++ b/lib/libalpm/server.c @@ -133,13 +133,19 @@ static struct url *url_for_file(pmserver_t *server, const char *filename) /* * Download a list of files from a list of servers * - if one server fails, we try the next one in the list + * - if *dl_total is non-NULL, then it will be used as the starting + * download amount when TotalDownload is set. It will also be + * set to the final download amount for the calling function to use. + * - totalsize is the total download size for use when TotalDownload + * is set. Use 0 if the total download size is not known. * * RETURN: 0 for successful download, 1 on error */ int _alpm_downloadfiles(alpm_list_t *servers, const char *localpath, - alpm_list_t *files) + alpm_list_t *files, int *dl_total, unsigned long totalsize) { - return(_alpm_downloadfiles_forreal(servers, localpath, files, NULL, NULL)); + return(_alpm_downloadfiles_forreal(servers, localpath, files, NULL, NULL, + dl_total, totalsize)); } /* @@ -150,15 +156,21 @@ int _alpm_downloadfiles(alpm_list_t *servers, const char *localpath, * "YYYYMMDDHHMMSS" to match the form of ftplib's FtpModDate() function. * - if *mtime2 is non-NULL, then it will be filled with the mtime * of the remote file (from MDTM FTP cmd or Last-Modified HTTP header). + * - if *dl_total is non-NULL, then it will be used as the starting + * download amount when TotalDownload is set. It will also be + * set to the final download amount for the calling function to use. + * - totalsize is the total download size for use when TotalDownload + * is set. Use 0 if the total download size is not known. * * RETURN: 0 for successful download * 1 if the mtimes are identical * -1 on error */ int _alpm_downloadfiles_forreal(alpm_list_t *servers, const char *localpath, - alpm_list_t *files, const char *mtime1, char *mtime2) + alpm_list_t *files, const char *mtime1, char *mtime2, int *dl_total, + unsigned long totalsize) { - int dltotal_bytes = 0; + int dl_thisfile = 0; alpm_list_t *lp; int done = 0; alpm_list_t *complete = NULL; @@ -206,12 +218,15 @@ int _alpm_downloadfiles_forreal(alpm_list_t *servers, const char *localpath, if(stat(output, &st) == 0 && st.st_size > 0) { _alpm_log(PM_LOG_DEBUG, "existing file found, using it\n"); fileurl->offset = (off_t)st.st_size; - dltotal_bytes = st.st_size; + dl_thisfile = st.st_size; + if (dl_total != NULL) { + *dl_total += st.st_size; + } localf = fopen(output, "a"); chk_resume = 1; } else { fileurl->offset = (off_t)0; - dltotal_bytes = 0; + dl_thisfile = 0; } /* libdownload does not reset the error code, reset it in the case of previous errors */ @@ -267,7 +282,7 @@ int _alpm_downloadfiles_forreal(alpm_list_t *servers, const char *localpath, if(localf == NULL) { _alpm_rmrf(output); fileurl->offset = (off_t)0; - dltotal_bytes = 0; + dl_thisfile = 0; localf = fopen(output, "w"); if(localf == NULL) { /* still null? */ _alpm_log(PM_LOG_ERROR, _("cannot write to file '%s'\n"), output); @@ -280,7 +295,10 @@ int _alpm_downloadfiles_forreal(alpm_list_t *servers, const char *localpath, } /* Progress 0 - initialize */ - if(handle->dlcb) handle->dlcb(pkgname, 0, ust.size); + if(handle->dlcb) { + handle->dlcb(pkgname, 0, ust.size, dl_total ? *dl_total : 0, + totalsize); + } int nread = 0; char buffer[PM_DLBUF_LEN]; @@ -310,10 +328,17 @@ int _alpm_downloadfiles_forreal(alpm_list_t *servers, const char *localpath, if(nwritten != nread) { } - dltotal_bytes += nread; + dl_thisfile += nread; + if (dl_total != NULL) { + *dl_total += nread; + } - if(handle->dlcb) handle->dlcb(pkgname, dltotal_bytes, ust.size); + if(handle->dlcb) { + handle->dlcb(pkgname, dl_thisfile, ust.size, + dl_total ? *dl_total : 0, totalsize); + } } + downloadFreeURL(fileurl); fclose(localf); fclose(dlf); @@ -429,7 +454,7 @@ char SYMEXPORT *alpm_fetch_pkgurl(const char *url) alpm_list_t *files = alpm_list_add(NULL, filename); /* download the file */ - if(_alpm_downloadfiles(servers, cachedir, files)) { + if(_alpm_downloadfiles(servers, cachedir, files, NULL, 0)) { _alpm_log(PM_LOG_WARNING, _("failed to download %s\n"), url); return(NULL); } diff --git a/lib/libalpm/server.h b/lib/libalpm/server.h index 462d9b2..914ee6d 100644 --- a/lib/libalpm/server.h +++ b/lib/libalpm/server.h @@ -37,9 +37,11 @@ struct __pmserver_t { pmserver_t *_alpm_server_new(const char *url); void _alpm_server_free(pmserver_t *server); -int _alpm_downloadfiles(alpm_list_t *servers, const char *localpath, alpm_list_t *files); +int _alpm_downloadfiles(alpm_list_t *servers, const char *localpath, + alpm_list_t *files, int *dl_total, unsigned long totalsize); int _alpm_downloadfiles_forreal(alpm_list_t *servers, const char *localpath, - alpm_list_t *files, const char *mtime1, char *mtime2); + alpm_list_t *files, const char *mtime1, char *mtime2, + int *dl_total, unsigned long totalsize); #endif /* _ALPM_SERVER_H */ diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c index 7791e74..1441e60 100644 --- a/lib/libalpm/sync.c +++ b/lib/libalpm/sync.c @@ -991,6 +991,7 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data) pmtrans_t *tr = NULL; int replaces = 0, retval = 0; const char *cachedir = NULL; + int dltotal = 0, dl = 0; ALPM_LOG_FUNC; @@ -999,6 +1000,15 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data) cachedir = _alpm_filecache_setup(); trans->state = STATE_DOWNLOADING; + + /* Sum up the download sizes. This has to be in its own loop because + * the download loop is grouped by db. */ + for(j = trans->packages; j; j = j->next) { + pmsyncpkg_t *sync = j->data; + pmpkg_t *spkg = sync->pkg; + dltotal += alpm_pkg_download_size(spkg, db_local); + } + /* group sync records by repository and download */ for(i = handle->dbs_sync; i; i = i->next) { pmdb_t *current = i->data; @@ -1062,7 +1072,7 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data) if(files) { EVENT(trans, PM_TRANS_EVT_RETRIEVE_START, current->treename, NULL); - if(_alpm_downloadfiles(current->servers, cachedir, files)) { + if(_alpm_downloadfiles(current->servers, cachedir, files, &dl, dltotal)) { _alpm_log(PM_LOG_WARNING, _("failed to retrieve some files from %s\n"), current->treename); RET_ERR(PM_ERR_RETRIEVE, -1); diff --git a/src/pacman/callback.c b/src/pacman/callback.c index e935c87..b7c96d9 100644 --- a/src/pacman/callback.c +++ b/src/pacman/callback.c @@ -85,16 +85,17 @@ static float get_update_timediff(int first_call) } /* refactored from cb_trans_progress */ -static void fill_progress(const int percent, const int proglen) +static void fill_progress(const int graph_percent, const int display_percent, + const int proglen) { const unsigned int hashlen = proglen - 8; - const unsigned int hash = percent * hashlen / 100; + const unsigned int hash = graph_percent * hashlen / 100; static unsigned int lasthash = 0, mouth = 0; unsigned int i; /* printf("\ndebug: proglen: %i\n", proglen); DEBUG*/ - if(percent == 0) { + if(graph_percent == 0) { lasthash = 0; mouth = 0; } @@ -139,10 +140,10 @@ static void fill_progress(const int percent, const int proglen) } /* print percent after progress bar */ if(proglen > 5) { - printf(" %3d%%", percent); + printf(" %3d%%", display_percent); } - if(percent == 100) { + if(graph_percent == 100) { printf("\n"); } else { printf("\r"); @@ -432,34 +433,55 @@ void cb_trans_progress(pmtransprog_t event, const char *pkgname, int percent, free(wcopr); /* call refactored fill progress function */ - fill_progress(percent, getcols() - infolen); + fill_progress(percent, percent, getcols() - infolen); } /* callback to handle display of download progress */ -void cb_dl_progress(const char *filename, int xfered, int total) +void cb_dl_progress(const char *filename, int file_xfered, int file_total, + int list_xfered, int list_total) { const int infolen = 50; char *fname, *p; float rate = 0.0, timediff = 0.0, f_xfered = 0.0; unsigned int eta_h = 0, eta_m = 0, eta_s = 0; - int percent; + int graph_percent = 0, display_percent = 0; char rate_size = 'K', xfered_size = 'K'; + int xfered = 0, total = 0; + + /* Need this variable when TotalDownload is set to know if we should + * reset xfered_last and rate_last. */ + static int has_init = 0; if(config->noprogressbar) { return; } - /* this is basically a switch on xferred: 0, total, and anything else */ - if(xfered == 0) { - /* set default starting values */ - gettimeofday(&initial_time, NULL); - xfered_last = 0; - rate_last = 0.0; - timediff = get_update_timediff(1); + /* Choose how to display the amount downloaded, rate, ETA, and + * percentage depending on the TotalDownload option. */ + if (config->totaldownload && list_total > 0) { + xfered = list_xfered; + total = list_total; + } else { + xfered = file_xfered; + total = file_total; + } + + /* this is basically a switch on file_xferred: 0, file_total, and + * anything else */ + if(file_xfered == 0) { + /* set default starting values, but only once for TotalDownload */ + if (!(config->totaldownload && list_total > 0) || + (config->totaldownload && list_total > 0 && !has_init)) { + gettimeofday(&initial_time, NULL); + timediff = get_update_timediff(1); + xfered_last = 0; + rate_last = 0.0; + has_init = 1; + } rate = 0.0; eta_s = 0; - } else if(xfered == total) { + } else if(file_xfered == file_total) { /* compute final values */ struct timeval current_time; float diff_sec, diff_usec; @@ -468,7 +490,7 @@ void cb_dl_progress(const char *filename, int xfered, int total) diff_sec = current_time.tv_sec - initial_time.tv_sec; diff_usec = current_time.tv_usec - initial_time.tv_usec; timediff = diff_sec + (diff_usec / 1000000.0); - rate = total / (timediff * 1024.0); + rate = xfered / (timediff * 1024.0); /* round elapsed time to the nearest second */ eta_s = (int)(timediff + 0.5); @@ -488,8 +510,6 @@ void cb_dl_progress(const char *filename, int xfered, int total) xfered_last = xfered; } - percent = (int)((float)xfered) / ((float)total) * 100; - /* fix up time for display */ eta_h = eta_s / 3600; eta_s -= eta_h * 3600; @@ -537,7 +557,11 @@ void cb_dl_progress(const char *filename, int xfered, int total) free(fname); - fill_progress(percent, getcols() - infolen); + /* The progress bar is based on the file percent regardless of the + * TotalDownload option. */ + graph_percent = (int)((float)file_xfered) / ((float)file_total) * 100; + display_percent = (int)((float)xfered) / ((float)total) * 100; + fill_progress(graph_percent, display_percent, getcols() - infolen); return; } diff --git a/src/pacman/callback.h b/src/pacman/callback.h index 742cd94..59d8a45 100644 --- a/src/pacman/callback.h +++ b/src/pacman/callback.h @@ -35,7 +35,8 @@ void cb_trans_progress(pmtransprog_t event, const char *pkgname, int percent, int howmany, int remain); /* callback to handle display of download progress */ -void cb_dl_progress(const char *filename, int xfered, int total); +void cb_dl_progress(const char *filename, int file_xfered, int file_total, + int list_xfered, int list_total); /* callback to handle messages/notifications from pacman library */ void cb_log(pmloglevel_t level, char *fmt, va_list args); -- 1.5.3.5
participants (8)
-
Aaron Griffin
-
Dan McGee
-
Eric Belanger
-
Nathan Jones
-
Roman Kyrylych
-
Scott Horowitz
-
Xavier
-
Xilon