Report abuse

require 'hpricot'
require 'net/http'
require 'iconv'

require 'cgi'

require 'md5'

require 'jcode'
$KCODE = 'u'


module VKontakte
  class Cookies
    PREFIX = 'remix'.freeze

    attr_accessor :id, :email, :pass

    def initialize(user)
      @id       = user.id 
      @email    = user.email    or raise "No Email given"
      @password = user.password or raise "No password given"
    end

    def id
      @id || User.new(@email, @password).id
    end

    def pass
      MD5.new @pass
    end

    def to_hash
      %w[id email password].inject({}) {|o, v| o[PREFIX + v] = send(v)}
    end 
  end

  class Request
    DOMAIN = 'vkontakte.ru'.freeze

    attr_accessor :path

    def initialize(path = '/')
      self.path = path
    end

    def as(user)
      self.cookies = Cookies.new(user).to_hash if user
      self
    end

    def get(data = nil)
      handle {connection.get(path)}
    end
    alias to_s get

    def post(data)
      handle {
        connection.post path, data.to_params, {
          'Content-Type' => 'application/x-www-form-urlencoded',
          'User-Agent' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.1) Gecko/20060111 Firefox/1.5.0.1',
          'Referer' => "http://#{DOMAIN}/index.php"
        }
      }
    end

    private
      def connection
        @connection ||= Net::HTTP.start DOMAIN
      end

      def handle(&block)
        begin
          response = block.call
        rescue Net::HTTPBadResponse => e
          raise "Oh crap, cant handle the request because of #{e}"
        end
      end

      def convert(string)
        Iconv.iconv("UTF-8", "CP1251", string)
      end
  end

  class UserPage

    def initialize(response)

    end
  end


  class User
    attr_accessor :id, :email, :pass
    attr_accessor :authorized

    def initialize(*args)
      if (args.size == 1)
        self.id = args.first
      else
        self.email, self.pass = args
      end      
    end

    def id
      return @id if @id
      authorize
      @id
    end

    def data(response) 
      @data ||= UserPage.new(response || request('/'))
    end

    def request(url, personal)
      Request.new(url).as(personal ? self : nil)
    end

    def authorize
      self.authorized = !! send_authorization_request
    end

    def authorized?
      authorized
    end

    private 
      def send_authorization_request
        response = request('/login.php', false).post :email => email, :pass => pass
        begin
          self.id = ::CGI::Cookie.parse(response['Set-Cookie'])['remixmid'].first.to_i
        rescue
          raise "Can't sign in with #{email}:#{pass}"
        end
        data(response)
        self.id
      end

  end

end