diff options
Diffstat (limited to 'shell-rss-torrent')
-rwxr-xr-x | shell-rss-torrent | 374 |
1 files changed, 374 insertions, 0 deletions
diff --git a/shell-rss-torrent b/shell-rss-torrent new file mode 100755 index 0000000..16d416c --- /dev/null +++ b/shell-rss-torrent @@ -0,0 +1,374 @@ +#!/bin/sh + +echo " +------------------------ + SHELL RSS TORRENT v2.5 + Script by Rafostar +------------------------ +" + +INDENT1=" " +INDENT2=" " +UPPER="ABCDEFGHIJKLMNOPQRSTUVWXYZ/ĄĆĘŁŃÓŚŹŻ" +LOWER="abcdefghijklmnopqrstuvwxyz/ąćęłńóśźż" +UA="Mozilla/5.0 (Windows NT 6.1; WOW64; rv:54.0) Gecko/20100101 Firefox/72.0" + +parse_config() { + WatchDir=$(echo "$ConfigData" | xmllint --xpath "string(//config/watchdir[1]/text())" - 2> /dev/null) + if [ "$?" -ne 0 ] + then + echo "Error: invalid config file" + exit 1 + fi + + Downloader=$(xmllint_from_config "string(//config/downloader[1]/text())") + if [ ! -z "$Downloader" ] + then + echo "Using <downloader> tag command" + DwnPrint=$(xmllint_from_config "count(//config/downloader[1][@print='1'])") + + if [ -z "$WatchDir" ] + then + echo "Downloading without <watchdir> tag" + fi + else + if [ ! -z "$WatchDir" ] + then + echo "Torrents will be downloaded to: $WatchDir" + else + echo "Error: no <watchdir> in config file" + exit 1 + fi + fi + + HistoryPath=$(xmllint_from_config "string(//config/history[1]/text())") + if [ ! -z "$HistoryPath" ] + then + echo "Using download history file: $HistoryPath" + + if [ -f "$HistoryPath" ] + then + HistoryData=$(cat "$HistoryPath") + fi + fi + + TimeMax=$(xmllint_from_config "string(//config/time-max[1]/text())") + if [ ! -z "$TimeMax" ] + then + echo "Downloading releases within seconds: $TimeMax" + fi + + FeedsCount=$(xmllint_from_config "count(//config/feed)") + echo "Total feeds in config: $FeedsCount" + echo "" + + feed=1 + while [ $feed -le $FeedsCount ] + do + FeedUrl=$(xmllint_from_config "string(//config/feed[$feed]/@url)") + if [ -z "$FeedUrl" ] + then + echo "Error: feed $feed has no url" + else + FeedUser=$(xmllint_from_config "string(//config/feed[$feed]/@user)") + if [ ! -z "$FeedUser" ] + then + FeedUser="--user=$FeedUser" + fi + + FeedPass=$(xmllint_from_config "string(//config/feed[$feed]/@pass)") + if [ ! -z "$FeedPass" ] + then + FeedPass="--password=$FeedPass" + fi + + FeedData=$(wget "$FeedUser" "$FeedPass" -U "$UA" -O - "$FeedUrl" 2> /dev/null) + if [ -z "$FeedData" ] + then + FeedData=$(wget "$FeedUser" "$FeedPass" -O - "$FeedUrl" 2> /dev/null) + fi + + if [ -z "$FeedData" ] + then + echo "Error: feed $feed has no data" + else + echo "feed $feed: $FeedUrl" + + for QueryFn in "starts-with" "contains" + do + find_in_feed $feed + done + + find_in_feed_multi $feed + fi + fi + + feed=$(( feed + 1 )) + done +} + +find_in_feed() { + QueryPath="//config/feed[$1]/$QueryFn" + QueryCount=$(xmllint_from_config "count($QueryPath)") + + if [ "$QueryCount" -ge 1 ] + then + query=1 + while [ $query -le $QueryCount ] + do + find_attributes_matches $query + TorrentCount=$(xmllint_from_feed "count($Matches/link)") + echo "$INDENT1 $QueryFn $query: $QueryText, found: $TorrentCount" + + if [ "$TorrentCount" -ge 1 ] + then + get_torrents + fi + + query=$(( query + 1 )) + done + fi +} + +find_in_feed_multi() { + MultiPath="//config/feed[$1]/multi" + MultiCount=$(xmllint_from_config "count($MultiPath)") + + if [ "$MultiCount" -ge 1 ] + then + multi=1 + while [ $multi -le $MultiCount ] + do + MultiText="" + CustomFeed="" + + for QueryFn in "starts-with" "contains" + do + QueryPath="$MultiPath[$multi]/$QueryFn" + QueryCount=$(xmllint_from_config "count($QueryPath)") + + if [ "$QueryCount" -ge 1 ] + then + query=1 + while [ $query -le $QueryCount ] + do + find_attributes_matches "$query" + CustomFeed=$(xmllint_from_feed "$Matches") + + if [ ! -z "$MultiText" ] + then + MultiText="$MultiText | $QueryText" + else + MultiText="$QueryText" + fi + + if [ ! -z "$CustomFeed" ] + then + CustomFeed="<rss>$CustomFeed</rss>" + else + CustomFeed="" + echo "$INDENT1 multi $multi: $MultiText, found: 0" + break + fi + + query=$(( query + 1 )) + done + fi + done + + if [ ! -z "$CustomFeed" ] + then + get_torrents_multi $multi + CustomFeed="" + fi + + multi=$(( multi + 1 )) + done + fi +} + +find_attributes_matches() { + QueryText=$(xmllint_from_config "string($QueryPath[$1]/text())") + IgnoreCase=$(xmllint_from_config "count($QueryPath[$1][@ignore-case='1'])") + + if [ "$IgnoreCase" -eq 1 ] + then + ParsedQuery=$(xmllint_from_config "translate($QueryPath[$query]/text(), '$UPPER', '$LOWER')") + Matches="//item[title[$QueryFn(translate(., '$UPPER', '$LOWER'), '$ParsedQuery')]]" + else + Matches="//item[title[$QueryFn(., '$QueryText')]]" + fi +} + +find_torrent_attr() { + ATTR=$(xmllint_from_feed "count($Matches[$torrent]/$1)") + if [ "$ATTR" -eq 1 ] + then + ATTR_TORRENT=$(xmllint_from_feed "count($Matches[$torrent]/$1[@type='application/x-bittorrent'])") + if [ "$ATTR_TORRENT" -eq 1 ] + then + ATTR_URL=$(xmllint_from_feed "string($Matches[$torrent]/$1/@url)") + if [ ! -z "$ATTR_URL" ] + then + echo "$ATTR_URL" + fi + fi + fi +} + +get_torrents() { + torrent=1 + while [ $torrent -le $TorrentCount ] + do + TorrentLink=$(find_torrent_attr "enclosure") + + if [ -z "$TorrentLink" ] + then + TorrentLink=$(xmllint_from_feed "string($Matches[$torrent]/link/text())") + fi + + if [ ! -z "$TorrentLink" ] + then + if [ ! -z "$HistoryData" ] + then + case "$HistoryData" in + *"$TorrentLink"*) echo "$INDENT2 torrent $torrent in download history" ;; + *) try_download ;; + esac + else + try_download + fi + else + echo "$INDENT2 torrent $torrent without a link" + fi + + torrent=$(( torrent + 1 )) + done +} + +get_torrents_multi() { + TorrentCount=$(xmllint_from_feed "count($Matches/link)") + echo "$INDENT1 multi $1: $MultiText, found: $TorrentCount" + + if [ "$TorrentCount" -ge 1 ] + then + get_torrents + fi +} + +xmllint_from_config() { + RESULT=$(echo "$ConfigData" | xmllint --xpath "$1" - 2> /dev/null) + echo "$RESULT" +} + +xmllint_from_feed() { + if [ ! -z "$CustomFeed" ] + then + XmlData="$CustomFeed" + else + XmlData="$FeedData" + fi + + RESULT=$(echo "$XmlData" | xmllint --format --xpath "$1" - 2> /dev/null) + echo "$RESULT" +} + +write_to_history() { + if [ ! -z "$HistoryPath" ] + then + echo "$1" >> "$HistoryPath" + fi + + HistoryData=$(echo -e "$HistoryData\n$1") +} + +try_download() { + if [ ! -z "$TimeMax" ] + then + check_date + else + download_torrent "$TorrentLink" + fi +} + +check_date() { + DateCount=$(xmllint_from_feed "count($Matches[$torrent]/pubDate)") + if [ "$DateCount" -ge 1 ] + then + PubDate=$(xmllint_from_feed "string($Matches[$torrent]/pubDate/text())") + if [ ! -z "$PubDate" ] + then + TorrentEpoch=$(date -d "$PubDate" +%s) + CurrentEpoch=$(date +%s) + Elapsed=$((CurrentEpoch - TorrentEpoch)) + if [ "$Elapsed" -le $TimeMax ] + then + download_torrent "$TorrentLink" + else + echo "$INDENT2 torrent $torrent is too old" + fi + fi + else + download_torrent "$TorrentLink" + fi +} + +download_torrent() { + echo "$INDENT2 torrent $torrent: $1" + + if [ ! -z "$Downloader" ] + then + Title=$(xmllint_from_feed "string($Matches[$torrent]/title/text())") + + if [ "$DwnPrint" -eq 1 ] + then + eval "$Downloader "$1"" + else + eval "$Downloader "$1"" > /dev/null 2> /dev/null + fi + + if [ $? -eq 0 ] + then + write_to_history "$1" + else + echo "$INDENT1 $INDENT2 download failed" + fi + else + wget -q --content-disposition -U "$UA" -P "$WatchDir" "$1" 2> /dev/null + if [ $? -ne 0 ] + then + wget -P "$WatchDir" "$1" > /dev/null 2> /dev/null + if [ $? -eq 0 ] + then + write_to_history "$1" + else + echo "$INDENT1 $INDENT2 download failed" + fi + else + write_to_history "$1" + fi + fi +} + +ConfigPath=$1 +if [ -z "$ConfigPath" ] +then + ME=$(basename "$0") + echo "Usage: $ME <config_path>" +else + if [ -f "$ConfigPath" ] + then + XmlInstalled=$(xmllint --version > /dev/null 2> /dev/null) + if [ $? -eq 0 ] + then + ConfigData=$(cat "$ConfigPath") + parse_config + else + echo "Error: xmllint is not installed" + exit 1 + fi + else + echo "Error: file $ConfigPath does not exist" + exit 1 + fi +fi |