Архивы по Категориям: Scriptz

Очередная качалка торрентов с lostfilm.tv

Предыстория.

Я давно написал bash-скрипт для парсинга и загрузки с лостфильма торрентов нужных мне сериалов. Работал он как часы, и поэтому я был настолько уверен в своём творении, что даже не удивлялся отсутствию новых серий последние пару месяцев. А оказывается как раз пару месяцев назад на сайте поменялся дизайн, вёрстка и многое другое. Об этих изменениях узнал случайно — пришла рассылка, что, мол, мы изменили дизайн сайта и всё такое. Я из интереса зашёл на сайт посмотреть и обнаружил, что есть новые серии сериалов, которые у меня почему-то не скачались. Сел рыть дальше и понял, что надо переделывать скрипт. Поменялось многое.

Результатом хочу поделиться. Может кому ещё сгодится. После тела скрипта будет разбор полётов, что там и к чему.

#!/bin/bash

# lostfilm.tv smart rss parser and torrent downloader, version 2.2
# 2017.04.03 by jack
# required external programs: curl, wget, lynx

INPUT="/home/jack/.rtorrent.rc"
OUTPUT="/data/video"
LYNX="eval lynx -nonumbers -stdin -dump -listonly -hiddenlinks=ignore|uniq"

LC_ALL=c wget --timeout=5 --tries=1 --timestamping -P /tmp http://www.lostfilm.tv/rss.xml 2>&1 >/dev/null|grep -q "not retrieving"
if [[ ${PIPESTATUS[0]} -ne 0 || ${PIPESTATUS[1]} -eq 0 ]]; then exit; fi

for LINE in `grep -o 'video.*torrent' $INPUT`; do
    STRING=`expr $LINE : '.*\(/.*\.\)'`                          # extract everything between / and .
    SERIAL=${STRING//[!a-z]/}                                    # remove everything except [a-z]
    STRINGS=`egrep "series.*$SERIAL" /tmp/rss.xml`               # search for link with serial in rss
    if [[ -n $STRINGS ]]; then
        for STRING in $STRINGS; do
            STRING=${STRING//}; LINK=${STRING/<\/link>/}         # clean link from  and  tags
            STRING=${LINK//[!0-9]/ }                             # remove from link everything except digits
            set $STRING; SEASON=$1; EPISODE=$2                   # get season and episode
            STRING=`curl -sL $LINK|egrep -o 'PlayEpisode\(.*\)'` # search on the page string with serial id
            STRING=${STRING//[!0-9]/ }                           # remove everything except digits
            set $STRING; SERIALID=$1                             # get serial id
            URL_REDIRECT=`curl -sLb "lf_session=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" "http://www.lostfilm.tv/v_search.php?c=${SERIALID}&s=${SEASON}&e=${EPISODE}"|$LYNX`
            URL_TORRENT=`curl -sL $URL_REDIRECT|$LYNX|head -2|tail -1|sed 's/+/%2B/g'`
            wget -q -nc --content-disposition -P $OUTPUT $URL_TORRENT
#            echo -e "$SERIAL $SERIALID $SEASON $EPISODE\n$LINK\n$URL_REDIRECT\n$URL_TORRENT"
        done
    else
        rm -f $OUTPUT/*$SERIAL*.torrent
    fi
done

Итак, для начала список сериалов берётся из конфига rtorrent. Интересующие нас строки там имеют вид:

schedule = watch_directory_6,0,5,"load_start=/data/video/Vikings*.torrent,d.set_directory=/data/video/Vikings"

Если кому интересно, расшифрую: rtorrent каждые 5 секунд проверяет каталог /data/video на предмет появления в нём файлов Vikings*.torrent. Как только появляется такой файл, он добавляется в загрузку, а данные из торрента качаются в каталог /data/video/Vikings.

Конечно, этот конфиг не является обязательным. Список сериалов можно передать в виде списка из внешнего файла или прямо в теле скрипта. Единственное условие — это должно быть одно слово, и такое, чтобы уникально идентифицировать только один сериал. Мне так удобнее, так как я указываю сериалы только в одном файле. Для сравнения в первой версии скрипта у меня было два списка.

Идём дальше. Переменная OUTPUT задаёт каталог, куда будут складываться скачанные торрент-файлы. По описанию выше ясно, зачем я так делаю.

Третьим важным входным параметром является куки lf_session для авторизации на сайте. Без неё торрент-файл не получить. Я брал её из браузера после авторизации. В старой версии сайта название куки было другим и их было два. Теперь стало проще. Кука действует до 2038 года, так что хватит надолго.

На этом из самого необходимого вроде как всё.

Теперь, для тех, кого интересует bash-программирование, хочу немого остановиться на логике. Может мои решения не самые оптимальные, но они могут дать пищу для размышлений и отправную точку для дальнейшего усовершенствования скрипта или использования идей в других решениях.

Итак, всё начинается с загрузки rss-ленты. Скрипт выполняется по крону каждые 15 минут. Чтобы не тиранить почём зря сервер лостфильма, я не качаю файл полностью, а для начала только проверяю его временную метку. За это отвечает параметр timestamping в wget. Если файл не менялся, он не скачивается и скрипт завершает свою работу (exit). Это проверяется наличием в выхлопе wget’а фразы «not retrieving». LC_ALL=c перед вызовом нужно потому, что если wget локализован, ответ будет на соответствующем языке и grep’ать нужно будет другую фразу.

Два PIPESTATUS нужны для того, чтобы завершить скрипт по двум причинам: файл не удалось скачать (проверить его временную метку) или он не изменился. Первое может быть вызвано кучей причин: сайт лежит, нет сети, файл более недоступен по данному адресу и т.п. Второе описано выше.

lynx используется сугубо для выдирания гиперссылок из html-страницы. Решение топорное, но писать свой парсер html мне очень не хотелось.

Важным моментом является определение переменной URL_TORRENT. Это фактически ссылка на торрент-файл. Лостфильм обычно даёт для каждой серии три варианта: SD, HD и FullHD (480p, 720p и 1080p соответственно). Я качаю сугубо 1080p. Поэтому конструкция из head и tail выбирает из списка только одну ссылку. Можно подкрутить это место так, чтобы качались, например, все три варианта или только 720p. Но это уже кому как захочется.

Также здесь важным является замена плюсов в ссылке на %2B. Как я не экранировал это дело, так и не смог добиться того, чтобы bash не бил ссылки из-за плюсов в них. В итоге такой вот костыль.

Чтобы скрипт не качал торрент повторно, если он уже есть в каталоге назначения, wget’у передается параметр -nc (no-clobber). То есть если в ленте была серия одного сериала (и она уже была скачана) и появилась ещё одна, то скачается торрент-файл только новой серии. Хотя здесь может получиться накладка. Честно говоря, не знаю, как отработает скрипт, если в ленте будет несколько серий сериала. Надо будет проверить это дело. Таки да, была проблема. Добавил ещё один цикл. Теперь из rss-ленты качаются все серии сериала.

Вывод переменных echo нужен только для отладки.

Поскольку список серий идёт в rss как по конвейеру, то когда сериал выпадает из ленты, соответствующие торрент-файлы этого сериала удаляются из каталога назначения (rm -f). У меня настроена 5-кратная раздача торрентов, после чего они останавливюется. Торрент-файл, соответственно, больше не нужен. Таким образом rtorrent не захлямляется тоннами старых раздач. Если кто-то хочет вручную контролировать удаление торрентов, могут переделать на своё усмотрение.

UPD: чуток подправил скрипт, так как из-за обновления то ли lynx, то ли сайта, скачивался торрент на SD-качество, а не FullHD.

Простенький скрипт для управления XBMC из консоли

#!/bin/bash

case "$1" in
    on)
        wakeonlan -i 192.168.2.255 00:01:2E:2B:C0:98
    ;;
    off)
        echo '{ "jsonrpc": "2.0", "method": "System.suspend", "id": 1 }' | nc zorg 9090 -w1
    ;;
    check)
        echo '{ "jsonrpc": "2.0", "method": "JSONRPC.Ping", "id": 1 }' | nc zorg 9090 -w1
    ;;
    *)
    echo "Usage: $0 on|off|check"
esac

MRTG без SNMP: скрипты для сбора данных + конфиг

mrtg_cpu.sh
#!/bin/sh
DATA=`vmstat 1 2 | tail -n1`
echo $DATA | awk '{print $14}'
echo $DATA | awk '{print $13}'





mrtg_disk.sh #!/bin/sh DATA=`df -B1 | grep $1` echo $DATA | awk '{print $3}' echo $DATA | awk '{print $2}'
mrtg_la.sh #!/bin/sh DATA=`cat /proc/loadavg` FIRST=`echo $DATA | cut -d" " -f1` SECOND=`echo $DATA | cut -d" " -f3` echo $FIRST*100 | bc echo $SECOND*100 | bc
mrtg_mem.sh #!/bin/sh DATA=`free -b | grep Mem` echo $DATA | awk '{print $3}' echo $DATA | awk '{print $7}'
mrtg_net.sh #!/bin/sh DATA=`grep $1 /proc/net/dev` echo $DATA | awk '{print $2}' echo $DATA | awk '{print $10}'
mrtg_uptime.sh #!/bin/sh DATA=`cat /proc/uptime | awk '{print $1}'` echo $DATA/\(60*60*24\)|bc echo $DATA/\(60*60*24\)|bc
 

Читать далее »

psplinker — воссоздание структуры паков с PSP-играми для раздачи на bitGAMER и PS2PTT

#!/bin/sh

prepare() {
    DIR=/media
    cd $DIR/ext2

    rm -fr psp
    mkdir psp
    for i in $DIR/fat32/psp/*/*; do
      ln -s $i ./psp/`basename $i`
    done
    echo "«psp» catalog was rebuilt"
}

bG() {
    echo "bG packs"
    for PUCK in .bG/*; do
      PACK=`basename $PUCK`
      rm -fr $PACK
      mkdir $PACK
      for RLZ in $(cat $PUCK); do
        find $DIR/ext2/psp -type l -name "$RLZ" -exec ln -s '{}' "$PACK"/$RLZ \;
      done
      echo $PACK
    done
}
PS2PTT() {
    echo "PS2PTT packs"
    for PUCK in .PS2PTT/*; do
      PACK=`basename "$PUCK"`
      rm -fr "$PACK"
      mkdir "$PACK"
      for RLZ in $(cat "$PUCK"); do
        find $DIR/ext2/psp -type l -name "$RLZ" -exec ln -s '{}' "$PACK"/"$RLZ" \;
      done
      echo $PACK
    done
}

case "$1" in
    rebuild)
	prepare
	;;
    bG)
	bG
	;;
    PS2PTT)
	PS2PTT
	;;
    *)
        echo "Usage: psplinker.sh {rebuild|bG|PS2PTT}" >&2
        exit 3
        ;;
esac

Обновление данных для mdk.jack.kiev.ua

mdk.jack.kiev.ua — это мой проект, где собирается и обрабатывается статистика переводов утилит для Mandriva Linux.

Работает эта статистика на скриптах l10n-stats v3.0 из проекта KDE. Однако для правильной работы этих скриптов структуру переводов Mandriva необходимо подогнать под структуру проекта переводов KDE, что и выполняется моим скриптом. Читать далее »

mailcheck.vbs v1.2

Проверка почты в Gmail из командной строки

До недавнего времени я успешно мониторил почтовый ящик с помощью gkrellm for windows, который в отличие от многих других программ проверки почты корректно работал с IMAP-ящиком Google Apps.

Но вот беда, gkrellm окончательно достал меня своими постоянными утечками памяти, приводившими к ежедневным многократным вылетам программы. В итоге я заменил его свежей версией winbar‘а. Но оставаться без монитора почты я не мог…

После перебора всевозможных программ проверки почты и отметания их одной за одной из-за того, что практически ни одна из этих программ не умела общаться с IMAP-сервером по SSL-протоколу, а те что умели, почему-то не могли пройти авторизацию на гугле. В общем начал я тогда гуглить проверку почты из командной строки и наконец наткнулся на хабре на весьма интересное решение, основанное на выгребании rss-ленты ящика по https с последующим разбором полученных данных.

В качестве реализации была выбрана связка из командной строки, curl.exe, grep.exe и VScript. Пришлось основательно попотеть над VB-скриптом, но результат того стоит. В общем конечный скрипт см. в продолжении статьи.

Читать далее »

fakeclicker 1.3

решил наконец-то выложить в паблик РАБОЧУЮ версию скрипта для накручивания кликов в различного рода голосовалках
«рабочая» означает, что в данный момент он отрабатывает каждую ночь по крону

в коде есть закомментированные строки (не комментарии!), об истории появления которых я бы хотел рассказать

Читать далее »

cuetter.sh

cuetter.sh — это скрипт, написанный на bash, и предназначенный для преобразования в cue-формат файлов со списком треков из больших миксов. Cue-файлы позволяют видеть в проигрывателе (например, amaroK’е или foobar’e) какой именно трек в миксе сейчас играет. Более подробную информацию о cue sheet’ах можно найти на википедии.

Чтобы скрипт создал правильный cue-файл, записи в треклистинге должны иметь определённый формат:
ВРЕМЯ — НОМЕР ТРЕКА — ИСПОЛНИТЕЛЬ — НАЗВАНИЕ ТРЕКА

ВРЕМЯ имеет формат ММ:СС, например 05:37
НОМЕР ТРЕКА — двузначное число, типа 01, 02 и т.д.

Название файла так же несёт определённый смысл:
ИСПОЛНИТЕЛЬ — НАЗВАНИЕ МИКСА.txt

запускается и работает скрипт очень просто:

$ cuetter "Arkon - Live @ Showcase.txt"

В результате выполнения скрипта в текущем каталоге появится файл «Arkon — Live @ Showcase.cue»
Если автором всех треков в миксе является один исполнитель, тогда из полученного cue-файла имеет смысл удалить все записи PERFORMER «Arkon» самой первой (в первой строке). Если же исполнители разные, то нужно удалить только самую первую строку PERFORMER «Arkon», иначе foobar будет ругаться на неверный формат файла (amaroK’у все эти заморочки пополам).

Ну и собственно, текст скрипта:

#!/bin/sh

FILENAME=`basename "$1" .txt`

echo $FILENAME | awk \
'BEGIN  { FS = " - " }
        {
#        print "PERFORMER \""$1"\""
        print "TITLE \""$1" - "$2"\""
        print "FILE \""$1" - "$2".mp3\" MP3"
        }' > $FILENAME.cue

awk \
'BEGIN  { FS = " - " }
        {
        print "  TRACK "$2" AUDIO"
        print "    TITLE \""$4"\""
        print "    PERFORMER \""$3"\""
        print "    INDEX 01 "$1":00"
        }' "$1" >> $FILENAME.cue