Satoko.rb
this is a axel wrapper that will crawl a http file directory and parse it for downloadable content and feed the links to axel back to back.
has a file directory listing to tell you which files are completed. outputs download speed from axel directly, and has a hacked on resume function.
usage: ruby satoko.rb "directory to download" <integer>
the integer tells the crawler how many files to skip before feeding it to axel, in case axel dies and you have to restart.
beware, this works but the code is a complete mess.
Code
require 'net/http'
require 'uri'
require 'cgi'
require 'pty'
def print_table( table )
listing = 0
length = 0
table.each do |file|
next if file.empty?
length = file[:name].length unless length > file[:name].length
end
table_width = ENV['COLUMNS'].to_i / (length + 30)
format = "%-#{length}s"
table.each do |file|
next if file.empty?
print "[*] File: "
print format % file[:name]
print " -> Completed: %-#{3}s" % file[:complete]
if listing.eql? table_width
print "\n"
listing = 0
else
print " "
listing += 1
end
end
end
def uri_escape( uri )
URI.escape uri
uri.gsub! "]", "%5D"
uri.gsub! "[", "%5B"
end
#################################################################
#################################################################
#################################################################
exit unless ARGV.length > 0
url = 'http://www.petfo.net/dds/'
anime = uri_escape ARGV[0]
filenum = ARGV[1].to_i unless ARGV[1].empty?
files = []
uri = URI.parse("#{url}#{anime}/".strip)
http = Net::HTTP.new( uri.host, uri.port )
request = Net::HTTP::Get.new( uri.request_uri )
puts 'Grabbing file listings...'
response = http.request(request)
response.body.each_line do |line|
arr = line.scan /(".*?")/
next if arr.empty? or arr.last.include? "\"/dds/\"" or arr.last.include? "\"-//W3C//DTD HTML 3.2 Final//EN\""
name = arr.last.to_s[4..-5]
hash = {:name => CGI.unescape(name), :url => URI.unescape("#{url}#{anime}/#{name}"), :complete => "No"}
files.push hash
end
files.push "" unless files.length.modulo(2).eql? 0
anime = URI.unescape(anime)
1.upto(filenum) { files.shift } if filenum.is_a? Fixnum
puts 'Grabbed file listings!'
puts 'Starting downloads in 3 seconds...'
sleep 3
files.each_index do |index|
begin
PTY.spawn "axel -n 12 \"#{files[index][:url]}\"" do |stdout, stdin, pid|
begin
stdout.each do |line|
next unless line.include? "["
puts "\e[H\e[2J"
print_table files
puts "\n\n"
puts "Server: #{url}"
puts "Anime: #{anime}"
puts "Current file: #{files[index][:name]}"
puts "\n"
puts line
end
rescue Errno::EIO
end
end
rescue PTY::ChildExited
end
files[index][:complete] = "Yes"
end