From 3a8aa504b7ab41a3d64903335f3b0bc5e57e212b Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Thu, 1 Apr 2010 18:53:27 -0400 Subject: [PATCH] Update the Redtube class. It is no longer necessary to perform magic rituals prior to calculating the video URL. --- src/websites/redtube.rb | 134 +++------------------------------------- 1 file changed, 9 insertions(+), 125 deletions(-) diff --git a/src/websites/redtube.rb b/src/websites/redtube.rb index 3b1a4fa..f65e8ad 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,132 +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() - # First, parse the video ID out of the URL. - video_id = parse_video_id() - - 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) - page_data = self.get_page_data(@url) - - # As far as I know, the MP4s don't work yet. - # So just default to the FLV. - top_secret_hash = parse_hash_flv(page_data) - - return 'http://dl.redtube.com/' + - self.get_root_server_dir() + - "/#{video_dir}/#{file_name}" + - top_secret_hash - end - - - def get_video_filename() - # Mildly redundant. - video_id = parse_video_id() - padded_id = video_id.to_s.pad_left('0', 7) - - return self.get_file_name(padded_id) + return self.parse_hashlink(page_data) end protected; - VIDEO_FILE_EXTENSION = '.flv' - def parse_video_id() return /\d+/.match(@url)[0] end + def parse_hashlink(page_data) + hashlink_regex = /hashlink=([^"]+)"/ - def parse_hash_flv(page_data) - # Hashes are generated for both flv/mp4 and are delivered - # along with the video page. We need to stick them back on - # the end of the final video URL, or else it doesn't work. - hash_flv_regex = /&hash_flv=(\/.*?)&/ - - matches = hash_flv_regex.match(page_data) + matches = hashlink_regex.match(page_data) if matches.nil? - raise StandardError.new("Couldn't parse the hash_flv variable.") + raise StandardError.new("Could not parse the 'hashlink' Flash variable.") end - return matches[1] - end - - - def get_root_server_dir() - # They hard code this shit into the SWF file. - return '467f9bca32b1989277b48582944f325afa3374' + # The hashlink variable /is/ the video URL, but it's encoded. + return CGI::unescape(matches[1]) end - # 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 - - - # 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 - 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 - - - # 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'] - - # 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 - 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 - - end -- 2.43.2