21

I'm writing my own script to download multiple items (simultaneously, one item per command) using wget and I need a progress bar. I currently utilize zenity --progress for my progress bars, but the problem is it spawns multiple progress bars when downloading.

What I want to achieve is something similar to the file transfer dialog in Nautilus:

Ubuntu's file transfer dialog

Can anyone point me to the right direction as to which program(s) or language(s) that will achieve this.

NOTE: I only have basic knowledge of shell scripting, not much else.

  • Have you tried axel-kapt? sudo apt-get install axel-kapt – user224082 May 13 '14 at 20:01
  • The bounty is pretty close to its end. Please don't forget to assign it, if you feel satisfied with my answer. – Glutanimate May 17 '14 at 12:13
  • No problem, man. Best of luck with your script! – Glutanimate May 17 '14 at 18:41
28
+100

Solution using YAD


Overview

Zenity hasn't been updated in quite a while. Luckily there's a fork called YAD with a lot of added features. It hasn't arrived in the official repositories, yet, but you can install it from a webupd8 PPA:

sudo add-apt-repository ppa:webupd8team/y-ppa-manager
sudo apt-get update
sudo apt-get install yad

One of the features added to YAD is a multi progress-bar dialog. Here's an excerpt from YAD's manual concerning multiple progress bars:

Multi progress bars dialog options
--bar=LABEL[:TYPE]
  Add progress bar. LABEL is a text label for progress bar. TYPE is a progress bar type. Types are:
  NORM for normal progress bar, RTL for inverted progress bar and PULSE for pulsate progress bar.
--vertical
  Set vertical orientation of progress bars.
--align=TYPE
  Set alignment of bar labels. Possible types are left, center or right. Default is left.

Initial values for bars set as extra arguments. Each lines with progress data passed to stdin must be started
from N: where N is a number of progress bar. Rest is the same as in progress dialog.

So a very simple a script with multiple progress bars could look like this:

for i in {1..100}; do
   printf "1:$i\n2:$i\n3:$i\n"
   sleep 0.2
done | yad --multi-progress --bar="Bar 1":NORM --bar="Bar 2":NORM --bar="Bar 3":NORM

This is what the result would look like:

simple yad multi progress script


We can add descriptions to the bars with #:

for i in {1..100}; do
   printf "1:$i\n2:$i\n3:$i\n"
   printf "1:#Progress 1 is at $i percent\n2:#Progress 2 is at $i percent\n3:#Progress 3 is at $i percent\n"
   sleep 0.2
done | yad --multi-progress --bar="Bar 1":NORM --bar="Bar 2":NORM --bar="Bar 3":NORM

Result:

enter image description here


If we want to implement this in a wget download script we will have to do a few things first:

  • find a way to extract the download progress and other interesting data out of the wget output
  • find a way to iterate over multiple files
  • find a way to pass all of the info we have to one single yad dialog

I found this project rather interesting so I sat down and composed a script that should do all of the above.


yad_wget

Here's what I came up with:

#!/bin/bash

# NAME:         yad_wget
# VERSION:      0.2
# AUTHOR:       (c) 2014 Glutanimate
# DESCRIPTION:  graphical frontend to wget in form of a yad script
# FEATURES:     - display progress of multiple simultaneous downloads
#               - set maximum number of simultaneous downloads
# DEPENDENCIES: yad
#
#               Install yad on Ubuntu with:
#
#                   sudo add-apt-repository ppa:webupd8team/y-ppa-manager
#                   sudo apt-get update
#                   sudo apt-get install yad
#
# LICENSE:      GNU GPLv3 (http://www.gnu.de/documents/gpl-3.0.en.html)
#
# NOTICE:       THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. 
#               EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 
#               PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR 
#               IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 
#               AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND 
#               PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE,
#               YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
#
#               IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY 
#               COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS 
#               PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, 
#               INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE 
#               THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED 
#               INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE 
#               PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER 
#               PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
#
# USAGE:        yad_wget <space-delimited URLs>
#               Closing the yad dialog will terminate all downloads in progress

# Variables and settings

MAXDLS="5" # set maximum number of simultaneous downloads

URILIST="$@" # gets list of URIs from stdin
USAGE="$0 <space-delimited URLs>"

# Set GUI variables up
TITLE="YAD wget downloader"                 # dialog title
TEXT="<b>Downloads</b> in progress:"        # dialog text
ICON="emblem-downloads"                     # window icon (appears in launcher)
IMAGE="browser-download"                    # window image (appears in dialog)

#URILIST="http://proof.ovh.net/files/100Mb.dat http://speedtest.wdc01.softlayer.com/downloads/test10.zip http://cachefly.cachefly.net/100mb.test"

# Usage checks

if [[ -z "$URILIST" ]]
  then
      echo "Error: No arguments provided"
      echo "Usage: $USAGE"
      exit 1
fi


# download file and extract progress, speed and ETA from wget
# we use sed regex for this
# source: http://ubuntuforums.org/showthread.php?t=306515&page=2&p=7455412#post7455412
# modified to work with different locales and decimal point conventions
download(){
    wget  "$1" 2>&1 | sed -u \
    "s/.* \([0-9]\+%\)\ \+\([0-9,.]\+.\) \(.*\)/$2:\1\n$2:# Downloading at \2\/s, ETA \3/"
    RET_WGET="${PIPESTATUS[0]}"             # get return code of wget
    if [[ "$RET_WGET" = 0 ]]                # check return code for errors
      then
          echo "$2:100%"
          echo "$2:#Download completed."
      else
          echo "$2:#Download error."
    fi
}


# compose list of bars for yad
for URI in $URILIST; do                     # iterate through all URIs
    FILENAME="${URI##*/}"                   # extract last field of URI as filename
    YADBARS="$YADBARS --bar=$FILENAME:NORM" # add filename to the list of URIs
done

IFS=" "
COUNTER="1"
DYNAMIC_COUNTER="1"

# main
# iterate through all URIs, download them in the background and 
# pipe all output simultaneously to yad
# source: http://pastebin.com/yBL2wjaY

for URI in $URILIST; do
    if [[ "$DYNAMIC_COUNTER" = "$MAXDLS" ]] # only download n files at a time
      then
          download "$URI" "$COUNTER"        # if limit reached wait until wget complete
          DYNAMIC_COUNTER="1"               # before proceeding (by not sending download() to bg)
      else
          download "$URI" "$COUNTER" &      # pass URI and URI number to download()
          DYNAMIC_COUNTER="$[$DYNAMIC_COUNTER+1]"
    fi
    COUNTER="$[$COUNTER+1]"                 # increment counter
done | yad --multi-progress --auto-kill $YADBARS --title "$TITLE" \
--text "$TEXT" --window-icon "$ICON" --image "$IMAGE"

# ↑ launch yad multi progress-bar window

And this is what it looks like:

enter image description here

           enter image description here

Make sure to read through all the comments to find out how the script works and if you have any questions please don't hesitate to ask in the comments below.


Edit:

I added support for setting the maximum number of simultaneous downloads. E.g. for MAXDLS="5":

enter image description here

| improve this answer | |
  • This is a very comprehensive and interesting post, and I'm liking what I'm seeing so far. Thanks for taking the time to tinker with this little project of mine. :) Q1: What happens to the progress bar of the completed files? Do they stay on the dialog until everything else is done? Q2: From what I'm seeing, there is no way to cancel individual operations from the dialog, is there? – Rey Leonard Amorato May 11 '14 at 6:32
  • 1
    +1 for yad; it's a great package. Be aware that --notification on yad will not work on Ubuntu 13.04 and later because of bug 1305835 and bug 1119420 (please follow the links and vote for the bugs). – Paddy Landau May 13 '14 at 10:29
  • 2
    To have additional controls, you would need to step up to GtkDialog which lets you do pretty much anything. However, it's a lot more involved. The PuppyLinux community makes extensive use of it. – DocSalvager May 13 '14 at 20:35
  • 1
    @Glutanimate - One brief note to avoid much confusion: Many of the references on PuppyLinux forums refer to "gtkdialog3" and "gtkdialog4". These are just simpler synonyms for the real GtkDialog versions and they're not even consistent. Version 0.8.3 that you grabbed is the latest and is quite stable. ( Moderators: No more on GtkDialog here. Anyone interested in it should please post new questions. ) – DocSalvager May 14 '14 at 18:13
  • 1
    @Glutanimate I've been using yad for a few months now and have been greatly impressed with its power. Your answer here though is absolutely brilliant and light years ahead of my own progress bars. I'll be very quick to adapt your wget progress bar code into my own app: askubuntu.com/questions/900319/…. – WinEunuuchs2Unix Jul 1 '17 at 17:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.