X-Git-Url: http://gitweb.michael.orlitzky.com/?a=blobdiff_plain;f=src%2Fwebsites%2Fredtube.rb;h=825a4ea727c9d476b20925cb18a855dfa328302f;hb=f1d848bba50556746c3fb28f854ffee09b6f2d0c;hp=9ecdceccd7d1575a0167d3d84738a048b10fba3a;hpb=168ef3b2ccf5b97d561a3c542a18e8e7587de291;p=dead%2Fwhatever-dl.git diff --git a/src/websites/redtube.rb b/src/websites/redtube.rb index 9ecdcec..825a4ea 100644 --- a/src/websites/redtube.rb +++ b/src/websites/redtube.rb @@ -14,25 +14,11 @@ # GNU General Public License for more details. # # http://www.fsf.org/licensing/licenses/gpl.html -# -# -# NOTE: -# -# All credit belongs to whomever reverse-engineered the Redtube -# Flash applet in the first place. I took the algorithm from this -# script: -# -# http://userscripts.org/scripts/review/8691 -# -# and merely cleaned it up a bit while porting it to Ruby. -# -# The Redtube class needs the extra string methods.. -require 'src/string' require 'src/website' +require 'cgi' + -# This class handles the algorithm magic needed to get -# the URL from a Redtube video id. class Redtube < Website VALID_REDTUBE_URL_REGEX = /^(http:\/\/)?(www\.)?redtube\.com\/(\d+)$/ @@ -42,89 +28,30 @@ class Redtube < Website end - # The only public method. This calls the other parts - # of the algorithm and, with any luck, we wind up with - # the URL to the video. - def get_video_url(url) - # First, parse the video ID out of the URL. - video_id = /\d+/.match(url)[0] - - padded_id = video_id.to_s.pad_left('0', 7) - - video_dir = self.get_video_dir(video_id) - file_name = self.get_file_name(padded_id) - - # This mess is actually the only directory out of - # which they serve videos. - return 'http://dl.redtube.com/_videos_t4vn23s9jc5498tgj49icfj4678/' + - "#{video_dir}/#{file_name}" + def get_video_url() + page_data = self.get_page_data(@url) + return self.parse_hashlink(page_data) end - - protected - VIDEO_FILE_EXTENSION = '.flv' - - # Not sure what they're thinking with this one. - def get_video_dir(video_id) - return (video_id.to_f / 1000.0).floor.to_s.pad_left('0', 7) - end + protected; - - # The first part of the algorithmic magic. Multiply each - # digit of the padded video id by the index of the - # following digit, and sum them up. - def int_magic(padded_video_id) - ret = 0 - - 0.upto(6) do |a| - ret += padded_video_id[a,1].to_i * (a+1) - end - - return ret + def parse_video_id() + return /\d+/.match(@url)[0] end - # Part 2 of the magic. Sum the digits of the result - # of the first magic. - def more_magic(file_string) - magic = self.int_magic(file_string).to_s - - ret = 0 - - 0.upto(magic.length - 1) do |a| - ret += magic[a,1].to_i - end - - return ret - end - + def parse_hashlink(page_data) + hashlink_regex = /hashlink=([^&]+)&/ - # Complete fricking mystery - def get_file_name(file_string) - map = ['R', '1', '5', '3', '4', '2', 'O', '7', 'K', '9', 'H', 'B', 'C', 'D', 'X', 'F', 'G', 'A', 'I', 'J', '8', 'L', 'M', 'Z', '6', 'P', 'Q', '0', 'S', 'T', 'U', 'V', 'W', 'E', 'Y', 'N'] + matches = hashlink_regex.match(page_data) - # The stupid variable names I copied from the - # source script. Considering myself disclaimed. - my_int = self.more_magic(file_string) - new_char = '0' + my_int.to_s - - if my_int >= 10 then - new_char = my_int.to_s + if matches.nil? + raise StandardError.new("Could not parse the 'hashlink' Flash variable.") end - - file_name = map[file_string[3] - 48 + my_int + 3] - file_name += new_char[1,1] - file_name += map[file_string[0] - 48 + my_int + 2] - file_name += map[file_string[2] - 48 + my_int + 1] - file_name += map[file_string[5] - 48 + my_int + 6] - file_name += map[file_string[1] - 48 + my_int + 5] - file_name += new_char[0,1] - file_name += map[file_string[4] - 48 + my_int + 7] - file_name += map[file_string[6] - 48 + my_int + 4] - file_name += VIDEO_FILE_EXTENSION - - return file_name - end + # The hashlink variable /is/ the video URL, but it's encoded. + return CGI::unescape(matches[1]) + end + end