Como posso criar uma GUI do wget com várias barras de progresso?

21

Estou escrevendo meu próprio script para baixar vários itens (simultaneamente, um item por comando) usando wgete preciso de uma barra de progresso. Atualmente, utilizo zenity --progressminhas barras de progresso, mas o problema é que ele gera várias barras de progresso ao fazer o download.

O que eu quero alcançar é algo semelhante à caixa de diálogo de transferência de arquivos do Nautilus:

Caixa de diálogo de transferência de arquivos do Ubuntu

Alguém pode me indicar a direção certa para qual programa ou idioma (s) que conseguirão isso.

NOTA: Eu só tenho conhecimento básico de scripts de shell, e não muito mais.

Rey Leonard Amorato
fonte
Você já tentou axel-kapt? sudo apt-get install axel-kapt
A recompensa está bem perto do fim. Por favor, não esqueça de atribuí-lo, se você estiver satisfeito com a minha resposta.
Glutanimado 17/05
Não é problema homem. Boa sorte com seu script!
Glutanimado 17/05

Respostas:

28

Solução usando YAD


visão global

O Zenity não é atualizado há um bom tempo. Felizmente, há um garfo chamado YAD com muitos recursos adicionais. Ainda não chegou aos repositórios oficiais, mas você pode instalá-lo a partir de um PPA webupd8:

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

Um dos recursos adicionados ao YAD é uma caixa de diálogo com várias barras de progresso. Aqui está um trecho do manual do YAD sobre várias barras de progresso:

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.

Portanto, um script muito simples com várias barras de progresso pode ser assim:

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

É assim que o resultado seria:

script de progresso simples yad simples


Podemos adicionar descrições às barras com #:

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

Resultado:

insira a descrição da imagem aqui


Se quisermos implementar isso em um script de download do wget, teremos que fazer algumas coisas primeiro:

  • encontre uma maneira de extrair o progresso do download e outros dados interessantes da saída do wget
  • encontre uma maneira de iterar sobre vários arquivos
  • encontre uma maneira de passar todas as informações que temos para um único diálogo do yad

Achei esse projeto bastante interessante, então me sentei e compus um script que deveria fazer tudo isso acima.


yad_wget

Aqui está o que eu vim com:

#!/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

E é assim que se parece:

insira a descrição da imagem aqui

           insira a descrição da imagem aqui

Leia todos os comentários para descobrir como o script funciona e, se você tiver alguma dúvida, não hesite em perguntar nos comentários abaixo.


Editar:

Eu adicionei suporte para definir o número máximo de downloads simultâneos. Por exemplo, para MAXDLS="5":

insira a descrição da imagem aqui

Glutanimado
fonte
Este é um post muito abrangente e interessante, e estou gostando do que estou vendo até agora. Obrigado por dedicar um tempo para mexer neste pequeno projeto meu. :) Q1: O que acontece com a barra de progresso dos arquivos concluídos? Eles permanecem no diálogo até que tudo o mais seja feito? P2: Pelo que estou vendo, não há como cancelar operações individuais da caixa de diálogo, existe?
Rey Leonard Amorato
1
+1 para yad; é um ótimo pacote. Esteja ciente de que o --notificationon yadnão funcionará no Ubuntu 13.04 e posterior devido aos erros 1305835 e 1119420 (siga os links e vote nos bugs).
Paddy Landau
2
Para ter controles adicionais, você precisará avançar para o GtkDialog, que permite fazer praticamente qualquer coisa. No entanto, é muito mais envolvido. A comunidade PuppyLinux faz uso extensivo dele.
DocSalvager
1
@ Glutanimate - Uma breve nota para evitar muita confusão: Muitas das referências nos fóruns do PuppyLinux se referem a "gtkdialog3" e "gtkdialog4". Estes são apenas sinônimos mais simples para as versões reais do GtkDialog e nem são consistentes. A versão 0.8.3 que você pegou é a mais recente e é bastante estável. (. Moderadores: Não mais no GtkDialog aqui qualquer pessoa interessada em que deve agradar novos postar perguntas.)
DocSalvager
1
@ Glutanimate Estou usando yadhá alguns meses e fiquei bastante impressionado com seu poder. Sua resposta aqui é absolutamente brilhante e anos-luz à frente das minhas próprias barras de progresso. Serei muito rápido para adaptar seu wgetcódigo de barras de progresso ao meu próprio aplicativo: askubuntu.com/questions/900319/… .
WinEunuuchs2Unix 01/07