#!/usr/bin/perl use strict; use Irssi; use File::Copy; use warnings; use vars qw($VERSION %IRSSI $authkey $torrent_pass $channel $botname $botaddr $tmp_dir $watch_dir $log_file $retry $leave_fail @AoH); $VERSION = "1.3.1-btn"; %IRSSI = ( authors => 'engywook - heavily modified by jctwda - modified by ScarS, deadeamil', contact => 'none', name => 'tdl-btn', description => 'downloads files from bot announces', license => 'free' ); $authkey = "asdf"; # your authkey variable retrieved from the rss link $torrent_pass = "asdf"; # your torrent pass retrieved from your download link $channel = "#BTN-WhatAuto"; $botname = "Barney"; $botaddr = "4505\@Barney.Bot.BroadcasThe.Net"; $tmp_dir = "/rtorrent/tmp/"; # temp dir for torrent downloading before moving to watchdir $watch_dir = "/rtorrent/watch/btn/"; # your torrentclient watchdir $log_file = ""; # path to logfile if you want an output of what happened while retrieving the torrent $retry = 3; # number of times to retry to download the torrent $leave_fail = 0; # leave the .torrent file in the tmp_dir when it fails (use to read contents to find out why it fails) # this will cause DUPE errors though (and if it does not it means the download failed) @AoH = ( # { # Settings for each filter to be used. required: setting and one of cat, filter, or except # cat => "", # resolution - sd, 720p, 1080p, 1080i, portable device # filter => "", # match what to download (case insensitive) # except => "", # match what to except from download match (case insensitive) # type => "", # season/episode # contain => "", # container type: mkv, avi, ts, etc # codec => "", # xvid, divx, x264, h.264, wmv # source => "", # hdtv, pdtv, dsr, dvdrip, bluray, web # fast => "", # fasttorrent Yes/No # scene => "", # scene torrent Yes/No # lang => "", # language - English, French, etc # setting => "" # setting used to enable/disable the filter with /set btn_setting ON/OFF # }, { # download everything, most likely used for testing purposes filter => ".*", setting => "debug" }, { # 720p x264 All DL cat => "720p", except => "internal|dubbed|flemish|swedish|german|french|dutch|nba|nhl", type => "episode", contain => "mkv", codec => "x264", fast => "yes", scene => "yes", setting => "x264_all" }, { # SD XViD All DL cat => "SD", except => "internal|dubbed|flemish|swedish|german|french|dutch|nba|nhl|nfl|espn|ncaa|w4f|nrl|wlt", type => "episode", contain => "avi", codec => "xvid", fast => "yes", scene => "yes", setting => "xvid_all" }, { # 720p x264 Select DL cat => "720p", filter => "^(Human.Target|Modern.Family|House|NCIS|Glee|Chuck|Weeds|Castle|Treme)", except => "internal|WEB-DL", type => "episode", contain => "mkv", codec => "x264", fast => "fast", scene => "yes", lang => "English|French", setting => "x264" } ); #DO NOT EDIT BELOW THIS LINE UNLESS YOU KNOW WHAT YOUR ARE DOING. $watch_dir .= $watch_dir =~ '/$' ? '' : '/'; $tmp_dir .= $tmp_dir =~ '/$' ? '' : '/'; sub getdata { my ($server, $msg, $nick, $address, $target) = @_; my $clean = Irssi::strip_codes($msg); if (lc($target) eq lc($channel) && lc($nick) eq lc($botname) && lc($address) eq lc($botaddr) && Irssi::settings_get_bool('btn_dls')) { if ($clean =~ /([^\|]*) \| (?:AutoFillFail|S(?:eason )?(\d+)(?:E(\d+))?|[^\|]*) \| (Episode|Season) \| (\d+) \| (AVI|MKV|VOB|MPEG|MP4|ISO|WMV|TS|M4V|M2TS|---) \| (XViD|x264|MPEG2|DiVX|DVDR|VC-1|h.264|WMV|BD|---) \| (HDTV|PDTV|DSR|DVDRip|TVRip|VHSRip|Bluray|BDRip|BRRip|DVD5|DVD9|HDDVD|WEB|BD5|BD9|BD25|BD50|Mixed|Unknown|---) \| (SD|720p|1080p|1080i|Portable Device|---) \| (Yes|No) \| (Yes|No) \| (\d+) \| Anonymous \| ([^\|]*)(?:\| (.*))?/) { match($14, $9, $12, $10, $4, $6, $7, $8, $11, $13); } } } sub match { my ($torrent_name, $torrent_category, $torrent_id, $torrent_scene, $torrent_type, $torrent_contain, $torrent_codec, $torrent_source, $torrent_fast, $torrent_lang) = @_; for my $i ( 0 .. $#AoH ) { my ($cat, $filter, $except, $type, $contain, $codec, $source, $scene, $fast, $setting, $lang) = ""; for my $key (keys %{$AoH[$i]}) { if ($key eq "cat") { $cat = $AoH[$i]{$key}; } elsif ($key eq "filter") { $filter = $AoH[$i]{$key}; } elsif ($key eq "except") { $except = $AoH[$i]{$key}; } elsif ($key eq "type") { $type = $AoH[$i]{$key}; } elsif ($key eq "contain") { $contain = $AoH[$i]{$key}; } elsif ($key eq "codec") { $codec = $AoH[$i]{$key}; } elsif ($key eq "source") { $source = $AoH[$i]{$key}; } elsif ($key eq "scene") { $scene = $AoH[$i]{$key}; } elsif ($key eq "fast") { $fast = $AoH[$i]{$key}; } elsif ($key eq "setting") { $setting = $AoH[$i]{$key}; } elsif ($key eq "lang") { $lang = $AoH[$i]{$key}; } } # skip null set next if (!($cat || $except || $filter)); # skip disabled filters next if ($setting && !Irssi::settings_get_bool("btn_" . $setting)); # torrent_category and cat not match next if ($cat && $torrent_category !~ qr/$cat/i); # torrent_name match except next if ($except && $torrent_name =~ qr/$except/i); # type, contain, codec, source, fast matching, scene, language not match next if ($type && $torrent_type !~ qr/$type/i); next if ($contain && $torrent_contain !~ qr/$contain/i); next if ($codec && $torrent_codec !~ qr/$codec/i); next if ($source && $torrent_source !~ qr/$source/i); next if ($fast && $torrent_fast !~ qr/$fast/i); next if ($scene && $torrent_scene !~ qr/$scene/i); next if ($lang && $torrent_lang !~ qr/$lang/i); # torrent_name and filter not match next if ($filter && $torrent_name !~ qr/$filter/i); # torrent release has an invalid name if ($torrent_name =~ /[^A-Za-z0-9\)\(\s_.-]/) { print CRAP "BTN WARNING: invalid char in release ($torrent_name)"; return; } # torrent_id is invalid if ($torrent_id =~ /[^0-9]/) { print CRAP "BTN WARNING: invalid char in id ($torrent_id) of release ($torrent_name)"; return; } my $msg = "[%M$torrent_type/$torrent_category%n] %W$torrent_name%n"; download($torrent_name . ".torrent", $torrent_id, $msg, $retry); last; } } sub download { my ($torrent, $torrent_id, $msg, $retry) = @_; if (-s $tmp_dir . $torrent || -s $watch_dir . $torrent) { print CRAP "BTN DUPE: $msg"; } else { my $opt_log = $log_file ? "-v --append-output='". $log_file . "'" : "-q"; my $url = $opt_log . " --no-check-certificate -O '" . $tmp_dir . $torrent . "' 'https://broadcasthe.net/torrents.php?action=download&id=" . $torrent_id . "&authkey=" . $authkey . "&torrent_pass=" . $torrent_pass . "'"; system("wget $url &"); Irssi::timeout_add_once(2000, 'download_check', \@_); } } sub download_check { my @args = @{$_[0]}; my ($torrent, $torrent_id, $msg, $retry) = @args; my $ret = system("ps x | grep wget | grep 'id=$torrent_id' | grep -v grep > /dev/null"); if ($ret eq 0) { Irssi::timeout_add_once(2000, 'download_check', \@args); return; } $ret = 0; if (valid_torrent($tmp_dir . $torrent)) { $ret = move($tmp_dir . $torrent, $watch_dir . $torrent); if (!$ret) { print CRAP "BTN MOVE FAIL: $msg"; return; } } $msg = ($ret ? "DL: " : "FAIL: ") . $msg; print CRAP "BTN " . $msg; if (!$ret) { if ($retry > 0) { $retry--; $args[3] = $retry; Irssi::timeout_add_once(10000, 'download_wrap', \@args); } unlink($tmp_dir . $torrent) if (!$leave_fail); } } sub download_wrap { my ($torrent_name, $torrent_id, $msg, $retry) = @{$_[0]}; download($torrent_name, $torrent_id, $msg, $retry); } sub valid_torrent { my ($torrent) = @_; my ($fh, $buff); my $ret = 0; return 0 if (-z $torrent || !-r $torrent); open($fh, $torrent); read($fh, $buff, 11); close($fh) or die "$fh: $!"; $ret = 1 if ($buff eq "d8:announce"); return $ret; } for my $i ( 0 .. $#AoH ) { for my $key (keys %{$AoH[$i]}) { if ($key =~ /setting/ && $AoH[$i]{$key}) { Irssi::settings_add_bool($IRSSI{'name'}, "btn_" . $AoH[$i]{$key}, 1); } } } Irssi::settings_add_bool($IRSSI{'name'}, 'btn_dls', 1); Irssi::signal_add("message public", \&getdata);