zenity + wget = GUI wget
Топик посвящается тем, кто не любит качать тяжелые файлы браузером из файлообменников, а также для тех кто хочет получше понять работу zenity.
В Linux есть много различных качальщиков от консольных до тяжелых java-приложений и мой скрипт это не еще один новый качальщик, это всего лишь приятная для глаз (eye-candy) обертка для стандартного Wget. Хотя в потенциале он умеет все что умеет Wget, но я реализовал только самые его основные функции. Цель данного скрипта — запустить закачку через wget (отвязав ее от браузера) и показывать ход ее выполнения.
В среде GTK+ есть замечательная утилита Zenity которую я и буду использовать для показа диалоговых окошек. По ссылке достаточно подробно показаны все аспекты использования, поэтому я не буду делать обзор, а сразу покажу как я ее применял.
Итак, в своем скрипте я реализовал минимальный функционал для того чтобы качать с комфортом: лист ссылок, выбор прокси, http, ftp-протоколы, исправление имени закачиваемого файла (очень полезно для роликов с YouTube и ему подобных), работа из командной строки (для работы с плагином Firefox FlashGot).
#!/bin/bash
#Usage: ./guiwget
# with FlashGot arguments are: [URL] [REFERER] [POST]
#Dependens: wget>=1.11.1, zenity
Да-да! Есть разница в версиях wget. В версии 1.11.1 wget стал поддерживать опцию --content-disposition которая необходима при скачивании с обменников, например, ifolder или youtube. Также показаны опции для FlashGot чтобы была возможность скачивать flv-ролики, и передавать закачки wget.
#Get URL
[ "$1" ] && url=$1 || url="$(zenity --text-info --editable --title="Введите список URL" --width=500 --height=300)";
[ "$url" ] || exit 0;
Если ссылка была передана через FlashGot, то праметры обработаются, а если он был запушен напрямую, то выведется окошко с запросом списка URL. Скрипт завершит работу если список закачек пуст.
#Proxy
proxy1="Ангола"; proxy1addr="41.210.252.11:80";
proxy2="Бангладеш"; proxy2addr="202.168.236.178:8080";
p="$(zenity --list --title="Выбор прокси" --print-column=2 --column="" --column="" "$proxy1" "$proxy1addr" "$proxy2" "$proxy2addr")";
[ "$p" = "" ] || proxy="export http_proxy=http://$p";
Работа с прокси, ничего необычного, для примера показаны два прокси. По идее нужно реализовать работу импорта подготовленного списка прокси, но мне это без надобности. Если хотите качать напрямую, жмите кнопку «Отмена» в окошке.
#Folder selection for file downloading
downdir="$(zenity --file-selection --directory --title="Выбор каталога для сохранения")";
[ "$downdir" ] || exit 0;
Выбор папки для скачивания. Можно жестко прописать путь в скрипте, но я люблю разнообразие :)
Настройка параметров окончена, начинается самая основная работа:
for urs in $url
do
#Log file
output="/tmp/`date +%N`-log";
#Wget start
id=$($proxy; wget -b -o"$output" -P"$downdir" --referer="$2" --post-data="$3" "$urs" | egrep -o "[0-9]+");
[ "$id" ] || exit 0;
Запускаем wget c полученными параметрами, отправляем в фон, пишем ход скачивания в лог, который и будет обрабатываться, запоминаем id процесса.
#Name file and size
h="";
while [ "$h" == "" ]; do
if [ -x /proc/$id ]
then
h=$(egrep -o "[^\/]+'.$" $output);
[ "$h" = "" ] && h=$( sed -n '/RETR/s/.*RETR \([[:print:]]*\)… готово.$/\1/p' $output);
realname="${h%\'.}";
downfile="${realname%%\?*}";
[ "$realname" != "$downfile" ] && [ -f "$downdir/$downfile" ] && downfile=`date +%N`"_"$downfile;
else
zenity --text-info --title="Ошибка" --filename=$output --width=700 --height=400;
h="FAIL";
rm $output;
fi
done;
[ "$h" == "FAIL" ] && continue;
size=$(grep "Длина:" $output | tail -1 | egrep -o "\(.+\)" | cut -d"(" -f2 | cut -d")" -f1);
Определяем имя файла, размер и вообще убеждаемся что сервер отдает нам файл, если что-то идет не так, показывается окошко с логом, там wget обычно пишет что именно не так. Переменная downfile нужна для того чтобы корректно показывать имя файла, а также для того чтобы превратить имя файла file?var=1&var=2 в file.
Один ньюанс — работа идет с логом на русском языке и перехватываются русские слова, если у вас это не так, поправьте слова «готово» и «Длина» в скрипте на свои.
#Grafical progressbar
(tail -f --pid=$id $output | sed -u -n 's/.*\.[ ]*\([[:print:]]*\)%[ ]*\([[:graph:]]*\) \([[:graph:]]*\)$/# '"$downfile"': '$size' \1% [\2Б\/с] (\3)\n\1/p') | zenity --title="Загрузка файла $p" --progress --percentage=0 --auto-close
[ $? -eq 0 ] && notify-send "Скачивание завершено" "Файл: $downfile" || ( [ -x /proc/$id ] && kill $id || zenity --text-info --title="Ошибка" --filename=$output --width=700 --height=400);
mv "$downdir/$realname" "$downdir/$downfile";
#Clean
rm $output;
done
А здесь и есть моё ноу-хау, рассказываю как это работает.
tail -f --pid идеально подходит для слежения за логом, причем он следит еще и за pid процесса, так что когда процесс с заданным pid завершится, tail тоже остановит работу конвейера. Потоковый tail передает потоковому (в отличии от awk) sed файл лога wget, который обрабатывает его, выцепляя нужную информацию и должным образом ее форматирует, ну и дальше текст приходит в zenity.
Немного поясню, в zenity --progress нужно подавать текст в виде:
# текст для отображения
0
# текст для отображения
10
…
где вторая строчка это число процентов. Таким преобразованием из лога wget заняты tail+sed. Дальше идет отработка ошибок или вывод всплывающего сообщения если закачка была завершена удачно, также следует переименование файла, если это требуется.
Ну вот и все, сохраняете файл где вам удобно, выставляете бит исполнения, добавляете кнопку запуска на панельку и пользуетесь или через Firefox+FlashGot отправляете задания.
И последний штрих, дабы победить Rapidshare и прочие файлообменники которые не любят перехватчиков ссылок, в файл .wgetrc добавьте такие строчки:
header = Accept-Language: ru,en-us;q=0.7,en;q=0.3
header = Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
header = Accept-Encoding: gzip,deflate
header = Accept-Charset: UTF-8,*
header = Keep-Alive: 300
header = Connection: keep-alive
user_agent = Mozilla/5.0 (X11; U; Linux i686; ru; rv:1.9.1.2) Gecko/20090804 Shiretoko/3.5.2
content_disposition = on
Юзер-агент поправьте в соответствии с вашим браузером.
Скрипт можно взять здесь: nebulosa2007.narod.ru/guiwget.tar.gz