tags:

views:

24

answers:

1

require 'net/http';
require 'uri';
require 'rexml/document';
require 'sqlite3';

def download_torrent(episode_id, torrent_url, limit = 10)
  # Check to make sure we haven't been trapped in an infinite loop
  if limit == 0 then
    puts "Too much redirection, skipping #{episode_id}";
    return true;
  else
    # Convert the URL of the torrent into a URI usable by Net:HTTP
    torrent_uri = URI.parse(torrent_url);
    # Open a connection to the torrent URL
    Net::HTTP.get_response(torrent_uri) { |http|
      # Check to see if we were able to connect to the torrent URL
      case http
      # We connected just fine
      when Net::HTTPSuccess then
        # Create a torrent file to store the data in
        File.open("#{episode_id}.torrent", 'wb') { |torrent_file|
          # Write the torrent data to the torrent file
          torrent_file.write(http.body);
          # Close the torrent file
          torrent_file.close
          # Check to see if we've download a 'locked' torrent file (html) instead of a regular torrent (.torrent)
          if(File.exists?('download.torrent.html'))
            # Delete the html file
            File.delete('download_torrent.html');
            return false;
          else
            return true;
          end
        }
      when Net::HTTPRedirection then
          download_torrent(episode_id, http['location'], limit - 1);
      end
    }
  end
end

My function does not return 'true' in the boolean sense. It keeps returning <Net::HTTPFound:0x3186c60> which causes my 'does this function return true' conditional to evaluate to false. Why is this function not exiting when it hits the first return statement (like every other language I've used)

I know this is totally a Ruby Newbie (I Rhymed!) question, but I appreciate the help.

+1  A: 

Apparently, Net::HTTP.get_response has passed Net::HTTPFound instance as http parameter into inner block. Therefore, return statement was never reached and your download_torrent method returned the last object "on stack", which happens to be return value of Net::HTTP.get_response.

If that description is a little vague, here's a shorter example. With return true part, do_it method will return true. Without it, do_it method will return object returned by do_that.

def do_it
  do_that {|param|
#    return true;
  }
end

I have little experience with net/http package, you'll probably have to read docs and handle Net::HTTPFound response in your case operator somehow.

Personally, this always worked for me in fetching webpage contents: Net::HTTP.get(URI.parse(url)). It's simpler without code block and simply returns content as string.

Nikita Rybak