+++ /dev/null
-#
-# Copyright Michael Orlitzky
-#
-# http://michael.orlitzky.com/
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# http://www.fsf.org/licensing/licenses/gpl.html
-#
-
-require 'src/website'
-
-class Megaporn < Website
-
- VALID_MEGAPORN_URL_REGEX = /^(http:\/\/)?(www\.)?(megaporn|megavideo)\.com\/video\/\?v=[[:alnum:]]+$/
-
- def self.owns_url?(url)
- return url =~ VALID_MEGAPORN_URL_REGEX
- end
-
-
- def get_video_filename
- # Just use the video id.
- id_regex = /v=([[:alnum:]]+)/
- matches = id_regex.match(@url)
-
- if (matches.nil? || matches.length < 2)
- return 'default.flv'
- else
- return (matches[1] + '.flv')
- end
- end
-
-
- def get_video_url()
- data = get_page_data(@url)
-
- # Megaporn attaches a numeric suffix to their 'www'
- # hostname that (I suppose) is necessary to find the
- # video file. The suffix is simply provided as a flash
- # variable, though.
- host_suffix = parse_flash_variable(data, 's')
-
- # There are also two or three keys, sent as Flash variables,
- # that are used in the "decryption" routine. We get integers
- # to be on the safe side.
- key1 = parse_flash_variable(data, 'k1').to_i
- key2 = parse_flash_variable(data, 'k2').to_i
-
- # This is a magic hex string, passed to the decryption
- # routine along with key1 and key2.
- seed = parse_flash_variable(data, 'un')
-
- secret_path = self.decrypt(seed, key1, key2)
-
- # Note that the path to the video file looks like a folder.
- # We need to remember to save it as a file.
- return "http://www#{host_suffix}.#{self.domain}/videos/#{secret_path}/"
- end
-
-
- protected
-
- def domain
- # I'm guessing they serve videos from both of these domains.
- if (@url.include?('megavideo.com'))
- return 'megavideo.com'
- else
- return 'megaporn.com'
- end
- end
-
-
- def parse_flash_variable(data, variable_name)
- # The Flash variables differ only in name, so this method can
- # parse them all.
- var_regex = /flashvars\.#{variable_name} = \"(.+?)\"/
- matches = var_regex.match(data)
-
- if (matches.nil? || matches.length < 2)
- raise StandardError.new("Could not parse Flash variable: #{variable_name}.")
- end
-
- return matches[1]
- end
-
-
- def string_to_binary_array(target_string)
- binary_array = []
-
- target_string.each_char do |c|
- binary_int = c.to_i(16).to_s(2).to_i
- binary_char = sprintf('%04d', binary_int)
- binary_char.each_char do |bc|
- binary_array << bc
- end
- end
-
- return binary_array
- end
-
-
- def binary_words_to_hex(target_array)
- hex = ''
-
- target_array.each do |word|
- hex << word.to_i(2).to_s(16)
- end
-
- return hex
- end
-
-
- def decrypt(seed, key1, key2)
- # I reverse-engineered this one myself. Suck it, megaporn.
- #
- # Round 1. Convert the seed to its binary reprentation,
- # storing each bit as an element of an array.
- loc1 = string_to_binary_array(seed)
-
- # Round 2
- loc6 = []
- key1 = key1.to_i
- key2 = key2.to_i
- 0.upto(383) do |loc3|
- key1 = (key1 * 11 + 77213) % 81371
- key2 = (key2 * 17 + 92717) % 192811
- loc6[loc3] = (key1 + key2) % 128
- end
-
-
- # Round 3
- 256.downto(0) do |loc3|
- loc5 = loc6[loc3]
- loc4 = loc3 % 128
- loc8 = loc1[loc5]
- loc1[loc5] = loc1[loc4]
- loc1[loc4] = loc8
- end
-
-
- # Round 4
- 0.upto(127) do |loc3|
- loc1[loc3] = (loc1[loc3].to_i ^ loc6[loc3 + 256]) & 1
- end
-
-
- # Round 5
- loc12 = loc1.to_s
- offset = 0
- loc7 = []
- while (offset < loc12.length)
- loc7 << loc12[offset, 4];
- offset += 4
- end
-
-
- # Round 6
- return binary_words_to_hex(loc7)
- end
-
-
-end